diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 881d8460710..827538cea99 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -355,3 +355,4 @@ c7be2a78c31b3b6132f2f5e9e4b3d3bb1c20245c jdk-9+108 925be13b3740d07a5958ccb5ab3c0ae1baba7055 jdk-9+110 f900d5afd9c83a0df8f36161c27c5e4c86a66f4c jdk-9+111 03543a758cd5890f2266e4b9678378a925dde22a jdk-9+112 +55b6d550828d1223b364e6ead4a56e56411c56df jdk-9+113 diff --git a/common/autoconf/compare.sh.in b/common/autoconf/compare.sh.in index f8f97ec02d2..67a69ff73bd 100644 --- a/common/autoconf/compare.sh.in +++ b/common/autoconf/compare.sh.in @@ -34,6 +34,7 @@ export LEGACY_BUILD_DIR=@OPENJDK_TARGET_OS@-@OPENJDK_TARGET_CPU_LEGACY@ export OPENJDK_TARGET_OS="@OPENJDK_TARGET_OS@" export OPENJDK_TARGET_CPU="@OPENJDK_TARGET_CPU@" export OPENJDK_TARGET_CPU_LIBDIR="@OPENJDK_TARGET_CPU_LIBDIR@" +export DEBUG_LEVEL="@DEBUG_LEVEL@" export AWK="@AWK@" export BASH="@BASH@" @@ -47,8 +48,6 @@ export EXPR="@EXPR@" export FILE="@FILE@" export FIND="@FIND@" export GREP="@GREP@" -export JAVAP="@FIXPATH@ @BOOT_JDK@/bin/javap @JAVA_TOOL_FLAGS_SMALL@" -export JIMAGE="@FIXPATH@ @BUILD_OUTPUT@/jdk/bin/jimage" export LDD="@LDD@" export LN="@LN@" export MKDIR="@MKDIR@" @@ -72,6 +71,17 @@ export UNARCHIVE="@UNZIP@ -q" export SRC_ROOT="@TOPDIR@" export OUTPUT_ROOT="@OUTPUT_ROOT@" +if [ "@COMPILE_TYPE@" != "cross" ]; then + export JAVAP="@FIXPATH@ $OUTPUT_ROOT/jdk/bin/javap @JAVA_TOOL_FLAGS_SMALL@" + export JIMAGE="@FIXPATH@ $OUTPUT_ROOT/jdk/bin/jimage" +elif [ "@CREATE_BUILDJDK@" = "true" ]; then + export JAVAP="@FIXPATH@ $OUTPUT_ROOT/buildjdk/jdk/bin/javap @JAVA_TOOL_FLAGS_SMALL@" + export JIMAGE="@FIXPATH@ $OUTPUT_ROOT/buildjdk/jdk/bin/jimage" +else + export JAVAP="@FIXPATH@ @BUILD_JDK@/bin/javap @JAVA_TOOL_FLAGS_SMALL@" + export JIMAGE="@FIXPATH@ @BUILD_JDK@/bin/jimage" +fi + if [ "$OPENJDK_TARGET_OS" = "windows" ]; then export PATH="@VS_PATH@" fi diff --git a/common/bin/compare.sh b/common/bin/compare.sh index d073fbbda32..e46c9f306ff 100644 --- a/common/bin/compare.sh +++ b/common/bin/compare.sh @@ -75,6 +75,7 @@ diff_text() { THIS_FILE=$2 SUFFIX="${THIS_FILE##*.}" + NAME="${THIS_FILE##*/}" TMP=1 @@ -92,6 +93,7 @@ diff_text() { $GREP '^[<>]' | \ $SED -e '/[<>] \* from.*\.idl/d' \ -e '/[<>] .*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \ + -e '/[<>] .*[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.*/d' \ -e '/[<>] \*.*[0-9]\{4\} [0-9][0-9]*:[0-9]\{2\}:[0-9]\{2\}.*/d' \ -e '/\/\/ Generated from input file.*/d' \ -e '/\/\/ This file was generated AUTOMATICALLY from a template file.*/d' \ @@ -100,12 +102,34 @@ diff_text() { # Ignore date strings in class files. # Anonymous lambda classes get randomly assigned counters in their names. if test "x$SUFFIX" = "xclass"; then + if [ "$NAME" = "module-info.class" ] || [ "$NAME" = "SystemModules.class" ] + then + # The SystemModules.class and module-info.class have several issues + # with random ordering of elements in HashSets. + MODULES_CLASS_FILTER="$SED \ + -e 's/,$//' \ + -e 's/;$//' \ + -e 's/^ *[0-9]*://' \ + -e 's/#[0-9]* */#/' \ + -e 's/ *\/\// \/\//' \ + -e 's/aload *[0-9]*/aload X/' \ + -e 's/ldc_w/ldc /' \ + | $SORT \ + " + $JAVAP -c -constants -l -p "${OTHER_FILE}" \ + | eval "$MODULES_CLASS_FILTER" > ${OTHER_FILE}.javap & + $JAVAP -c -constants -l -p "${THIS_FILE}" \ + | eval "$MODULES_CLASS_FILTER" > ${THIS_FILE}.javap & + wait + TMP=$($DIFF ${OTHER_FILE}.javap ${THIS_FILE}.javap) # To improve performance when large diffs are found, do a rough filtering of classes # elibeble for these exceptions - if $GREP -R -e '[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}' \ - -e 'lambda\$[a-zA-Z0-9]*\$[0-9]' ${THIS_FILE} > /dev/null; then - $JAVAP -c -constants -l -p "${OTHER_FILE}" > ${OTHER_FILE}.javap - $JAVAP -c -constants -l -p "${THIS_FILE}" > ${THIS_FILE}.javap + elif $GREP -R -e '[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}' \ + -e 'lambda\$[a-zA-Z0-9]*\$[0-9]' ${THIS_FILE} > /dev/null + then + $JAVAP -c -constants -l -p "${OTHER_FILE}" > ${OTHER_FILE}.javap & + $JAVAP -c -constants -l -p "${THIS_FILE}" > ${THIS_FILE}.javap & + wait TMP=$($DIFF ${OTHER_FILE}.javap ${THIS_FILE}.javap | \ $GREP '^[<>]' | \ $SED -e '/[<>].*[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.*/d' \ @@ -305,14 +329,19 @@ compare_general_files() { if [ -e $OTHER_DIR/$f ]; then SUFFIX="${f##*.}" if [ "$(basename $f)" = "release" ]; then - # Ignore differences in change numbers in release file. + # In release file, ignore differences in change numbers and order + # of modules in list. OTHER_FILE=$WORK_DIR/$f.other THIS_FILE=$WORK_DIR/$f.this $MKDIR -p $(dirname $OTHER_FILE) $MKDIR -p $(dirname $THIS_FILE) RELEASE_FILTER="$SED \ -e 's/\:[0-9a-f]\{12,12\}/:CHANGE/g' \ - -e 's/[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}//g' + -e 's/[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}//g' \ + -e 's/^#.*/#COMMENT/g' \ + -e 's/MODULES=/MODULES=\'$'\n/' \ + -e 's/,/\'$'\n/g' \ + | $SORT " $CAT $OTHER_DIR/$f | eval "$RELEASE_FILTER" > $OTHER_FILE $CAT $THIS_DIR/$f | eval "$RELEASE_FILTER" > $THIS_FILE @@ -330,8 +359,9 @@ compare_general_files() { -e 's/\(-- Generated by javadoc \).*\( --\)/\1(removed)\2/' \ -e 's/[A-Z][a-z]*, [A-Z][a-z]* [0-9][0-9]*, [0-9]\{4\} [0-9][0-9:]* [AMP]\{2,2\} [A-Z][A-Z]*//' " - $CAT $OTHER_DIR/$f | eval "$HTML_FILTER" > $OTHER_FILE - $CAT $THIS_DIR/$f | eval "$HTML_FILTER" > $THIS_FILE + $CAT $OTHER_DIR/$f | eval "$HTML_FILTER" > $OTHER_FILE & + $CAT $THIS_DIR/$f | eval "$HTML_FILTER" > $THIS_FILE & + wait else OTHER_FILE=$OTHER_DIR/$f THIS_FILE=$THIS_DIR/$f @@ -389,7 +419,7 @@ compare_zip_file() { $RM -rf $THIS_UNZIPDIR $OTHER_UNZIPDIR $MKDIR -p $THIS_UNZIPDIR $MKDIR -p $OTHER_UNZIPDIR - if [ "$TYPE" = "jar" || "$TYPE" = "war" || "$TYPE" = "zip" || "$TYPE" = "jmod"] + if [ "$TYPE" = "jar" -o "$TYPE" = "war" -o "$TYPE" = "zip" -o "$TYPE" = "jmod" ] then (cd $THIS_UNZIPDIR && $UNARCHIVE $THIS_ZIP) (cd $OTHER_UNZIPDIR && $UNARCHIVE $OTHER_ZIP) @@ -526,7 +556,7 @@ compare_all_jar_files() { # TODO filter? ZIPS=$(cd $THIS_DIR && $FIND . -type f -name "*.jar" -o -name "*.war" \ - -o -name "modules" -o -name "*.jmod" | $SORT | $FILTER) + -o -name "modules" | $SORT | $FILTER) if [ -n "$ZIPS" ]; then echo Jar files... @@ -600,8 +630,8 @@ compare_bin_file() { && [ -f "$OTHER/support/native/java.base/java_objs/java.diz" ]; then OTHER_DIZ_FILE="$OTHER/support/native/java.base/java_objs/java.diz" elif [ "$NAME" = "jimage.exe" ] \ - && [ -f "$OTHER/support/native/jdk.dev/jimage_objs/jimage.diz" ]; then - OTHER_DIZ_FILE="$OTHER/support/native/jdk.dev/jimage_objs/jimage.diz" + && [ -f "$OTHER/support/native/jdk.jlink/jimage_objs/jimage.diz" ]; then + OTHER_DIZ_FILE="$OTHER/support/native/jdk.jlink/jimage_objs/jimage.diz" elif [ "$NAME" = "javacpl.exe" ] \ && [ -f "$OTHER/support/native/jdk.plugin/javacpl/javacpl.diz" ]; then OTHER_DIZ_FILE="$OTHER/support/native/jdk.plugin/javacpl/javacpl.diz" @@ -632,8 +662,8 @@ compare_bin_file() { && [ -f "$THIS/support/native/java.base/java_objs/java.diz" ]; then THIS_DIZ_FILE="$THIS/support/native/java.base/java_objs/java.diz" elif [ "$NAME" = "jimage.exe" ] \ - && [ -f "$THIS/support/native/jdk.dev/jimage_objs/jimage.diz" ]; then - THIS_DIZ_FILE="$THIS/support/native/jdk.dev/jimage_objs/jimage.diz" + && [ -f "$THIS/support/native/jdk.jlink/jimage_objs/jimage.diz" ]; then + THIS_DIZ_FILE="$THIS/support/native/jdk.jlink/jimage_objs/jimage.diz" elif [ "$NAME" = "javacpl.exe" ] \ && [ -f "$THIS/support/native/jdk.plugin/javacpl/javacpl.diz" ]; then THIS_DIZ_FILE="$THIS/support/native/jdk.plugin/javacpl/javacpl.diz" @@ -732,6 +762,13 @@ compare_bin_file() { SYM_SORT_CMD="cat" fi + if [ -n "$SYMBOLS_DIFF_FILTER" ] && [ -z "$NEED_SYMBOLS_DIFF_FILTER" ] \ + || [[ "$NEED_SYMBOLS_DIFF_FILTER" = *"$BIN_FILE"* ]]; then + this_SYMBOLS_DIFF_FILTER="$SYMBOLS_DIFF_FILTER" + else + this_SYMBOLS_DIFF_FILTER="$CAT" + fi + # Check symbols if [ "$OPENJDK_TARGET_OS" = "windows" ]; then # The output from dumpbin on windows differs depending on if the debug symbol @@ -750,8 +787,16 @@ compare_bin_file() { $NM -j $ORIG_OTHER_FILE 2> /dev/null | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.other $NM -j $ORIG_THIS_FILE 2> /dev/null | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this else - $NM -a $ORIG_OTHER_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.other - $NM -a $ORIG_THIS_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this + $NM -a $ORIG_OTHER_FILE 2> /dev/null | $GREP -v $NAME \ + | $AWK '{print $2, $3, $4, $5}' \ + | eval "$this_SYMBOLS_DIFF_FILTER" \ + | $SYM_SORT_CMD \ + > $WORK_FILE_BASE.symbols.other + $NM -a $ORIG_THIS_FILE 2> /dev/null | $GREP -v $NAME \ + | $AWK '{print $2, $3, $4, $5}' \ + | eval "$this_SYMBOLS_DIFF_FILTER" \ + | $SYM_SORT_CMD \ + > $WORK_FILE_BASE.symbols.this fi LC_ALL=C $DIFF $WORK_FILE_BASE.symbols.other $WORK_FILE_BASE.symbols.this > $WORK_FILE_BASE.symbols.diff @@ -828,9 +873,10 @@ compare_bin_file() { FULLDUMP_DIFF_FILTER="$CAT" fi $FULLDUMP_CMD $OTHER_FILE | eval "$BUILD_ID_FILTER" | eval "$FULLDUMP_DIFF_FILTER" \ - > $WORK_FILE_BASE.fulldump.other 2>&1 + > $WORK_FILE_BASE.fulldump.other 2>&1 & $FULLDUMP_CMD $THIS_FILE | eval "$BUILD_ID_FILTER" | eval "$FULLDUMP_DIFF_FILTER" \ - > $WORK_FILE_BASE.fulldump.this 2>&1 + > $WORK_FILE_BASE.fulldump.this 2>&1 & + wait LC_ALL=C $DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this \ > $WORK_FILE_BASE.fulldump.diff @@ -854,18 +900,19 @@ compare_bin_file() { FULLDUMP_MSG=" " DIFF_FULLDUMP= if [[ "$KNOWN_FULLDUMP_DIFF $ACCEPTED_FULLDUMP_DIFF" = *"$BIN_FILE"* ]]; then - FULLDUMP_MSG=" ! " + FULLDUMP_MSG=" ! " fi fi fi # Compare disassemble output if [ -n "$DIS_CMD" ] && [ -z "$SKIP_DIS_DIFF" ]; then - # By default we filter out differences that include references to symbols. - # To get a raw diff with the complete disassembly, set - # DIS_DIFF_FILTER="$CAT" - if [ -z "$DIS_DIFF_FILTER" ]; then - DIS_DIFF_FILTER="$GREP -v ' # .* <.*>$' | $SED -r -e 's/(\b|x)([0-9a-fA-F]+)(\b|:|>)/X/g'" + this_DIS_DIFF_FILTER="$CAT" + if [ -n "$DIS_DIFF_FILTER" ]; then + if [ -z "$NEED_DIS_DIFF_FILTER" ] \ + || [[ "$NEED_DIS_DIFF_FILTER" = *"$BIN_FILE"* ]]; then + this_DIS_DIFF_FILTER="$DIS_DIFF_FILTER" + fi fi if [ "$OPENJDK_TARGET_OS" = "windows" ]; then DIS_GREP_ARG=-a @@ -873,9 +920,10 @@ compare_bin_file() { DIS_GREP_ARG= fi $DIS_CMD $OTHER_FILE | $GREP $DIS_GREP_ARG -v $NAME \ - | eval "$DIS_DIFF_FILTER" > $WORK_FILE_BASE.dis.other 2>&1 + | eval "$this_DIS_DIFF_FILTER" > $WORK_FILE_BASE.dis.other 2>&1 & $DIS_CMD $THIS_FILE | $GREP $DIS_GREP_ARG -v $NAME \ - | eval "$DIS_DIFF_FILTER" > $WORK_FILE_BASE.dis.this 2>&1 + | eval "$this_DIS_DIFF_FILTER" > $WORK_FILE_BASE.dis.this 2>&1 & + wait LC_ALL=C $DIFF $WORK_FILE_BASE.dis.other $WORK_FILE_BASE.dis.this > $WORK_FILE_BASE.dis.diff @@ -884,11 +932,15 @@ compare_bin_file() { DIS_MSG=$($PRINTF "%8d" $DIS_DIFF_SIZE) if [[ "$ACCEPTED_DIS_DIFF" != *"$BIN_FILE"* ]]; then DIFF_DIS=true - if [[ "$KNOWN_DIS_DIFF" != *"$BIN_FILE"* ]]; then + if [ "$MAX_KNOWN_DIS_DIFF_SIZE" = "" ]; then + MAX_KNOWN_DIS_DIFF_SIZE="0" + fi + if [[ "$KNOWN_DIS_DIFF" = *"$BIN_FILE"* ]] \ + && [ "$DIS_DIFF_SIZE" -lt "$MAX_KNOWN_DIS_DIFF_SIZE" ]; then + DIS_MSG=" $DIS_MSG " + else DIS_MSG="*$DIS_MSG*" REGRESSIONS=true - else - DIS_MSG=" $DIS_MSG " fi else DIS_MSG="($DIS_MSG)" diff --git a/common/bin/compare_exceptions.sh.incl b/common/bin/compare_exceptions.sh.incl index 30ae49c6fc1..7b76ab37029 100644 --- a/common/bin/compare_exceptions.sh.incl +++ b/common/bin/compare_exceptions.sh.incl @@ -89,7 +89,9 @@ if [ "$OPENJDK_TARGET_OS" = "linux" ]; then ./bin/jimage ./bin/jinfo ./bin/jjs + ./bin/jlink ./bin/jmap + ./bin/jmod ./bin/jps ./bin/jrunscript ./bin/jsadebugd @@ -113,21 +115,36 @@ if [ "$OPENJDK_TARGET_OS" = "linux" ]; then ./bin/xjc " - # Issue with __FILE__ usage in generated header files prevent clean fulldump diff of - # server jvm with old hotspot build. - KNOWN_FULLDUMP_DIFF=" - ./lib$OPENJDK_TARGET_CPU_LIBDIR/client/libjvm.so - ./lib$OPENJDK_TARGET_CPU_LIBDIR/server/libjvm.so - ./lib$OPENJDK_TARGET_CPU_LIBDIR/minimal/libjvm.so - " - - if [ "$OPENJDK_TARGET_CPU" = "x86" ]; then - KNOWN_DIS_DIFF=" - ./lib$OPENJDK_TARGET_CPU_LIBDIR/server/libjvm.so + if [ "$OPENJDK_TARGET_CPU" = "arm" ]; then + # NOTE: When comparing the old and new hotspot builds, the link time + # optimization makes good comparisons impossible. Fulldump compare always + # fails and disassembly can end up with some functions in different order. + # So for now, accept the difference but put a limit on the size. The + # different order of functions shouldn't result in a very big diff. + KNOWN_FULLDUMP_DIFF=" + ./lib$OPENJDK_TARGET_CPU_LIBDIR/minimal/libjvm.so + " + + # Link time optimization adds random numbers to symbol names + NEED_DIS_DIFF_FILTER=" + ./lib$OPENJDK_TARGET_CPU_LIBDIR/minimal/libjvm.so + " + DIS_DIFF_FILTER="$SED -r \ + -e 's/\.[0-9]+/.X/g' \ + -e 's/\t[0-9a-f]{4} [0-9a-f]{4} /\tXXXX XXXX /' \ + -e 's/\t[0-9a-f]{5,} /\t /' \ + " + KNOWN_DIS_DIFF=" + ./lib$OPENJDK_TARGET_CPU_LIBDIR/minimal/libjvm.so + " + MAX_KNOWN_DIS_DIFF_SIZE="3000" + + NEED_SYMBOLS_DIFF_FILTER=" + ./lib$OPENJDK_TARGET_CPU_LIBDIR/minimal/libjvm.so + " + SYMBOLS_DIFF_FILTER="$SED -r \ + -e 's/\.[0-9]+/.X/g' " - DIS_DIFF_FILTER="$SED \ - -e 's/\(:\t\)\([0-9a-z]\{2,2\} \)\{1,7\}/\1/g' \ - -e 's/0x[0-9a-z]\{2,9\}//g'" fi fi @@ -224,7 +241,9 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "x86_64" ]; ./bin/jimage ./bin/jinfo ./bin/jjs + ./bin/jlink ./bin/jmap + ./bin/jmod ./bin/jps ./bin/jrunscript ./bin/jsadebugd @@ -250,15 +269,10 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "x86_64" ]; SKIP_FULLDUMP_DIFF="true" - # Filter random C++ symbol strings. - # Some numbers differ randomly. + # Random strings looking like this differ: <.XAKoKoPIac2W0OA. DIS_DIFF_FILTER="$SED \ - -e 's/\.[a-zA-Z0-9_\$]\{15\}//g' \ - -e 's/\(\# \)[0-9a-f]*\( <\)/\1\2/g' \ - -e 's/0x[0-9a-f]*$//g' \ - -e 's/0x[0-9a-f]*\([,(>]\)/\1/g' \ - -e 's/: [0-9a-f][0-9a-f]\( [0-9a-f][0-9a-f]\)\{2,10\}/: /g' \ - -e 's/ [\.A-Za-z0-9%@]\{16\}$/ /g'" + -e 's/<\.[A-Za-z0-9]\{\15}\./<.SYM./' \ + " fi @@ -356,7 +370,9 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "sparcv9" ] ./bin/jimage ./bin/jinfo ./bin/jjs + ./bin/jlink ./bin/jmap + ./bin/jmod ./bin/jps ./bin/jrunscript ./bin/jsadebugd @@ -380,26 +396,32 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "sparcv9" ] ./bin/xjc " - # Some numbers differ randomly. DIS_DIFF_FILTER="$SED \ - -e 's/\$[a-zA-Z0-9_\$]\{15\}//g' \ - -e 's/: [0-9a-f][0-9a-f]\( [0-9a-f][0-9a-f]\)\{2,10\}/: /g' \ - -e 's/, [0-9a-fx\-]\{1,8\}/, /g' \ - -e 's/call [0-9a-f]\{7\}/call /g' \ + -e 's/^[0-9a-f]\{16\}/:/' \ + -e 's/^ *[0-9a-f]\{3,8\}:/ :/' \ + -e 's/: [0-9a-f][0-9a-f]\( [0-9a-f][0-9a-f]\)\{2,10\}/: /' \ + -e 's/\$[a-zA-Z0-9_\$]\{15\}\././' \ + -e 's/, [0-9a-fx\-]\{1,8\}/, /g' \ -e 's/0x[0-9a-f]\{1,8\}//g' \ - -e 's/\! [0-9a-f]\{1,8\} /! /g'" + -e 's/\! [0-9a-f]\{1,8\} /! /' \ + -e 's/call [0-9a-f]\{4,7\}/call /' \ + -e 's/%hi(0),/%hi(),/' \ + " - # libjvm.so - # __FILE__ macro usage in debug.hpp causes differences between old and new - # hotspot builds in ad_sparc.o and ad_sparc_clone.o. The .o files compare - # equal when stripped, but at link time differences appear. Removing - # __FILE__ from ShouldNotCallThis() and ShouldNotReachHere() removes - # the differences. KNOWN_DIS_DIFF=" - ./lib/sparcv9/server/libjvm.so ./lib/sparcv9/libsaproc.so " + MAX_KNOWN_DIS_DIFF_SIZE="3000" + + # On slowdebug the disassembly can differ randomly. + if [ "$DEBUG_LEVEL" = "slowdebug" ]; then + ACCEPTED_DIS_DIFF=" + ./lib/sparcv9/libfontmanager.so + ./lib/sparcv9/server/libjvm.so + " + fi + SKIP_FULLDUMP_DIFF="true" fi @@ -419,6 +441,7 @@ if [ "$OPENJDK_TARGET_OS" = "windows" ]; then ./demo/jvmti/minst/lib/minst.dll ./bin/attach.dll ./bin/jsoundds.dll + ./bin/client/jvm.dll ./bin/server/jvm.dll ./bin/appletviewer.exe ./bin/idlj.exe @@ -438,7 +461,9 @@ if [ "$OPENJDK_TARGET_OS" = "windows" ]; then ./bin/jimage.exe ./bin/jinfo.exe ./bin/jjs.exe + ./bin/jlink.exe ./bin/jmap.exe + ./bin/jmod.exe ./bin/jps.exe ./bin/jrunscript.exe ./bin/jsadebugd.exe @@ -469,22 +494,39 @@ if [ "$OPENJDK_TARGET_OS" = "windows" ]; then ./bin/jabswitch.exe " - # On windows, there are unavoidable allignment issues making - # a perfect disasm diff impossible. Filter out the following: - # * Random parts of C++ symbols (this is a bit greedy, but does the trick) - # @XXXXX - # * Hexadecimal addresses that are sometimes alligned differently. - # * Dates in version strings XXXX_XX_XX. - DIS_DIFF_FILTER="$SED \ - -e 's/^ [0-9A-F]\{16\}: //g' \ - -e 's/[@?][A-Za-z0-9_]\{1,25\}//g' \ - -e 's/\([\[+]\)[0-9A-F]\{4,16\}h\]/\1]/g' \ - -e 's/_[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}/_/g'" - #DIS_DIFF_FILTER="$CAT" + if [ "$OPENJDK_TARGET_CPU" = "x86" ]; then + DIS_DIFF_FILTER="$SED -r \ + -e 's/^ [0-9A-F]{16}: //' \ + -e 's/^ [0-9A-F]{8}: / : /' \ + -e 's/(offset \?\?)_C@_.*/\1/' \ + -e 's/[@?][A-Za-z0-9_]{1,25}//' \ + -e 's/([-,+])[0-9A-F]{2,16}/\1/g' \ + -e 's/\[[0-9A-F]{4,16}h\]/[]/' \ + -e 's/: ([a-z]{2}[a-z ]{2}) [0-9A-F]{2,16}h?$/: \1 /' \ + -e 's/_20[0-9]{2}_[0-1][0-9]_[0-9]{2}/_/' \ + " + elif [ "$OPENJDK_TARGET_CPU" = "x86_64" ]; then + DIS_DIFF_FILTER="$SED -r \ + -e 's/^ [0-9A-F]{16}: //' \ + -e 's/\[[0-9A-F]{4,16}h\]/[]/' \ + -e 's/([,+])[0-9A-F]{2,16}h/\1/' \ + -e 's/([a-z]{2}[a-z ]{2}) [0-9A-F]{4,16}$/\1 /' \ + -e 's/\[\?\?_C@_.*/[]/' \ + " + fi SKIP_BIN_DIFF="true" SKIP_FULLDUMP_DIFF="true" + # NOTE: When comparing the old and new hotspot builds, the server jvm.dll + # cannot be made equal in disassembly. Some functions just always end up + # in different order. So for now, accept the difference but put a limit + # on the size. The different order of functions shouldn't result in a very + # big diff. + KNOWN_DIS_DIFF=" + ./bin/server/jvm.dll + " + MAX_KNOWN_DIS_DIFF_SIZE="2000000" fi @@ -512,7 +554,9 @@ if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then ./bin/jimage ./bin/jinfo ./bin/jjs + ./bin/jlink ./bin/jmap + ./bin/jmod ./bin/jps ./bin/jrunscript ./bin/jsadebugd @@ -565,6 +609,7 @@ if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then ./Contents/Home/lib/libverify.dylib ./Contents/Home/lib/libsaproc.dylib ./Contents/Home/lib/libsplashscreen.dylib + ./Contents/Home/lib/server/libjsig.dylib ./Contents/Home/lib/server/libjvm.dylib ./Contents/Home/lib/deploy/JavaControlPanel.prefPane/Contents/MacOS/JavaControlPanel ./Contents/Resources/JavaControlPanelHelper @@ -590,6 +635,7 @@ if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then ./lib/libverify.dylib ./lib/libsaproc.dylib ./lib/libsplashscreen.dylib + ./lib/server/libjsig.dylib ./lib/server/libjvm.dylib ./lib/deploy/JavaControlPanel.prefPane/Contents/MacOS/JavaControlPanel ./Versions/A/Resources/finish_installation.app/Contents/MacOS/finish_installation @@ -606,7 +652,8 @@ if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then DIS_DIFF_FILTER="LANG=C $SED \ -e 's/0x[0-9a-f]\{3,16\}//g' -e 's/^[0-9a-f]\{12,20\}//' \ - -e 's/## literal pool for: .Java HotSpot(TM) 64-Bit Server VM.*//g' + -e 's/-20[0-9][0-9]-[0-1][0-9]-[0-3][0-9]-[0-2][0-9]\{5\}//g' \ + -e 's/), built on .*/), /' \ " fi diff --git a/corba/.hgtags b/corba/.hgtags index 1d06c1f36bb..c9e18d22968 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -355,3 +355,4 @@ b75afa17aefe480c23c616a6a2497063312f7189 jdk-9+109 9666775734fb6028ee86df9972626b3667b6a318 jdk-9+110 2bb92dd44275679edb29fdbffc3b7cbebc9a6bf0 jdk-9+111 780d0620add32bf545471cf65038c9ac6d9c036d jdk-9+112 +cc30faa2da498c478e89ab062ff160653ca1b170 jdk-9+113 diff --git a/corba/src/java.corba/share/classes/module-info.java b/corba/src/java.corba/share/classes/module-info.java index 23da4b785a9..25f79def5cb 100644 --- a/corba/src/java.corba/share/classes/module-info.java +++ b/corba/src/java.corba/share/classes/module-info.java @@ -29,6 +29,8 @@ module java.corba { requires java.logging; requires java.naming; requires java.transaction; + // 8148863 + requires jdk.unsupported; exports javax.activity; exports javax.rmi; diff --git a/hotspot/.hgtags b/hotspot/.hgtags index f7acd50ad2b..c5580667c41 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -515,3 +515,4 @@ c5146d4da417f76edfc43097d2e2ced042a65b4e jdk-9+107 2f5d1578b24060ea06bd1f340a124db95d1475b2 jdk-9+110 c558850fac5750d8ca98a45180121980f57cdd28 jdk-9+111 76582e8dc9e6374e4f99ab797c8d364b6e9449b4 jdk-9+112 +c569f8d89269fb6205b90f727581eb8cc04132f9 jdk-9+113 diff --git a/hotspot/.mx.jvmci/suite.py b/hotspot/.mx.jvmci/suite.py index 110b1138ea9..514994c5190 100644 --- a/hotspot/.mx.jvmci/suite.py +++ b/hotspot/.mx.jvmci/suite.py @@ -32,24 +32,9 @@ suite = { "libraries" : { - "HCFDIS" : { - "urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/hcfdis-3.jar"], - "sha1" : "a71247c6ddb90aad4abf7c77e501acc60674ef57", - }, - - "C1VISUALIZER_DIST" : { - "urls" : ["https://java.net/downloads/c1visualizer/c1visualizer_2015-07-22.zip"], - "sha1" : "7ead6b2f7ed4643ef4d3343a5562e3d3f39564ac", - }, - - "JOL_INTERNALS" : { - "urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/truffle/jol/jol-internals.jar"], - "sha1" : "508bcd26a4d7c4c44048990c6ea789a3b11a62dc", - }, - - "BATIK" : { - "sha1" : "122b87ca88e41a415cf8b523fd3d03b4325134a3", - "urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/batik-all-1.7.jar"], + "TESTNG" : { + "urls" : ["http://central.maven.org/maven2/org/testng/testng/6.9.10/testng-6.9.10.jar"], + "sha1" : "6feb3e964aeb7097aff30c372aac3ec0f8d87ede", }, # Stubs for classes introduced in JDK9 that allow compilation with a JDK8 javac and Eclipse. @@ -175,6 +160,18 @@ suite = { "workingSets" : "JVMCI", }, + "jdk.vm.ci.hotspot.test" : { + "subDir" : "test/compiler/jvmci", + "sourceDirs" : ["src"], + "dependencies" : [ + "mx:TESTNG", + "jdk.vm.ci.hotspot", + ], + "checkstyle" : "jdk.vm.ci.services", + "javaCompliance" : "1.8", + "workingSets" : "API,JVMCI", + }, + "jdk.vm.ci.hotspotvmconfig" : { "subDir" : "src/jdk.vm.ci/share/classes", "sourceDirs" : ["src"], diff --git a/hotspot/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp index b302548557b..a4110534eec 100644 --- a/hotspot/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp +++ b/hotspot/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp @@ -65,7 +65,7 @@ void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, T Unimplemented(); } else { NativeMovConstReg* move = nativeMovConstReg_at(pc); - Metadata* reference = record_metadata_reference(constant, CHECK); + void* reference = record_metadata_reference(constant, CHECK); move->set_data((intptr_t) reference); TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(reference)); } diff --git a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp index 82640865457..c7966aea22e 100644 --- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp +++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp @@ -211,10 +211,6 @@ static int reg2offset_out(VMReg r) { return (r->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size; } -template static const T& min (const T& a, const T& b) { - return (a > b) ? b : a; -} - // --------------------------------------------------------------------------- // Read the array of BasicTypes from a signature, and compute where the // arguments should go. Values in the VMRegPair regs array refer to 4-byte diff --git a/hotspot/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp b/hotspot/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp index e1e3bb153f8..1abf436bc13 100644 --- a/hotspot/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp @@ -79,7 +79,7 @@ void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, T #endif } else { NativeMovConstReg* move = nativeMovConstReg_at(pc); - Metadata* reference = record_metadata_reference(constant, CHECK); + void* reference = record_metadata_reference(constant, CHECK); move->set_data((intptr_t)reference); TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(reference)); } diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp index 9524e707ff4..f6770b0c3db 100644 --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp @@ -4666,8 +4666,109 @@ void MacroAssembler::array_equals(bool is_array_equ, Register ary1, Register ary bind(Ldone); } +void MacroAssembler::has_negatives(Register inp, Register size, Register result, Register t2, Register t3, Register t4, Register t5) { + + // test for negative bytes in input string of a given size + // result 1 if found, 0 otherwise. + + Label Lcore, Ltail, Lreturn, Lcore_rpt; + + assert_different_registers(inp, size, t2, t3, t4, t5, result); + + Register i = result; // result used as integer index i until very end + Register lmask = t2; // t2 is aliased to lmask + + // INITIALIZATION + // =========================================================== + // initialize highbits mask -> lmask = 0x8080808080808080 (8B/64b) + // compute unaligned offset -> i + // compute core end index -> t5 + Assembler::sethi(0x80808000, t2); //! sethi macro fails to emit optimal + add(t2, 0x80, t2); + sllx(t2, 32, t3); + or3(t3, t2, lmask); // 0x8080808080808080 -> lmask + sra(size,0,size); + andcc(inp, 0x7, i); // unaligned offset -> i + br(Assembler::zero, true, Assembler::pn, Lcore); // starts 8B aligned? + delayed()->add(size, -8, t5); // (annuled) core end index -> t5 + + // =========================================================== + + // UNALIGNED HEAD + // =========================================================== + // * unaligned head handling: grab aligned 8B containing unaligned inp(ut) + // * obliterate (ignore) bytes outside string by shifting off reg ends + // * compare with bitmask, short circuit return true if one or more high + // bits set. + cmp(size, 0); + br(Assembler::zero, true, Assembler::pn, Lreturn); // short-circuit? + delayed()->mov(0,result); // annuled so i not clobbered for following + neg(i, t4); + add(i, size, t5); + ldx(inp, t4, t3); // raw aligned 8B containing unaligned head -> t3 + mov(8, t4); + sub(t4, t5, t4); + sra(t4, 31, t5); + andn(t4, t5, t5); + add(i, t5, t4); + sll(t5, 3, t5); + sll(t4, 3, t4); // # bits to shift right, left -> t5,t4 + srlx(t3, t5, t3); + sllx(t3, t4, t3); // bytes outside string in 8B header obliterated -> t3 + andcc(lmask, t3, G0); + brx(Assembler::notZero, true, Assembler::pn, Lreturn); // short circuit? + delayed()->mov(1,result); // annuled so i not clobbered for following + add(size, -8, t5); // core end index -> t5 + mov(8, t4); + sub(t4, i, i); // # bytes examined in unalgn head (<8) -> i + // =========================================================== + + // ALIGNED CORE + // =========================================================== + // * iterate index i over aligned 8B sections of core, comparing with + // bitmask, short circuit return true if one or more high bits set + // t5 contains core end index/loop limit which is the index + // of the MSB of last (unaligned) 8B fully contained in the string. + // inp contains address of first byte in string/array + // lmask contains 8B high bit mask for comparison + // i contains next index to be processed (adr. inp+i is on 8B boundary) + bind(Lcore); + cmp_and_br_short(i, t5, Assembler::greater, Assembler::pn, Ltail); + bind(Lcore_rpt); + ldx(inp, i, t3); + andcc(t3, lmask, G0); + brx(Assembler::notZero, true, Assembler::pn, Lreturn); + delayed()->mov(1, result); // annuled so i not clobbered for following + add(i, 8, i); + cmp_and_br_short(i, t5, Assembler::lessEqual, Assembler::pn, Lcore_rpt); + // =========================================================== + + // ALIGNED TAIL (<8B) + // =========================================================== + // handle aligned tail of 7B or less as complete 8B, obliterating end of + // string bytes by shifting them off end, compare what's left with bitmask + // inp contains address of first byte in string/array + // lmask contains 8B high bit mask for comparison + // i contains next index to be processed (adr. inp+i is on 8B boundary) + bind(Ltail); + subcc(size, i, t4); // # of remaining bytes in string -> t4 + // return 0 if no more remaining bytes + br(Assembler::lessEqual, true, Assembler::pn, Lreturn); + delayed()->mov(0, result); // annuled so i not clobbered for following + ldx(inp, i, t3); // load final 8B (aligned) containing tail -> t3 + mov(8, t5); + sub(t5, t4, t4); + mov(0, result); // ** i clobbered at this point + sll(t4, 3, t4); // bits beyond end of string -> t4 + srlx(t3, t4, t3); // bytes beyond end now obliterated -> t3 + andcc(lmask, t3, G0); + movcc(Assembler::notZero, false, xcc, 1, result); + bind(Lreturn); +} + #endif + // Use BIS for zeroing (count is in bytes). void MacroAssembler::bis_zeroing(Register to, Register count, Register temp, Label& Ldone) { assert(UseBlockZeroing && VM_Version::has_block_zeroing(), "only works with BIS zeroing"); diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp index fe0c36ace97..dbbfbbc1267 100644 --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -1392,6 +1392,11 @@ public: void array_equals(bool is_array_equ, Register ary1, Register ary2, Register limit, Register tmp, Register result, bool is_byte); + // test for negative bytes in input string of a given size, result 0 if none + void has_negatives(Register inp, Register size, Register result, + Register t2, Register t3, Register t4, + Register t5); + #endif // Use BIS for zeroing diff --git a/hotspot/src/cpu/sparc/vm/sparc.ad b/hotspot/src/cpu/sparc/vm/sparc.ad index f24c1f9b384..d669d8732b8 100644 --- a/hotspot/src/cpu/sparc/vm/sparc.ad +++ b/hotspot/src/cpu/sparc/vm/sparc.ad @@ -10168,6 +10168,22 @@ instruct array_equalsC(o0RegP ary1, o1RegP ary2, g3RegI tmp1, notemp_iRegI resul ins_pipe(long_memory_op); %} +instruct has_negatives(o0RegP pAryR, g3RegI iSizeR, notemp_iRegI resultR, + iRegL tmp1L, iRegL tmp2L, iRegL tmp3L, iRegL tmp4L, + flagsReg ccr) +%{ + match(Set resultR (HasNegatives pAryR iSizeR)); + effect(TEMP resultR, TEMP tmp1L, TEMP tmp2L, TEMP tmp3L, TEMP tmp4L, USE pAryR, USE iSizeR, KILL ccr); + format %{ "has negatives byte[] $pAryR,$iSizeR -> $resultR // KILL $tmp1L,$tmp2L,$tmp3L,$tmp4L" %} + ins_encode %{ + __ has_negatives($pAryR$$Register, $iSizeR$$Register, + $resultR$$Register, + $tmp1L$$Register, $tmp2L$$Register, + $tmp3L$$Register, $tmp4L$$Register); + %} + ins_pipe(long_memory_op); +%} + // char[] to byte[] compression instruct string_compress(o0RegP src, o1RegP dst, g3RegI len, notemp_iRegI result, iRegL tmp, flagsReg ccr) %{ predicate(UseVIS < 3); diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp index ffdd9fe2338..dd9e30156e1 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp @@ -394,7 +394,7 @@ bool Assembler::emit_compressed_disp_byte(int &disp) { int mod_idx = 0; // We will test if the displacement fits the compressed format and if so // apply the compression to the displacment iff the result is8bit. - if (VM_Version::supports_evex() && (_attributes != NULL) && _attributes->is_evex_instruction()) { + if (VM_Version::supports_evex() && _attributes && _attributes->is_evex_instruction()) { int evex_encoding = _attributes->get_evex_encoding(); int tuple_type = _attributes->get_tuple_type(); switch (tuple_type) { @@ -2154,7 +2154,7 @@ void Assembler::movb(Register dst, Address src) { void Assembler::movddup(XMMRegister dst, XMMRegister src) { NOT_LP64(assert(VM_Version::supports_sse3(), "")); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_128bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_128bit; InstructionAttr attributes(vector_len, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); emit_int8(0x12); @@ -2423,7 +2423,8 @@ void Assembler::vmovdqu(Address dst, XMMRegister src) { void Assembler::evmovdqub(XMMRegister dst, XMMRegister src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); - int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); + int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3; + int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); emit_int8((unsigned char)(0xC0 | encode)); } @@ -2432,8 +2433,9 @@ void Assembler::evmovdqub(XMMRegister dst, Address src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); + int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3; attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); - vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); + vex_prefix(src, 0, dst->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); emit_operand(dst, src); } @@ -2443,8 +2445,9 @@ void Assembler::evmovdqub(Address dst, XMMRegister src, int vector_len) { assert(src != xnoreg, "sanity"); InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); + int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3; attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); - vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); + vex_prefix(dst, 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes); emit_int8(0x7F); emit_operand(src, dst); } @@ -2452,7 +2455,8 @@ void Assembler::evmovdqub(Address dst, XMMRegister src, int vector_len) { void Assembler::evmovdquw(XMMRegister dst, XMMRegister src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); - int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); + int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3; + int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); emit_int8((unsigned char)(0xC0 | encode)); } @@ -2462,7 +2466,8 @@ void Assembler::evmovdquw(XMMRegister dst, Address src, int vector_len) { InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); - vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); + int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3; + vex_prefix(src, 0, dst->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); emit_operand(dst, src); } @@ -2473,13 +2478,16 @@ void Assembler::evmovdquw(Address dst, XMMRegister src, int vector_len) { InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); - vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); + int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3; + vex_prefix(dst, 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes); emit_int8(0x7F); emit_operand(src, dst); } + void Assembler::evmovdqul(XMMRegister dst, XMMRegister src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); emit_int8((unsigned char)(0xC0 | encode)); @@ -2490,6 +2498,7 @@ void Assembler::evmovdqul(XMMRegister dst, Address src, int vector_len) { InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false , /* uses_vl */ true); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); + attributes.set_is_evex_instruction(); vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); emit_operand(dst, src); @@ -2500,6 +2509,7 @@ void Assembler::evmovdqul(Address dst, XMMRegister src, int vector_len) { assert(src != xnoreg, "sanity"); InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes); emit_int8(0x7F); @@ -2509,6 +2519,7 @@ void Assembler::evmovdqul(Address dst, XMMRegister src, int vector_len) { void Assembler::evmovdquq(XMMRegister dst, XMMRegister src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); emit_int8((unsigned char)(0xC0 | encode)); @@ -2518,6 +2529,7 @@ void Assembler::evmovdquq(XMMRegister dst, Address src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); @@ -2529,6 +2541,7 @@ void Assembler::evmovdquq(Address dst, XMMRegister src, int vector_len) { assert(src != xnoreg, "sanity"); InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes); emit_int8(0x7F); @@ -3196,6 +3209,7 @@ void Assembler::vpcmpeqb(XMMRegister dst, XMMRegister nds, XMMRegister src, int void Assembler::evpcmpeqb(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) { assert(VM_Version::supports_avx512bw(), ""); InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int encode = vex_prefix_and_encode(kdst->encoding(), nds_enc, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int8(0x74); @@ -3206,6 +3220,7 @@ void Assembler::evpcmpeqb(KRegister kdst, XMMRegister nds, Address src, int vect assert(VM_Version::supports_avx512bw(), ""); InstructionMark im(this); InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int dst_enc = kdst->encoding(); @@ -3237,6 +3252,7 @@ void Assembler::vpcmpeqw(XMMRegister dst, XMMRegister nds, XMMRegister src, int void Assembler::evpcmpeqw(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) { assert(VM_Version::supports_avx512bw(), ""); InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int encode = vex_prefix_and_encode(kdst->encoding(), nds_enc, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int8(0x75); @@ -3248,6 +3264,7 @@ void Assembler::evpcmpeqw(KRegister kdst, XMMRegister nds, Address src, int vect InstructionMark im(this); InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); + attributes.set_is_evex_instruction(); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int dst_enc = kdst->encoding(); vex_prefix(src, nds_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes); @@ -3278,6 +3295,7 @@ void Assembler::vpcmpeqd(XMMRegister dst, XMMRegister nds, XMMRegister src, int void Assembler::evpcmpeqd(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int encode = vex_prefix_and_encode(kdst->encoding(), nds_enc, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int8(0x76); @@ -3289,6 +3307,7 @@ void Assembler::evpcmpeqd(KRegister kdst, XMMRegister nds, Address src, int vect InstructionMark im(this); InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit); + attributes.set_is_evex_instruction(); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int dst_enc = kdst->encoding(); vex_prefix(src, nds_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes); @@ -3319,6 +3338,7 @@ void Assembler::vpcmpeqq(XMMRegister dst, XMMRegister nds, XMMRegister src, int void Assembler::evpcmpeqq(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int encode = vex_prefix_and_encode(kdst->encoding(), nds_enc, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); emit_int8(0x29); @@ -3330,6 +3350,7 @@ void Assembler::evpcmpeqq(KRegister kdst, XMMRegister nds, Address src, int vect assert(VM_Version::supports_evex(), ""); InstructionMark im(this); InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int dst_enc = kdst->encoding(); @@ -3634,7 +3655,7 @@ void Assembler::pshufb(XMMRegister dst, Address src) { void Assembler::pshufd(XMMRegister dst, XMMRegister src, int mode) { assert(isByte(mode), "invalid value"); NOT_LP64(assert(VM_Version::supports_sse2(), "")); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_128bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_128bit; InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int8(0x70); @@ -5702,7 +5723,7 @@ void Assembler::vpxor(XMMRegister dst, XMMRegister nds, Address src, int vector_ void Assembler::vinsertf128(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) { assert(VM_Version::supports_avx(), ""); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int encode = vex_prefix_and_encode(dst->encoding(), nds_enc, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); @@ -5782,7 +5803,7 @@ void Assembler::vinsertf128(XMMRegister dst, XMMRegister nds, Address src, uint8 assert(VM_Version::supports_avx(), ""); assert(dst != xnoreg, "sanity"); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; int nds_enc = nds->is_valid() ? nds->encoding() : 0; InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); @@ -5799,7 +5820,7 @@ void Assembler::vinsertf128(XMMRegister dst, XMMRegister nds, Address src, uint8 void Assembler::vextractf128(XMMRegister dst, XMMRegister src, uint8_t imm8) { assert(VM_Version::supports_avx(), ""); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); emit_int8(0x19); @@ -5813,7 +5834,7 @@ void Assembler::vextractf128(Address dst, XMMRegister src, uint8_t imm8) { assert(VM_Version::supports_avx(), ""); assert(src != xnoreg, "sanity"); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit); @@ -5828,7 +5849,7 @@ void Assembler::vextractf128(Address dst, XMMRegister src, uint8_t imm8) { void Assembler::vinserti128(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) { assert(VM_Version::supports_avx2(), ""); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int encode = vex_prefix_and_encode(dst->encoding(), nds_enc, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); @@ -5856,7 +5877,7 @@ void Assembler::vinserti128(XMMRegister dst, XMMRegister nds, Address src, uint8 assert(VM_Version::supports_avx2(), ""); assert(dst != xnoreg, "sanity"); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; int nds_enc = nds->is_valid() ? nds->encoding() : 0; InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); @@ -5873,7 +5894,7 @@ void Assembler::vinserti128(XMMRegister dst, XMMRegister nds, Address src, uint8 void Assembler::vextracti128(XMMRegister dst, XMMRegister src, uint8_t imm8) { assert(VM_Version::supports_avx(), ""); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); emit_int8(0x39); @@ -5887,7 +5908,7 @@ void Assembler::vextracti128(Address dst, XMMRegister src, uint8_t imm8) { assert(VM_Version::supports_avx2(), ""); assert(src != xnoreg, "sanity"); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit); @@ -6147,7 +6168,11 @@ void Assembler::evpbroadcastb(XMMRegister dst, Register src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); - emit_int8(0x7A); + if (attributes.is_evex_instruction()) { + emit_int8(0x7A); + } else { + emit_int8(0x78); + } emit_int8((unsigned char)(0xC0 | encode)); } @@ -6156,7 +6181,11 @@ void Assembler::evpbroadcastw(XMMRegister dst, Register src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); - emit_int8(0x7B); + if (attributes.is_evex_instruction()) { + emit_int8(0x7B); + } else { + emit_int8(0x79); + } emit_int8((unsigned char)(0xC0 | encode)); } @@ -6165,7 +6194,11 @@ void Assembler::evpbroadcastd(XMMRegister dst, Register src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); - emit_int8(0x7C); + if (attributes.is_evex_instruction()) { + emit_int8(0x7C); + } else { + emit_int8(0x58); + } emit_int8((unsigned char)(0xC0 | encode)); } @@ -6174,7 +6207,11 @@ void Assembler::evpbroadcastq(XMMRegister dst, Register src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); - emit_int8(0x7C); + if (attributes.is_evex_instruction()) { + emit_int8(0x7C); + } else { + emit_int8(0x59); + } emit_int8((unsigned char)(0xC0 | encode)); } @@ -6793,7 +6830,7 @@ void Assembler::vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix attributes->set_current_assembler(this); // if vector length is turned off, revert to AVX for vectors smaller than 512-bit - if ((UseAVX > 2) && _legacy_mode_vl && attributes->uses_vl()) { + if (UseAVX > 2 && _legacy_mode_vl && attributes->uses_vl()) { switch (attributes->get_vector_len()) { case AVX_128bit: case AVX_256bit: @@ -6802,7 +6839,27 @@ void Assembler::vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix } } - if ((UseAVX > 2) && !attributes->is_legacy_mode()) + // For pure EVEX check and see if this instruction + // is allowed in legacy mode and has resources which will + // fit in it. Pure EVEX instructions will use set_is_evex_instruction in their definition, + // else that field is set when we encode to EVEX + if (UseAVX > 2 && !attributes->is_legacy_mode() && + !_is_managed && !attributes->is_evex_instruction()) { + if (!_legacy_mode_vl && attributes->get_vector_len() != AVX_512bit) { + bool check_register_bank = NOT_IA32(true) IA32_ONLY(false); + if (check_register_bank) { + // check nds_enc and xreg_enc for upper bank usage + if (nds_enc < 16 && xreg_enc < 16) { + attributes->set_is_legacy_mode(); + } + } else { + attributes->set_is_legacy_mode(); + } + } + } + + _is_managed = false; + if (UseAVX > 2 && !attributes->is_legacy_mode()) { bool evex_r = (xreg_enc >= 16); bool evex_v = (nds_enc >= 16); @@ -6819,15 +6876,20 @@ int Assembler::vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc, VexS bool vex_x = false; set_attributes(attributes); attributes->set_current_assembler(this); + bool check_register_bank = NOT_IA32(true) IA32_ONLY(false); // if vector length is turned off, revert to AVX for vectors smaller than 512-bit - if ((UseAVX > 2) && _legacy_mode_vl && attributes->uses_vl()) { + if (UseAVX > 2 && _legacy_mode_vl && attributes->uses_vl()) { switch (attributes->get_vector_len()) { case AVX_128bit: case AVX_256bit: - if ((dst_enc >= 16) | (nds_enc >= 16) | (src_enc >= 16)) { - // up propagate arithmetic instructions to meet RA requirements - attributes->set_vector_len(AVX_512bit); + if (check_register_bank) { + if (dst_enc >= 16 || nds_enc >= 16 || src_enc >= 16) { + // up propagate arithmetic instructions to meet RA requirements + attributes->set_vector_len(AVX_512bit); + } else { + attributes->set_is_legacy_mode(); + } } else { attributes->set_is_legacy_mode(); } @@ -6835,7 +6897,26 @@ int Assembler::vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc, VexS } } - if ((UseAVX > 2) && !attributes->is_legacy_mode()) + // For pure EVEX check and see if this instruction + // is allowed in legacy mode and has resources which will + // fit in it. Pure EVEX instructions will use set_is_evex_instruction in their definition, + // else that field is set when we encode to EVEX + if (UseAVX > 2 && !attributes->is_legacy_mode() && + !_is_managed && !attributes->is_evex_instruction()) { + if (!_legacy_mode_vl && attributes->get_vector_len() != AVX_512bit) { + if (check_register_bank) { + // check dst_enc, nds_enc and src_enc for upper bank usage + if (dst_enc < 16 && nds_enc < 16 && src_enc < 16) { + attributes->set_is_legacy_mode(); + } + } else { + attributes->set_is_legacy_mode(); + } + } + } + + _is_managed = false; + if (UseAVX > 2 && !attributes->is_legacy_mode()) { bool evex_r = (dst_enc >= 16); bool evex_v = (nds_enc >= 16); diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.hpp b/hotspot/src/cpu/x86/vm/assembler_x86.hpp index 561278599b7..4423d4a5bde 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp @@ -605,6 +605,7 @@ private: bool _legacy_mode_dq; bool _legacy_mode_vl; bool _legacy_mode_vlbw; + bool _is_managed; class InstructionAttr *_attributes; @@ -811,12 +812,17 @@ private: _legacy_mode_dq = (VM_Version::supports_avx512dq() == false); _legacy_mode_vl = (VM_Version::supports_avx512vl() == false); _legacy_mode_vlbw = (VM_Version::supports_avx512vlbw() == false); + _is_managed = false; _attributes = NULL; } void set_attributes(InstructionAttr *attributes) { _attributes = attributes; } void clear_attributes(void) { _attributes = NULL; } + void set_managed(void) { _is_managed = true; } + void clear_managed(void) { _is_managed = false; } + bool is_managed(void) { return _is_managed; } + void lea(Register dst, Address src); void mov(Register dst, Register src); diff --git a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp index 1d057e20adf..0b607df2606 100644 --- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp @@ -1646,31 +1646,15 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ jmp(done); __ bind(runtime); - __ push(rcx); -#ifdef _LP64 - __ push(r8); - __ push(r9); - __ push(r10); - __ push(r11); -# ifndef _WIN64 - __ push(rdi); - __ push(rsi); -# endif -#endif + + save_live_registers(sasm, 3); + // load the pre-value f.load_argument(0, rcx); __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), rcx, thread); -#ifdef _LP64 -# ifndef _WIN64 - __ pop(rsi); - __ pop(rdi); -# endif - __ pop(r11); - __ pop(r10); - __ pop(r9); - __ pop(r8); -#endif - __ pop(rcx); + + restore_live_registers(sasm); + __ bind(done); __ pop(rdx); @@ -1744,27 +1728,13 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ jmp(enqueued); __ bind(runtime); -#ifdef _LP64 - __ push(r8); - __ push(r9); - __ push(r10); - __ push(r11); -# ifndef _WIN64 - __ push(rdi); - __ push(rsi); -# endif -#endif + + save_live_registers(sasm, 3); + __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread); -#ifdef _LP64 -# ifndef _WIN64 - __ pop(rsi); - __ pop(rdi); -# endif - __ pop(r11); - __ pop(r10); - __ pop(r9); - __ pop(r8); -#endif + + restore_live_registers(sasm); + __ bind(enqueued); __ pop(rdx); diff --git a/hotspot/src/cpu/x86/vm/jvmciCodeInstaller_x86.cpp b/hotspot/src/cpu/x86/vm/jvmciCodeInstaller_x86.cpp index 2e476524351..ff308c09c5f 100644 --- a/hotspot/src/cpu/x86/vm/jvmciCodeInstaller_x86.cpp +++ b/hotspot/src/cpu/x86/vm/jvmciCodeInstaller_x86.cpp @@ -96,7 +96,7 @@ void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, T #endif } else { address operand = Assembler::locate_operand(pc, Assembler::imm_operand); - *((Metadata**) operand) = record_metadata_reference(constant, CHECK); + *((void**) operand) = record_metadata_reference(constant, CHECK); TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand)); } } diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp index f5652df8b31..756c032861e 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp @@ -2600,15 +2600,12 @@ class StubGenerator: public StubCodeGenerator { // rax - input length // - address generate_cipherBlockChaining_decryptAESCrypt() { + address generate_cipherBlockChaining_decryptAESCrypt_Parallel() { assert(UseAES, "need AES instructions and misaligned SSE support"); __ align(CodeEntryAlignment); StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_decryptAESCrypt"); address start = __ pc(); - Label L_exit, L_key_192_256, L_key_256; - Label L_singleBlock_loopTop_128; - Label L_singleBlock_loopTop_192, L_singleBlock_loopTop_256; const Register from = rsi; // source array address const Register to = rdx; // destination array address const Register key = rcx; // key array address @@ -2617,14 +2614,24 @@ class StubGenerator: public StubCodeGenerator { const Register len_reg = rbx; // src len (must be multiple of blocksize 16) const Register pos = rax; - // xmm register assignments for the loops below - const XMMRegister xmm_result = xmm0; - const XMMRegister xmm_temp = xmm1; - // first 6 keys preloaded into xmm2-xmm7 - const int XMM_REG_NUM_KEY_FIRST = 2; - const int XMM_REG_NUM_KEY_LAST = 7; - const int FIRST_NON_REG_KEY_offset = 0x70; - const XMMRegister xmm_key_first = as_XMMRegister(XMM_REG_NUM_KEY_FIRST); + const int PARALLEL_FACTOR = 4; + const int ROUNDS[3] = { 10, 12, 14 }; //aes rounds for key128, key192, key256 + + Label L_exit; + Label L_singleBlock_loopTop[3]; //128, 192, 256 + Label L_multiBlock_loopTop[3]; //128, 192, 256 + + const XMMRegister xmm_prev_block_cipher = xmm0; // holds cipher of previous block + const XMMRegister xmm_key_shuf_mask = xmm1; + + const XMMRegister xmm_key_tmp0 = xmm2; + const XMMRegister xmm_key_tmp1 = xmm3; + + // registers holding the six results in the parallelized loop + const XMMRegister xmm_result0 = xmm4; + const XMMRegister xmm_result1 = xmm5; + const XMMRegister xmm_result2 = xmm6; + const XMMRegister xmm_result3 = xmm7; __ enter(); // required for proper stackwalking of RuntimeStub frame handleSOERegisters(true /*saving*/); @@ -2643,126 +2650,123 @@ class StubGenerator: public StubCodeGenerator { const Address key_param (rbp, 8+8); const Address rvec_param (rbp, 8+12); const Address len_param (rbp, 8+16); + __ movptr(from , from_param); __ movptr(to , to_param); __ movptr(key , key_param); __ movptr(rvec , rvec_param); __ movptr(len_reg , len_param); - // the java expanded key ordering is rotated one position from what we want - // so we start from 0x10 here and hit 0x00 last - const XMMRegister xmm_key_shuf_mask = xmm1; // used temporarily to swap key bytes up front __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr())); - // load up xmm regs 2 thru 6 with first 5 keys - for (int rnum = XMM_REG_NUM_KEY_FIRST, offset = 0x10; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) { - load_key(as_XMMRegister(rnum), key, offset, xmm_key_shuf_mask); - offset += 0x10; - } + __ movdqu(xmm_prev_block_cipher, Address(rvec, 0x00)); // initialize with initial rvec - // inside here, use the rvec register to point to previous block cipher - // with which we xor at the end of each newly decrypted block - const Register prev_block_cipher_ptr = rvec; + __ xorptr(pos, pos); // now split to different paths depending on the keylen (len in ints of AESCrypt.KLE array (52=192, or 60=256)) - __ movl(rax, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT))); - __ cmpl(rax, 44); - __ jcc(Assembler::notEqual, L_key_192_256); + // rvec is reused + __ movl(rvec, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT))); + __ cmpl(rvec, 52); + __ jcc(Assembler::equal, L_multiBlock_loopTop[1]); + __ cmpl(rvec, 60); + __ jcc(Assembler::equal, L_multiBlock_loopTop[2]); +#define DoFour(opc, src_reg) \ + __ opc(xmm_result0, src_reg); \ + __ opc(xmm_result1, src_reg); \ + __ opc(xmm_result2, src_reg); \ + __ opc(xmm_result3, src_reg); \ - // 128-bit code follows here, parallelized - __ movl(pos, 0); - __ align(OptoLoopAlignment); - __ BIND(L_singleBlock_loopTop_128); - __ cmpptr(len_reg, 0); // any blocks left?? - __ jcc(Assembler::equal, L_exit); - __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input - __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds - for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) { - __ aesdec(xmm_result, as_XMMRegister(rnum)); - } - for (int key_offset = FIRST_NON_REG_KEY_offset; key_offset <= 0xa0; key_offset += 0x10) { // 128-bit runs up to key offset a0 - aes_dec_key(xmm_result, xmm_temp, key, key_offset); - } - load_key(xmm_temp, key, 0x00); // final key is stored in java expanded array at offset 0 - __ aesdeclast(xmm_result, xmm_temp); - __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00)); - __ pxor (xmm_result, xmm_temp); // xor with the current r vector - __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output - // no need to store r to memory until we exit - __ lea(prev_block_cipher_ptr, Address(from, pos, Address::times_1, 0)); // set up new ptr - __ addptr(pos, AESBlockSize); - __ subptr(len_reg, AESBlockSize); - __ jmp(L_singleBlock_loopTop_128); + for (int k = 0; k < 3; ++k) { + __ align(OptoLoopAlignment); + __ BIND(L_multiBlock_loopTop[k]); + __ cmpptr(len_reg, PARALLEL_FACTOR * AESBlockSize); // see if at least 4 blocks left + __ jcc(Assembler::less, L_singleBlock_loopTop[k]); + __ movdqu(xmm_result0, Address(from, pos, Address::times_1, 0 * AESBlockSize)); // get next 4 blocks into xmmresult registers + __ movdqu(xmm_result1, Address(from, pos, Address::times_1, 1 * AESBlockSize)); + __ movdqu(xmm_result2, Address(from, pos, Address::times_1, 2 * AESBlockSize)); + __ movdqu(xmm_result3, Address(from, pos, Address::times_1, 3 * AESBlockSize)); + + // the java expanded key ordering is rotated one position from what we want + // so we start from 0x10 here and hit 0x00 last + load_key(xmm_key_tmp0, key, 0x10, xmm_key_shuf_mask); + DoFour(pxor, xmm_key_tmp0); //xor with first key + // do the aes dec rounds + for (int rnum = 1; rnum <= ROUNDS[k];) { + //load two keys at a time + //k1->0x20, ..., k9->0xa0, k10->0x00 + load_key(xmm_key_tmp1, key, (rnum + 1) * 0x10, xmm_key_shuf_mask); + load_key(xmm_key_tmp0, key, ((rnum + 2) % (ROUNDS[k] + 1)) * 0x10, xmm_key_shuf_mask); // hit 0x00 last! + DoFour(aesdec, xmm_key_tmp1); + rnum++; + if (rnum != ROUNDS[k]) { + DoFour(aesdec, xmm_key_tmp0); + } + else { + DoFour(aesdeclast, xmm_key_tmp0); + } + rnum++; + } + + // for each result, xor with the r vector of previous cipher block + __ pxor(xmm_result0, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 0 * AESBlockSize)); + __ pxor(xmm_result1, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 1 * AESBlockSize)); + __ pxor(xmm_result2, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 2 * AESBlockSize)); + __ pxor(xmm_result3, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 3 * AESBlockSize)); // this will carry over to next set of blocks + + // store 4 results into the next 64 bytes of output + __ movdqu(Address(to, pos, Address::times_1, 0 * AESBlockSize), xmm_result0); + __ movdqu(Address(to, pos, Address::times_1, 1 * AESBlockSize), xmm_result1); + __ movdqu(Address(to, pos, Address::times_1, 2 * AESBlockSize), xmm_result2); + __ movdqu(Address(to, pos, Address::times_1, 3 * AESBlockSize), xmm_result3); + + __ addptr(pos, 4 * AESBlockSize); + __ subptr(len_reg, 4 * AESBlockSize); + __ jmp(L_multiBlock_loopTop[k]); + + //singleBlock starts here + __ align(OptoLoopAlignment); + __ BIND(L_singleBlock_loopTop[k]); + __ cmpptr(len_reg, 0); // any blocks left? + __ jcc(Assembler::equal, L_exit); + __ movdqu(xmm_result0, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input + __ movdqa(xmm_result1, xmm_result0); + + load_key(xmm_key_tmp0, key, 0x10, xmm_key_shuf_mask); + __ pxor(xmm_result0, xmm_key_tmp0); + // do the aes dec rounds + for (int rnum = 1; rnum < ROUNDS[k]; rnum++) { + // the java expanded key ordering is rotated one position from what we want + load_key(xmm_key_tmp0, key, (rnum + 1) * 0x10, xmm_key_shuf_mask); + __ aesdec(xmm_result0, xmm_key_tmp0); + } + load_key(xmm_key_tmp0, key, 0x00, xmm_key_shuf_mask); + __ aesdeclast(xmm_result0, xmm_key_tmp0); + __ pxor(xmm_result0, xmm_prev_block_cipher); // xor with the current r vector + __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result0); // store into the next 16 bytes of output + // no need to store r to memory until we exit + __ movdqa(xmm_prev_block_cipher, xmm_result1); // set up next r vector with cipher input from this block + + __ addptr(pos, AESBlockSize); + __ subptr(len_reg, AESBlockSize); + __ jmp(L_singleBlock_loopTop[k]); + }//for 128/192/256 __ BIND(L_exit); - __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00)); - __ movptr(rvec , rvec_param); // restore this since used in loop - __ movdqu(Address(rvec, 0), xmm_temp); // final value of r stored in rvec of CipherBlockChaining object + __ movptr(rvec, rvec_param); // restore this since reused earlier + __ movdqu(Address(rvec, 0), xmm_prev_block_cipher); // final value of r stored in rvec of CipherBlockChaining object handleSOERegisters(false /*restoring*/); - __ movptr(rax, len_param); // return length - __ leave(); // required for proper stackwalking of RuntimeStub frame + __ movptr(rax, len_param); // return length + __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - - __ BIND(L_key_192_256); - // here rax = len in ints of AESCrypt.KLE array (52=192, or 60=256) - __ cmpl(rax, 52); - __ jcc(Assembler::notEqual, L_key_256); - - // 192-bit code follows here (could be optimized to use parallelism) - __ movl(pos, 0); - __ align(OptoLoopAlignment); - __ BIND(L_singleBlock_loopTop_192); - __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input - __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds - for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) { - __ aesdec(xmm_result, as_XMMRegister(rnum)); - } - for (int key_offset = FIRST_NON_REG_KEY_offset; key_offset <= 0xc0; key_offset += 0x10) { // 192-bit runs up to key offset c0 - aes_dec_key(xmm_result, xmm_temp, key, key_offset); - } - load_key(xmm_temp, key, 0x00); // final key is stored in java expanded array at offset 0 - __ aesdeclast(xmm_result, xmm_temp); - __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00)); - __ pxor (xmm_result, xmm_temp); // xor with the current r vector - __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output - // no need to store r to memory until we exit - __ lea(prev_block_cipher_ptr, Address(from, pos, Address::times_1, 0)); // set up new ptr - __ addptr(pos, AESBlockSize); - __ subptr(len_reg, AESBlockSize); - __ jcc(Assembler::notEqual,L_singleBlock_loopTop_192); - __ jmp(L_exit); - - __ BIND(L_key_256); - // 256-bit code follows here (could be optimized to use parallelism) - __ movl(pos, 0); - __ align(OptoLoopAlignment); - __ BIND(L_singleBlock_loopTop_256); - __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input - __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds - for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) { - __ aesdec(xmm_result, as_XMMRegister(rnum)); - } - for (int key_offset = FIRST_NON_REG_KEY_offset; key_offset <= 0xe0; key_offset += 0x10) { // 256-bit runs up to key offset e0 - aes_dec_key(xmm_result, xmm_temp, key, key_offset); - } - load_key(xmm_temp, key, 0x00); // final key is stored in java expanded array at offset 0 - __ aesdeclast(xmm_result, xmm_temp); - __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00)); - __ pxor (xmm_result, xmm_temp); // xor with the current r vector - __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output - // no need to store r to memory until we exit - __ lea(prev_block_cipher_ptr, Address(from, pos, Address::times_1, 0)); // set up new ptr - __ addptr(pos, AESBlockSize); - __ subptr(len_reg, AESBlockSize); - __ jcc(Assembler::notEqual,L_singleBlock_loopTop_256); - __ jmp(L_exit); - return start; } - // CTR AES crypt. // In 32-bit stub, parallelize 4 blocks at a time // Arguments: @@ -3894,7 +3898,7 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock(); StubRoutines::_aescrypt_decryptBlock = generate_aescrypt_decryptBlock(); StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt(); - StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt(); + StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel(); } if (UseAESCTRIntrinsics) { diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp index d1df1eac653..882969c5695 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -3469,16 +3469,12 @@ class StubGenerator: public StubCodeGenerator { // Output: // rax - input length // - address generate_cipherBlockChaining_decryptAESCrypt_Parallel() { assert(UseAES, "need AES instructions and misaligned SSE support"); __ align(CodeEntryAlignment); StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_decryptAESCrypt"); address start = __ pc(); - Label L_exit, L_key_192_256, L_key_256; - Label L_singleBlock_loopTop_128, L_multiBlock_loopTop_128; - Label L_singleBlock_loopTop_192, L_singleBlock_loopTop_256; const Register from = c_rarg0; // source array address const Register to = c_rarg1; // destination array address const Register key = c_rarg2; // key array address @@ -3492,7 +3488,17 @@ class StubGenerator: public StubCodeGenerator { #endif const Register pos = rax; - // keys 0-10 preloaded into xmm2-xmm12 + const int PARALLEL_FACTOR = 4; + const int ROUNDS[3] = { 10, 12, 14 }; // aes rounds for key128, key192, key256 + + Label L_exit; + Label L_singleBlock_loopTopHead[3]; // 128, 192, 256 + Label L_singleBlock_loopTopHead2[3]; // 128, 192, 256 + Label L_singleBlock_loopTop[3]; // 128, 192, 256 + Label L_multiBlock_loopTopHead[3]; // 128, 192, 256 + Label L_multiBlock_loopTop[3]; // 128, 192, 256 + + // keys 0-10 preloaded into xmm5-xmm15 const int XMM_REG_NUM_KEY_FIRST = 5; const int XMM_REG_NUM_KEY_LAST = 15; const XMMRegister xmm_key_first = as_XMMRegister(XMM_REG_NUM_KEY_FIRST); @@ -3519,7 +3525,7 @@ class StubGenerator: public StubCodeGenerator { #else __ push(len_reg); // Save #endif - + __ push(rbx); // the java expanded key ordering is rotated one position from what we want // so we start from 0x10 here and hit 0x00 last const XMMRegister xmm_key_shuf_mask = xmm1; // used temporarily to swap key bytes up front @@ -3541,85 +3547,173 @@ class StubGenerator: public StubCodeGenerator { __ movdqu(xmm_prev_block_cipher, Address(rvec, 0x00)); // initialize with initial rvec + __ xorptr(pos, pos); + // now split to different paths depending on the keylen (len in ints of AESCrypt.KLE array (52=192, or 60=256)) - __ movl(rax, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT))); - __ cmpl(rax, 44); - __ jcc(Assembler::notEqual, L_key_192_256); + __ movl(rbx, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT))); + __ cmpl(rbx, 52); + __ jcc(Assembler::equal, L_multiBlock_loopTopHead[1]); + __ cmpl(rbx, 60); + __ jcc(Assembler::equal, L_multiBlock_loopTopHead[2]); +#define DoFour(opc, src_reg) \ + __ opc(xmm_result0, src_reg); \ + __ opc(xmm_result1, src_reg); \ + __ opc(xmm_result2, src_reg); \ + __ opc(xmm_result3, src_reg); \ - // 128-bit code follows here, parallelized - __ movptr(pos, 0); - __ align(OptoLoopAlignment); - __ BIND(L_multiBlock_loopTop_128); - __ cmpptr(len_reg, 4*AESBlockSize); // see if at least 4 blocks left - __ jcc(Assembler::less, L_singleBlock_loopTop_128); + for (int k = 0; k < 3; ++k) { + __ BIND(L_multiBlock_loopTopHead[k]); + if (k != 0) { + __ cmpptr(len_reg, PARALLEL_FACTOR * AESBlockSize); // see if at least 4 blocks left + __ jcc(Assembler::less, L_singleBlock_loopTopHead2[k]); + } + if (k == 1) { + __ subptr(rsp, 6 * wordSize); + __ movdqu(Address(rsp, 0), xmm15); //save last_key from xmm15 + load_key(xmm15, key, 0xb0); // 0xb0; 192-bit key goes up to 0xc0 + __ movdqu(Address(rsp, 2 * wordSize), xmm15); + load_key(xmm1, key, 0xc0); // 0xc0; + __ movdqu(Address(rsp, 4 * wordSize), xmm1); + } else if (k == 2) { + __ subptr(rsp, 10 * wordSize); + __ movdqu(Address(rsp, 0), xmm15); //save last_key from xmm15 + load_key(xmm15, key, 0xd0); // 0xd0; 256-bit key goes upto 0xe0 + __ movdqu(Address(rsp, 6 * wordSize), xmm15); + load_key(xmm1, key, 0xe0); // 0xe0; + __ movdqu(Address(rsp, 8 * wordSize), xmm1); + load_key(xmm15, key, 0xb0); // 0xb0; + __ movdqu(Address(rsp, 2 * wordSize), xmm15); + load_key(xmm1, key, 0xc0); // 0xc0; + __ movdqu(Address(rsp, 4 * wordSize), xmm1); + } + __ align(OptoLoopAlignment); + __ BIND(L_multiBlock_loopTop[k]); + __ cmpptr(len_reg, PARALLEL_FACTOR * AESBlockSize); // see if at least 4 blocks left + __ jcc(Assembler::less, L_singleBlock_loopTopHead[k]); - __ movdqu(xmm_result0, Address(from, pos, Address::times_1, 0*AESBlockSize)); // get next 4 blocks into xmmresult registers - __ movdqu(xmm_result1, Address(from, pos, Address::times_1, 1*AESBlockSize)); - __ movdqu(xmm_result2, Address(from, pos, Address::times_1, 2*AESBlockSize)); - __ movdqu(xmm_result3, Address(from, pos, Address::times_1, 3*AESBlockSize)); + if (k != 0) { + __ movdqu(xmm15, Address(rsp, 2 * wordSize)); + __ movdqu(xmm1, Address(rsp, 4 * wordSize)); + } -#define DoFour(opc, src_reg) \ - __ opc(xmm_result0, src_reg); \ - __ opc(xmm_result1, src_reg); \ - __ opc(xmm_result2, src_reg); \ - __ opc(xmm_result3, src_reg); + __ movdqu(xmm_result0, Address(from, pos, Address::times_1, 0 * AESBlockSize)); // get next 4 blocks into xmmresult registers + __ movdqu(xmm_result1, Address(from, pos, Address::times_1, 1 * AESBlockSize)); + __ movdqu(xmm_result2, Address(from, pos, Address::times_1, 2 * AESBlockSize)); + __ movdqu(xmm_result3, Address(from, pos, Address::times_1, 3 * AESBlockSize)); - DoFour(pxor, xmm_key_first); - for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST - 1; rnum++) { - DoFour(aesdec, as_XMMRegister(rnum)); - } - DoFour(aesdeclast, xmm_key_last); - // for each result, xor with the r vector of previous cipher block - __ pxor(xmm_result0, xmm_prev_block_cipher); - __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 0*AESBlockSize)); - __ pxor(xmm_result1, xmm_prev_block_cipher); - __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 1*AESBlockSize)); - __ pxor(xmm_result2, xmm_prev_block_cipher); - __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 2*AESBlockSize)); - __ pxor(xmm_result3, xmm_prev_block_cipher); - __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 3*AESBlockSize)); // this will carry over to next set of blocks + DoFour(pxor, xmm_key_first); + if (k == 0) { + for (int rnum = 1; rnum < ROUNDS[k]; rnum++) { + DoFour(aesdec, as_XMMRegister(rnum + XMM_REG_NUM_KEY_FIRST)); + } + DoFour(aesdeclast, xmm_key_last); + } else if (k == 1) { + for (int rnum = 1; rnum <= ROUNDS[k]-2; rnum++) { + DoFour(aesdec, as_XMMRegister(rnum + XMM_REG_NUM_KEY_FIRST)); + } + __ movdqu(xmm_key_last, Address(rsp, 0)); // xmm15 needs to be loaded again. + DoFour(aesdec, xmm1); // key : 0xc0 + __ movdqu(xmm_prev_block_cipher, Address(rvec, 0x00)); // xmm1 needs to be loaded again + DoFour(aesdeclast, xmm_key_last); + } else if (k == 2) { + for (int rnum = 1; rnum <= ROUNDS[k] - 4; rnum++) { + DoFour(aesdec, as_XMMRegister(rnum + XMM_REG_NUM_KEY_FIRST)); + } + DoFour(aesdec, xmm1); // key : 0xc0 + __ movdqu(xmm15, Address(rsp, 6 * wordSize)); + __ movdqu(xmm1, Address(rsp, 8 * wordSize)); + DoFour(aesdec, xmm15); // key : 0xd0 + __ movdqu(xmm_key_last, Address(rsp, 0)); // xmm15 needs to be loaded again. + DoFour(aesdec, xmm1); // key : 0xe0 + __ movdqu(xmm_prev_block_cipher, Address(rvec, 0x00)); // xmm1 needs to be loaded again + DoFour(aesdeclast, xmm_key_last); + } - __ movdqu(Address(to, pos, Address::times_1, 0*AESBlockSize), xmm_result0); // store 4 results into the next 64 bytes of output - __ movdqu(Address(to, pos, Address::times_1, 1*AESBlockSize), xmm_result1); - __ movdqu(Address(to, pos, Address::times_1, 2*AESBlockSize), xmm_result2); - __ movdqu(Address(to, pos, Address::times_1, 3*AESBlockSize), xmm_result3); + // for each result, xor with the r vector of previous cipher block + __ pxor(xmm_result0, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 0 * AESBlockSize)); + __ pxor(xmm_result1, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 1 * AESBlockSize)); + __ pxor(xmm_result2, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 2 * AESBlockSize)); + __ pxor(xmm_result3, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 3 * AESBlockSize)); // this will carry over to next set of blocks + if (k != 0) { + __ movdqu(Address(rvec, 0x00), xmm_prev_block_cipher); + } - __ addptr(pos, 4*AESBlockSize); - __ subptr(len_reg, 4*AESBlockSize); - __ jmp(L_multiBlock_loopTop_128); + __ movdqu(Address(to, pos, Address::times_1, 0 * AESBlockSize), xmm_result0); // store 4 results into the next 64 bytes of output + __ movdqu(Address(to, pos, Address::times_1, 1 * AESBlockSize), xmm_result1); + __ movdqu(Address(to, pos, Address::times_1, 2 * AESBlockSize), xmm_result2); + __ movdqu(Address(to, pos, Address::times_1, 3 * AESBlockSize), xmm_result3); - // registers used in the non-parallelized loops - // xmm register assignments for the loops below - const XMMRegister xmm_result = xmm0; - const XMMRegister xmm_prev_block_cipher_save = xmm2; - const XMMRegister xmm_key11 = xmm3; - const XMMRegister xmm_key12 = xmm4; - const XMMRegister xmm_temp = xmm4; + __ addptr(pos, PARALLEL_FACTOR * AESBlockSize); + __ subptr(len_reg, PARALLEL_FACTOR * AESBlockSize); + __ jmp(L_multiBlock_loopTop[k]); - __ align(OptoLoopAlignment); - __ BIND(L_singleBlock_loopTop_128); - __ cmpptr(len_reg, 0); // any blocks left?? - __ jcc(Assembler::equal, L_exit); - __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input - __ movdqa(xmm_prev_block_cipher_save, xmm_result); // save for next r vector - __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds - for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST - 1; rnum++) { - __ aesdec(xmm_result, as_XMMRegister(rnum)); - } - __ aesdeclast(xmm_result, xmm_key_last); - __ pxor (xmm_result, xmm_prev_block_cipher); // xor with the current r vector - __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output - // no need to store r to memory until we exit - __ movdqa(xmm_prev_block_cipher, xmm_prev_block_cipher_save); // set up next r vector with cipher input from this block + // registers used in the non-parallelized loops + // xmm register assignments for the loops below + const XMMRegister xmm_result = xmm0; + const XMMRegister xmm_prev_block_cipher_save = xmm2; + const XMMRegister xmm_key11 = xmm3; + const XMMRegister xmm_key12 = xmm4; + const XMMRegister key_tmp = xmm4; - __ addptr(pos, AESBlockSize); - __ subptr(len_reg, AESBlockSize); - __ jmp(L_singleBlock_loopTop_128); + __ BIND(L_singleBlock_loopTopHead[k]); + if (k == 1) { + __ addptr(rsp, 6 * wordSize); + } else if (k == 2) { + __ addptr(rsp, 10 * wordSize); + } + __ cmpptr(len_reg, 0); // any blocks left?? + __ jcc(Assembler::equal, L_exit); + __ BIND(L_singleBlock_loopTopHead2[k]); + if (k == 1) { + load_key(xmm_key11, key, 0xb0); // 0xb0; 192-bit key goes upto 0xc0 + load_key(xmm_key12, key, 0xc0); // 0xc0; 192-bit key goes upto 0xc0 + } + if (k == 2) { + load_key(xmm_key11, key, 0xb0); // 0xb0; 256-bit key goes upto 0xe0 + } + __ align(OptoLoopAlignment); + __ BIND(L_singleBlock_loopTop[k]); + __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input + __ movdqa(xmm_prev_block_cipher_save, xmm_result); // save for next r vector + __ pxor(xmm_result, xmm_key_first); // do the aes dec rounds + for (int rnum = 1; rnum <= 9 ; rnum++) { + __ aesdec(xmm_result, as_XMMRegister(rnum + XMM_REG_NUM_KEY_FIRST)); + } + if (k == 1) { + __ aesdec(xmm_result, xmm_key11); + __ aesdec(xmm_result, xmm_key12); + } + if (k == 2) { + __ aesdec(xmm_result, xmm_key11); + load_key(key_tmp, key, 0xc0); + __ aesdec(xmm_result, key_tmp); + load_key(key_tmp, key, 0xd0); + __ aesdec(xmm_result, key_tmp); + load_key(key_tmp, key, 0xe0); + __ aesdec(xmm_result, key_tmp); + } + __ aesdeclast(xmm_result, xmm_key_last); // xmm15 always came from key+0 + __ pxor(xmm_result, xmm_prev_block_cipher); // xor with the current r vector + __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output + // no need to store r to memory until we exit + __ movdqa(xmm_prev_block_cipher, xmm_prev_block_cipher_save); // set up next r vector with cipher input from this block + __ addptr(pos, AESBlockSize); + __ subptr(len_reg, AESBlockSize); + __ jcc(Assembler::notEqual, L_singleBlock_loopTop[k]); + if (k != 2) { + __ jmp(L_exit); + } + } //for 128/192/256 __ BIND(L_exit); __ movdqu(Address(rvec, 0), xmm_prev_block_cipher); // final value of r stored in rvec of CipherBlockChaining object + __ pop(rbx); #ifdef _WIN64 // restore regs belonging to calling function for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) { @@ -3631,69 +3725,8 @@ class StubGenerator: public StubCodeGenerator { #endif __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - - - __ BIND(L_key_192_256); - // here rax = len in ints of AESCrypt.KLE array (52=192, or 60=256) - load_key(xmm_key11, key, 0xb0); - __ cmpl(rax, 52); - __ jcc(Assembler::notEqual, L_key_256); - - // 192-bit code follows here (could be optimized to use parallelism) - load_key(xmm_key12, key, 0xc0); // 192-bit key goes up to c0 - __ movptr(pos, 0); - __ align(OptoLoopAlignment); - - __ BIND(L_singleBlock_loopTop_192); - __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input - __ movdqa(xmm_prev_block_cipher_save, xmm_result); // save for next r vector - __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds - for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST - 1; rnum++) { - __ aesdec(xmm_result, as_XMMRegister(rnum)); - } - __ aesdec(xmm_result, xmm_key11); - __ aesdec(xmm_result, xmm_key12); - __ aesdeclast(xmm_result, xmm_key_last); // xmm15 always came from key+0 - __ pxor (xmm_result, xmm_prev_block_cipher); // xor with the current r vector - __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output - // no need to store r to memory until we exit - __ movdqa(xmm_prev_block_cipher, xmm_prev_block_cipher_save); // set up next r vector with cipher input from this block - __ addptr(pos, AESBlockSize); - __ subptr(len_reg, AESBlockSize); - __ jcc(Assembler::notEqual,L_singleBlock_loopTop_192); - __ jmp(L_exit); - - __ BIND(L_key_256); - // 256-bit code follows here (could be optimized to use parallelism) - __ movptr(pos, 0); - __ align(OptoLoopAlignment); - - __ BIND(L_singleBlock_loopTop_256); - __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input - __ movdqa(xmm_prev_block_cipher_save, xmm_result); // save for next r vector - __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds - for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST - 1; rnum++) { - __ aesdec(xmm_result, as_XMMRegister(rnum)); - } - __ aesdec(xmm_result, xmm_key11); - load_key(xmm_temp, key, 0xc0); - __ aesdec(xmm_result, xmm_temp); - load_key(xmm_temp, key, 0xd0); - __ aesdec(xmm_result, xmm_temp); - load_key(xmm_temp, key, 0xe0); // 256-bit key goes up to e0 - __ aesdec(xmm_result, xmm_temp); - __ aesdeclast(xmm_result, xmm_key_last); // xmm15 came from key+0 - __ pxor (xmm_result, xmm_prev_block_cipher); // xor with the current r vector - __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output - // no need to store r to memory until we exit - __ movdqa(xmm_prev_block_cipher, xmm_prev_block_cipher_save); // set up next r vector with cipher input from this block - __ addptr(pos, AESBlockSize); - __ subptr(len_reg, AESBlockSize); - __ jcc(Assembler::notEqual,L_singleBlock_loopTop_256); - __ jmp(L_exit); - return start; - } +} address generate_upper_word_mask() { __ align(64); diff --git a/hotspot/src/cpu/x86/vm/x86_32.ad b/hotspot/src/cpu/x86/vm/x86_32.ad index c9583ba13e0..a7ee85d03ae 100644 --- a/hotspot/src/cpu/x86/vm/x86_32.ad +++ b/hotspot/src/cpu/x86/vm/x86_32.ad @@ -795,6 +795,9 @@ static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load, } if (cbuf) { MacroAssembler _masm(cbuf); + // EVEX spills remain EVEX: Compressed displacemement is better than AVX on spill mem operations, + // it maps more cases to single byte displacement + _masm.set_managed(); if (reg_lo+1 == reg_hi) { // double move? if (is_load) { __ movdbl(as_XMMRegister(Matcher::_regEncode[reg_lo]), Address(rsp, offset)); @@ -845,6 +848,8 @@ static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst int src_hi, int dst_hi, int size, outputStream* st ) { if (cbuf) { MacroAssembler _masm(cbuf); + // EVEX spills remain EVEX: logic complex between full EVEX, partial and AVX, manage EVEX spill code one way. + _masm.set_managed(); if (src_lo+1 == src_hi && dst_lo+1 == dst_hi) { // double move? __ movdbl(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo])); @@ -883,6 +888,8 @@ static int impl_movgpr2x_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int // 32-bit if (cbuf) { MacroAssembler _masm(cbuf); + // EVEX spills remain EVEX: logic complex between full EVEX, partial and AVX, manage EVEX spill code one way. + _masm.set_managed(); __ movdl(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_Register(Matcher::_regEncode[src_lo])); #ifndef PRODUCT @@ -899,6 +906,8 @@ static int impl_movx2gpr_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int // 32-bit if (cbuf) { MacroAssembler _masm(cbuf); + // EVEX spills remain EVEX: logic complex between full EVEX, partial and AVX, manage EVEX spill code one way. + _masm.set_managed(); __ movdl(as_Register(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo])); #ifndef PRODUCT diff --git a/hotspot/src/cpu/zero/vm/globals_zero.hpp b/hotspot/src/cpu/zero/vm/globals_zero.hpp index a9a2f45fe5d..52a3cacbd70 100644 --- a/hotspot/src/cpu/zero/vm/globals_zero.hpp +++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp @@ -42,7 +42,8 @@ define_pd_global(bool, UncommonNullCast, true); define_pd_global(intx, CodeEntryAlignment, 32); define_pd_global(intx, OptoLoopAlignment, 16); define_pd_global(intx, InlineFrequencyCount, 100); -define_pd_global(intx, InlineSmallCode, 1000 ); +define_pd_global(intx, InlineSmallCode, 1000); +define_pd_global(intx, InitArrayShortSize, -1); // not used #define DEFAULT_STACK_YELLOW_PAGES (2) #define DEFAULT_STACK_RED_PAGES (1) diff --git a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java index 7c8d43a287a..df8202dbd41 100644 --- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java @@ -249,7 +249,6 @@ public class NMethod extends CodeBlob { // public int age(); // public boolean isMarkedForDeoptimization(); // public boolean isMarkedForUnloading(); - // public boolean isMarkedForReclamation(); // public int level(); // public int version(); diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java index ef3fd7cf1c5..09901998ffb 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -479,6 +479,11 @@ final class CompilerToVM { */ native String getSymbol(long metaspaceSymbol); + /** + * Lookup a VMSymbol from a String. + */ + native long lookupSymbol(String symbol); + /** * Looks for the next Java stack frame matching an entry in {@code methods}. * diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java index a352bb4d842..eb156fe74ab 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -39,4 +39,6 @@ public interface HotSpotMemoryAccessProvider extends MemoryAccessProvider { Constant readNarrowKlassPointerConstant(Constant base, long displacement, CompressEncoding encoding); Constant readMethodPointerConstant(Constant base, long displacement); + + Constant readSymbolConstant(Constant base, long displacement); } diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java index 44e7c64cc19..3a74ac51d0d 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -82,13 +82,13 @@ class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, Ho Object base = asObject(baseConstant); if (base != null) { switch (bits) { - case 8: + case Byte.SIZE: return UNSAFE.getByte(base, displacement); - case 16: + case Short.SIZE: return UNSAFE.getShort(base, displacement); - case 32: + case Integer.SIZE: return UNSAFE.getInt(base, displacement); - case 64: + case Long.SIZE: return UNSAFE.getLong(base, displacement); default: throw new JVMCIError("%d", bits); @@ -96,13 +96,13 @@ class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, Ho } else { long pointer = asRawPointer(baseConstant); switch (bits) { - case 8: + case Byte.SIZE: return UNSAFE.getByte(pointer + displacement); - case 16: + case Short.SIZE: return UNSAFE.getShort(pointer + displacement); - case 32: + case Integer.SIZE: return UNSAFE.getInt(pointer + displacement); - case 64: + case Long.SIZE: return UNSAFE.getLong(pointer + displacement); default: throw new JVMCIError("%d", bits); @@ -151,7 +151,8 @@ class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, Ho Object o = readRawObject(baseConstant, displacement, runtime.getConfig().useCompressedOops); return HotSpotObjectConstantImpl.forObject(o); } else { - return readPrimitiveConstant(kind, baseConstant, displacement, kind.getByteCount() * 8); + int bits = kind.getByteCount() * Byte.SIZE; + return readPrimitiveConstant(kind, baseConstant, displacement, bits); } } @@ -229,4 +230,16 @@ class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, Ho HotSpotResolvedJavaMethodImpl method = runtime.getCompilerToVM().getResolvedJavaMethod(baseObject, displacement); return HotSpotMetaspaceConstantImpl.forMetaspaceObject(method, false); } + + @Override + public Constant readSymbolConstant(Constant base, long displacement) { + int bits = runtime.getConfig().symbolPointerSize * Byte.SIZE; + long pointer = readRawValue(base, displacement, bits); + if (pointer == 0) { + return JavaConstant.NULL_POINTER; + } else { + String symbol = runtime.getCompilerToVM().getSymbol(pointer); + return new HotSpotSymbol(symbol, pointer).asConstant(); + } + } } diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java index fd92a15bd96..1eef812be32 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -78,6 +78,15 @@ public class HotSpotMetaAccessProvider implements MetaAccessProvider, HotSpotPro return new HotSpotSignature(runtime, signature); } + public HotSpotSymbol lookupSymbol(String symbol) { + long pointer = runtime.getCompilerToVM().lookupSymbol(symbol); + if (pointer == 0) { + return null; + } else { + return new HotSpotSymbol(symbol, pointer); + } + } + /** * {@link Field} object of {@link Method#slot}. */ diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java index a19aa486e2c..f02fd38884c 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -29,4 +29,6 @@ public interface HotSpotMetaspaceConstant extends HotSpotConstant, VMConstant { HotSpotResolvedObjectType asResolvedJavaType(); HotSpotResolvedJavaMethod asResolvedJavaMethod(); + + HotSpotSymbol asSymbol(); } diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java index 43051ab5e2a..abf349e7690 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -108,4 +108,11 @@ final class HotSpotMetaspaceConstantImpl implements HotSpotMetaspaceConstant, VM } return null; } + + public HotSpotSymbol asSymbol() { + if (metaspaceObject instanceof HotSpotSymbol) { + return (HotSpotSymbol) metaspaceObject; + } + return null; + } } diff --git a/jdk/test/sun/net/InetAddress/nameservice/deadlock/ThrowingNameService.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSymbol.java similarity index 57% rename from jdk/test/sun/net/InetAddress/nameservice/deadlock/ThrowingNameService.java rename to hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSymbol.java index 292b31dda88..cfb11f338d7 100644 --- a/jdk/test/sun/net/InetAddress/nameservice/deadlock/ThrowingNameService.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSymbol.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -20,28 +20,38 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ +package jdk.vm.ci.hotspot; -import java.net.InetAddress; -import java.net.UnknownHostException; -import sun.net.spi.nameservice.NameService; +import jdk.vm.ci.meta.Constant; -public class ThrowingNameService implements NameService { - static boolean firstCall = true; +/** + * Class to access the C++ {@code vmSymbols} table. + */ +public final class HotSpotSymbol implements MetaspaceWrapperObject { - @Override - public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException { - if (firstCall) { - firstCall = false; - // throw unchecked exception first time round - throw new IllegalStateException(); - } + private final String symbol; + private final long pointer; - // return any valid address - return new InetAddress[] { InetAddress.getLoopbackAddress() }; + HotSpotSymbol(String symbol, long pointer) { + this.symbol = symbol; + this.pointer = pointer; + } + + public String getSymbol() { + return symbol; + } + + public Constant asConstant() { + return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false); } @Override - public String getHostByAddr(byte[] addr) throws UnknownHostException { - throw new IllegalStateException(); + public long getMetaspacePointer() { + return pointer; + } + + @Override + public String toString() { + return "Symbol<" + symbol + ">"; } } diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java index 744ec27c044..72c2552adf3 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java @@ -1001,6 +1001,7 @@ public class HotSpotVMConfig { @HotSpotVMField(name = "Klass::_modifier_flags", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassModifierFlagsOffset; @HotSpotVMField(name = "Klass::_access_flags", type = "AccessFlags", get = HotSpotVMField.Type.OFFSET) @Stable public int klassAccessFlagsOffset; @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassLayoutHelperOffset; + @HotSpotVMField(name = "Klass::_name", type = "Symbol*", get = HotSpotVMField.Type.OFFSET) @Stable public int klassNameOffset; @HotSpotVMConstant(name = "Klass::_lh_neutral_value") @Stable public int klassLayoutHelperNeutralValue; @HotSpotVMConstant(name = "Klass::_lh_instance_slow_path_bit") @Stable public int klassLayoutHelperInstanceSlowPathBit; @@ -1536,8 +1537,9 @@ public class HotSpotVMConfig { @HotSpotVMAddress(name = "JVMCIRuntime::exception_handler_for_pc") @Stable public long exceptionHandlerForPcAddress; @HotSpotVMAddress(name = "JVMCIRuntime::monitorenter") @Stable public long monitorenterAddress; @HotSpotVMAddress(name = "JVMCIRuntime::monitorexit") @Stable public long monitorexitAddress; - @HotSpotVMAddress(name = "JVMCIRuntime::create_null_exception") @Stable public long createNullPointerExceptionAddress; - @HotSpotVMAddress(name = "JVMCIRuntime::create_out_of_bounds_exception") @Stable public long createOutOfBoundsExceptionAddress; + @HotSpotVMAddress(name = "JVMCIRuntime::throw_and_post_jvmti_exception") @Stable public long throwAndPostJvmtiExceptionAddress; + @HotSpotVMAddress(name = "JVMCIRuntime::throw_klass_external_name_exception") @Stable public long throwKlassExternalNameExceptionAddress; + @HotSpotVMAddress(name = "JVMCIRuntime::throw_class_cast_exception") @Stable public long throwClassCastExceptionAddress; @HotSpotVMAddress(name = "JVMCIRuntime::log_primitive") @Stable public long logPrimitiveAddress; @HotSpotVMAddress(name = "JVMCIRuntime::log_object") @Stable public long logObjectAddress; @HotSpotVMAddress(name = "JVMCIRuntime::log_printf") @Stable public long logPrintfAddress; diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java index 7bb1f592224..8262924bf5a 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java @@ -28,8 +28,7 @@ package jdk.vm.ci.runtime; public interface JVMCICompilerFactory { /** - * Get the name of this compiler. The compiler will be selected when the jvmci.compiler system - * property is equal to this name. + * Get the name of this compiler. */ String getCompilerName(); diff --git a/hotspot/src/jdk.vm.ci/share/classes/module-info.java b/hotspot/src/jdk.vm.ci/share/classes/module-info.java index a59a37d56e2..e105f01e10a 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/module-info.java +++ b/hotspot/src/jdk.vm.ci/share/classes/module-info.java @@ -24,6 +24,9 @@ */ module jdk.vm.ci { + // 8153756 + requires jdk.unsupported; + uses jdk.vm.ci.hotspot.HotSpotVMEventListener; uses jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory; uses jdk.vm.ci.runtime.JVMCICompilerFactory; diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp index 5fd0e0a78af..f6a8ad3d53d 100644 --- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp +++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp @@ -277,7 +277,7 @@ bool os::Solaris::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_ return false; } else { *fr = os::fetch_frame_from_ucontext(thread, uc); - *fr = frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc()); + *fr = frame(fr->sender_sp(), fr->sp()); if (!fr->is_java_frame()) { assert(fr->safe_for_sender(thread), "Safety check"); *fr = fr->java_sender(); diff --git a/hotspot/src/share/vm/c1/c1_Compiler.cpp b/hotspot/src/share/vm/c1/c1_Compiler.cpp index b7885a31cfc..1829ff8f887 100644 --- a/hotspot/src/share/vm/c1/c1_Compiler.cpp +++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp @@ -209,9 +209,6 @@ bool Compiler::is_intrinsic_supported(const methodHandle& method) { case vmIntrinsics::_putLong_raw: case vmIntrinsics::_putFloat_raw: case vmIntrinsics::_putDouble_raw: - case vmIntrinsics::_putOrderedObject: - case vmIntrinsics::_putOrderedInt: - case vmIntrinsics::_putOrderedLong: case vmIntrinsics::_getShortUnaligned: case vmIntrinsics::_getCharUnaligned: case vmIntrinsics::_getIntUnaligned: diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp index c3483a5fe00..a15a521adaf 100644 --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp @@ -3450,9 +3450,6 @@ void GraphBuilder::build_graph_for_intrinsic(ciMethod* callee) { case vmIntrinsics::_putLong_raw : append_unsafe_put_raw(callee, T_LONG ); return; case vmIntrinsics::_putFloat_raw : append_unsafe_put_raw(callee, T_FLOAT ); return; case vmIntrinsics::_putDouble_raw : append_unsafe_put_raw(callee, T_DOUBLE); return; - case vmIntrinsics::_putOrderedObject : append_unsafe_put_obj(callee, T_OBJECT, true); return; - case vmIntrinsics::_putOrderedInt : append_unsafe_put_obj(callee, T_INT, true); return; - case vmIntrinsics::_putOrderedLong : append_unsafe_put_obj(callee, T_LONG, true); return; case vmIntrinsics::_compareAndSwapLong: case vmIntrinsics::_compareAndSwapInt: case vmIntrinsics::_compareAndSwapObject: append_unsafe_CAS(callee); return; diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp index b8df66256b3..03438c5ee8e 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp @@ -999,8 +999,16 @@ void LIRGenerator::move_to_phi(PhiResolver* resolver, Value cur_val, Value sux_v Phi* phi = sux_val->as_Phi(); // cur_val can be null without phi being null in conjunction with inlining if (phi != NULL && cur_val != NULL && cur_val != phi && !phi->is_illegal()) { + Phi* cur_phi = cur_val->as_Phi(); + if (cur_phi != NULL && cur_phi->is_illegal()) { + // Phi and local would need to get invalidated + // (which is unexpected for Linear Scan). + // But this case is very rare so we simply bail out. + bailout("propagation of illegal phi"); + return; + } LIR_Opr operand = cur_val->operand(); - if (cur_val->operand()->is_illegal()) { + if (operand->is_illegal()) { assert(cur_val->as_Constant() != NULL || cur_val->as_Local() != NULL, "these can be produced lazily"); operand = operand_for_instruction(cur_val); diff --git a/hotspot/src/share/vm/c1/c1_ValueStack.hpp b/hotspot/src/share/vm/c1/c1_ValueStack.hpp index 8340adbd289..14efe073551 100644 --- a/hotspot/src/share/vm/c1/c1_ValueStack.hpp +++ b/hotspot/src/share/vm/c1/c1_ValueStack.hpp @@ -99,14 +99,14 @@ class ValueStack: public CompilationResourceObj { void clear_locals(); // sets all locals to NULL; void invalidate_local(int i) { - assert(_locals.at(i)->type()->is_single_word() || + assert(!_locals.at(i)->type()->is_double_word() || _locals.at(i + 1) == NULL, "hi-word of doubleword value must be NULL"); _locals.at_put(i, NULL); } Value local_at(int i) const { Value x = _locals.at(i); - assert(x == NULL || x->type()->is_single_word() || + assert(x == NULL || !x->type()->is_double_word() || _locals.at(i + 1) == NULL, "hi-word of doubleword value must be NULL"); return x; } @@ -131,7 +131,7 @@ class ValueStack: public CompilationResourceObj { // stack access Value stack_at(int i) const { Value x = _stack.at(i); - assert(x->type()->is_single_word() || + assert(!x->type()->is_double_word() || _stack.at(i + 1) == NULL, "hi-word of doubleword value must be NULL"); return x; } diff --git a/hotspot/src/share/vm/c1/c1_globals.hpp b/hotspot/src/share/vm/c1/c1_globals.hpp index ad6548e4928..168262cf20a 100644 --- a/hotspot/src/share/vm/c1/c1_globals.hpp +++ b/hotspot/src/share/vm/c1/c1_globals.hpp @@ -176,7 +176,7 @@ product(bool, InlineSynchronizedMethods, true, \ "Inline synchronized methods") \ \ - develop(bool, InlineNIOCheckIndex, true, \ + diagnostic(bool, InlineNIOCheckIndex, true, \ "Intrinsify java.nio.Buffer.checkIndex") \ \ develop(bool, CanonicalizeNodes, true, \ diff --git a/hotspot/src/share/vm/ci/ciEnv.cpp b/hotspot/src/share/vm/ci/ciEnv.cpp index 21e952ee57f..4170a2375ba 100644 --- a/hotspot/src/share/vm/ci/ciEnv.cpp +++ b/hotspot/src/share/vm/ci/ciEnv.cpp @@ -773,7 +773,7 @@ ciMethod* ciEnv::get_method_by_index_impl(const constantPoolHandle& cpool, Symbol* sig_sym = cpool->signature_ref_at(index); if (cpool->has_preresolution() - || (holder == ciEnv::MethodHandle_klass() && + || ((holder == ciEnv::MethodHandle_klass() || holder == ciEnv::VarHandle_klass()) && MethodHandles::is_signature_polymorphic_name(holder->get_Klass(), name_sym))) { // Short-circuit lookups for JSR 292-related call sites. // That is, do not rely only on name-based lookups, because they may fail diff --git a/hotspot/src/share/vm/ci/ciReplay.cpp b/hotspot/src/share/vm/ci/ciReplay.cpp index aee1baf56e8..0181836f6cb 100644 --- a/hotspot/src/share/vm/ci/ciReplay.cpp +++ b/hotspot/src/share/vm/ci/ciReplay.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2013, 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 @@ -1057,8 +1057,6 @@ void* ciReplay::load_inline_data(ciMethod* method, int entry_bci, int comp_level int ciReplay::replay_impl(TRAPS) { HandleMark hm; ResourceMark rm; - // Make sure we don't run with background compilation - BackgroundCompilation = false; if (ReplaySuppressInitializers > 2) { // ReplaySuppressInitializers > 2 means that we want to allow diff --git a/hotspot/src/share/vm/classfile/classLoader.cpp b/hotspot/src/share/vm/classfile/classLoader.cpp index d4196c38bd6..12e256e3d10 100644 --- a/hotspot/src/share/vm/classfile/classLoader.cpp +++ b/hotspot/src/share/vm/classfile/classLoader.cpp @@ -1455,8 +1455,7 @@ void ClassLoader::compile_the_world() { EXCEPTION_MARK; HandleMark hm(THREAD); ResourceMark rm(THREAD); - // Make sure we don't run with background compilation - BackgroundCompilation = false; + // Find bootstrap loader Handle system_class_loader (THREAD, SystemDictionary::java_system_loader()); // Iterate over all bootstrap class path entries diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index 71f176bd988..2851bccb3be 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -2563,7 +2563,8 @@ static methodHandle unpack_method_and_appendix(Handle mname, return empty; } -methodHandle SystemDictionary::find_method_handle_invoker(Symbol* name, +methodHandle SystemDictionary::find_method_handle_invoker(KlassHandle klass, + Symbol* name, Symbol* signature, KlassHandle accessing_klass, Handle *appendix_result, @@ -2574,7 +2575,6 @@ methodHandle SystemDictionary::find_method_handle_invoker(Symbol* name, Handle method_type = SystemDictionary::find_method_handle_type(signature, accessing_klass, CHECK_(empty)); - KlassHandle mh_klass = SystemDictionary::MethodHandle_klass(); int ref_kind = JVM_REF_invokeVirtual; Handle name_str = StringTable::intern(name, CHECK_(empty)); objArrayHandle appendix_box = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1, CHECK_(empty)); @@ -2589,7 +2589,7 @@ methodHandle SystemDictionary::find_method_handle_invoker(Symbol* name, JavaCallArguments args; args.push_oop(accessing_klass()->java_mirror()); args.push_int(ref_kind); - args.push_oop(mh_klass()->java_mirror()); + args.push_oop(klass()->java_mirror()); args.push_oop(name_str()); args.push_oop(method_type()); args.push_oop(appendix_box()); diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp index 1e148322348..aaee2858dc5 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.hpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp @@ -153,6 +153,7 @@ class SymbolPropertyTable; /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \ do_klass(DirectMethodHandle_klass, java_lang_invoke_DirectMethodHandle, Opt ) \ do_klass(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre ) \ + do_klass(VarHandle_klass, java_lang_invoke_VarHandle, Pre ) \ do_klass(MemberName_klass, java_lang_invoke_MemberName, Pre ) \ do_klass(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre ) \ do_klass(LambdaForm_klass, java_lang_invoke_LambdaForm, Opt ) \ @@ -518,7 +519,8 @@ public: // JSR 292 // find a java.lang.invoke.MethodHandle.invoke* method for a given signature // (asks Java to compute it if necessary, except in a compiler thread) - static methodHandle find_method_handle_invoker(Symbol* name, + static methodHandle find_method_handle_invoker(KlassHandle klass, + Symbol* name, Symbol* signature, KlassHandle accessing_klass, Handle *appendix_result, diff --git a/hotspot/src/share/vm/classfile/vmSymbols.cpp b/hotspot/src/share/vm/classfile/vmSymbols.cpp index 73324bc9ec6..42555054305 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.cpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp @@ -592,9 +592,6 @@ bool vmIntrinsics::is_disabled_by_flags(const methodHandle& method) { case vmIntrinsics::_putLong_raw: case vmIntrinsics::_putFloat_raw: case vmIntrinsics::_putDouble_raw: - case vmIntrinsics::_putOrderedObject: - case vmIntrinsics::_putOrderedLong: - case vmIntrinsics::_putOrderedInt: case vmIntrinsics::_getAndAddInt: case vmIntrinsics::_getAndAddLong: case vmIntrinsics::_getAndSetInt: diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index e54c48b1aa3..2a3eeba36bb 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -120,7 +120,7 @@ template(jdk_internal_misc_Signal, "jdk/internal/misc/Signal") \ template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \ template(getBootClassPathEntryForClass_name, "getBootClassPathEntryForClass") \ - template(sun_misc_PostVMInitHook, "sun/misc/PostVMInitHook") \ + template(jdk_internal_vm_PostVMInitHook, "jdk/internal/vm/PostVMInitHook") \ template(sun_net_www_ParseUtil, "sun/net/www/ParseUtil") \ \ template(jdk_internal_loader_ClassLoaders_AppClassLoader, "jdk/internal/loader/ClassLoaders$AppClassLoader") \ @@ -289,6 +289,7 @@ template(java_lang_invoke_MutableCallSite, "java/lang/invoke/MutableCallSite") \ template(java_lang_invoke_VolatileCallSite, "java/lang/invoke/VolatileCallSite") \ template(java_lang_invoke_MethodHandle, "java/lang/invoke/MethodHandle") \ + template(java_lang_invoke_VarHandle, "java/lang/invoke/VarHandle") \ template(java_lang_invoke_MethodType, "java/lang/invoke/MethodType") \ template(java_lang_invoke_MethodType_signature, "Ljava/lang/invoke/MethodType;") \ template(java_lang_invoke_MemberName_signature, "Ljava/lang/invoke/MemberName;") \ @@ -655,7 +656,7 @@ \ /* JVMTI/java.lang.instrument support and VM Attach mechanism */ \ template(jdk_internal_module_Modules, "jdk/internal/module/Modules") \ - template(sun_misc_VMSupport, "sun/misc/VMSupport") \ + template(jdk_internal_vm_VMSupport, "jdk/internal/vm/VMSupport") \ template(transformedByAgent_name, "transformedByAgent") \ template(transformedByAgent_signature, "(Ljava/lang/reflect/Module;)V") \ template(appendToClassPathForInstrumentation_name, "appendToClassPathForInstrumentation") \ @@ -1329,16 +1330,6 @@ do_intrinsic(_weakCompareAndSwapIntAcquire, jdk_internal_misc_Unsafe, weakCompareAndSwapIntAcquire_name, compareAndSwapInt_signature, F_R) \ do_intrinsic(_weakCompareAndSwapIntRelease, jdk_internal_misc_Unsafe, weakCompareAndSwapIntRelease_name, compareAndSwapInt_signature, F_R) \ \ - do_intrinsic(_putOrderedObject, jdk_internal_misc_Unsafe, putOrderedObject_name, putOrderedObject_signature, F_RN) \ - do_name( putOrderedObject_name, "putOrderedObject") \ - do_alias( putOrderedObject_signature, /*(LObject;JLObject;)V*/ putObject_signature) \ - do_intrinsic(_putOrderedLong, jdk_internal_misc_Unsafe, putOrderedLong_name, putOrderedLong_signature, F_RN) \ - do_name( putOrderedLong_name, "putOrderedLong") \ - do_alias( putOrderedLong_signature, /*(Ljava/lang/Object;JJ)V*/ putLong_signature) \ - do_intrinsic(_putOrderedInt, jdk_internal_misc_Unsafe, putOrderedInt_name, putOrderedInt_signature, F_RN) \ - do_name( putOrderedInt_name, "putOrderedInt") \ - do_alias( putOrderedInt_signature, /*(Ljava/lang/Object;JI)V*/ putInt_signature) \ - \ do_intrinsic(_getAndAddInt, jdk_internal_misc_Unsafe, getAndAddInt_name, getAndAddInt_signature, F_R) \ do_name( getAndAddInt_name, "getAndAddInt") \ do_signature(getAndAddInt_signature, "(Ljava/lang/Object;JI)I" ) \ diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp index dc1ea6fa031..fb83ce224ed 100644 --- a/hotspot/src/share/vm/code/nmethod.cpp +++ b/hotspot/src/share/vm/code/nmethod.cpp @@ -530,7 +530,6 @@ const char* nmethod::compile_kind() const { void nmethod::init_defaults() { _state = in_use; _unloading_clock = 0; - _marked_for_reclamation = 0; _has_flushed_dependencies = 0; _has_unsafe_access = 0; _has_method_handle_invokes = 0; @@ -1332,8 +1331,19 @@ void nmethod::make_unloaded(BoolObjectClosure* is_alive, oop cause) { } // Unlink the osr method, so we do not look this up again if (is_osr_method()) { - invalidate_osr_method(); + // Invalidate the osr nmethod only once + if (is_in_use()) { + invalidate_osr_method(); + } +#ifdef ASSERT + if (method() != NULL) { + // Make sure osr nmethod is invalidated, i.e. not on the list + bool found = method()->method_holder()->remove_osr_nmethod(this); + assert(!found, "osr nmethod should have been invalidated"); + } +#endif } + // If _method is already NULL the Method* is about to be unloaded, // so we don't have to break the cycle. Note that it is possible to // have the Method* live here, in case we unload the nmethod because @@ -1387,8 +1397,9 @@ void nmethod::make_unloaded(BoolObjectClosure* is_alive, oop cause) { void nmethod::invalidate_osr_method() { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); // Remove from list of active nmethods - if (method() != NULL) + if (method() != NULL) { method()->method_holder()->remove_osr_nmethod(this); + } } void nmethod::log_state_change() const { @@ -1436,8 +1447,9 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) { // invalidate osr nmethod before acquiring the patching lock since // they both acquire leaf locks and we don't want a deadlock. // This logic is equivalent to the logic below for patching the - // verified entry point of regular methods. - if (is_osr_method()) { + // verified entry point of regular methods. We check that the + // nmethod is in use to ensure that it is invalidated only once. + if (is_osr_method() && is_in_use()) { // this effectively makes the osr nmethod not entrant invalidate_osr_method(); } @@ -1503,13 +1515,21 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) { } } // leave critical region under Patching_lock +#ifdef ASSERT + if (is_osr_method() && method() != NULL) { + // Make sure osr nmethod is invalidated, i.e. not on the list + bool found = method()->method_holder()->remove_osr_nmethod(this); + assert(!found, "osr nmethod should have been invalidated"); + } +#endif + // When the nmethod becomes zombie it is no longer alive so the // dependencies must be flushed. nmethods in the not_entrant // state will be flushed later when the transition to zombie // happens or they get unloaded. if (state == zombie) { { - // Flushing dependecies must be done before any possible + // Flushing dependencies must be done before any possible // safepoint can sneak in, otherwise the oops used by the // dependency logic could have become stale. MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); @@ -1525,7 +1545,7 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) { // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload // event and it hasn't already been reported for this nmethod then - // report it now. The event may have been reported earilier if the GC + // report it now. The event may have been reported earlier if the GC // marked it for unloading). JvmtiDeferredEventQueue support means // we no longer go to a safepoint here. post_compiled_method_unload(); @@ -1553,18 +1573,18 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) { void nmethod::flush() { // Note that there are no valid oops in the nmethod anymore. - assert(is_zombie() || (is_osr_method() && is_unloaded()), "must be a zombie method"); - assert(is_marked_for_reclamation() || (is_osr_method() && is_unloaded()), "must be marked for reclamation"); - + assert(!is_osr_method() || is_unloaded() || is_zombie(), + "osr nmethod must be unloaded or zombie before flushing"); + assert(is_zombie() || is_osr_method(), "must be a zombie method"); assert (!is_locked_by_vm(), "locked methods shouldn't be flushed"); assert_locked_or_safepoint(CodeCache_lock); // completely deallocate this method Events::log(JavaThread::current(), "flushing nmethod " INTPTR_FORMAT, p2i(this)); if (PrintMethodFlushing) { - tty->print_cr("*flushing nmethod %3d/" INTPTR_FORMAT ". Live blobs:" UINT32_FORMAT + tty->print_cr("*flushing %s nmethod %3d/" INTPTR_FORMAT ". Live blobs:" UINT32_FORMAT "/Free CodeCache:" SIZE_FORMAT "Kb", - _compile_id, p2i(this), CodeCache::blob_count(), + is_osr_method() ? "osr" : "",_compile_id, p2i(this), CodeCache::blob_count(), CodeCache::unallocated_capacity(CodeCache::get_code_blob_type(this))/1024); } @@ -2916,10 +2936,7 @@ void nmethod::print() const { tty->print("((nmethod*) " INTPTR_FORMAT ") ", p2i(this)); tty->print(" for method " INTPTR_FORMAT , p2i(method())); tty->print(" { "); - if (is_in_use()) tty->print("in_use "); - if (is_not_entrant()) tty->print("not_entrant "); - if (is_zombie()) tty->print("zombie "); - if (is_unloaded()) tty->print("unloaded "); + tty->print_cr("%s ", state()); if (on_scavenge_root_list()) tty->print("scavenge_root "); tty->print_cr("}:"); } diff --git a/hotspot/src/share/vm/code/nmethod.hpp b/hotspot/src/share/vm/code/nmethod.hpp index 6c0d9f839ac..5d18b582c88 100644 --- a/hotspot/src/share/vm/code/nmethod.hpp +++ b/hotspot/src/share/vm/code/nmethod.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -188,8 +188,6 @@ class nmethod : public CodeBlob { // protected by CodeCache_lock bool _has_flushed_dependencies; // Used for maintenance of dependencies (CodeCache_lock) - bool _marked_for_reclamation; // Used by NMethodSweeper (set only by sweeper) - enum MarkForDeoptimizationStatus { not_marked, deoptimize, @@ -207,7 +205,7 @@ class nmethod : public CodeBlob { unsigned int _has_wide_vectors:1; // Preserve wide vectors at safepoints // Protected by Patching_lock - volatile unsigned char _state; // {alive, not_entrant, zombie, unloaded} + volatile unsigned char _state; // {in_use, not_entrant, zombie, unloaded} volatile unsigned char _unloading_clock; // Incremented after GC unloaded/cleaned the nmethod @@ -438,7 +436,20 @@ class nmethod : public CodeBlob { bool is_alive() const { return _state == in_use || _state == not_entrant; } bool is_not_entrant() const { return _state == not_entrant; } bool is_zombie() const { return _state == zombie; } - bool is_unloaded() const { return _state == unloaded; } + bool is_unloaded() const { return _state == unloaded; } + + // returns a string version of the nmethod state + const char* state() const { + switch(_state) { + case in_use: return "in use"; + case not_entrant: return "not_entrant"; + case zombie: return "zombie"; + case unloaded: return "unloaded"; + default: + fatal("unexpected nmethod state: %d", _state); + return NULL; + } + } #if INCLUDE_RTM_OPT // rtm state accessing and manipulating @@ -490,9 +501,6 @@ class nmethod : public CodeBlob { _has_flushed_dependencies = 1; } - bool is_marked_for_reclamation() const { return _marked_for_reclamation; } - void mark_for_reclamation() { _marked_for_reclamation = 1; } - bool has_unsafe_access() const { return _has_unsafe_access; } void set_has_unsafe_access(bool z) { _has_unsafe_access = z; } diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp index 672fed6f7f4..08e80cfde6e 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.cpp +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp @@ -773,7 +773,8 @@ void CompileBroker::init_compiler_sweeper_threads(int c1_compiler_count, int c2_ #endif // !ZERO && !SHARK // Initialize the compilation queue if (c2_compiler_count > 0) { - _c2_compile_queue = new CompileQueue("C2 compile queue"); + const char* name = JVMCI_ONLY(UseJVMCICompiler ? "JVMCI compile queue" :) "C2 compile queue"; + _c2_compile_queue = new CompileQueue(name); _compilers[1]->set_num_compiler_threads(c2_compiler_count); } if (c1_compiler_count > 0) { @@ -1169,7 +1170,8 @@ nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci, CompilationPolicy::policy()->delay_compilation(method()); return NULL; } - compile_method_base(method, osr_bci, comp_level, hot_method, hot_count, comment, !directive->BackgroundCompilationOption, THREAD); + bool is_blocking = !directive->BackgroundCompilationOption || CompileTheWorld || ReplayCompiles; + compile_method_base(method, osr_bci, comp_level, hot_method, hot_count, comment, is_blocking, THREAD); } // return requested nmethod @@ -1649,6 +1651,10 @@ void CompileBroker::init_compiler_thread_log() { tty->print_cr("Opening compilation log %s", file_name); } CompileLog* log = new(ResourceObj::C_HEAP, mtCompiler) CompileLog(file_name, fp, thread_id); + if (log == NULL) { + fclose(fp); + return; + } thread->init_log(log); if (xtty != NULL) { diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp index 5c7e9b13d35..6bae45b4661 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp @@ -90,10 +90,16 @@ void CallInfo::set_virtual(KlassHandle resolved_klass, void CallInfo::set_handle(const methodHandle& resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS) { + set_handle(SystemDictionary::MethodHandle_klass(), resolved_method, resolved_appendix, resolved_method_type, CHECK); +} + +void CallInfo::set_handle(KlassHandle resolved_klass, + const methodHandle& resolved_method, + Handle resolved_appendix, + Handle resolved_method_type, TRAPS) { if (resolved_method.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "resolved method is null"); } - KlassHandle resolved_klass = SystemDictionary::MethodHandle_klass(); assert(resolved_method->intrinsic_id() == vmIntrinsics::_invokeBasic || resolved_method->is_compiled_lambda_form(), "linkMethod must return one of these"); @@ -433,7 +439,8 @@ methodHandle LinkResolver::lookup_polymorphic_method( vmIntrinsics::name_at(iid), klass->external_name(), name->as_C_string(), full_signature->as_C_string()); } - if (klass() == SystemDictionary::MethodHandle_klass() && + if ((klass() == SystemDictionary::MethodHandle_klass() || + klass() == SystemDictionary::VarHandle_klass()) && iid != vmIntrinsics::_none) { if (MethodHandles::is_signature_polymorphic_intrinsic(iid)) { // Most of these do not need an up-call to Java to resolve, so can be done anywhere. @@ -482,6 +489,7 @@ methodHandle LinkResolver::lookup_polymorphic_method( Handle appendix; Handle method_type; methodHandle result = SystemDictionary::find_method_handle_invoker( + klass, name, full_signature, link_info.current_klass(), @@ -1561,13 +1569,15 @@ void LinkResolver::resolve_handle_call(CallInfo& result, const LinkInfo& link_info, TRAPS) { // JSR 292: this must be an implicitly generated method MethodHandle.invokeExact(*...) or similar - assert(link_info.resolved_klass()() == SystemDictionary::MethodHandle_klass(), ""); + KlassHandle resolved_klass = link_info.resolved_klass(); + assert(resolved_klass() == SystemDictionary::MethodHandle_klass() || + resolved_klass() == SystemDictionary::VarHandle_klass(), ""); assert(MethodHandles::is_signature_polymorphic_name(link_info.name()), ""); Handle resolved_appendix; Handle resolved_method_type; methodHandle resolved_method = lookup_polymorphic_method(link_info, &resolved_appendix, &resolved_method_type, CHECK); - result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK); + result.set_handle(resolved_klass, resolved_method, resolved_appendix, resolved_method_type, CHECK); } static void wrap_invokedynamic_exception(TRAPS) { diff --git a/hotspot/src/share/vm/interpreter/linkResolver.hpp b/hotspot/src/share/vm/interpreter/linkResolver.hpp index 20bd8f31ffa..a197070dadd 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.hpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp @@ -69,6 +69,9 @@ class CallInfo : public StackObj { int vtable_index, TRAPS); void set_handle(const methodHandle& resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS); + void set_handle(KlassHandle resolved_klass, + const methodHandle& resolved_method, + Handle resolved_appendix, Handle resolved_method_type, TRAPS); void set_common(KlassHandle resolved_klass, KlassHandle selected_klass, const methodHandle& resolved_method, const methodHandle& selected_method, diff --git a/hotspot/src/share/vm/interpreter/rewriter.cpp b/hotspot/src/share/vm/interpreter/rewriter.cpp index 55cec0f70e3..41e29a6ee53 100644 --- a/hotspot/src/share/vm/interpreter/rewriter.cpp +++ b/hotspot/src/share/vm/interpreter/rewriter.cpp @@ -54,8 +54,10 @@ void Rewriter::compute_index_maps() { add_resolved_references_entry(i); break; case JVM_CONSTANT_Utf8: - if (_pool->symbol_at(i) == vmSymbols::java_lang_invoke_MethodHandle()) + if (_pool->symbol_at(i) == vmSymbols::java_lang_invoke_MethodHandle() || + _pool->symbol_at(i) == vmSymbols::java_lang_invoke_VarHandle()) { saw_mh_symbol = true; + } break; } } @@ -200,6 +202,12 @@ void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, int cache_i // we may need a resolved_refs entry for the appendix add_invokedynamic_resolved_references_entries(cp_index, cache_index); status = +1; + } else if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_VarHandle() && + MethodHandles::is_signature_polymorphic_name(SystemDictionary::VarHandle_klass(), + _pool->name_ref_at(cp_index))) { + // we may need a resolved_refs entry for the appendix + add_invokedynamic_resolved_references_entries(cp_index, cache_index); + status = +1; } else { status = -1; } diff --git a/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp index 2043b59d5e1..9586d4438c1 100644 --- a/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp +++ b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp @@ -177,7 +177,13 @@ OopMap* CodeInstaller::create_oop_map(Handle debug_info, TRAPS) { return map; } -Metadata* CodeInstaller::record_metadata_reference(Handle constant, TRAPS) { +void* CodeInstaller::record_metadata_reference(Handle constant, TRAPS) { + /* + * This method needs to return a raw (untyped) pointer, since the value of a pointer to the base + * class is in general not equal to the pointer of the subclass. When patching metaspace pointers, + * the compiler expects a direct pointer to the subclass (Klass*, Method* or Symbol*), not a + * pointer to the base class (Metadata* or MetaspaceObj*). + */ oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant); if (obj->is_a(HotSpotResolvedObjectTypeImpl::klass())) { Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj)); @@ -191,6 +197,11 @@ Metadata* CodeInstaller::record_metadata_reference(Handle constant, TRAPS) { int index = _oop_recorder->find_index(method); TRACE_jvmci_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), method->name()->as_C_string()); return method; + } else if (obj->is_a(HotSpotSymbol::klass())) { + Symbol* symbol = (Symbol*) (address) HotSpotSymbol::pointer(obj); + assert(!HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected compressed symbol pointer %s @ " INTPTR_FORMAT, symbol->as_C_string(), p2i(symbol)); + TRACE_jvmci_3("symbol = %s", symbol->as_C_string()); + return symbol; } else { JVMCI_ERROR_NULL("unexpected metadata reference for constant of type %s", obj->klass()->signature_name()); } @@ -706,7 +717,7 @@ JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer, JVMCI_ERROR_OK("unexpected compressed Klass* in 32-bit mode"); #endif } else { - *((Metadata**) dest) = record_metadata_reference(constant, CHECK_OK); + *((void**) dest) = record_metadata_reference(constant, CHECK_OK); } } else if (constant->is_a(HotSpotObjectConstantImpl::klass())) { Handle obj = HotSpotObjectConstantImpl::object(constant); diff --git a/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.hpp b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.hpp index c5fc3da05b7..d9afec758e6 100644 --- a/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.hpp +++ b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.hpp @@ -189,7 +189,7 @@ protected: ScopeValue* get_scope_value(Handle value, BasicType type, GrowableArray* objects, ScopeValue* &second, TRAPS); MonitorValue* get_monitor_value(Handle value, GrowableArray* objects, TRAPS); - Metadata* record_metadata_reference(Handle constant, TRAPS); + void* record_metadata_reference(Handle constant, TRAPS); #ifdef _LP64 narrowKlass record_narrow_metadata_reference(Handle constant, TRAPS); #endif diff --git a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp index a444c909e9e..6ebf89a58d7 100644 --- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp +++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp @@ -448,7 +448,10 @@ C2V_END C2V_VMENTRY(jboolean, canInlineMethod,(JNIEnv *, jobject, jobject jvmci_method)) methodHandle method = CompilerToVM::asMethod(jvmci_method); - return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method) && !method->dont_inline(); + // In hosted mode ignore the not_compilable flags since they are never set by + // the JVMCI compiler. + bool is_compilable = UseJVMCICompiler ? !method->is_not_compilable(CompLevel_full_optimization) : true; + return is_compilable && !CompilerOracle::should_not_inline(method) && !method->dont_inline(); C2V_END C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv *, jobject, jobject jvmci_method)) @@ -1048,6 +1051,11 @@ C2V_VMENTRY(jobject, getSymbol, (JNIEnv*, jobject, jlong symbol)) return JNIHandles::make_local(THREAD, sym()); C2V_END +C2V_VMENTRY(jlong, lookupSymbol, (JNIEnv*, jobject, jobject string)) + Symbol* symbol = java_lang_String::as_symbol_or_null(JNIHandles::resolve(string)); + return (jlong) symbol; +C2V_END + bool matches(jobjectArray methods, Method* method) { objArrayOop methods_oop = (objArrayOop) JNIHandles::resolve(methods); @@ -1475,6 +1483,7 @@ JNINativeMethod CompilerToVM::methods[] = { {CC"isMature", CC"("METASPACE_METHOD_DATA")Z", FN_PTR(isMature)}, {CC"hasCompiledCodeForOSR", CC"("HS_RESOLVED_METHOD"II)Z", FN_PTR(hasCompiledCodeForOSR)}, {CC"getSymbol", CC"(J)"STRING, FN_PTR(getSymbol)}, + {CC"lookupSymbol", CC"("STRING")J", FN_PTR(lookupSymbol)}, {CC"getNextStackFrame", CC"("HS_STACK_FRAME_REF "["RESOLVED_METHOD"I)"HS_STACK_FRAME_REF, FN_PTR(getNextStackFrame)}, {CC"materializeVirtualObjects", CC"("HS_STACK_FRAME_REF"Z)V", FN_PTR(materializeVirtualObjects)}, {CC"shouldDebugNonSafepoints", CC"()Z", FN_PTR(shouldDebugNonSafepoints)}, diff --git a/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp b/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp index e9fd2b29929..0988998b599 100644 --- a/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp +++ b/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp @@ -64,6 +64,9 @@ class JVMCIJavaClasses : AllStatic { start_class(HotSpotResolvedJavaMethodImpl) \ long_field(HotSpotResolvedJavaMethodImpl, metaspaceMethod) \ end_class \ + start_class(HotSpotSymbol) \ + long_field(HotSpotSymbol, pointer) \ + end_class \ start_class(InstalledCode) \ long_field(InstalledCode, address) \ long_field(InstalledCode, entryPoint) \ diff --git a/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp b/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp index 367afbf36e1..c398f7442b7 100644 --- a/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp +++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp @@ -363,20 +363,6 @@ address JVMCIRuntime::exception_handler_for_pc(JavaThread* thread) { return continuation; } -JRT_ENTRY(void, JVMCIRuntime::create_null_exception(JavaThread* thread)) - SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException()); - thread->set_vm_result(PENDING_EXCEPTION); - CLEAR_PENDING_EXCEPTION; -JRT_END - -JRT_ENTRY(void, JVMCIRuntime::create_out_of_bounds_exception(JavaThread* thread, jint index)) - char message[jintAsStringSize]; - sprintf(message, "%d", index); - SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message); - thread->set_vm_result(PENDING_EXCEPTION); - CLEAR_PENDING_EXCEPTION; -JRT_END - JRT_ENTRY_NO_ASYNC(void, JVMCIRuntime::monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock)) IF_TRACE_jvmci_3 { char type[O_BUFLEN]; @@ -438,6 +424,21 @@ JRT_LEAF(void, JVMCIRuntime::monitorexit(JavaThread* thread, oopDesc* obj, Basic } JRT_END +JRT_ENTRY(void, JVMCIRuntime::throw_and_post_jvmti_exception(JavaThread* thread, Symbol* name, const char* message)) + SharedRuntime::throw_and_post_jvmti_exception(thread, name, message); +JRT_END + +JRT_ENTRY(void, JVMCIRuntime::throw_klass_external_name_exception(JavaThread* thread, Symbol* exception, Klass* klass)) + ResourceMark rm(thread); + SharedRuntime::throw_and_post_jvmti_exception(thread, exception, klass->external_name()); +JRT_END + +JRT_ENTRY(void, JVMCIRuntime::throw_class_cast_exception(JavaThread* thread, Symbol* exception, Klass* caster_klass, Klass* target_klass)) + ResourceMark rm(thread); + const char* message = SharedRuntime::generate_class_cast_message(caster_klass, target_klass); + SharedRuntime::throw_and_post_jvmti_exception(thread, exception, message); +JRT_END + JRT_LEAF(void, JVMCIRuntime::log_object(JavaThread* thread, oopDesc* obj, bool as_string, bool newline)) ttyLocker ttyl; @@ -800,12 +801,9 @@ void JVMCIRuntime::shutdown(TRAPS) { bool JVMCIRuntime::treat_as_trivial(Method* method) { if (_HotSpotJVMCIRuntime_initialized) { - oop loader = method->method_holder()->class_loader(); - if (loader == NULL) { - for (int i = 0; i < _trivial_prefixes_count; i++) { - if (method->method_holder()->name()->starts_with(_trivial_prefixes[i])) { - return true; - } + for (int i = 0; i < _trivial_prefixes_count; i++) { + if (method->method_holder()->name()->starts_with(_trivial_prefixes[i])) { + return true; } } } diff --git a/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp b/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp index 4c37817537d..256872aee4d 100644 --- a/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp +++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp @@ -141,8 +141,6 @@ class JVMCIRuntime: public AllStatic { static address exception_handler_for_pc(JavaThread* thread); static void monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock); static void monitorexit (JavaThread* thread, oopDesc* obj, BasicLock* lock); - static void create_null_exception(JavaThread* thread); - static void create_out_of_bounds_exception(JavaThread* thread, jint index); static void vm_error(JavaThread* thread, jlong where, jlong format, jlong value); static oopDesc* load_and_clear_exception(JavaThread* thread); static void log_printf(JavaThread* thread, oopDesc* format, jlong v1, jlong v2, jlong v3); @@ -157,6 +155,12 @@ class JVMCIRuntime: public AllStatic { static jboolean validate_object(JavaThread* thread, oopDesc* parent, oopDesc* child); static void new_store_pre_barrier(JavaThread* thread); + // used to throw exceptions from compiled JVMCI code + static void throw_and_post_jvmti_exception(JavaThread* thread, Symbol* exception, const char* message); + // helper methods to throw exception with complex messages + static void throw_klass_external_name_exception(JavaThread* thread, Symbol* exception, Klass* klass); + static void throw_class_cast_exception(JavaThread* thread, Symbol* exception, Klass* caster_klass, Klass* target_klass); + // Test only function static int test_deoptimize_call_int(JavaThread* thread, int value); }; diff --git a/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp b/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp index 864539f6654..1d51114071a 100644 --- a/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp +++ b/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp @@ -49,6 +49,7 @@ do_klass(HotSpotJVMCIMetaAccessContext_klass, jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext, Jvmci) \ do_klass(HotSpotJVMCIRuntime_klass, jdk_vm_ci_hotspot_HotSpotJVMCIRuntime, Jvmci) \ do_klass(HotSpotSpeculationLog_klass, jdk_vm_ci_hotspot_HotSpotSpeculationLog, Jvmci) \ + do_klass(HotSpotSymbol_klass, jdk_vm_ci_hotspot_HotSpotSymbol, Jvmci) \ do_klass(Assumptions_ConcreteMethod_klass, jdk_vm_ci_meta_Assumptions_ConcreteMethod, Jvmci) \ do_klass(Assumptions_NoFinalizableSubclass_klass, jdk_vm_ci_meta_Assumptions_NoFinalizableSubclass, Jvmci) \ do_klass(Assumptions_ConcreteSubtype_klass, jdk_vm_ci_meta_Assumptions_ConcreteSubtype, Jvmci) \ diff --git a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp index 9c754133a40..b668737d709 100644 --- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp +++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp @@ -165,6 +165,7 @@ nonstatic_field(Klass, _super_check_offset, juint) \ nonstatic_field(Klass, _subklass, Klass*) \ nonstatic_field(Klass, _layout_helper, jint) \ + nonstatic_field(Klass, _name, Symbol*) \ nonstatic_field(Klass, _prototype_header, markOop) \ nonstatic_field(Klass, _next_sibling, Klass*) \ nonstatic_field(Klass, _java_mirror, oop) \ @@ -551,8 +552,9 @@ declare_function(JVMCIRuntime::exception_handler_for_pc) \ declare_function(JVMCIRuntime::monitorenter) \ declare_function(JVMCIRuntime::monitorexit) \ - declare_function(JVMCIRuntime::create_null_exception) \ - declare_function(JVMCIRuntime::create_out_of_bounds_exception) \ + declare_function(JVMCIRuntime::throw_and_post_jvmti_exception) \ + declare_function(JVMCIRuntime::throw_klass_external_name_exception) \ + declare_function(JVMCIRuntime::throw_class_cast_exception) \ declare_function(JVMCIRuntime::log_primitive) \ declare_function(JVMCIRuntime::log_object) \ declare_function(JVMCIRuntime::log_printf) \ diff --git a/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp b/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp index f7aada3b81b..49e141715b7 100644 --- a/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp +++ b/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp @@ -50,6 +50,7 @@ template(jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext, "jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext") \ template(jdk_vm_ci_hotspot_HotSpotJVMCIRuntime, "jdk/vm/ci/hotspot/HotSpotJVMCIRuntime") \ template(jdk_vm_ci_hotspot_HotSpotSpeculationLog, "jdk/vm/ci/hotspot/HotSpotSpeculationLog") \ + template(jdk_vm_ci_hotspot_HotSpotSymbol, "jdk/vm/ci/hotspot/HotSpotSymbol") \ template(jdk_vm_ci_meta_JavaConstant, "jdk/vm/ci/meta/JavaConstant") \ template(jdk_vm_ci_meta_PrimitiveConstant, "jdk/vm/ci/meta/PrimitiveConstant") \ template(jdk_vm_ci_meta_RawConstant, "jdk/vm/ci/meta/RawConstant") \ diff --git a/hotspot/src/share/vm/memory/metachunk.cpp b/hotspot/src/share/vm/memory/metachunk.cpp index 63d4cd13ac3..8ecbaacc821 100644 --- a/hotspot/src/share/vm/memory/metachunk.cpp +++ b/hotspot/src/share/vm/memory/metachunk.cpp @@ -30,8 +30,6 @@ class VirtualSpaceNode; -const size_t metadata_chunk_initialize = 0xf7f7f7f7; - size_t Metachunk::object_alignment() { // Must align pointers and sizes to 8, // so that 64 bit types get correctly aligned. @@ -58,12 +56,7 @@ Metachunk::Metachunk(size_t word_size, _top = initial_top(); #ifdef ASSERT set_is_tagged_free(false); - size_t data_word_size = pointer_delta(end(), - _top, - sizeof(MetaWord)); - Copy::fill_to_words((HeapWord*)_top, - data_word_size, - metadata_chunk_initialize); + mangle(uninitMetaWordVal); #endif } @@ -98,12 +91,12 @@ void Metachunk::print_on(outputStream* st) const { } #ifndef PRODUCT -void Metachunk::mangle() { - // Mangle the payload of the chunk and not the links that +void Metachunk::mangle(juint word_value) { + // Overwrite the payload of the chunk and not the links that // maintain list of chunks. - HeapWord* start = (HeapWord*)(bottom() + overhead()); + HeapWord* start = (HeapWord*)initial_top(); size_t size = word_size() - overhead(); - Copy::fill_to_words(start, size, metadata_chunk_initialize); + Copy::fill_to_words(start, size, word_value); } #endif // PRODUCT diff --git a/hotspot/src/share/vm/memory/metachunk.hpp b/hotspot/src/share/vm/memory/metachunk.hpp index e873dc6a32c..b116d27ead8 100644 --- a/hotspot/src/share/vm/memory/metachunk.hpp +++ b/hotspot/src/share/vm/memory/metachunk.hpp @@ -145,7 +145,9 @@ class Metachunk : public Metabase { bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; } - NOT_PRODUCT(void mangle();) +#ifndef PRODUCT + void mangle(juint word_value); +#endif void print_on(outputStream* st) const; void verify(); diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 199702e083e..352fc09ea17 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -811,11 +811,6 @@ void VirtualSpaceNode::verify_container_count() { BlockFreelist::BlockFreelist() : _dictionary(new BlockTreeDictionary()) {} BlockFreelist::~BlockFreelist() { - LogHandle(gc, metaspace, freelist) log; - if (log.is_trace()) { - ResourceMark rm; - dictionary()->print_free_lists(log.trace_stream()); - } delete _dictionary; } @@ -2145,6 +2140,7 @@ void ChunkManager::return_chunks(ChunkIndex index, Metachunk* chunks) { // by the call to return_chunk_at_head(); Metachunk* next = cur->next(); DEBUG_ONLY(cur->set_is_tagged_free(true);) + NOT_PRODUCT(cur->mangle(badMetaWordVal);) list->return_chunk_at_head(cur); cur = next; } @@ -2169,11 +2165,9 @@ SpaceManager::~SpaceManager() { log.trace("~SpaceManager(): " PTR_FORMAT, p2i(this)); ResourceMark rm; locked_print_chunks_in_use_on(log.trace_stream()); + block_freelists()->print_on(log.trace_stream()); } - // Do not mangle freed Metachunks. The chunk size inside Metachunks - // is during the freeing of a VirtualSpaceNodes. - // Have to update before the chunks_in_use lists are emptied // below. chunk_manager()->inc_free_chunks_total(allocated_chunks_words(), @@ -2206,9 +2200,8 @@ SpaceManager::~SpaceManager() { Metachunk* humongous_chunks = chunks_in_use(HumongousIndex); while (humongous_chunks != NULL) { -#ifdef ASSERT - humongous_chunks->set_is_tagged_free(true); -#endif + DEBUG_ONLY(humongous_chunks->set_is_tagged_free(true);) + NOT_PRODUCT(humongous_chunks->mangle(badMetaWordVal);) log.trace(PTR_FORMAT " (" SIZE_FORMAT ") ", p2i(humongous_chunks), humongous_chunks->word_size()); assert(humongous_chunks->word_size() == (size_t) align_size_up(humongous_chunks->word_size(), @@ -2527,7 +2520,7 @@ void SpaceManager::mangle_freed_chunks() { for (Metachunk* curr = chunks_in_use(index); curr != NULL; curr = curr->next()) { - curr->mangle(); + curr->mangle(uninitMetaWordVal); } } } diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index f526756a0ce..5eb39b8fa70 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -2614,8 +2614,8 @@ void InstanceKlass::add_osr_nmethod(nmethod* n) { } } - -void InstanceKlass::remove_osr_nmethod(nmethod* n) { +// Remove osr nmethod from the list. Return true if found and removed. +bool InstanceKlass::remove_osr_nmethod(nmethod* n) { // This is a short non-blocking critical region, so the no safepoint check is ok. MutexLockerEx ml(OsrList_lock, Mutex::_no_safepoint_check_flag); assert(n->is_osr_method(), "wrong kind of nmethod"); @@ -2624,6 +2624,7 @@ void InstanceKlass::remove_osr_nmethod(nmethod* n) { int max_level = CompLevel_none; // Find the max comp level excluding n Method* m = n->method(); // Search for match + bool found = false; while(cur != NULL && cur != n) { if (TieredCompilation && m == cur->method()) { // Find max level before n @@ -2634,6 +2635,7 @@ void InstanceKlass::remove_osr_nmethod(nmethod* n) { } nmethod* next = NULL; if (cur == n) { + found = true; next = cur->osr_link(); if (last == NULL) { // Remove first element @@ -2654,6 +2656,7 @@ void InstanceKlass::remove_osr_nmethod(nmethod* n) { } m->set_highest_osr_comp_level(max_level); } + return found; } int InstanceKlass::mark_osr_nmethods(const Method* m) { diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index 4fdcc440e09..768b3535ab4 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -878,7 +878,7 @@ public: nmethod* osr_nmethods_head() const { return _osr_nmethods_head; }; void set_osr_nmethods_head(nmethod* h) { _osr_nmethods_head = h; }; void add_osr_nmethod(nmethod* n); - void remove_osr_nmethod(nmethod* n); + bool remove_osr_nmethod(nmethod* n); int mark_osr_nmethods(const Method* m); nmethod* lookup_osr_nmethod(const Method* m, int bci, int level, bool match_level) const; diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index 6f6b995de1c..0b41252b558 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -1351,11 +1351,16 @@ void Method::init_intrinsic_id() { // ditto for method and signature: vmSymbols::SID name_id = vmSymbols::find_sid(name()); if (klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle) - && name_id == vmSymbols::NO_SID) + && klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_VarHandle) + && name_id == vmSymbols::NO_SID) { return; + } vmSymbols::SID sig_id = vmSymbols::find_sid(signature()); if (klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle) - && sig_id == vmSymbols::NO_SID) return; + && klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_VarHandle) + && sig_id == vmSymbols::NO_SID) { + return; + } jshort flags = access_flags().as_short(); vmIntrinsics::ID id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags); @@ -1383,8 +1388,9 @@ void Method::init_intrinsic_id() { } break; - // Signature-polymorphic methods: MethodHandle.invoke*, InvokeDynamic.*. + // Signature-polymorphic methods: MethodHandle.invoke*, InvokeDynamic.*., VarHandle case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle): + case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_VarHandle): if (!is_native()) break; id = MethodHandles::signature_polymorphic_name_id(method_holder(), name()); if (is_static() != MethodHandles::is_signature_polymorphic_static(id)) diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index ef70518af81..9507ca64dc8 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -595,26 +595,26 @@ product(bool, BlockLayoutRotateLoops, true, \ "Allow back branches to be fall throughs in the block layour") \ \ - develop(bool, InlineReflectionGetCallerClass, true, \ + diagnostic(bool, InlineReflectionGetCallerClass, true, \ "inline sun.reflect.Reflection.getCallerClass(), known to be " \ "part of base library DLL") \ \ - develop(bool, InlineObjectCopy, true, \ + diagnostic(bool, InlineObjectCopy, true, \ "inline Object.clone and Arrays.copyOf[Range] intrinsics") \ \ - develop(bool, SpecialStringCompareTo, true, \ + diagnostic(bool, SpecialStringCompareTo, true, \ "special version of string compareTo") \ \ - develop(bool, SpecialStringIndexOf, true, \ + diagnostic(bool, SpecialStringIndexOf, true, \ "special version of string indexOf") \ \ - develop(bool, SpecialStringEquals, true, \ + diagnostic(bool, SpecialStringEquals, true, \ "special version of string equals") \ \ - develop(bool, SpecialArraysEquals, true, \ + diagnostic(bool, SpecialArraysEquals, true, \ "special version of Arrays.equals(char[],char[])") \ \ - product(bool, SpecialEncodeISOArray, true, \ + diagnostic(bool, SpecialEncodeISOArray, true, \ "special version of ISO_8859_1$Encoder.encodeISOArray") \ \ develop(bool, BailoutToInterpreterForThrows, false, \ @@ -716,22 +716,22 @@ diagnostic(bool, OptimizeExpensiveOps, true, \ "Find best control for expensive operations") \ \ - product(bool, UseMathExactIntrinsics, true, \ + diagnostic(bool, UseMathExactIntrinsics, true, \ "Enables intrinsification of various java.lang.Math functions") \ \ - product(bool, UseMultiplyToLenIntrinsic, false, \ + diagnostic(bool, UseMultiplyToLenIntrinsic, false, \ "Enables intrinsification of BigInteger.multiplyToLen()") \ \ - product(bool, UseSquareToLenIntrinsic, false, \ + diagnostic(bool, UseSquareToLenIntrinsic, false, \ "Enables intrinsification of BigInteger.squareToLen()") \ \ - product(bool, UseMulAddIntrinsic, false, \ + diagnostic(bool, UseMulAddIntrinsic, false, \ "Enables intrinsification of BigInteger.mulAdd()") \ \ - product(bool, UseMontgomeryMultiplyIntrinsic, false, \ + diagnostic(bool, UseMontgomeryMultiplyIntrinsic, false, \ "Enables intrinsification of BigInteger.montgomeryMultiply()") \ \ - product(bool, UseMontgomerySquareIntrinsic, false, \ + diagnostic(bool, UseMontgomerySquareIntrinsic, false, \ "Enables intrinsification of BigInteger.montgomerySquare()") \ \ product(bool, UseTypeSpeculation, true, \ diff --git a/hotspot/src/share/vm/opto/c2compiler.cpp b/hotspot/src/share/vm/opto/c2compiler.cpp index 33c5918a95a..a93742fe545 100644 --- a/hotspot/src/share/vm/opto/c2compiler.cpp +++ b/hotspot/src/share/vm/opto/c2compiler.cpp @@ -484,9 +484,6 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method, bool is_virt case vmIntrinsics::_putCharUnaligned: case vmIntrinsics::_putIntUnaligned: case vmIntrinsics::_putLongUnaligned: - case vmIntrinsics::_putOrderedObject: - case vmIntrinsics::_putOrderedInt: - case vmIntrinsics::_putOrderedLong: case vmIntrinsics::_loadFence: case vmIntrinsics::_storeFence: case vmIntrinsics::_fullFence: diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index e2df36deeba..a31760c8ea9 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -621,10 +621,6 @@ bool LibraryCallKit::try_to_inline(int predicate) { case vmIntrinsics::_putIntUnaligned: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, Relaxed, true); case vmIntrinsics::_putLongUnaligned: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, Relaxed, true); - case vmIntrinsics::_putOrderedObject: return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, Release, false); - case vmIntrinsics::_putOrderedInt: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, Release, false); - case vmIntrinsics::_putOrderedLong: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, Release, false); - case vmIntrinsics::_getObjectAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, Acquire, false); case vmIntrinsics::_getBooleanAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, Acquire, false); case vmIntrinsics::_getByteAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, Acquire, false); diff --git a/hotspot/src/share/vm/opto/loopTransform.cpp b/hotspot/src/share/vm/opto/loopTransform.cpp index 8c077f11d5f..d819e69059e 100644 --- a/hotspot/src/share/vm/opto/loopTransform.cpp +++ b/hotspot/src/share/vm/opto/loopTransform.cpp @@ -1453,20 +1453,14 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad Node *opaq = NULL; if (adjust_min_trip) { // If not maximally unrolling, need adjustment // Search for zero-trip guard. - assert( loop_head->is_main_loop(), "" ); - assert( ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, "" ); - Node *iff = ctrl->in(0); - assert( iff->Opcode() == Op_If, "" ); - Node *bol = iff->in(1); - assert( bol->Opcode() == Op_Bool, "" ); - Node *cmp = bol->in(1); - assert( cmp->Opcode() == Op_CmpI, "" ); - opaq = cmp->in(2); - // Occasionally it's possible for a zero-trip guard Opaque1 node to be - // optimized away and then another round of loop opts attempted. - // We can not optimize this particular loop in that case. - if (opaq->Opcode() != Op_Opaque1) - return; // Cannot find zero-trip guard! Bail out! + + // Check the shape of the graph at the loop entry. If an inappropriate + // graph shape is encountered, the compiler bails out loop unrolling; + // compilation of the method will still succeed. + if (!is_canonical_main_loop_entry(loop_head)) { + return; + } + opaq = ctrl->in(0)->in(1)->in(1)->in(2); // Zero-trip test uses an 'opaque' node which is not shared. assert(opaq->outcnt() == 1 && opaq->in(1) == limit, ""); } @@ -2109,7 +2103,6 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) { #endif assert(RangeCheckElimination, ""); CountedLoopNode *cl = loop->_head->as_CountedLoop(); - assert(cl->is_main_loop(), ""); // protect against stride not being a constant if (!cl->stride_is_con()) @@ -2121,20 +2114,17 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) { // to not ever trip end tests Node *main_limit = cl->limit(); + // Check graph shape. Cannot optimize a loop if zero-trip + // Opaque1 node is optimized away and then another round + // of loop opts attempted. + if (!is_canonical_main_loop_entry(cl)) { + return; + } + // Need to find the main-loop zero-trip guard Node *ctrl = cl->in(LoopNode::EntryControl); - assert(ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, ""); Node *iffm = ctrl->in(0); - assert(iffm->Opcode() == Op_If, ""); - Node *bolzm = iffm->in(1); - assert(bolzm->Opcode() == Op_Bool, ""); - Node *cmpzm = bolzm->in(1); - assert(cmpzm->is_Cmp(), ""); - Node *opqzm = cmpzm->in(2); - // Can not optimize a loop if zero-trip Opaque1 node is optimized - // away and then another round of loop opts attempted. - if (opqzm->Opcode() != Op_Opaque1) - return; + Node *opqzm = iffm->in(1)->in(1)->in(2); assert(opqzm->in(1) == main_limit, "do not understand situation"); // Find the pre-loop limit; we will expand its iterations to diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp index 9ead9464abb..59ca3261c20 100644 --- a/hotspot/src/share/vm/opto/loopnode.cpp +++ b/hotspot/src/share/vm/opto/loopnode.cpp @@ -3275,6 +3275,41 @@ Node* PhaseIdealLoop::compute_lca_of_uses(Node* n, Node* early, bool verify) { return LCA; } +// Check the shape of the graph at the loop entry. In some cases, +// the shape of the graph does not match the shape outlined below. +// That is caused by the Opaque1 node "protecting" the shape of +// the graph being removed by, for example, the IGVN performed +// in PhaseIdealLoop::build_and_optimize(). +// +// After the Opaque1 node has been removed, optimizations (e.g., split-if, +// loop unswitching, and IGVN, or a combination of them) can freely change +// the graph's shape. As a result, the graph shape outlined below cannot +// be guaranteed anymore. +bool PhaseIdealLoop::is_canonical_main_loop_entry(CountedLoopNode* cl) { + assert(cl->is_main_loop(), "check should be applied to main loops"); + Node* ctrl = cl->in(LoopNode::EntryControl); + if (ctrl == NULL || (!ctrl->is_IfTrue() && !ctrl->is_IfFalse())) { + return false; + } + Node* iffm = ctrl->in(0); + if (iffm == NULL || !iffm->is_If()) { + return false; + } + Node* bolzm = iffm->in(1); + if (bolzm == NULL || !bolzm->is_Bool()) { + return false; + } + Node* cmpzm = bolzm->in(1); + if (cmpzm == NULL || !cmpzm->is_Cmp()) { + return false; + } + Node* opqzm = cmpzm->in(2); + if (opqzm == NULL || opqzm->Opcode() != Op_Opaque1) { + return false; + } + return true; +} + //------------------------------get_late_ctrl---------------------------------- // Compute latest legal control. Node *PhaseIdealLoop::get_late_ctrl( Node *n, Node *early ) { diff --git a/hotspot/src/share/vm/opto/loopnode.hpp b/hotspot/src/share/vm/opto/loopnode.hpp index c853a2a6145..09512cdafb5 100644 --- a/hotspot/src/share/vm/opto/loopnode.hpp +++ b/hotspot/src/share/vm/opto/loopnode.hpp @@ -656,6 +656,9 @@ class PhaseIdealLoop : public PhaseTransform { bool cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop); public: + + static bool is_canonical_main_loop_entry(CountedLoopNode* cl); + bool has_node( Node* n ) const { guarantee(n != NULL, "No Node."); return _nodes[n->_idx] != NULL; diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index a09caf81bb7..e79abac0c19 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -742,7 +742,7 @@ void LoadNode::dump_spec(outputStream *st) const { // standard dump does this in Verbose and WizardMode st->print(" #"); _type->dump_on(st); } - if (!_depends_only_on_test) { + if (!depends_only_on_test()) { st->print(" (does not depend only on test)"); } } @@ -914,7 +914,7 @@ Node* LoadNode::can_see_arraycopy_value(Node* st, PhaseTransform* phase) const { } } // load depends on the tests that validate the arraycopy - ld->as_Load()->_depends_only_on_test = Pinned; + ld->as_Load()->_control_dependency = Pinned; return ld; } return NULL; @@ -1118,6 +1118,44 @@ Node* LoadNode::Identity(PhaseGVN* phase) { return this; } +// Construct an equivalent unsigned load. +Node* LoadNode::convert_to_unsigned_load(PhaseGVN& gvn) { + BasicType bt = T_ILLEGAL; + const Type* rt = NULL; + switch (Opcode()) { + case Op_LoadUB: return this; + case Op_LoadUS: return this; + case Op_LoadB: bt = T_BOOLEAN; rt = TypeInt::UBYTE; break; + case Op_LoadS: bt = T_CHAR; rt = TypeInt::CHAR; break; + default: + assert(false, "no unsigned variant: %s", Name()); + return NULL; + } + return LoadNode::make(gvn, in(MemNode::Control), in(MemNode::Memory), in(MemNode::Address), + raw_adr_type(), rt, bt, _mo, _control_dependency, + is_unaligned_access(), is_mismatched_access()); +} + +// Construct an equivalent signed load. +Node* LoadNode::convert_to_signed_load(PhaseGVN& gvn) { + BasicType bt = T_ILLEGAL; + const Type* rt = NULL; + switch (Opcode()) { + case Op_LoadUB: bt = T_BYTE; rt = TypeInt::BYTE; break; + case Op_LoadUS: bt = T_SHORT; rt = TypeInt::SHORT; break; + case Op_LoadB: // fall through + case Op_LoadS: // fall through + case Op_LoadI: // fall through + case Op_LoadL: return this; + default: + assert(false, "no signed variant: %s", Name()); + return NULL; + } + return LoadNode::make(gvn, in(MemNode::Control), in(MemNode::Memory), in(MemNode::Address), + raw_adr_type(), rt, bt, _mo, _control_dependency, + is_unaligned_access(), is_mismatched_access()); +} + // We're loading from an object which has autobox behaviour. // If this object is result of a valueOf call we'll have a phi // merging a newly allocated object and a load from the cache. @@ -1582,7 +1620,7 @@ LoadNode::load_array_final_field(const TypeKlassPtr *tkls, return NULL; } -static bool is_mismatched_access(ciConstant con, BasicType loadbt) { +static ciConstant check_mismatched_access(ciConstant con, BasicType loadbt, bool is_unsigned) { BasicType conbt = con.basic_type(); switch (conbt) { case T_BOOLEAN: conbt = T_BYTE; break; @@ -1594,23 +1632,40 @@ static bool is_mismatched_access(ciConstant con, BasicType loadbt) { case T_ARRAY: loadbt = T_OBJECT; break; case T_ADDRESS: loadbt = T_OBJECT; break; } - return (conbt != loadbt); + if (conbt == loadbt) { + if (is_unsigned && conbt == T_BYTE) { + // LoadB (T_BYTE) with a small mask (<=8-bit) is converted to LoadUB (T_BYTE). + return ciConstant(T_INT, con.as_int() & 0xFF); + } else { + return con; + } + } + if (conbt == T_SHORT && loadbt == T_CHAR) { + // LoadS (T_SHORT) with a small mask (<=16-bit) is converted to LoadUS (T_CHAR). + return ciConstant(T_INT, con.as_int() & 0xFFFF); + } + return ciConstant(); // T_ILLEGAL } // Try to constant-fold a stable array element. -static const Type* fold_stable_ary_elem(const TypeAryPtr* ary, int off, BasicType loadbt) { +static const Type* fold_stable_ary_elem(const TypeAryPtr* ary, int off, bool is_unsigned_load, BasicType loadbt) { assert(ary->const_oop(), "array should be constant"); assert(ary->is_stable(), "array should be stable"); // Decode the results of GraphKit::array_element_address. ciArray* aobj = ary->const_oop()->as_array(); - ciConstant con = aobj->element_value_by_offset(off); - if (con.basic_type() != T_ILLEGAL && !con.is_null_or_zero()) { - bool is_mismatched = is_mismatched_access(con, loadbt); - assert(!is_mismatched, "conbt=%s; loadbt=%s", type2name(con.basic_type()), type2name(loadbt)); + ciConstant element_value = aobj->element_value_by_offset(off); + if (element_value.basic_type() == T_ILLEGAL) { + return NULL; // wrong offset + } + ciConstant con = check_mismatched_access(element_value, loadbt, is_unsigned_load); + assert(con.basic_type() != T_ILLEGAL, "elembt=%s; loadbt=%s; unsigned=%d", + type2name(element_value.basic_type()), type2name(loadbt), is_unsigned_load); + + if (con.basic_type() != T_ILLEGAL && // not a mismatched access + !con.is_null_or_zero()) { // not a default value const Type* con_type = Type::make_from_constant(con); - // Guard against erroneous constant folding. - if (!is_mismatched && con_type != NULL) { + if (con_type != NULL) { if (con_type->isa_aryptr()) { // Join with the array element type, in case it is also stable. int dim = ary->stable_dimension(); @@ -1662,7 +1717,7 @@ const Type* LoadNode::Value(PhaseGVN* phase) const { if (FoldStableValues && !is_mismatched_access() && ary->is_stable() && ary->const_oop() != NULL) { // Make sure the reference is not into the header and the offset is constant if (off_beyond_header && adr->is_AddP() && off != Type::OffsetBot) { - const Type* con_type = fold_stable_ary_elem(ary, off, memory_type()); + const Type* con_type = fold_stable_ary_elem(ary, off, is_unsigned(), memory_type()); if (con_type != NULL) { return con_type; } diff --git a/hotspot/src/share/vm/opto/memnode.hpp b/hotspot/src/share/vm/opto/memnode.hpp index c1477bb2e4c..87238ac4cfe 100644 --- a/hotspot/src/share/vm/opto/memnode.hpp +++ b/hotspot/src/share/vm/opto/memnode.hpp @@ -148,9 +148,8 @@ public: class LoadNode : public MemNode { public: // Some loads (from unsafe) should be pinned: they don't depend only - // on the dominating test. The boolean field _depends_only_on_test - // below records whether that node depends only on the dominating - // test. + // on the dominating test. The field _control_dependency below records + // whether that node depends only on the dominating test. // Methods used to build LoadNodes pass an argument of type enum // ControlDependency instead of a boolean because those methods // typically have multiple boolean parameters with default values: @@ -162,7 +161,7 @@ public: DependsOnlyOnTest }; private: - // LoadNode::hash() doesn't take the _depends_only_on_test field + // LoadNode::hash() doesn't take the _control_dependency field // into account: If the graph already has a non-pinned LoadNode and // we add a pinned LoadNode with the same inputs, it's safe for GVN // to replace the pinned LoadNode with the non-pinned LoadNode, @@ -171,7 +170,7 @@ private: // pinned LoadNode and we add a non pinned LoadNode with the same // inputs, it's safe (but suboptimal) for GVN to replace the // non-pinned LoadNode by the pinned LoadNode. - bool _depends_only_on_test; + ControlDependency _control_dependency; // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish // loads that can be reordered, and such requiring acquire semantics to @@ -190,7 +189,7 @@ protected: public: LoadNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *rt, MemOrd mo, ControlDependency control_dependency) - : MemNode(c,mem,adr,at), _type(rt), _mo(mo), _depends_only_on_test(control_dependency == DependsOnlyOnTest) { + : MemNode(c,mem,adr,at), _type(rt), _mo(mo), _control_dependency(control_dependency) { init_class_id(Class_Load); } inline bool is_unordered() const { return !is_acquire(); } @@ -198,6 +197,10 @@ public: assert(_mo == unordered || _mo == acquire, "unexpected"); return _mo == acquire; } + inline bool is_unsigned() const { + int lop = Opcode(); + return (lop == Op_LoadUB) || (lop == Op_LoadUS); + } // Polymorphic factory method: static Node* make(PhaseGVN& gvn, Node *c, Node *mem, Node *adr, @@ -252,6 +255,9 @@ public: // Check if the load's memory input is a Phi node with the same control. bool is_instance_field_load_with_local_phi(Node* ctrl); + Node* convert_to_unsigned_load(PhaseGVN& gvn); + Node* convert_to_signed_load(PhaseGVN& gvn); + #ifndef PRODUCT virtual void dump_spec(outputStream *st) const; #endif @@ -274,7 +280,9 @@ protected: // which produce results (new raw memory state) inside of loops preventing all // manner of other optimizations). Basically, it's ugly but so is the alternative. // See comment in macro.cpp, around line 125 expand_allocate_common(). - virtual bool depends_only_on_test() const { return adr_type() != TypeRawPtr::BOTTOM && _depends_only_on_test; } + virtual bool depends_only_on_test() const { + return adr_type() != TypeRawPtr::BOTTOM && _control_dependency == DependsOnlyOnTest; + } }; //------------------------------LoadBNode-------------------------------------- diff --git a/hotspot/src/share/vm/opto/mulnode.cpp b/hotspot/src/share/vm/opto/mulnode.cpp index d5a7de73e92..fde86a85bfd 100644 --- a/hotspot/src/share/vm/opto/mulnode.cpp +++ b/hotspot/src/share/vm/opto/mulnode.cpp @@ -483,11 +483,7 @@ Node *AndINode::Ideal(PhaseGVN *phase, bool can_reshape) { if (can_reshape && load->outcnt() == 1 && load->unique_out() == this) { if (lop == Op_LoadS && (mask & 0xFFFF0000) == 0 ) { - Node *ldus = new LoadUSNode(load->in(MemNode::Control), - load->in(MemNode::Memory), - load->in(MemNode::Address), - load->adr_type(), - TypeInt::CHAR, MemNode::unordered); + Node* ldus = load->as_Load()->convert_to_unsigned_load(*phase); ldus = phase->transform(ldus); return new AndINode(ldus, phase->intcon(mask & 0xFFFF)); } @@ -495,11 +491,7 @@ Node *AndINode::Ideal(PhaseGVN *phase, bool can_reshape) { // Masking sign bits off of a Byte? Do an unsigned byte load plus // an and. if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) { - Node* ldub = new LoadUBNode(load->in(MemNode::Control), - load->in(MemNode::Memory), - load->in(MemNode::Address), - load->adr_type(), - TypeInt::UBYTE, MemNode::unordered); + Node* ldub = load->as_Load()->convert_to_unsigned_load(*phase); ldub = phase->transform(ldub); return new AndINode(ldub, phase->intcon(mask)); } @@ -934,11 +926,7 @@ Node *RShiftINode::Ideal(PhaseGVN *phase, bool can_reshape) { ld->Opcode() == Op_LoadUS && ld->outcnt() == 1 && ld->unique_out() == shl) // Replace zero-extension-load with sign-extension-load - return new LoadSNode( ld->in(MemNode::Control), - ld->in(MemNode::Memory), - ld->in(MemNode::Address), - ld->adr_type(), TypeInt::SHORT, - MemNode::unordered); + return ld->as_Load()->convert_to_signed_load(*phase); } // Check for "(byte[i] <<24)>>24" which simply sign-extends diff --git a/hotspot/src/share/vm/opto/reg_split.cpp b/hotspot/src/share/vm/opto/reg_split.cpp index 5e14b9d5abc..781a53cc00b 100644 --- a/hotspot/src/share/vm/opto/reg_split.cpp +++ b/hotspot/src/share/vm/opto/reg_split.cpp @@ -287,7 +287,7 @@ uint PhaseChaitin::split_USE(MachSpillCopyNode::SpillType spill_type, Node *def, Node* clone_node(Node* def, Block *b, Compile* C) { if (def->needs_anti_dependence_check()) { #ifdef ASSERT - if (Verbose) { + if (PrintOpto && WizardMode) { tty->print_cr("RA attempts to clone node with anti_dependence:"); def->dump(-1); tty->cr(); tty->print_cr("into block:"); diff --git a/hotspot/src/share/vm/opto/superword.cpp b/hotspot/src/share/vm/opto/superword.cpp index 9b4fe74d66c..74c7de0cc14 100644 --- a/hotspot/src/share/vm/opto/superword.cpp +++ b/hotspot/src/share/vm/opto/superword.cpp @@ -3074,21 +3074,13 @@ void SuperWord::align_initial_loop_index(MemNode* align_to_ref) { //----------------------------get_pre_loop_end--------------------------- // Find pre loop end from main loop. Returns null if none. CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode* cl) { - Node* ctrl = cl->in(LoopNode::EntryControl); - if (!ctrl->is_IfTrue() && !ctrl->is_IfFalse()) return NULL; - Node* iffm = ctrl->in(0); - if (!iffm->is_If()) return NULL; - Node* bolzm = iffm->in(1); - if (!bolzm->is_Bool()) return NULL; - Node* cmpzm = bolzm->in(1); - if (!cmpzm->is_Cmp()) return NULL; - Node* opqzm = cmpzm->in(2); - // Can not optimize a loop if zero-trip Opaque1 node is optimized - // away and then another round of loop opts attempted. - if (opqzm->Opcode() != Op_Opaque1) { + // The loop cannot be optimized if the graph shape at + // the loop entry is inappropriate. + if (!PhaseIdealLoop::is_canonical_main_loop_entry(cl)) { return NULL; } - Node* p_f = iffm->in(0); + + Node* p_f = cl->in(LoopNode::EntryControl)->in(0)->in(0); if (!p_f->is_IfFalse()) return NULL; if (!p_f->in(0)->is_CountedLoopEnd()) return NULL; CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd(); diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp index de66179e45b..fa1cc2cc392 100644 --- a/hotspot/src/share/vm/prims/methodHandles.cpp +++ b/hotspot/src/share/vm/prims/methodHandles.cpp @@ -318,9 +318,9 @@ oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool // JVM 2.9 Special Methods: // A method is signature polymorphic if and only if all of the following conditions hold : -// * It is declared in the java.lang.invoke.MethodHandle class. +// * It is declared in the java.lang.invoke.MethodHandle/VarHandle classes. // * It has a single formal parameter of type Object[]. -// * It has a return type of Object. +// * It has a return type of Object for a polymorphic return type, otherwise a fixed return type. // * It has the ACC_VARARGS and ACC_NATIVE flags set. bool MethodHandles::is_method_handle_invoke_name(Klass* klass, Symbol* name) { if (klass == NULL) @@ -328,14 +328,36 @@ bool MethodHandles::is_method_handle_invoke_name(Klass* klass, Symbol* name) { // The following test will fail spuriously during bootstrap of MethodHandle itself: // if (klass != SystemDictionary::MethodHandle_klass()) // Test the name instead: - if (klass->name() != vmSymbols::java_lang_invoke_MethodHandle()) + if (klass->name() != vmSymbols::java_lang_invoke_MethodHandle() && + klass->name() != vmSymbols::java_lang_invoke_VarHandle()) { return false; + } + + // Look up signature polymorphic method with polymorphic return type Symbol* poly_sig = vmSymbols::object_array_object_signature(); - Method* m = InstanceKlass::cast(klass)->find_method(name, poly_sig); - if (m == NULL) return false; - int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS; - int flags = m->access_flags().as_int(); - return (flags & required) == required; + InstanceKlass* iklass = InstanceKlass::cast(klass); + Method* m = iklass->find_method(name, poly_sig); + if (m != NULL) { + int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS; + int flags = m->access_flags().as_int(); + if ((flags & required) == required) { + return true; + } + } + + // Look up signature polymorphic method with non-polymorphic (non Object) return type + int me; + int ms = iklass->find_method_by_name(name, &me); + if (ms == -1) return false; + for (; ms < me; ms++) { + Method* m = iklass->methods()->at(ms); + int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS; + int flags = m->access_flags().as_int(); + if ((flags & required) == required && ArgumentCount(m->signature()).size() == 1) { + return true; + } + } + return false; } @@ -395,8 +417,16 @@ vmIntrinsics::ID MethodHandles::signature_polymorphic_name_id(Symbol* name) { // Cover the case of invokeExact and any future variants of invokeFoo. Klass* mh_klass = SystemDictionary::well_known_klass( SystemDictionary::WK_KLASS_ENUM_NAME(MethodHandle_klass) ); - if (mh_klass != NULL && is_method_handle_invoke_name(mh_klass, name)) + if (mh_klass != NULL && is_method_handle_invoke_name(mh_klass, name)) { return vmIntrinsics::_invokeGeneric; + } + + // Cover the case of methods on VarHandle. + Klass* vh_klass = SystemDictionary::well_known_klass( + SystemDictionary::WK_KLASS_ENUM_NAME(VarHandle_klass) ); + if (vh_klass != NULL && is_method_handle_invoke_name(vh_klass, name)) { + return vmIntrinsics::_invokeGeneric; + } // Note: The pseudo-intrinsic _compiledLambdaForm is never linked against. // Instead it is used to mark lambda forms bound to invokehandle or invokedynamic. @@ -405,7 +435,8 @@ vmIntrinsics::ID MethodHandles::signature_polymorphic_name_id(Symbol* name) { vmIntrinsics::ID MethodHandles::signature_polymorphic_name_id(Klass* klass, Symbol* name) { if (klass != NULL && - klass->name() == vmSymbols::java_lang_invoke_MethodHandle()) { + (klass->name() == vmSymbols::java_lang_invoke_MethodHandle() || + klass->name() == vmSymbols::java_lang_invoke_VarHandle())) { vmIntrinsics::ID iid = signature_polymorphic_name_id(name); if (iid != vmIntrinsics::_none) return iid; @@ -1197,10 +1228,10 @@ JVM_ENTRY(jobject, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "obsolete MemberName format"); } if ((flags & ALL_KINDS) == IS_FIELD) { - THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(), "field resolution failed"); + THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), "field resolution failed"); } else if ((flags & ALL_KINDS) == IS_METHOD || (flags & ALL_KINDS) == IS_CONSTRUCTOR) { - THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), "method resolution failed"); + THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(), "method resolution failed"); } else { THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "resolution failed"); } diff --git a/hotspot/src/share/vm/prims/methodHandles.hpp b/hotspot/src/share/vm/prims/methodHandles.hpp index f0bbdbde805..3a2bcae1a12 100644 --- a/hotspot/src/share/vm/prims/methodHandles.hpp +++ b/hotspot/src/share/vm/prims/methodHandles.hpp @@ -120,7 +120,8 @@ class MethodHandles: AllStatic { iid <= vmIntrinsics::_linkToInterface); } static bool has_member_arg(Symbol* klass, Symbol* name) { - if ((klass == vmSymbols::java_lang_invoke_MethodHandle()) && + if ((klass == vmSymbols::java_lang_invoke_MethodHandle() || + klass == vmSymbols::java_lang_invoke_VarHandle()) && is_signature_polymorphic_name(name)) { vmIntrinsics::ID iid = signature_polymorphic_name_id(name); return has_member_arg(iid); diff --git a/hotspot/src/share/vm/prims/unsafe.cpp b/hotspot/src/share/vm/prims/unsafe.cpp index dc60ebfd208..47c4d7fe6e5 100644 --- a/hotspot/src/share/vm/prims/unsafe.cpp +++ b/hotspot/src/share/vm/prims/unsafe.cpp @@ -378,44 +378,6 @@ DEFINE_GETSETOOP_VOLATILE(jlong, Long); #undef DEFINE_GETSETOOP_VOLATILE -// The non-intrinsified versions of setOrdered just use setVolatile - -UNSAFE_ENTRY(void, Unsafe_SetOrderedInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint x)) { - SET_FIELD_VOLATILE(obj, offset, jint, x); -} UNSAFE_END - -UNSAFE_ENTRY(void, Unsafe_SetOrderedObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) { - oop x = JNIHandles::resolve(x_h); - oop p = JNIHandles::resolve(obj); - void* addr = index_oop_from_field_offset_long(p, offset); - OrderAccess::release(); - - if (UseCompressedOops) { - oop_store((narrowOop*)addr, x); - } else { - oop_store((oop*)addr, x); - } - - OrderAccess::fence(); -} UNSAFE_END - -UNSAFE_ENTRY(void, Unsafe_SetOrderedLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x)) { -#ifdef SUPPORTS_NATIVE_CX8 - SET_FIELD_VOLATILE(obj, offset, jlong, x); -#else - - // Keep old code for platforms which may not have atomic long (8 bytes) instructions - if (VM_Version::supports_cx8()) { - SET_FIELD_VOLATILE(obj, offset, jlong, x); - } else { - Handle p(THREAD, JNIHandles::resolve(obj)); - jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); - MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag); - Atomic::store(x, addr); - } -#endif -} UNSAFE_END - UNSAFE_LEAF(void, Unsafe_LoadFence(JNIEnv *env, jobject unsafe)) { OrderAccess::acquire(); } UNSAFE_END @@ -1230,9 +1192,6 @@ static JNINativeMethod jdk_internal_misc_Unsafe_methods[] = { {CC "compareAndExchangeIntVolatile", CC "(" OBJ "J""I""I"")I", FN_PTR(Unsafe_CompareAndExchangeInt)}, {CC "compareAndExchangeLongVolatile", CC "(" OBJ "J""J""J"")J", FN_PTR(Unsafe_CompareAndExchangeLong)}, - {CC "putOrderedObject", CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_SetOrderedObject)}, - {CC "putOrderedInt", CC "(" OBJ "JI)V", FN_PTR(Unsafe_SetOrderedInt)}, - {CC "putOrderedLong", CC "(" OBJ "JJ)V", FN_PTR(Unsafe_SetOrderedLong)}, {CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)}, {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)}, diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 33ab3df3c63..629b1267071 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -2550,6 +2550,13 @@ bool Arguments::check_vm_args_consistency() { warning("Reserved Stack Area not supported on this platform"); } #endif + + if (BackgroundCompilation && (CompileTheWorld || ReplayCompiles)) { + if (!FLAG_IS_DEFAULT(BackgroundCompilation)) { + warning("BackgroundCompilation disabled due to CompileTheWorld or ReplayCompiles options."); + } + FLAG_SET_CMDLINE(bool, BackgroundCompilation, false); + } return status; } diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index d52e97e7f2b..2dfa4965849 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -727,7 +727,7 @@ public: "Control whether SHA instructions can be used " \ "on SPARC, on ARM and on x86") \ \ - product(bool, UseGHASHIntrinsics, false, \ + diagnostic(bool, UseGHASHIntrinsics, false, \ "Use intrinsics for GHASH versions of crypto") \ \ product(size_t, LargePageSizeInBytes, 0, \ @@ -797,27 +797,27 @@ public: product(bool, UseInlineCaches, true, \ "Use Inline Caches for virtual calls ") \ \ - develop(bool, InlineArrayCopy, true, \ + diagnostic(bool, InlineArrayCopy, true, \ "Inline arraycopy native that is known to be part of " \ "base library DLL") \ \ - develop(bool, InlineObjectHash, true, \ + diagnostic(bool, InlineObjectHash, true, \ "Inline Object::hashCode() native that is known to be part " \ "of base library DLL") \ \ - develop(bool, InlineNatives, true, \ + diagnostic(bool, InlineNatives, true, \ "Inline natives that are known to be part of base library DLL") \ \ - develop(bool, InlineMathNatives, true, \ + diagnostic(bool, InlineMathNatives, true, \ "Inline SinD, CosD, etc.") \ \ - develop(bool, InlineClassNatives, true, \ + diagnostic(bool, InlineClassNatives, true, \ "Inline Class.isInstance, etc") \ \ - develop(bool, InlineThreadNatives, true, \ + diagnostic(bool, InlineThreadNatives, true, \ "Inline Thread.currentThread, etc") \ \ - develop(bool, InlineUnsafeOps, true, \ + diagnostic(bool, InlineUnsafeOps, true, \ "Inline memory ops (native methods) from Unsafe") \ \ product(bool, CriticalJNINatives, true, \ @@ -826,34 +826,34 @@ public: notproduct(bool, StressCriticalJNINatives, false, \ "Exercise register saving code in critical natives") \ \ - product(bool, UseAESIntrinsics, false, \ + diagnostic(bool, UseAESIntrinsics, false, \ "Use intrinsics for AES versions of crypto") \ \ - product(bool, UseAESCTRIntrinsics, false, \ + diagnostic(bool, UseAESCTRIntrinsics, false, \ "Use intrinsics for the paralleled version of AES/CTR crypto") \ \ - product(bool, UseSHA1Intrinsics, false, \ + diagnostic(bool, UseSHA1Intrinsics, false, \ "Use intrinsics for SHA-1 crypto hash function. " \ "Requires that UseSHA is enabled.") \ \ - product(bool, UseSHA256Intrinsics, false, \ + diagnostic(bool, UseSHA256Intrinsics, false, \ "Use intrinsics for SHA-224 and SHA-256 crypto hash functions. " \ "Requires that UseSHA is enabled.") \ \ - product(bool, UseSHA512Intrinsics, false, \ + diagnostic(bool, UseSHA512Intrinsics, false, \ "Use intrinsics for SHA-384 and SHA-512 crypto hash functions. " \ "Requires that UseSHA is enabled.") \ \ - product(bool, UseCRC32Intrinsics, false, \ + diagnostic(bool, UseCRC32Intrinsics, false, \ "use intrinsics for java.util.zip.CRC32") \ \ - product(bool, UseCRC32CIntrinsics, false, \ + diagnostic(bool, UseCRC32CIntrinsics, false, \ "use intrinsics for java.util.zip.CRC32C") \ \ - product(bool, UseAdler32Intrinsics, false, \ + diagnostic(bool, UseAdler32Intrinsics, false, \ "use intrinsics for java.util.zip.Adler32") \ \ - product(bool, UseVectorizedMismatchIntrinsic, false, \ + diagnostic(bool, UseVectorizedMismatchIntrinsic, false, \ "Enables intrinsification of ArraysSupport.vectorizedMismatch()") \ \ diagnostic(ccstrlist, DisableIntrinsic, "", \ diff --git a/hotspot/src/share/vm/runtime/sweeper.cpp b/hotspot/src/share/vm/runtime/sweeper.cpp index 5a902266205..3bd5a0f1d29 100644 --- a/hotspot/src/share/vm/runtime/sweeper.cpp +++ b/hotspot/src/share/vm/runtime/sweeper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -146,7 +146,6 @@ volatile bool NMethodSweeper::_force_sweep = false;// Indicates if w volatile int NMethodSweeper::_bytes_changed = 0; // Counts the total nmethod size if the nmethod changed from: // 1) alive -> not_entrant // 2) not_entrant -> zombie - // 3) zombie -> marked_for_reclamation int NMethodSweeper::_hotness_counter_reset_val = 0; long NMethodSweeper::_total_nof_methods_reclaimed = 0; // Accumulated nof methods flushed @@ -355,8 +354,8 @@ void NMethodSweeper::possibly_sweep() { bool forced = _force_sweep; // Force stack scanning if there is only 10% free space in the code cache. - // We force stack scanning only non-profiled code heap gets full, since critical - // allocation go to the non-profiled heap and we must be make sure that there is + // We force stack scanning only if the non-profiled code heap gets full, since critical + // allocations go to the non-profiled heap and we must be make sure that there is // enough space. double free_percent = 1 / CodeCache::reverse_free_ratio(CodeBlobType::MethodNonProfiled) * 100; if (free_percent <= StartAggressiveSweepingAt) { @@ -397,7 +396,6 @@ void NMethodSweeper::sweep_code_cache() { int flushed_count = 0; int zombified_count = 0; - int marked_for_reclamation_count = 0; int flushed_c2_count = 0; if (PrintMethodFlushing && Verbose) { @@ -423,22 +421,27 @@ void NMethodSweeper::sweep_code_cache() { // Now ready to process nmethod and give up CodeCache_lock { MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + // Save information before potentially flushing the nmethod int size = nm->total_size(); bool is_c2_method = nm->is_compiled_by_c2(); + bool is_osr = nm->is_osr_method(); + int compile_id = nm->compile_id(); + intptr_t address = p2i(nm); + const char* state_before = nm->state(); + const char* state_after = ""; MethodStateChange type = process_nmethod(nm); switch (type) { case Flushed: + state_after = "flushed"; freed_memory += size; ++flushed_count; if (is_c2_method) { ++flushed_c2_count; } break; - case MarkedForReclamation: - ++marked_for_reclamation_count; - break; case MadeZombie: + state_after = "made zombie"; ++zombified_count; break; case None: @@ -446,7 +449,11 @@ void NMethodSweeper::sweep_code_cache() { default: ShouldNotReachHere(); } + if (PrintMethodFlushing && Verbose && type != None) { + tty->print_cr("### %s nmethod %3d/" PTR_FORMAT " (%s) %s", is_osr ? "osr" : "", compile_id, address, state_before, state_after); + } } + _seen++; handle_safepoint_request(); } @@ -473,7 +480,6 @@ void NMethodSweeper::sweep_code_cache() { event.set_sweepIndex(_traversals); event.set_sweptCount(swept_count); event.set_flushedCount(flushed_count); - event.set_markedCount(marked_for_reclamation_count); event.set_zombifiedCount(zombified_count); event.commit(); } @@ -533,7 +539,7 @@ class NMethodMarker: public StackObj { NMethodMarker(nmethod* nm) { JavaThread* current = JavaThread::current(); assert (current->is_Code_cache_sweeper_thread(), "Must be"); - _thread = (CodeCacheSweeperThread*)JavaThread::current(); + _thread = (CodeCacheSweeperThread*)current; if (!nm->is_zombie() && !nm->is_unloaded()) { // Only expose live nmethods for scanning _thread->set_scanned_nmethod(nm); @@ -545,6 +551,10 @@ class NMethodMarker: public StackObj { }; void NMethodSweeper::release_nmethod(nmethod* nm) { + // Make sure the released nmethod is no longer referenced by the sweeper thread + CodeCacheSweeperThread* thread = (CodeCacheSweeperThread*)JavaThread::current(); + thread->set_scanned_nmethod(NULL); + // Clean up any CompiledICHolders { ResourceMark rm; @@ -575,7 +585,7 @@ NMethodSweeper::MethodStateChange NMethodSweeper::process_nmethod(nmethod* nm) { if (nm->is_locked_by_vm()) { // But still remember to clean-up inline caches for alive nmethods if (nm->is_alive()) { - // Clean inline caches that point to zombie/non-entrant methods + // Clean inline caches that point to zombie/non-entrant/unloaded nmethods MutexLocker cl(CompiledIC_lock); nm->cleanup_inline_caches(); SWEEP(nm); @@ -584,47 +594,41 @@ NMethodSweeper::MethodStateChange NMethodSweeper::process_nmethod(nmethod* nm) { } if (nm->is_zombie()) { - // If it is the first time we see nmethod then we mark it. Otherwise, - // we reclaim it. When we have seen a zombie method twice, we know that - // there are no inline caches that refer to it. - if (nm->is_marked_for_reclamation()) { - assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); - if (PrintMethodFlushing && Verbose) { - tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), p2i(nm)); - } - release_nmethod(nm); - assert(result == None, "sanity"); - result = Flushed; - } else { - if (PrintMethodFlushing && Verbose) { - tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), p2i(nm)); - } - nm->mark_for_reclamation(); - // Keep track of code cache state change - _bytes_changed += nm->total_size(); - SWEEP(nm); - assert(result == None, "sanity"); - result = MarkedForReclamation; - } + // All inline caches that referred to this nmethod were cleaned in the + // previous sweeper cycle. Now flush the nmethod from the code cache. + assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); + release_nmethod(nm); + assert(result == None, "sanity"); + result = Flushed; } else if (nm->is_not_entrant()) { // If there are no current activations of this method on the // stack we can safely convert it to a zombie method if (nm->can_convert_to_zombie()) { - // Clear ICStubs to prevent back patching stubs of zombie or unloaded + // Clear ICStubs to prevent back patching stubs of zombie or flushed // nmethods during the next safepoint (see ICStub::finalize). { MutexLocker cl(CompiledIC_lock); nm->clear_ic_stubs(); } - if (PrintMethodFlushing && Verbose) { - tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), p2i(nm)); - } // Code cache state change is tracked in make_zombie() nm->make_zombie(); SWEEP(nm); - assert(result == None, "sanity"); - result = MadeZombie; - assert(nm->is_zombie(), "nmethod must be zombie"); + // The nmethod may have been locked by JVMTI after being made zombie (see + // JvmtiDeferredEvent::compiled_method_unload_event()). If so, we cannot + // flush the osr nmethod directly but have to wait for a later sweeper cycle. + if (nm->is_osr_method() && !nm->is_locked_by_vm()) { + // No inline caches will ever point to osr methods, so we can just remove it. + // Make sure that we unregistered the nmethod with the heap and flushed all + // dependencies before removing the nmethod (done in make_zombie()). + assert(nm->is_zombie(), "nmethod must be unregistered"); + release_nmethod(nm); + assert(result == None, "sanity"); + result = Flushed; + } else { + assert(result == None, "sanity"); + result = MadeZombie; + assert(nm->is_zombie(), "nmethod must be zombie"); + } } else { // Still alive, clean up its inline caches MutexLocker cl(CompiledIC_lock); @@ -632,9 +636,13 @@ NMethodSweeper::MethodStateChange NMethodSweeper::process_nmethod(nmethod* nm) { SWEEP(nm); } } else if (nm->is_unloaded()) { - // Unloaded code, just make it a zombie - if (PrintMethodFlushing && Verbose) { - tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), p2i(nm)); + // Code is unloaded, so there are no activations on the stack. + // Convert the nmethod to zombie or flush it directly in the OSR case. + { + // Clean ICs of unloaded nmethods as well because they may reference other + // unloaded nmethods that may be flushed earlier in the sweeper cycle. + MutexLocker cl(CompiledIC_lock); + nm->cleanup_inline_caches(); } if (nm->is_osr_method()) { SWEEP(nm); @@ -643,12 +651,6 @@ NMethodSweeper::MethodStateChange NMethodSweeper::process_nmethod(nmethod* nm) { assert(result == None, "sanity"); result = Flushed; } else { - { - // Clean ICs of unloaded nmethods as well because they may reference other - // unloaded nmethods that may be flushed earlier in the sweeper cycle. - MutexLocker cl(CompiledIC_lock); - nm->cleanup_inline_caches(); - } // Code cache state change is tracked in make_zombie() nm->make_zombie(); SWEEP(nm); @@ -657,7 +659,7 @@ NMethodSweeper::MethodStateChange NMethodSweeper::process_nmethod(nmethod* nm) { } } else { possibly_flush(nm); - // Clean-up all inline caches that point to zombie/non-reentrant methods + // Clean inline caches that point to zombie/non-entrant/unloaded nmethods MutexLocker cl(CompiledIC_lock); nm->cleanup_inline_caches(); SWEEP(nm); @@ -668,10 +670,10 @@ NMethodSweeper::MethodStateChange NMethodSweeper::process_nmethod(nmethod* nm) { void NMethodSweeper::possibly_flush(nmethod* nm) { if (UseCodeCacheFlushing) { - if (!nm->is_locked_by_vm() && !nm->is_osr_method() && !nm->is_native_method()) { + if (!nm->is_locked_by_vm() && !nm->is_native_method()) { bool make_not_entrant = false; - // Do not make native methods and OSR-methods not-entrant + // Do not make native methods not-entrant nm->dec_hotness_counter(); // Get the initial value of the hotness counter. This value depends on the // ReservedCodeCacheSize diff --git a/hotspot/src/share/vm/runtime/sweeper.hpp b/hotspot/src/share/vm/runtime/sweeper.hpp index ccf5125c808..eb29e7de660 100644 --- a/hotspot/src/share/vm/runtime/sweeper.hpp +++ b/hotspot/src/share/vm/runtime/sweeper.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -45,12 +45,12 @@ class WhiteBox; // and sweep_code_cache() cannot execute at the same time. // To reclaim memory, nmethods are first marked as 'not-entrant'. Methods can // be made not-entrant by (i) the sweeper, (ii) deoptimization, (iii) dependency -// invalidation, and (iv) being replaced be a different method version (tiered -// compilation). Not-entrant nmethod cannot be called by Java threads, but they -// can still be active on the stack. To ensure that active nmethod are not reclaimed, +// invalidation, and (iv) being replaced by a different method version (tiered +// compilation). Not-entrant nmethods cannot be called by Java threads, but they +// can still be active on the stack. To ensure that active nmethods are not reclaimed, // we have to wait until the next marking phase has completed. If a not-entrant // nmethod was NOT marked as active, it can be converted to 'zombie' state. To safely -// remove the nmethod, all inline caches (IC) that point to the the nmethod must be +// remove the nmethod, all inline caches (IC) that point to the nmethod must be // cleared. After that, the nmethod can be evicted from the code cache. Each nmethod's // state change happens during separate sweeps. It may take at least 3 sweeps before an // nmethod's space is freed. @@ -60,7 +60,6 @@ class NMethodSweeper : public AllStatic { enum MethodStateChange { None, MadeZombie, - MarkedForReclamation, Flushed }; static long _traversals; // Stack scan count, also sweep ID. @@ -76,7 +75,6 @@ class NMethodSweeper : public AllStatic { static volatile int _bytes_changed; // Counts the total nmethod size if the nmethod changed from: // 1) alive -> not_entrant // 2) not_entrant -> zombie - // 3) zombie -> marked_for_reclamation // Stat counters static long _total_nof_methods_reclaimed; // Accumulated nof methods flushed static long _total_nof_c2_methods_reclaimed; // Accumulated nof C2-compiled methods flushed diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index d2691323ee3..c8348999d9a 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -1051,7 +1051,7 @@ static const char* get_java_runtime_version(TRAPS) { // General purpose hook into Java code, run once when the VM is initialized. // The Java library method itself may be changed independently from the VM. static void call_postVMInitHook(TRAPS) { - Klass* k = SystemDictionary::resolve_or_null(vmSymbols::sun_misc_PostVMInitHook(), THREAD); + Klass* k = SystemDictionary::resolve_or_null(vmSymbols::jdk_internal_vm_PostVMInitHook(), THREAD); instanceKlassHandle klass (THREAD, k); if (klass.not_null()) { JavaValue result(T_VOID); diff --git a/hotspot/src/share/vm/services/attachListener.cpp b/hotspot/src/share/vm/services/attachListener.cpp index c412325ce18..0de704d6913 100644 --- a/hotspot/src/share/vm/services/attachListener.cpp +++ b/hotspot/src/share/vm/services/attachListener.cpp @@ -43,7 +43,7 @@ volatile bool AttachListener::_initialized; // Implementation of "properties" command. // -// Invokes sun.misc.VMSupport.serializePropertiesToByteArray to serialize +// Invokes VMSupport.serializePropertiesToByteArray to serialize // the system properties into a byte array. static Klass* load_and_initialize_klass(Symbol* sh, TRAPS) { @@ -59,8 +59,8 @@ static jint get_properties(AttachOperation* op, outputStream* out, Symbol* seria Thread* THREAD = Thread::current(); HandleMark hm; - // load sun.misc.VMSupport - Symbol* klass = vmSymbols::sun_misc_VMSupport(); + // load VMSupport + Symbol* klass = vmSymbols::jdk_internal_vm_VMSupport(); Klass* k = load_and_initialize_klass(klass, THREAD); if (HAS_PENDING_EXCEPTION) { java_lang_Throwable::print(PENDING_EXCEPTION, out); diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp index 3beb7786c16..dc2b2171408 100644 --- a/hotspot/src/share/vm/services/diagnosticCommand.cpp +++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp @@ -316,8 +316,8 @@ int JVMTIAgentLoadDCmd::num_arguments() { } void PrintSystemPropertiesDCmd::execute(DCmdSource source, TRAPS) { - // load sun.misc.VMSupport - Symbol* klass = vmSymbols::sun_misc_VMSupport(); + // load VMSupport + Symbol* klass = vmSymbols::jdk_internal_vm_VMSupport(); Klass* k = SystemDictionary::resolve_or_fail(klass, true, CHECK); instanceKlassHandle ik (THREAD, k); if (ik->should_be_initialized()) { diff --git a/hotspot/src/share/vm/trace/trace.xml b/hotspot/src/share/vm/trace/trace.xml index d6d76d9398f..5bcdfd1c4d0 100644 --- a/hotspot/src/share/vm/trace/trace.xml +++ b/hotspot/src/share/vm/trace/trace.xml @@ -550,7 +550,6 @@ Declares a structure type that can be used in other events. - diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp index 69fc1c5a5a6..4c2c0baf84a 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp @@ -1056,6 +1056,7 @@ const int badHandleValue = 0xBC; // value used to zap const int badResourceValue = 0xAB; // value used to zap resource area const int freeBlockPad = 0xBA; // value used to pad freed blocks. const int uninitBlockPad = 0xF1; // value used to zap newly malloc'd blocks. +const juint uninitMetaWordVal= 0xf7f7f7f7; // value used to zap newly allocated metachunk const intptr_t badJNIHandleVal = (intptr_t) UCONST64(0xFEFEFEFEFEFEFEFE); // value used to zap jni handle area const juint badHeapWordVal = 0xBAADBABE; // value used to zap heap after GC const juint badMetaWordVal = 0xBAADFADE; // value used to zap metadata heap after GC diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index 61e159a2167..0a2acb997da 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -98,7 +98,7 @@ needs_jdk = \ serviceability/attach/AttachWithStalePidFile.java \ serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java \ serviceability/dcmd/vm/DynLibsTest.java \ - serviceability/tmtools + serviceability/tmtools # JRE adds further tests to compact3 @@ -248,7 +248,7 @@ needs_g1gc = \ gc/metaspace/G1AddMetaspaceDependency.java \ gc/metaspace/TestMetaspacePerfCounters.java \ gc/startup_warnings/TestG1.java \ - gc/whitebox/TestConcMarkCycleWB.java + gc/whitebox/TestConcMarkCycleWB.java hotspot_native_sanity = \ native_sanity @@ -267,7 +267,7 @@ hotspot_compiler_1 = \ -compiler/c2/6792161 \ -compiler/c2/7070134 \ -compiler/c2/8004867 - + hotspot_compiler_2 = \ compiler/classUnloading/ \ compiler/codecache/ \ @@ -284,8 +284,9 @@ hotspot_compiler_2 = \ compiler/interpreter/ \ compiler/jvmci/ \ -compiler/codegen/7184394 \ - -compiler/codecache/stress - + -compiler/codecache/stress \ + -compiler/gcbarriers/PreserveFPRegistersTest.java + hotspot_compiler_3 = \ compiler/intrinsics/ \ compiler/jsr292/ \ @@ -370,4 +371,4 @@ not_needs_nashorn = \ -:needs_nashorn hotspot_tmtools = \ - serviceability/tmtools + serviceability/tmtools diff --git a/hotspot/test/compiler/arguments/CheckCICompilerCount.java b/hotspot/test/compiler/arguments/CheckCICompilerCount.java index 5c5e5edf767..b07af8da62e 100644 --- a/hotspot/test/compiler/arguments/CheckCICompilerCount.java +++ b/hotspot/test/compiler/arguments/CheckCICompilerCount.java @@ -29,7 +29,7 @@ import jdk.test.lib.*; * @bug 8132525 * @summary Check that correct range of values for CICompilerCount are allowed depending on whether tiered is enabled or not * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main CheckCICompilerCount */ diff --git a/hotspot/test/compiler/arguments/CheckCompileThresholdScaling.java b/hotspot/test/compiler/arguments/CheckCompileThresholdScaling.java index c1da06a5d1f..cdb2a27ae03 100644 --- a/hotspot/test/compiler/arguments/CheckCompileThresholdScaling.java +++ b/hotspot/test/compiler/arguments/CheckCompileThresholdScaling.java @@ -28,7 +28,7 @@ import jdk.test.lib.*; * @bug 8059604 * @summary "Add CompileThresholdScaling flag to control when methods are first compiled (with +/-TieredCompilation)" * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main CheckCompileThresholdScaling */ diff --git a/hotspot/test/compiler/arguments/TestUseBMI1InstructionsOnSupportedCPU.java b/hotspot/test/compiler/arguments/TestUseBMI1InstructionsOnSupportedCPU.java index 94102f45d0a..d05a24e9586 100644 --- a/hotspot/test/compiler/arguments/TestUseBMI1InstructionsOnSupportedCPU.java +++ b/hotspot/test/compiler/arguments/TestUseBMI1InstructionsOnSupportedCPU.java @@ -27,7 +27,7 @@ * @summary Verify processing of UseBMI1Instructions option on CPU with * BMI1 feature support. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseBMI1InstructionsOnSupportedCPU * BMISupportedCPUTest diff --git a/hotspot/test/compiler/arguments/TestUseBMI1InstructionsOnUnsupportedCPU.java b/hotspot/test/compiler/arguments/TestUseBMI1InstructionsOnUnsupportedCPU.java index 5581bdecc35..716e0690874 100644 --- a/hotspot/test/compiler/arguments/TestUseBMI1InstructionsOnUnsupportedCPU.java +++ b/hotspot/test/compiler/arguments/TestUseBMI1InstructionsOnUnsupportedCPU.java @@ -27,7 +27,7 @@ * @summary Verify processing of UseBMI1Instructions option on CPU without * BMI1 feature support. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseBMI1InstructionsOnUnsupportedCPU * BMIUnsupportedCPUTest diff --git a/hotspot/test/compiler/arguments/TestUseCountLeadingZerosInstructionOnSupportedCPU.java b/hotspot/test/compiler/arguments/TestUseCountLeadingZerosInstructionOnSupportedCPU.java index 6f29097065a..0ffa6ea8dd3 100644 --- a/hotspot/test/compiler/arguments/TestUseCountLeadingZerosInstructionOnSupportedCPU.java +++ b/hotspot/test/compiler/arguments/TestUseCountLeadingZerosInstructionOnSupportedCPU.java @@ -27,7 +27,7 @@ * @summary Verify processing of UseCountLeadingZerosInstruction option * on CPU with LZCNT support. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseCountLeadingZerosInstructionOnSupportedCPU * BMISupportedCPUTest diff --git a/hotspot/test/compiler/arguments/TestUseCountLeadingZerosInstructionOnUnsupportedCPU.java b/hotspot/test/compiler/arguments/TestUseCountLeadingZerosInstructionOnUnsupportedCPU.java index 25ce1d916c3..12093151861 100644 --- a/hotspot/test/compiler/arguments/TestUseCountLeadingZerosInstructionOnUnsupportedCPU.java +++ b/hotspot/test/compiler/arguments/TestUseCountLeadingZerosInstructionOnUnsupportedCPU.java @@ -27,7 +27,7 @@ * @summary Verify processing of UseCountLeadingZerosInstruction option * on CPU without LZCNT support. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseCountLeadingZerosInstructionOnUnsupportedCPU * BMIUnsupportedCPUTest diff --git a/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnSupportedCPU.java b/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnSupportedCPU.java index 81519c09a04..397bdc93acc 100644 --- a/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnSupportedCPU.java +++ b/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnSupportedCPU.java @@ -27,7 +27,7 @@ * @summary Verify processing of UseCountTrailingZerosInstruction option * on CPU with TZCNT (BMI1 feature) support. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseCountTrailingZerosInstructionOnSupportedCPU * BMISupportedCPUTest diff --git a/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnUnsupportedCPU.java b/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnUnsupportedCPU.java index 0ffcf279149..73aad61f4b7 100644 --- a/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnUnsupportedCPU.java +++ b/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnUnsupportedCPU.java @@ -27,7 +27,7 @@ * @summary Verify processing of UseCountTrailingZerosInstruction option * on CPU without TZCNT instruction (BMI1 feature) support. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseCountTrailingZerosInstructionOnUnsupportedCPU * BMIUnsupportedCPUTest diff --git a/hotspot/test/compiler/arraycopy/TestArrayCopyNoInitDeopt.java b/hotspot/test/compiler/arraycopy/TestArrayCopyNoInitDeopt.java index dcfceb29185..a2430dcf478 100644 --- a/hotspot/test/compiler/arraycopy/TestArrayCopyNoInitDeopt.java +++ b/hotspot/test/compiler/arraycopy/TestArrayCopyNoInitDeopt.java @@ -26,7 +26,7 @@ * @bug 8072016 * @summary Infinite deoptimization/recompilation cycles in case of arraycopy with tightly coupled allocation * @library /testlibrary /test/lib /compiler/whitebox / - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestArrayCopyNoInitDeopt * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/c2/6589834/Test_ia32.java b/hotspot/test/compiler/c2/6589834/Test_ia32.java index d35c70d8a59..a9d11c62821 100644 --- a/hotspot/test/compiler/c2/6589834/Test_ia32.java +++ b/hotspot/test/compiler/c2/6589834/Test_ia32.java @@ -27,7 +27,7 @@ * @summary Safepoint placed between stack pointer increment and decrement leads * to interpreter's stack corruption after deoptimization. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/compiler/c2/6857159/Test6857159.java b/hotspot/test/compiler/c2/6857159/Test6857159.java index 0948367f1f0..1d4b7520865 100644 --- a/hotspot/test/compiler/c2/6857159/Test6857159.java +++ b/hotspot/test/compiler/c2/6857159/Test6857159.java @@ -27,7 +27,7 @@ * @bug 6857159 * @summary local schedule failed with checkcast of Thread.currentThread() * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/compiler/c2/6968348/Test6968348.java b/hotspot/test/compiler/c2/6968348/Test6968348.java index c1af273bfc9..b13b7e638cd 100644 --- a/hotspot/test/compiler/c2/6968348/Test6968348.java +++ b/hotspot/test/compiler/c2/6968348/Test6968348.java @@ -27,7 +27,7 @@ * @bug 6968348 * @summary Byteswapped memory access can point to wrong location after JIT * - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @run main Test6968348 */ diff --git a/hotspot/test/compiler/c2/7068051/Test7068051.java b/hotspot/test/compiler/c2/7068051/Test7068051.java index c83f28ccc6d..7f75fe6857d 100644 --- a/hotspot/test/compiler/c2/7068051/Test7068051.java +++ b/hotspot/test/compiler/c2/7068051/Test7068051.java @@ -28,7 +28,7 @@ * @summary SIGSEGV in PhaseIdealLoop::build_loop_late_post on T5440 * @library /testlibrary * - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm -showversion -Xbatch Test7068051 */ diff --git a/hotspot/test/compiler/c2/7190310/Test7190310_unsafe.java b/hotspot/test/compiler/c2/7190310/Test7190310_unsafe.java index d9881d69f6f..08d6848df4d 100644 --- a/hotspot/test/compiler/c2/7190310/Test7190310_unsafe.java +++ b/hotspot/test/compiler/c2/7190310/Test7190310_unsafe.java @@ -26,7 +26,7 @@ * @test * @bug 7190310 * @summary Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @run main/othervm -Xbatch Test7190310_unsafe */ diff --git a/hotspot/test/compiler/c2/8004867/TestIntUnsafeCAS.java b/hotspot/test/compiler/c2/8004867/TestIntUnsafeCAS.java index 0eb50008c2d..fc8ab3bbdaa 100644 --- a/hotspot/test/compiler/c2/8004867/TestIntUnsafeCAS.java +++ b/hotspot/test/compiler/c2/8004867/TestIntUnsafeCAS.java @@ -27,7 +27,7 @@ * @bug 8004867 * @summary VM crashing with assert "share/vm/opto/node.hpp:357 - assert(i < _max) failed: oob" * - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntUnsafeCAS * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+OptimizeFill TestIntUnsafeCAS */ diff --git a/hotspot/test/compiler/c2/8004867/TestIntUnsafeOrdered.java b/hotspot/test/compiler/c2/8004867/TestIntUnsafeOrdered.java index ef932a1e6b4..137080eb289 100644 --- a/hotspot/test/compiler/c2/8004867/TestIntUnsafeOrdered.java +++ b/hotspot/test/compiler/c2/8004867/TestIntUnsafeOrdered.java @@ -27,7 +27,7 @@ * @bug 8004867 * @summary VM crashing with assert "share/vm/opto/node.hpp:357 - assert(i < _max) failed: oob" * - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntUnsafeOrdered * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+OptimizeFill TestIntUnsafeOrdered */ diff --git a/hotspot/test/compiler/c2/8004867/TestIntUnsafeVolatile.java b/hotspot/test/compiler/c2/8004867/TestIntUnsafeVolatile.java index dc6639d2647..3c8ddf37046 100644 --- a/hotspot/test/compiler/c2/8004867/TestIntUnsafeVolatile.java +++ b/hotspot/test/compiler/c2/8004867/TestIntUnsafeVolatile.java @@ -27,7 +27,7 @@ * @bug 8004867 * @summary VM crashing with assert "share/vm/opto/node.hpp:357 - assert(i < _max) failed: oob" * - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntUnsafeVolatile * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+OptimizeFill TestIntUnsafeVolatile */ diff --git a/hotspot/test/compiler/c2/8005956/PolynomialRoot.java b/hotspot/test/compiler/c2/8005956/PolynomialRoot.java index 3d9c012d98f..ae59572fb89 100644 --- a/hotspot/test/compiler/c2/8005956/PolynomialRoot.java +++ b/hotspot/test/compiler/c2/8005956/PolynomialRoot.java @@ -14,7 +14,7 @@ * @bug 8005956 * @summary C2: assert(!def_outside->member(r)) failed: Use of external LRG overlaps the same LRG defined in this block * @library /testlibrary -* @modules java.base/sun.misc +* @modules java.base/jdk.internal.misc * java.management * @run main/timeout=300 PolynomialRoot */ diff --git a/hotspot/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java b/hotspot/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java index 05a86f923b3..3745d73a008 100644 --- a/hotspot/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java +++ b/hotspot/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java @@ -34,7 +34,7 @@ import java.net.URLConnection; * @bug 8054402 * @summary "Tests unloading of anonymous classes." * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @compile TestAnonymousClassUnloading.java * @run main ClassFileInstaller TestAnonymousClassUnloading * sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/codecache/CheckReservedInitialCodeCacheSizeArgOrder.java b/hotspot/test/compiler/codecache/CheckReservedInitialCodeCacheSizeArgOrder.java index 364a69a584c..0fee258c2c4 100644 --- a/hotspot/test/compiler/codecache/CheckReservedInitialCodeCacheSizeArgOrder.java +++ b/hotspot/test/compiler/codecache/CheckReservedInitialCodeCacheSizeArgOrder.java @@ -28,7 +28,7 @@ * InitialCodeCacheSize are passed to the VM is irrelevant. * @library /testlibrary * - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ import jdk.test.lib.*; diff --git a/hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java b/hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java index 7c97cf30ea7..c002cdbe94b 100644 --- a/hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java +++ b/hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java @@ -29,7 +29,7 @@ import sun.hotspot.WhiteBox; * @bug 8015774 * @library /testlibrary /test/lib * @summary "Checks VM options related to the segmented code cache" - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build CheckSegmentedCodeCache * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/codecache/CheckUpperLimit.java b/hotspot/test/compiler/codecache/CheckUpperLimit.java index 8185d05cfef..086532f0eba 100644 --- a/hotspot/test/compiler/codecache/CheckUpperLimit.java +++ b/hotspot/test/compiler/codecache/CheckUpperLimit.java @@ -27,7 +27,7 @@ * @summary Test ensures that the ReservedCodeCacheSize is at most MAXINT * @library /testlibrary * - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ import jdk.test.lib.*; diff --git a/hotspot/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java b/hotspot/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java index 65079c600c5..5bb55b3724b 100644 --- a/hotspot/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java +++ b/hotspot/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java @@ -31,7 +31,7 @@ import sun.hotspot.code.BlobType; * @bug 8015774 * @summary Verify SegmentedCodeCache option's processing * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java b/hotspot/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java index c96e80b59b5..f664e1bda14 100644 --- a/hotspot/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java +++ b/hotspot/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java @@ -32,7 +32,7 @@ import java.util.EnumSet; * @bug 8015774 * @summary Verify processing of options related to code heaps sizing. * @library /testlibrary .. /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java b/hotspot/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java index 8d0162277f7..efbf2fe49a9 100644 --- a/hotspot/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java +++ b/hotspot/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java @@ -31,7 +31,7 @@ import java.util.EnumSet; * @bug 8015774 * @summary Verify that PrintCodeCache option print correct information. * @library /testlibrary .. /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/compiler/codecache/jmx/GetUsageTest.java b/hotspot/test/compiler/codecache/jmx/GetUsageTest.java index a730f8c8ee0..c4fdc5b8796 100644 --- a/hotspot/test/compiler/codecache/jmx/GetUsageTest.java +++ b/hotspot/test/compiler/codecache/jmx/GetUsageTest.java @@ -30,7 +30,7 @@ import sun.hotspot.code.BlobType; /* * @test GetUsageTest * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build GetUsageTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java b/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java index b58b5b0f6a7..a67812fc683 100644 --- a/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java +++ b/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java @@ -30,7 +30,7 @@ import sun.hotspot.code.BlobType; /* * @test InitialAndMaxUsageTest * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build InitialAndMaxUsageTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/codecache/jmx/PeakUsageTest.java b/hotspot/test/compiler/codecache/jmx/PeakUsageTest.java index dced25799d7..d00aabbf728 100644 --- a/hotspot/test/compiler/codecache/jmx/PeakUsageTest.java +++ b/hotspot/test/compiler/codecache/jmx/PeakUsageTest.java @@ -29,7 +29,7 @@ import sun.hotspot.code.BlobType; * @test PeakUsageTest * @ignore 8151345 * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build PeakUsageTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java b/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java index d5c96601bc7..7fde9594881 100644 --- a/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java +++ b/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java @@ -35,7 +35,7 @@ import sun.hotspot.code.BlobType; /* * @test ThresholdNotificationsTest * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build ThresholdNotificationsTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededSeveralTimesTest.java b/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededSeveralTimesTest.java index 8dd03969d33..aa605074379 100644 --- a/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededSeveralTimesTest.java +++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededSeveralTimesTest.java @@ -24,7 +24,7 @@ /* * @test UsageThresholdExceededSeveralTimesTest * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build UsageThresholdExceededTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java b/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java index 79a38cf8a4e..07008753870 100644 --- a/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java +++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java @@ -28,7 +28,7 @@ import sun.hotspot.code.BlobType; /* * @test UsageThresholdExceededTest * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build UsageThresholdExceededTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java b/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java index dc1af4d5e1f..765eede8938 100644 --- a/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java +++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java @@ -28,7 +28,7 @@ import sun.hotspot.code.BlobType; /* * @test UsageThresholdIncreasedTest * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build UsageThresholdIncreasedTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java b/hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java index 0481edfa77d..29b5263bdad 100644 --- a/hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java +++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java @@ -28,7 +28,7 @@ import sun.hotspot.code.BlobType; /* * @test UsageThresholdNotExceededTest * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build UsageThresholdNotExceededTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/codecache/stress/OverloadCompileQueueTest.java b/hotspot/test/compiler/codecache/stress/OverloadCompileQueueTest.java index 520a02b01ab..e4b60181575 100644 --- a/hotspot/test/compiler/codecache/stress/OverloadCompileQueueTest.java +++ b/hotspot/test/compiler/codecache/stress/OverloadCompileQueueTest.java @@ -30,7 +30,7 @@ import jdk.test.lib.Platform; /* * @test OverloadCompileQueueTest * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @ignore 8071905 * @build OverloadCompileQueueTest diff --git a/hotspot/test/compiler/codecache/stress/RandomAllocationTest.java b/hotspot/test/compiler/codecache/stress/RandomAllocationTest.java index 7a02a7bd775..3000cae7466 100644 --- a/hotspot/test/compiler/codecache/stress/RandomAllocationTest.java +++ b/hotspot/test/compiler/codecache/stress/RandomAllocationTest.java @@ -29,7 +29,7 @@ import sun.hotspot.code.BlobType; /* * @test RandomAllocationTest * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build RandomAllocationTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/codecache/stress/UnexpectedDeoptimizationTest.java b/hotspot/test/compiler/codecache/stress/UnexpectedDeoptimizationTest.java index 6f7f0b0fd67..0eb051ef671 100644 --- a/hotspot/test/compiler/codecache/stress/UnexpectedDeoptimizationTest.java +++ b/hotspot/test/compiler/codecache/stress/UnexpectedDeoptimizationTest.java @@ -25,7 +25,7 @@ /* * @test UnexpectedDeoptimizationTest * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build UnexpectedDeoptimizationTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/codegen/6896617/Test6896617.java b/hotspot/test/compiler/codegen/6896617/Test6896617.java index 310e38aaae7..c83a22a982d 100644 --- a/hotspot/test/compiler/codegen/6896617/Test6896617.java +++ b/hotspot/test/compiler/codegen/6896617/Test6896617.java @@ -26,7 +26,7 @@ * @bug 6896617 * @summary Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() with SSE instructions on x86 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.base/sun.nio.cs * java.management * @run main/othervm/timeout=1200 -Xbatch -Xmx256m Test6896617 diff --git a/hotspot/test/compiler/codegen/7100757/Test7100757.java b/hotspot/test/compiler/codegen/7100757/Test7100757.java index 920ef4db608..d4006168670 100644 --- a/hotspot/test/compiler/codegen/7100757/Test7100757.java +++ b/hotspot/test/compiler/codegen/7100757/Test7100757.java @@ -27,7 +27,7 @@ * @bug 7100757 * @summary The BitSet.nextSetBit() produces incorrect result in 32bit VM on Sparc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/timeout=300 Test7100757 */ diff --git a/hotspot/test/compiler/codegen/7184394/TestAESMain.java b/hotspot/test/compiler/codegen/7184394/TestAESMain.java index a4ed27f3bc2..23a04c236eb 100644 --- a/hotspot/test/compiler/codegen/7184394/TestAESMain.java +++ b/hotspot/test/compiler/codegen/7184394/TestAESMain.java @@ -28,7 +28,7 @@ * @summary add intrinsics to use AES instructions * @library /testlibrary * - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=CBC TestAESMain * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=CBC -DencInputOffset=1 TestAESMain diff --git a/hotspot/test/compiler/codegen/8011901/Test8011901.java b/hotspot/test/compiler/codegen/8011901/Test8011901.java index a9172888dcb..9f071d58563 100644 --- a/hotspot/test/compiler/codegen/8011901/Test8011901.java +++ b/hotspot/test/compiler/codegen/8011901/Test8011901.java @@ -25,7 +25,7 @@ * @test * @bug 8011901 * @summary instruct xaddL_no_res shouldn't allow 64 bit constants. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @run main/othervm -XX:-BackgroundCompilation Test8011901 * */ diff --git a/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityBase.java b/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityBase.java index ff5f70eceaa..bd776c103de 100644 --- a/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityBase.java +++ b/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityBase.java @@ -25,7 +25,7 @@ * @test TestCompilerDirectivesCompatibilityBase * @bug 8137167 * @library /testlibrary /test/lib / - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * @build jdk.test.lib.* diff --git a/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityCommandOff.java b/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityCommandOff.java index 661b06036c0..4b06129a99b 100644 --- a/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityCommandOff.java +++ b/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityCommandOff.java @@ -25,7 +25,7 @@ * @test TestCompilerDirectivesCompatibilityCommandOff * @bug 8137167 * @library /testlibrary /test/lib / - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * @build jdk.test.lib.* diff --git a/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityCommandOn.java b/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityCommandOn.java index 8fd0eec6d53..e9f2bf1c4b4 100644 --- a/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityCommandOn.java +++ b/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityCommandOn.java @@ -25,7 +25,7 @@ * @test TestCompilerDirectivesCompatibilityCommandOn * @bug 8137167 * @library /testlibrary /test/lib / - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * @build jdk.test.lib.* diff --git a/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityFlag.java b/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityFlag.java index 8ec1fc9ee4e..d4d3718f027 100644 --- a/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityFlag.java +++ b/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityFlag.java @@ -25,7 +25,7 @@ * @test TestCompilerDirectivesCompatibilityFlag * @bug 8137167 * @library /testlibrary /test/lib / - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * @build jdk.test.lib.* diff --git a/hotspot/test/compiler/compilercontrol/commandfile/CompileOnlyTest.java b/hotspot/test/compiler/compilercontrol/commandfile/CompileOnlyTest.java index e128f500901..2541d9d0b83 100644 --- a/hotspot/test/compiler/compilercontrol/commandfile/CompileOnlyTest.java +++ b/hotspot/test/compiler/compilercontrol/commandfile/CompileOnlyTest.java @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.commandfile.CompileOnlyTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commandfile.CompileOnlyTest + * @run driver compiler.compilercontrol.commandfile.CompileOnlyTest */ package compiler.compilercontrol.commandfile; diff --git a/hotspot/test/compiler/compilercontrol/commandfile/ExcludeTest.java b/hotspot/test/compiler/compilercontrol/commandfile/ExcludeTest.java index 2b40af6182e..77c2a2e0748 100644 --- a/hotspot/test/compiler/compilercontrol/commandfile/ExcludeTest.java +++ b/hotspot/test/compiler/compilercontrol/commandfile/ExcludeTest.java @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.commandfile.ExcludeTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commandfile.ExcludeTest + * @run driver compiler.compilercontrol.commandfile.ExcludeTest */ package compiler.compilercontrol.commandfile; diff --git a/hotspot/test/compiler/compilercontrol/commandfile/LogTest.java b/hotspot/test/compiler/compilercontrol/commandfile/LogTest.java index a35474235e8..ce45d52b11c 100644 --- a/hotspot/test/compiler/compilercontrol/commandfile/LogTest.java +++ b/hotspot/test/compiler/compilercontrol/commandfile/LogTest.java @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.commandfile.LogTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commandfile.LogTest + * @run driver compiler.compilercontrol.commandfile.LogTest */ package compiler.compilercontrol.commandfile; diff --git a/hotspot/test/compiler/compilercontrol/commandfile/PrintTest.java b/hotspot/test/compiler/compilercontrol/commandfile/PrintTest.java index ede2eb65776..5e90521eabf 100644 --- a/hotspot/test/compiler/compilercontrol/commandfile/PrintTest.java +++ b/hotspot/test/compiler/compilercontrol/commandfile/PrintTest.java @@ -30,9 +30,9 @@ * @build compiler.compilercontrol.commandfile.PrintTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commandfile.PrintTest + * @run driver compiler.compilercontrol.commandfile.PrintTest */ package compiler.compilercontrol.commandfile; diff --git a/hotspot/test/compiler/compilercontrol/commands/CompileOnlyTest.java b/hotspot/test/compiler/compilercontrol/commands/CompileOnlyTest.java index f08fb34e318..7a1b0c1da40 100644 --- a/hotspot/test/compiler/compilercontrol/commands/CompileOnlyTest.java +++ b/hotspot/test/compiler/compilercontrol/commands/CompileOnlyTest.java @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.commands.CompileOnlyTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commands.CompileOnlyTest + * @run driver compiler.compilercontrol.commands.CompileOnlyTest */ package compiler.compilercontrol.commands; diff --git a/hotspot/test/compiler/compilercontrol/commands/ExcludeTest.java b/hotspot/test/compiler/compilercontrol/commands/ExcludeTest.java index 0af19c1a35e..b84befca8c2 100644 --- a/hotspot/test/compiler/compilercontrol/commands/ExcludeTest.java +++ b/hotspot/test/compiler/compilercontrol/commands/ExcludeTest.java @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.commands.ExcludeTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commands.ExcludeTest + * @run driver compiler.compilercontrol.commands.ExcludeTest */ package compiler.compilercontrol.commands; diff --git a/hotspot/test/compiler/compilercontrol/commands/LogTest.java b/hotspot/test/compiler/compilercontrol/commands/LogTest.java index 07a437853cc..4ffebe41a32 100644 --- a/hotspot/test/compiler/compilercontrol/commands/LogTest.java +++ b/hotspot/test/compiler/compilercontrol/commands/LogTest.java @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.commands.LogTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commands.LogTest + * @run driver compiler.compilercontrol.commands.LogTest */ package compiler.compilercontrol.commands; diff --git a/hotspot/test/compiler/compilercontrol/commands/PrintTest.java b/hotspot/test/compiler/compilercontrol/commands/PrintTest.java index eddeadbfbe7..d9ac685ca8f 100644 --- a/hotspot/test/compiler/compilercontrol/commands/PrintTest.java +++ b/hotspot/test/compiler/compilercontrol/commands/PrintTest.java @@ -30,9 +30,9 @@ * @build compiler.compilercontrol.commands.PrintTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commands.PrintTest + * @run driver compiler.compilercontrol.commands.PrintTest */ package compiler.compilercontrol.commands; diff --git a/hotspot/test/compiler/compilercontrol/directives/CompileOnlyTest.java b/hotspot/test/compiler/compilercontrol/directives/CompileOnlyTest.java index bdc3a39f32f..439e5e9505d 100644 --- a/hotspot/test/compiler/compilercontrol/directives/CompileOnlyTest.java +++ b/hotspot/test/compiler/compilercontrol/directives/CompileOnlyTest.java @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.directives.CompileOnlyTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.directives.CompileOnlyTest + * @run driver compiler.compilercontrol.directives.CompileOnlyTest */ package compiler.compilercontrol.directives; diff --git a/hotspot/test/compiler/compilercontrol/directives/ExcludeTest.java b/hotspot/test/compiler/compilercontrol/directives/ExcludeTest.java index 44b33dd43c1..0569cdfe323 100644 --- a/hotspot/test/compiler/compilercontrol/directives/ExcludeTest.java +++ b/hotspot/test/compiler/compilercontrol/directives/ExcludeTest.java @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.directives.ExcludeTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.directives.ExcludeTest + * @run driver compiler.compilercontrol.directives.ExcludeTest */ package compiler.compilercontrol.directives; diff --git a/hotspot/test/compiler/compilercontrol/directives/LogTest.java b/hotspot/test/compiler/compilercontrol/directives/LogTest.java index 634aee5cb01..1f84d4aea5e 100644 --- a/hotspot/test/compiler/compilercontrol/directives/LogTest.java +++ b/hotspot/test/compiler/compilercontrol/directives/LogTest.java @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.directives.LogTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.directives.LogTest + * @run driver compiler.compilercontrol.directives.LogTest */ package compiler.compilercontrol.directives; diff --git a/hotspot/test/compiler/compilercontrol/directives/PrintTest.java b/hotspot/test/compiler/compilercontrol/directives/PrintTest.java index 78ac4de4cee..bbd92c1704b 100644 --- a/hotspot/test/compiler/compilercontrol/directives/PrintTest.java +++ b/hotspot/test/compiler/compilercontrol/directives/PrintTest.java @@ -30,9 +30,9 @@ * @build compiler.compilercontrol.directives.PrintTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.directives.PrintTest + * @run driver compiler.compilercontrol.directives.PrintTest */ package compiler.compilercontrol.directives; diff --git a/hotspot/test/compiler/compilercontrol/jcmd/AddAndRemoveTest.java b/hotspot/test/compiler/compilercontrol/jcmd/AddAndRemoveTest.java index 21d7af2efb7..372b50a72b6 100644 --- a/hotspot/test/compiler/compilercontrol/jcmd/AddAndRemoveTest.java +++ b/hotspot/test/compiler/compilercontrol/jcmd/AddAndRemoveTest.java @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.jcmd.AddAndRemoveTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.AddAndRemoveTest + * @run driver compiler.compilercontrol.jcmd.AddAndRemoveTest */ package compiler.compilercontrol.jcmd; diff --git a/hotspot/test/compiler/compilercontrol/jcmd/AddCompileOnlyTest.java b/hotspot/test/compiler/compilercontrol/jcmd/AddCompileOnlyTest.java index 5f17ad0cc27..5b2a9e26843 100644 --- a/hotspot/test/compiler/compilercontrol/jcmd/AddCompileOnlyTest.java +++ b/hotspot/test/compiler/compilercontrol/jcmd/AddCompileOnlyTest.java @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.jcmd.AddCompileOnlyTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.AddCompileOnlyTest + * @run driver compiler.compilercontrol.jcmd.AddCompileOnlyTest */ package compiler.compilercontrol.jcmd; diff --git a/hotspot/test/compiler/compilercontrol/jcmd/AddExcludeTest.java b/hotspot/test/compiler/compilercontrol/jcmd/AddExcludeTest.java index c72b6c06e4e..a06c32616d8 100644 --- a/hotspot/test/compiler/compilercontrol/jcmd/AddExcludeTest.java +++ b/hotspot/test/compiler/compilercontrol/jcmd/AddExcludeTest.java @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.jcmd.AddExcludeTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.AddExcludeTest + * @run driver compiler.compilercontrol.jcmd.AddExcludeTest */ package compiler.compilercontrol.jcmd; diff --git a/hotspot/test/compiler/compilercontrol/jcmd/AddLogTest.java b/hotspot/test/compiler/compilercontrol/jcmd/AddLogTest.java index 900c57978ab..266cf3c5dda 100644 --- a/hotspot/test/compiler/compilercontrol/jcmd/AddLogTest.java +++ b/hotspot/test/compiler/compilercontrol/jcmd/AddLogTest.java @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.jcmd.AddLogTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.AddLogTest + * @run driver compiler.compilercontrol.jcmd.AddLogTest */ package compiler.compilercontrol.jcmd; diff --git a/hotspot/test/compiler/compilercontrol/jcmd/AddPrintAssemblyTest.java b/hotspot/test/compiler/compilercontrol/jcmd/AddPrintAssemblyTest.java index 8f9c0250138..9697711c294 100644 --- a/hotspot/test/compiler/compilercontrol/jcmd/AddPrintAssemblyTest.java +++ b/hotspot/test/compiler/compilercontrol/jcmd/AddPrintAssemblyTest.java @@ -30,9 +30,9 @@ * @build compiler.compilercontrol.jcmd.AddPrintAssemblyTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.AddPrintAssemblyTest + * @run driver compiler.compilercontrol.jcmd.AddPrintAssemblyTest */ package compiler.compilercontrol.jcmd; diff --git a/hotspot/test/compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java b/hotspot/test/compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java index 25966f9f726..da1fef49141 100644 --- a/hotspot/test/compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java +++ b/hotspot/test/compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java @@ -30,9 +30,9 @@ * @build compiler.compilercontrol.jcmd.ClearDirectivesFileStackTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.ClearDirectivesFileStackTest + * @run driver compiler.compilercontrol.jcmd.ClearDirectivesFileStackTest */ package compiler.compilercontrol.jcmd; diff --git a/hotspot/test/compiler/compilercontrol/jcmd/ClearDirectivesStackTest.java b/hotspot/test/compiler/compilercontrol/jcmd/ClearDirectivesStackTest.java index f9f382da110..c9d9f8dcfd0 100644 --- a/hotspot/test/compiler/compilercontrol/jcmd/ClearDirectivesStackTest.java +++ b/hotspot/test/compiler/compilercontrol/jcmd/ClearDirectivesStackTest.java @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.jcmd.ClearDirectivesStackTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.ClearDirectivesStackTest + * @run driver compiler.compilercontrol.jcmd.ClearDirectivesStackTest */ package compiler.compilercontrol.jcmd; diff --git a/hotspot/test/compiler/compilercontrol/jcmd/PrintDirectivesTest.java b/hotspot/test/compiler/compilercontrol/jcmd/PrintDirectivesTest.java index 5821de76d75..7afd4d6f8b3 100644 --- a/hotspot/test/compiler/compilercontrol/jcmd/PrintDirectivesTest.java +++ b/hotspot/test/compiler/compilercontrol/jcmd/PrintDirectivesTest.java @@ -30,9 +30,9 @@ * @build compiler.compilercontrol.jcmd.PrintDirectivesTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.PrintDirectivesTest + * @run driver compiler.compilercontrol.jcmd.PrintDirectivesTest */ package compiler.compilercontrol.jcmd; diff --git a/hotspot/test/compiler/compilercontrol/jcmd/StressAddMultiThreadedTest.java b/hotspot/test/compiler/compilercontrol/jcmd/StressAddMultiThreadedTest.java index 5bf1464fd55..26c225380ac 100644 --- a/hotspot/test/compiler/compilercontrol/jcmd/StressAddMultiThreadedTest.java +++ b/hotspot/test/compiler/compilercontrol/jcmd/StressAddMultiThreadedTest.java @@ -31,7 +31,7 @@ * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils * compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission * @run driver compiler.compilercontrol.jcmd.StressAddMultiThreadedTest */ diff --git a/hotspot/test/compiler/compilercontrol/matcher/MethodMatcherTest.java b/hotspot/test/compiler/compilercontrol/matcher/MethodMatcherTest.java index 00ca74d108d..87cd26a8958 100644 --- a/hotspot/test/compiler/compilercontrol/matcher/MethodMatcherTest.java +++ b/hotspot/test/compiler/compilercontrol/matcher/MethodMatcherTest.java @@ -42,7 +42,7 @@ import java.util.regex.Pattern; * @summary Tests CompilerCommand's method matcher * @library /testlibrary /test/lib /compiler/whitebox ../share / * @build compiler.compilercontrol.matcher.MethodMatcherTest - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI compiler.compilercontrol.matcher.MethodMatcherTest diff --git a/hotspot/test/compiler/compilercontrol/mixed/RandomCommandsTest.java b/hotspot/test/compiler/compilercontrol/mixed/RandomCommandsTest.java index 13df53afdfe..c954dba9011 100644 --- a/hotspot/test/compiler/compilercontrol/mixed/RandomCommandsTest.java +++ b/hotspot/test/compiler/compilercontrol/mixed/RandomCommandsTest.java @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.mixed.RandomCommandsTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm/timeout=600 compiler.compilercontrol.mixed.RandomCommandsTest + * @run driver/timeout=600 compiler.compilercontrol.mixed.RandomCommandsTest */ package compiler.compilercontrol.mixed; diff --git a/hotspot/test/compiler/compilercontrol/mixed/RandomValidCommandsTest.java b/hotspot/test/compiler/compilercontrol/mixed/RandomValidCommandsTest.java index 7b837e672c5..e8739e8abde 100644 --- a/hotspot/test/compiler/compilercontrol/mixed/RandomValidCommandsTest.java +++ b/hotspot/test/compiler/compilercontrol/mixed/RandomValidCommandsTest.java @@ -30,7 +30,7 @@ * @build compiler.compilercontrol.mixed.RandomValidCommandsTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm/timeout=600 compiler.compilercontrol.mixed.RandomValidCommandsTest */ diff --git a/hotspot/test/compiler/compilercontrol/share/MultiCommand.java b/hotspot/test/compiler/compilercontrol/share/MultiCommand.java index 8072e5b712b..f85591da663 100644 --- a/hotspot/test/compiler/compilercontrol/share/MultiCommand.java +++ b/hotspot/test/compiler/compilercontrol/share/MultiCommand.java @@ -72,6 +72,7 @@ public class MultiCommand extends AbstractTestBase { @Override public void test() { Scenario.Builder builder = Scenario.getBuilder(); + builder.addFlag("-Xmixed"); for (CompileCommand cc : testCases) { cc.print(); builder.add(cc); diff --git a/hotspot/test/compiler/compilercontrol/share/scenario/Scenario.java b/hotspot/test/compiler/compilercontrol/share/scenario/Scenario.java index 49109151d82..505f36e7272 100644 --- a/hotspot/test/compiler/compilercontrol/share/scenario/Scenario.java +++ b/hotspot/test/compiler/compilercontrol/share/scenario/Scenario.java @@ -200,6 +200,7 @@ public final class Scenario { private final List jcmdCommands = new ArrayList<>(); public Builder() { + addFlag("-Xmixed"); builders.put(Type.FILE, new CommandFileBuilder(Type.FILE.fileName)); builders.put(Type.OPTION, new CommandOptionsBuilder()); builders.put(Type.DIRECTIVE, new DirectiveBuilder( @@ -207,6 +208,10 @@ public final class Scenario { jcmdStateBuilder = new JcmdStateBuilder(Type.JCMD.fileName); } + public void addFlag(String flag) { + vmopts.add(flag); + } + public void add(CompileCommand compileCommand) { String[] vmOptions = compileCommand.command.vmOpts; Collections.addAll(vmopts, vmOptions); diff --git a/hotspot/test/compiler/cpuflags/RestoreMXCSR.java b/hotspot/test/compiler/cpuflags/RestoreMXCSR.java index a9efba545ad..9b753745c41 100644 --- a/hotspot/test/compiler/cpuflags/RestoreMXCSR.java +++ b/hotspot/test/compiler/cpuflags/RestoreMXCSR.java @@ -26,7 +26,7 @@ * @bug 8020433 * @summary Crash when using -XX:+RestoreMXCSROnJNICalls * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ import jdk.test.lib.*; diff --git a/hotspot/test/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java b/hotspot/test/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java index 15e265663de..3c16553a549 100644 --- a/hotspot/test/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java +++ b/hotspot/test/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java @@ -29,7 +29,7 @@ import jdk.test.lib.ProcessTools; * @test * @library /testlibrary /test/lib /compiler/whitebox * /compiler/testlibrary /compiler/codegen/7184394 - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @ignore 8146128 * @build TestAESIntrinsicsOnSupportedConfig TestAESMain diff --git a/hotspot/test/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java b/hotspot/test/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java index 7b2c42eda00..0aeca412d17 100644 --- a/hotspot/test/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java +++ b/hotspot/test/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java @@ -30,7 +30,7 @@ import jdk.test.lib.ProcessTools; * @test * @library /testlibrary /test/lib /compiler/whitebox * /compiler/testlibrary /compiler/codegen/7184394 - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestAESIntrinsicsOnUnsupportedConfig TestAESMain * @run main ClassFileInstaller diff --git a/hotspot/test/compiler/debug/VerifyAdapterSharing.java b/hotspot/test/compiler/debug/VerifyAdapterSharing.java index 7a45c4cd3fd..418eed7b688 100644 --- a/hotspot/test/compiler/debug/VerifyAdapterSharing.java +++ b/hotspot/test/compiler/debug/VerifyAdapterSharing.java @@ -26,7 +26,7 @@ * @bug 8030783 * @summary Regression test for 8026478 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ import jdk.test.lib.*; diff --git a/hotspot/test/compiler/dependencies/MonomorphicObjectCall/TestMonomorphicObjectCall.java b/hotspot/test/compiler/dependencies/MonomorphicObjectCall/TestMonomorphicObjectCall.java index 24a8222f23f..7a4539a684f 100644 --- a/hotspot/test/compiler/dependencies/MonomorphicObjectCall/TestMonomorphicObjectCall.java +++ b/hotspot/test/compiler/dependencies/MonomorphicObjectCall/TestMonomorphicObjectCall.java @@ -34,7 +34,7 @@ import jdk.test.lib.*; * @bug 8050079 * @summary Compiles a monomorphic call to finalizeObject() on a modified java.lang.Object to test C1 CHA. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * java.base/jdk.internal * @ignore 8132924 diff --git a/hotspot/test/compiler/escapeAnalysis/TestUnsafePutAddressNullObjMustNotEscape.java b/hotspot/test/compiler/escapeAnalysis/TestUnsafePutAddressNullObjMustNotEscape.java index ce7be99f7a1..3f38678351d 100644 --- a/hotspot/test/compiler/escapeAnalysis/TestUnsafePutAddressNullObjMustNotEscape.java +++ b/hotspot/test/compiler/escapeAnalysis/TestUnsafePutAddressNullObjMustNotEscape.java @@ -25,7 +25,7 @@ * @test * @bug 8038048 * @summary assert(null_obj->escape_state() == PointsToNode::NoEscape,etc) - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+DoEscapeAnalysis -XX:-TieredCompilation -Xbatch TestUnsafePutAddressNullObjMustNotEscape * @author Richard Reingruber richard DOT reingruber AT sap DOT com */ diff --git a/hotspot/test/compiler/gcbarriers/PreserveFPRegistersTest.java b/hotspot/test/compiler/gcbarriers/PreserveFPRegistersTest.java new file mode 100644 index 00000000000..cf63431a3e3 --- /dev/null +++ b/hotspot/test/compiler/gcbarriers/PreserveFPRegistersTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 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 + * @bug 8148175 + * @ignore 8153194 + * @run main/othervm/timeout=300 -Xbatch -Xmx128m PreserveFPRegistersTest + */ +public class PreserveFPRegistersTest { + + public static void main(String... args) throws InterruptedException { + new PreserveFPRegistersTest().go(); + } + + public final Object[][] storage; + + /** + * Number of objects per region. + */ + public final int K = 10; + + /** + * Length of object array: sizeOf(Object[N]) ~= regionSize / K . + */ + public final int N; + + /** + * How many regions involved into testing. + */ + public final int regionCount; + + PreserveFPRegistersTest() { + long regionSize = 1_000_000; //WB.g1RegionSize(); + + Runtime rt = Runtime.getRuntime(); + long used = rt.totalMemory() - rt.freeMemory(); + long totalFree = rt.maxMemory() - used; + regionCount = (int) ( (totalFree / regionSize) * 0.9); + int refSize = 4; + + N = (int) ((regionSize / K ) / refSize) - 5; + storage = new Object[regionCount * K][]; + for (int i = 0; i < storage.length; i++) { + storage[i] = new Object[N]; + } + } + + public void go() throws InterruptedException { + final float FINAL = getValue(); + + for (int to = 0; to < regionCount; to++) { + Object celebrity = storage[to * K]; + for (int from = 0; from < regionCount; from++) { + for (int rn = 0; rn != 100; rn++) { + storage[getY(to, from, rn)][getX(to, from, rn)] = celebrity; + } + if (FINAL != getValue()) { + throw new AssertionError("Final value has changed: " + FINAL + " != " + getValue()); + } + } + } + + System.out.println("TEST PASSED"); + } + + public float getValue() { + return 6; + } + + private int getX(int to, int from, int rn) { + return (rn*regionCount + to) % N; + } + + private int getY(int to, int from, int rn) { + return ((rn*regionCount + to) / N + from * K) % (regionCount*K) ; + } +} diff --git a/hotspot/test/compiler/intrinsics/bmi/TestAndnI.java b/hotspot/test/compiler/intrinsics/bmi/TestAndnI.java index 0f74509722d..31df8625c42 100644 --- a/hotspot/test/compiler/intrinsics/bmi/TestAndnI.java +++ b/hotspot/test/compiler/intrinsics/bmi/TestAndnI.java @@ -28,7 +28,7 @@ * @summary Verify that results of computations are the same w/ * and w/o usage of ANDN instruction * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestAndnI BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/TestAndnL.java b/hotspot/test/compiler/intrinsics/bmi/TestAndnL.java index c8bf93344cc..8f81d11c96e 100644 --- a/hotspot/test/compiler/intrinsics/bmi/TestAndnL.java +++ b/hotspot/test/compiler/intrinsics/bmi/TestAndnL.java @@ -28,7 +28,7 @@ * @summary Verify that results of computations are the same w/ * and w/o usage of ANDN instruction * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestAndnL BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/TestBlsiI.java b/hotspot/test/compiler/intrinsics/bmi/TestBlsiI.java index 4ec017795df..72d2bfa3ab8 100644 --- a/hotspot/test/compiler/intrinsics/bmi/TestBlsiI.java +++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsiI.java @@ -28,7 +28,7 @@ * @summary Verify that results of computations are the same w/ * and w/o usage of BLSI instruction * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestBlsiI BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/TestBlsiL.java b/hotspot/test/compiler/intrinsics/bmi/TestBlsiL.java index 3f19ace7a56..88137320a73 100644 --- a/hotspot/test/compiler/intrinsics/bmi/TestBlsiL.java +++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsiL.java @@ -28,7 +28,7 @@ * @summary Verify that results of computations are the same w/ * and w/o usage of BLSI instruction * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestBlsiL BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/TestBlsmskI.java b/hotspot/test/compiler/intrinsics/bmi/TestBlsmskI.java index c2ad135f1ba..bf6339cc894 100644 --- a/hotspot/test/compiler/intrinsics/bmi/TestBlsmskI.java +++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsmskI.java @@ -28,7 +28,7 @@ * @summary Verify that results of computations are the same w/ * and w/o usage of BLSMSK instruction * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestBlsmskI BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/TestBlsmskL.java b/hotspot/test/compiler/intrinsics/bmi/TestBlsmskL.java index 9753ff2a7b1..62b799c6205 100644 --- a/hotspot/test/compiler/intrinsics/bmi/TestBlsmskL.java +++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsmskL.java @@ -28,7 +28,7 @@ * @summary Verify that results of computations are the same w/ * and w/o usage of BLSMSK instruction * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestBlsmskL BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/TestBlsrI.java b/hotspot/test/compiler/intrinsics/bmi/TestBlsrI.java index c877c87e969..916cde50466 100644 --- a/hotspot/test/compiler/intrinsics/bmi/TestBlsrI.java +++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsrI.java @@ -28,7 +28,7 @@ * @summary Verify that results of computations are the same w/ * and w/o usage of BLSR instruction * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestBlsrI BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/TestBlsrL.java b/hotspot/test/compiler/intrinsics/bmi/TestBlsrL.java index 514feced349..cbc4eec4671 100644 --- a/hotspot/test/compiler/intrinsics/bmi/TestBlsrL.java +++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsrL.java @@ -28,7 +28,7 @@ * @summary Verify that results of computations are the same w/ * and w/o usage of BLSR instruction * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestBlsrL BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/TestLzcntI.java b/hotspot/test/compiler/intrinsics/bmi/TestLzcntI.java index e1104bd4aee..613f1dbaf16 100644 --- a/hotspot/test/compiler/intrinsics/bmi/TestLzcntI.java +++ b/hotspot/test/compiler/intrinsics/bmi/TestLzcntI.java @@ -28,7 +28,7 @@ * @summary Verify that results of computations are the same w/ * and w/o usage of intrinsic * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestLzcntI BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/TestLzcntL.java b/hotspot/test/compiler/intrinsics/bmi/TestLzcntL.java index 9d3f48267f0..1e15c48b2fd 100644 --- a/hotspot/test/compiler/intrinsics/bmi/TestLzcntL.java +++ b/hotspot/test/compiler/intrinsics/bmi/TestLzcntL.java @@ -28,7 +28,7 @@ * @summary Verify that results of computations are the same w/ * and w/o usage of intrinsic * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestLzcntL BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/TestTzcntI.java b/hotspot/test/compiler/intrinsics/bmi/TestTzcntI.java index 76c2d8dc31c..a05109961f5 100644 --- a/hotspot/test/compiler/intrinsics/bmi/TestTzcntI.java +++ b/hotspot/test/compiler/intrinsics/bmi/TestTzcntI.java @@ -28,7 +28,7 @@ * @summary Verify that results of computations are the same w/ * and w/o usage of intrinsic * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestTzcntI BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/TestTzcntL.java b/hotspot/test/compiler/intrinsics/bmi/TestTzcntL.java index 76be757221a..788e00f84f3 100644 --- a/hotspot/test/compiler/intrinsics/bmi/TestTzcntL.java +++ b/hotspot/test/compiler/intrinsics/bmi/TestTzcntL.java @@ -28,7 +28,7 @@ * @summary Verify that results of computations are the same w/ * and w/o usage of intrinsic * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestTzcntL BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestI.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestI.java index c6897440012..fa72d45b0d1 100644 --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestI.java +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestI.java @@ -25,7 +25,7 @@ * @test * @bug 8031321 * @library /testlibrary /test/lib /compiler/whitebox / .. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build AndnTestI * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestL.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestL.java index 8725cb7f0bb..5bd9ebdb057 100644 --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestL.java +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestL.java @@ -25,7 +25,7 @@ * @test * @bug 8031321 * @library /testlibrary /test/lib /compiler/whitebox / .. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build AndnTestL * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java index 7b71a7706d5..fa944503aba 100644 --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java @@ -25,7 +25,7 @@ * @test * @bug 8031321 * @library /testlibrary /test/lib /compiler/whitebox / .. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build BlsiTestI * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java index 7f8d5e37398..0ed38997ab5 100644 --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java @@ -25,7 +25,7 @@ * @test * @bug 8031321 * @library /testlibrary /test/lib /compiler/whitebox / .. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build BlsiTestL * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java index 0e8158c9eb8..bed3688eeed 100644 --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java @@ -25,7 +25,7 @@ * @test * @bug 8031321 * @library /testlibrary /test/lib /compiler/whitebox / .. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build BlsmskTestI * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java index 798b2dc4eca..a419019fe0a 100644 --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java @@ -25,7 +25,7 @@ * @test * @bug 8031321 * @library /testlibrary /test/lib /compiler/whitebox / .. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build BlsmskTestL * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java index 79d1ba7da20..bb67b4185e9 100644 --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java @@ -25,7 +25,7 @@ * @test * @bug 8031321 * @library /testlibrary /test/lib /compiler/whitebox / .. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build BlsrTestI * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java index 29fa2ad239c..b9ee3f3f12d 100644 --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java @@ -25,7 +25,7 @@ * @test * @bug 8031321 * @library /testlibrary /test/lib /compiler/whitebox / .. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build BlsrTestL * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java index 7436044e78e..0cceb5847f5 100644 --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java @@ -25,7 +25,7 @@ * @test * @bug 8031321 * @library /testlibrary /test/lib /compiler/whitebox / .. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build LZcntTestI * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java index c96df728df8..051999739c5 100644 --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java @@ -25,7 +25,7 @@ * @test * @bug 8031321 * @library /testlibrary /test/lib /compiler/whitebox / .. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build LZcntTestL * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java index 25f90f2e89e..a6d12248c47 100644 --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java @@ -25,7 +25,7 @@ * @test * @bug 8031321 * @library /testlibrary /test/lib /compiler/whitebox / .. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TZcntTestI * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java index 812123d422a..618c18aa02e 100644 --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java @@ -25,7 +25,7 @@ * @test * @bug 8031321 * @library /testlibrary /test/lib /compiler/whitebox / .. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TZcntTestL * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/classcast/NullCheckDroppingsTest.java b/hotspot/test/compiler/intrinsics/classcast/NullCheckDroppingsTest.java index 4815141f461..90b4fa142c8 100644 --- a/hotspot/test/compiler/intrinsics/classcast/NullCheckDroppingsTest.java +++ b/hotspot/test/compiler/intrinsics/classcast/NullCheckDroppingsTest.java @@ -26,7 +26,7 @@ * @bug 8054492 * @summary "Casting can result in redundant null checks in generated code" * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.* * @build NullCheckDroppingsTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/AddExactIConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/AddExactIConstantTest.java index 1507a53abef..0e9b7021366 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/AddExactIConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactIConstantTest.java @@ -26,7 +26,7 @@ * @bug 8024924 * @summary Test constant addExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile AddExactIConstantTest.java Verify.java * @run main AddExactIConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/AddExactILoadTest.java b/hotspot/test/compiler/intrinsics/mathexact/AddExactILoadTest.java index f24c2417537..2c353d686a2 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/AddExactILoadTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactILoadTest.java @@ -26,7 +26,7 @@ * @bug 8024924 * @summary Test non constant addExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile AddExactILoadTest.java Verify.java * @run main AddExactILoadTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/AddExactILoopDependentTest.java b/hotspot/test/compiler/intrinsics/mathexact/AddExactILoopDependentTest.java index b4a22eb3c91..4093783bd98 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/AddExactILoopDependentTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactILoopDependentTest.java @@ -26,7 +26,7 @@ * @bug 8024924 * @summary Test non constant addExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile AddExactILoopDependentTest.java Verify.java * @run main AddExactILoopDependentTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/AddExactINonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/AddExactINonConstantTest.java index 5833d78fdea..64d518e5562 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/AddExactINonConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactINonConstantTest.java @@ -26,7 +26,7 @@ * @bug 8024924 * @summary Test non constant addExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile AddExactINonConstantTest.java Verify.java * @run main AddExactINonConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/AddExactIRepeatTest.java b/hotspot/test/compiler/intrinsics/mathexact/AddExactIRepeatTest.java index db15f6c6580..f1fe0c652d8 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/AddExactIRepeatTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactIRepeatTest.java @@ -26,7 +26,7 @@ * @bug 8025657 * @summary Test repeating addExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile AddExactIRepeatTest.java Verify.java * @run main AddExactIRepeatTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/AddExactLConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/AddExactLConstantTest.java index c42914f06c5..8e2826650a4 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/AddExactLConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactLConstantTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test constant addExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile AddExactLConstantTest.java Verify.java * @run main AddExactLConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/AddExactLNonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/AddExactLNonConstantTest.java index 6f8c898baae..969899c851a 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/AddExactLNonConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactLNonConstantTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test non constant addExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile AddExactLNonConstantTest.java Verify.java * @run main AddExactLNonConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/DecExactITest.java b/hotspot/test/compiler/intrinsics/mathexact/DecExactITest.java index ac769b91513..fd76e367026 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/DecExactITest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/DecExactITest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test decrementExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile DecExactITest.java Verify.java * @run main DecExactITest diff --git a/hotspot/test/compiler/intrinsics/mathexact/DecExactLTest.java b/hotspot/test/compiler/intrinsics/mathexact/DecExactLTest.java index 416ec96102d..2399b9bb5c5 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/DecExactLTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/DecExactLTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test decrementExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile DecExactLTest.java Verify.java * @run main DecExactLTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/IncExactITest.java b/hotspot/test/compiler/intrinsics/mathexact/IncExactITest.java index 6037ddf5073..d4f5a80aad7 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/IncExactITest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/IncExactITest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test incrementExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile IncExactITest.java Verify.java * @run main IncExactITest diff --git a/hotspot/test/compiler/intrinsics/mathexact/IncExactLTest.java b/hotspot/test/compiler/intrinsics/mathexact/IncExactLTest.java index 0dd009c86c5..a4b456fdad8 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/IncExactLTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/IncExactLTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test incrementExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile IncExactLTest.java Verify.java * @run main IncExactLTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/MulExactIConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/MulExactIConstantTest.java index c47794474d9..9b0ef7000df 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/MulExactIConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactIConstantTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test constant multiplyExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile MulExactIConstantTest.java Verify.java * @run main MulExactIConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/MulExactILoadTest.java b/hotspot/test/compiler/intrinsics/mathexact/MulExactILoadTest.java index 32ea6074eb7..5b24bb60782 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/MulExactILoadTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactILoadTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test multiplyExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile MulExactILoadTest.java Verify.java * @run main MulExactILoadTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/MulExactILoopDependentTest.java b/hotspot/test/compiler/intrinsics/mathexact/MulExactILoopDependentTest.java index 2a5b3ea53e1..c37ee65c994 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/MulExactILoopDependentTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactILoopDependentTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test loop dependent multiplyExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile MulExactILoopDependentTest.java Verify.java * @run main MulExactILoopDependentTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/MulExactINonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/MulExactINonConstantTest.java index ec2ba1ec403..ed0e4f99449 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/MulExactINonConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactINonConstantTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test non constant multiplyExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile MulExactINonConstantTest.java Verify.java * @run main MulExactINonConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/MulExactIRepeatTest.java b/hotspot/test/compiler/intrinsics/mathexact/MulExactIRepeatTest.java index fc07375fdf9..d404cac42cd 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/MulExactIRepeatTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactIRepeatTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test repeating multiplyExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile MulExactIRepeatTest.java Verify.java * @run main MulExactIRepeatTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/MulExactLConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/MulExactLConstantTest.java index a0f5e9bb378..f45f31decea 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/MulExactLConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactLConstantTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test constant mulExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile MulExactLConstantTest.java Verify.java * @run main MulExactLConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/MulExactLNonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/MulExactLNonConstantTest.java index 22e475f67a3..4dee223caa3 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/MulExactLNonConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactLNonConstantTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test non constant mulExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile MulExactLNonConstantTest.java Verify.java * @run main MulExactLNonConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/NegExactIConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/NegExactIConstantTest.java index c2f77b943c5..fc285e1280d 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/NegExactIConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactIConstantTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test constant negExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile NegExactIConstantTest.java Verify.java * @run main NegExactIConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/NegExactILoadTest.java b/hotspot/test/compiler/intrinsics/mathexact/NegExactILoadTest.java index d4a92dc09ea..74aeb86905d 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/NegExactILoadTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactILoadTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test negExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile NegExactILoadTest.java Verify.java * @run main NegExactILoadTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/NegExactILoopDependentTest.java b/hotspot/test/compiler/intrinsics/mathexact/NegExactILoopDependentTest.java index 3897a1fcae9..1d7a1e35387 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/NegExactILoopDependentTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactILoopDependentTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test negExact loop dependent * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile NegExactILoopDependentTest.java Verify.java * @run main NegExactILoopDependentTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/NegExactINonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/NegExactINonConstantTest.java index 703cf25065c..b7f773620b1 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/NegExactINonConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactINonConstantTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test non constant negExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile NegExactINonConstantTest.java Verify.java * @run main NegExactINonConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/NegExactLConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/NegExactLConstantTest.java index 52ea8a70547..b10da7b232b 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/NegExactLConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactLConstantTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test constant negExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile NegExactLConstantTest.java Verify.java * @run main NegExactLConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/NegExactLNonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/NegExactLNonConstantTest.java index 3932147cba2..c3ecae769ac 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/NegExactLNonConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactLNonConstantTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test constant negExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile NegExactLNonConstantTest.java Verify.java * @run main NegExactLNonConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactICondTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactICondTest.java index cef59196493..249b459e151 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/SubExactICondTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactICondTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test subtractExact as condition * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile SubExactICondTest.java Verify.java * @run main SubExactICondTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactIConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactIConstantTest.java index 96127d1e396..cb4cd779fff 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/SubExactIConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactIConstantTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test constant subtractExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile SubExactIConstantTest.java Verify.java * @run main SubExactIConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactILoadTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactILoadTest.java index 7b8f017c805..e88486af1d8 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/SubExactILoadTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactILoadTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test non constant subtractExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile SubExactILoadTest.java Verify.java * @run main SubExactILoadTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactILoopDependentTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactILoopDependentTest.java index 71ea0dc3628..4afec64f6fb 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/SubExactILoopDependentTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactILoopDependentTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test non constant subtractExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile SubExactILoopDependentTest.java Verify.java * @run main SubExactILoopDependentTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactINonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactINonConstantTest.java index c0de7d3d959..a9c1efb8596 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/SubExactINonConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactINonConstantTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test non constant subtractExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile SubExactINonConstantTest.java Verify.java * @run main SubExactINonConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactIRepeatTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactIRepeatTest.java index b9ed7eb395f..1e133142cd7 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/SubExactIRepeatTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactIRepeatTest.java @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test repeating subtractExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile SubExactIRepeatTest.java Verify.java * @run main SubExactIRepeatTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactLConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactLConstantTest.java index 722886847ef..d9730273a71 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/SubExactLConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactLConstantTest.java @@ -27,7 +27,7 @@ * @bug 8027353 * @summary Test constant subtractExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile SubExactLConstantTest.java Verify.java * @run main SubExactLConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactLNonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactLNonConstantTest.java index 942939ed132..be9badca0e2 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/SubExactLNonConstantTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactLNonConstantTest.java @@ -27,7 +27,7 @@ * @bug 8027353 * @summary Test non constant subtractExact * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile SubExactLNonConstantTest.java Verify.java * @run main SubExactLNonConstantTest diff --git a/hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactIntTest.java b/hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactIntTest.java index 89ad29a5fc4..0a183ffe102 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactIntTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactIntTest.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary /test/lib /compiler/whitebox / /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build AddExactIntTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactLongTest.java b/hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactLongTest.java index a5cae206498..961a3e2dfe6 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactLongTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactLongTest.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary /test/lib /compiler/whitebox / /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build AddExactLongTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactIntTest.java b/hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactIntTest.java index 6011d913025..2e182ce6eb0 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactIntTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactIntTest.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary /test/lib /compiler/whitebox / /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build DecrementExactIntTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactLongTest.java b/hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactLongTest.java index 973403bc055..7c8121afab7 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactLongTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactLongTest.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary /test/lib /compiler/whitebox / /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build DecrementExactLongTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactIntTest.java b/hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactIntTest.java index bddaeb92351..ee47968b7e6 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactIntTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactIntTest.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary /test/lib /compiler/whitebox / /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build IncrementExactIntTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactLongTest.java b/hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactLongTest.java index 7f32d312b50..eb65784e18f 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactLongTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactLongTest.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary /test/lib /compiler/whitebox / /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build IncrementExactLongTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactIntTest.java b/hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactIntTest.java index c02bbe1c2c8..7c53f29b0df 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactIntTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactIntTest.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary /test/lib /compiler/whitebox / /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build MultiplyExactIntTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactLongTest.java b/hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactLongTest.java index 3a480147ead..7c82e7328fd 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactLongTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactLongTest.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary /test/lib /compiler/whitebox / /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build MultiplyExactLongTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactIntTest.java b/hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactIntTest.java index ed99f769e15..c1ddb1649b7 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactIntTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactIntTest.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary /test/lib /compiler/whitebox / /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build NegateExactIntTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactLongTest.java b/hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactLongTest.java index 946da7ed44f..dc18373ce95 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactLongTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactLongTest.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary /test/lib /compiler/whitebox / /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build NegateExactLongTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactIntTest.java b/hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactIntTest.java index 3681ffe35d9..12813886b2d 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactIntTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactIntTest.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary /test/lib /compiler/whitebox / /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build SubtractExactIntTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactLongTest.java b/hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactLongTest.java index f0a8903131a..dd3e1c233df 100644 --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactLongTest.java +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactLongTest.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary /test/lib /compiler/whitebox / /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build SubtractExactLongTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/muladd/TestMulAdd.java b/hotspot/test/compiler/intrinsics/muladd/TestMulAdd.java index 4d7b274c284..4b310e9069e 100644 --- a/hotspot/test/compiler/intrinsics/muladd/TestMulAdd.java +++ b/hotspot/test/compiler/intrinsics/muladd/TestMulAdd.java @@ -28,7 +28,7 @@ * @summary Add C2 x86 intrinsic for BigInteger::mulAdd() method * * @run main/othervm/timeout=600 -XX:-TieredCompilation -Xbatch - * -XX:+IgnoreUnrecognizedVMOptions -XX:-UseSquareToLenIntrinsic -XX:-UseMultiplyToLenIntrinsic + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:-UseSquareToLenIntrinsic -XX:-UseMultiplyToLenIntrinsic * -XX:CompileCommand=dontinline,TestMulAdd::main * -XX:CompileCommand=option,TestMulAdd::base_multiply,ccstr,DisableIntrinsic,_mulAdd * -XX:CompileCommand=option,java.math.BigInteger::multiply,ccstr,DisableIntrinsic,_mulAdd diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnSupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnSupportedCPU.java index 77f9fd274be..ad85544a188 100644 --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnSupportedCPU.java +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnSupportedCPU.java @@ -26,7 +26,7 @@ * @bug 8035968 * @summary Verify UseSHA1Intrinsics option processing on supported CPU, * @library /testlibrary /test/lib /compiler/testlibrary testcases - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseSHA1IntrinsicsOptionOnSupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java index 5ca1f1a2ecf..f48613971eb 100644 --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java @@ -26,7 +26,7 @@ * @bug 8035968 * @summary Verify UseSHA1Intrinsics option processing on unsupported CPU, * @library /testlibrary /test/lib /compiler/testlibrary testcases - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseSHA1IntrinsicsOptionOnUnsupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnSupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnSupportedCPU.java index bad4bf1bb9d..692bf2262fb 100644 --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnSupportedCPU.java +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnSupportedCPU.java @@ -26,7 +26,7 @@ * @bug 8035968 * @summary Verify UseSHA256Intrinsics option processing on supported CPU, * @library /testlibrary /test/lib /compiler/testlibrary testcases - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseSHA256IntrinsicsOptionOnSupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java index 13c46a46a76..665a05f3f41 100644 --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java @@ -26,7 +26,7 @@ * @bug 8035968 * @summary Verify UseSHA256Intrinsics option processing on unsupported CPU, * @library /testlibrary /test/lib /compiler/testlibrary testcases - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseSHA256IntrinsicsOptionOnUnsupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnSupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnSupportedCPU.java index 06851873f9e..e9dec043dce 100644 --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnSupportedCPU.java +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnSupportedCPU.java @@ -26,7 +26,7 @@ * @bug 8035968 * @summary Verify UseSHA512Intrinsics option processing on supported CPU. * @library /testlibrary /test/lib /compiler/testlibrary testcases - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseSHA512IntrinsicsOptionOnSupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java index 4d776611daa..ac270b055f8 100644 --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java @@ -26,7 +26,7 @@ * @bug 8035968 * @summary Verify UseSHA512Intrinsics option processing on unsupported CPU, * @library /testlibrary /test/lib /compiler/testlibrary testcases - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseSHA512IntrinsicsOptionOnUnsupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnSupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnSupportedCPU.java index 8c5bd2f0307..7873eef1c95 100644 --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnSupportedCPU.java +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnSupportedCPU.java @@ -26,7 +26,7 @@ * @bug 8035968 * @summary Verify UseSHA option processing on supported CPU, * @library /testlibrary /test/lib /compiler/testlibrary testcases - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseSHAOptionOnSupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java index e6d1161a1e6..3a5f6f08cda 100644 --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java @@ -26,7 +26,7 @@ * @bug 8035968 * @summary Verify UseSHA option processing on unsupported CPU. * @library /testlibrary /test/lib /compiler/testlibrary testcases - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseSHAOptionOnUnsupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1Intrinsics.java b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1Intrinsics.java index c490762e2bf..7f1dba6213c 100644 --- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1Intrinsics.java +++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1Intrinsics.java @@ -26,7 +26,7 @@ * @bug 8035968 * @summary Verify that SHA-1 intrinsic is actually used. * @library /testlibrary /test/lib /compiler/testlibrary ../ - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestSHA intrinsics.Verifier TestSHA1Intrinsics * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1MultiBlockIntrinsics.java b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1MultiBlockIntrinsics.java index 4ebd58c7120..f4909da982b 100644 --- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1MultiBlockIntrinsics.java +++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1MultiBlockIntrinsics.java @@ -28,7 +28,7 @@ import sha.predicate.IntrinsicPredicates; * @bug 8035968 * @summary Verify that SHA-1 multi block intrinsic is actually used. * @library /testlibrary /test/lib /compiler/testlibrary ../ - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestSHA intrinsics.Verifier TestSHA1MultiBlockIntrinsics * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256Intrinsics.java b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256Intrinsics.java index dc8a00f9c46..2154daf85de 100644 --- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256Intrinsics.java +++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256Intrinsics.java @@ -28,7 +28,7 @@ import sha.predicate.IntrinsicPredicates; * @bug 8035968 * @summary Verify that SHA-256 intrinsic is actually used. * @library /testlibrary /test/lib /compiler/testlibrary ../ - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestSHA intrinsics.Verifier TestSHA256Intrinsics * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256MultiBlockIntrinsics.java b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256MultiBlockIntrinsics.java index ba42a968d7c..3d6809fbf61 100644 --- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256MultiBlockIntrinsics.java +++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256MultiBlockIntrinsics.java @@ -28,7 +28,7 @@ import sha.predicate.IntrinsicPredicates; * @bug 8035968 * @summary Verify that SHA-256 multi block intrinsic is actually used. * @library /testlibrary /test/lib /compiler/testlibrary ../ - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestSHA intrinsics.Verifier TestSHA256MultiBlockIntrinsics * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512Intrinsics.java b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512Intrinsics.java index dbd78e157d5..771113cbef2 100644 --- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512Intrinsics.java +++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512Intrinsics.java @@ -28,7 +28,7 @@ import sha.predicate.IntrinsicPredicates; * @bug 8035968 * @summary Verify that SHA-512 intrinsic is actually used. * @library /testlibrary /test/lib /compiler/testlibrary ../ - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestSHA intrinsics.Verifier TestSHA512Intrinsics * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512MultiBlockIntrinsics.java b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512MultiBlockIntrinsics.java index 00c8a40aa64..0497415059e 100644 --- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512MultiBlockIntrinsics.java +++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512MultiBlockIntrinsics.java @@ -28,7 +28,7 @@ import sha.predicate.IntrinsicPredicates; * @bug 8035968 * @summary Verify that SHA-512 multi block intrinsic is actually used. * @library /testlibrary /test/lib /compiler/testlibrary ../ - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestSHA intrinsics.Verifier TestSHA512MultiBlockIntrinsics * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/intrinsics/string/TestHasNegatives.java b/hotspot/test/compiler/intrinsics/string/TestHasNegatives.java new file mode 100644 index 00000000000..587eb0c34ec --- /dev/null +++ b/hotspot/test/compiler/intrinsics/string/TestHasNegatives.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 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. 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. + */ + +/* + * @test + * @bug 8054307 + * @summary Validates StringCoding.hasNegatives intrinsic with a small range of tests. + * @library /compiler/patches + * @build java.base/java.lang.Helper + * @build compiler.intrinsics.string.TestHasNegatives + * @run main compiler.intrinsics.string.TestHasNegatives + */ +package compiler.intrinsics.string; + +import java.lang.Helper; + +/* + * @summary Validates StringCoding.hasNegatives intrinsic with a small + * range of tests. + */ +public class TestHasNegatives { + + private static byte[] tBa = new byte[4096 + 16]; + + /** + * Completely initialize the test array, preparing it for tests of the + * StringCoding.hasNegatives method with a given array segment offset, + * length, and number of negative bytes. + */ + public static void initialize(int off, int len, int neg) { + assert (len + off <= tBa.length); + // insert "canary" (negative) values before offset + for (int i = 0; i < off; ++i) { + tBa[i] = (byte) (((i + 15) & 0x7F) | 0x80); + } + // fill the array segment + for (int i = off; i < len + off; ++i) { + tBa[i] = (byte) (((i - off + 15) & 0x7F)); + } + if (neg != 0) { + // modify a number (neg) disparate array bytes inside + // segment to be negative. + int div = (neg > 1) ? (len - 1) / (neg - 1) : 0; + int idx; + for (int i = 0; i < neg; ++i) { + idx = off + (len - 1) - div * i; + tBa[idx] = (byte) (0x80 | tBa[idx]); + } + } + // insert "canary" negative values after array segment + for (int i = len + off; i < tBa.length; ++i) { + tBa[i] = (byte) (((i + 15) & 0x7F) | 0x80); + } + } + + /** Sizes of array segments to test. */ + private static int sizes[] = { 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 13, 17, 19, 23, 37, 61, 131, + 4099 }; + + /** + * Test different array segment sizes, offsets, and number of negative + * bytes. + */ + public static void test_hasNegatives() throws Exception { + int len, off; + int ng; + boolean r; + + for (ng = 0; ng < 57; ++ng) { // number of negatives in array segment + for (off = 0; off < 8; ++off) { // starting offset of array segment + for (int i = 0; i < sizes.length; ++i) { // array segment size + // choice + len = sizes[i]; + if (len + off > tBa.length) + continue; + initialize(off, len, ng); + r = Helper.StringCodingHasNegatives(tBa, off, len); + if (r ^ ((ng == 0) ? false : true)) { + throw new Exception("Failed test hasNegatives " + "offset: " + off + " " + + "length: " + len + " " + "return: " + r + " " + "negatives: " + + ng); + } + } + } + } + } + + public void run() throws Exception { + // iterate to eventually get intrinsic inlined + for (int j = 0; j < 1000; ++j) { + test_hasNegatives(); + } + } + + public static void main(String[] args) throws Exception { + (new TestHasNegatives()).run(); + System.out.println("hasNegatives validated"); + } +} diff --git a/hotspot/test/compiler/intrinsics/unsafe/UnsafeGetAddressTest.java b/hotspot/test/compiler/intrinsics/unsafe/UnsafeGetAddressTest.java index 468a99df521..5ed225fd871 100644 --- a/hotspot/test/compiler/intrinsics/unsafe/UnsafeGetAddressTest.java +++ b/hotspot/test/compiler/intrinsics/unsafe/UnsafeGetAddressTest.java @@ -25,7 +25,7 @@ * @test * @bug 6653795 * @summary C2 intrinsic for Unsafe.getAddress performs pointer sign extension on 32-bit systems - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @run main UnsafeGetAddressTest * */ diff --git a/hotspot/test/compiler/jsr292/ConcurrentClassLoadingTest.java b/hotspot/test/compiler/jsr292/ConcurrentClassLoadingTest.java index b13d75cd6df..cf591ff7218 100644 --- a/hotspot/test/compiler/jsr292/ConcurrentClassLoadingTest.java +++ b/hotspot/test/compiler/jsr292/ConcurrentClassLoadingTest.java @@ -26,7 +26,7 @@ * @bug 8022595 * @summary JSR292: deadlock during class loading of MethodHandles, MethodHandleImpl & MethodHandleNatives * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm ConcurrentClassLoadingTest */ diff --git a/hotspot/test/compiler/jsr292/VMAnonymousClasses.java b/hotspot/test/compiler/jsr292/VMAnonymousClasses.java index efe252f9067..50bb3432642 100644 --- a/hotspot/test/compiler/jsr292/VMAnonymousClasses.java +++ b/hotspot/test/compiler/jsr292/VMAnonymousClasses.java @@ -25,7 +25,7 @@ * @test * @bug 8058828 * @modules java.base/jdk.internal.org.objectweb.asm - * java.base/sun.misc + * java.base/jdk.internal.misc * @run main/bootclasspath -Xbatch VMAnonymousClasses */ diff --git a/hotspot/test/compiler/jvmci/code/DataPatchTest.java b/hotspot/test/compiler/jvmci/code/DataPatchTest.java index 60e46915202..294d21e571d 100644 --- a/hotspot/test/compiler/jvmci/code/DataPatchTest.java +++ b/hotspot/test/compiler/jvmci/code/DataPatchTest.java @@ -40,6 +40,8 @@ package compiler.jvmci.code; import jdk.vm.ci.code.Register; import jdk.vm.ci.code.site.DataSectionReference; import jdk.vm.ci.hotspot.HotSpotConstant; +import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider; +import jdk.vm.ci.hotspot.HotSpotSymbol; import jdk.vm.ci.hotspot.HotSpotVMConfig; import jdk.vm.ci.meta.ResolvedJavaType; @@ -155,4 +157,33 @@ public class DataPatchTest extends CodeInstallationTest { asm.emitPointerRet(ret); }); } + + + public static long getConstSymbol(HotSpotMetaAccessProvider meta) { + HotSpotSymbol symbol = meta.lookupSymbol("java/lang/Object"); + return symbol.getMetaspacePointer(); + } + + private void testSymbol(TestCompiler compiler) { + test(compiler, getMethod("getConstSymbol", HotSpotMetaAccessProvider.class), (HotSpotMetaAccessProvider) metaAccess); + } + + @Test + public void testInlineSymbol() { + testSymbol(asm -> { + HotSpotSymbol symbol = ((HotSpotMetaAccessProvider) metaAccess).lookupSymbol("java/lang/Object"); + Register ret = asm.emitLoadPointer((HotSpotConstant) symbol.asConstant()); + asm.emitPointerRet(ret); + }); + } + + @Test + public void testSymbolInDataSection() { + testSymbol(asm -> { + HotSpotSymbol symbol = ((HotSpotMetaAccessProvider) metaAccess).lookupSymbol("java/lang/Object"); + DataSectionReference ref = asm.emitDataItem((HotSpotConstant) symbol.asConstant()); + Register ret = asm.emitLoadPointer(ref); + asm.emitPointerRet(ret); + }); + } } diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/AsJavaTypeDataProvider.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/AsJavaTypeDataProvider.java new file mode 100644 index 00000000000..24bedbca695 --- /dev/null +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/AsJavaTypeDataProvider.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 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. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; + +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class AsJavaTypeDataProvider { + + @DataProvider(name = "asJavaTypeDataProvider") + public static Object[][] asJavaTypeDataProvider() { + return new Object[][]{ + {CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.class), + "jdk.vm.ci.hotspot.test.DummyClass"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(boolean.class), "boolean"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(byte.class), "byte"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(short.class), "short"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(char.class), "char"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(int.class), "int"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(long.class), "long"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(float.class), "float"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(double.class), "double"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(Object.class), "java.lang.Object"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(boolean[].class), "boolean[]"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(boolean[][].class), "boolean[][]"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(Object[].class), "java.lang.Object[]"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(Object[][].class), "java.lang.Object[][]"}, + {JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanField), null}, + {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField), null}, + {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE), null}, + {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayWithValues), null}, + {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues), null}, + {JavaConstant.NULL_POINTER, null}, {null, null}}; + } +} diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/BoxPrimitiveDataProvider.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/BoxPrimitiveDataProvider.java new file mode 100644 index 00000000000..4aa25b5c678 --- /dev/null +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/BoxPrimitiveDataProvider.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 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. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; + +import java.util.LinkedList; +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class BoxPrimitiveDataProvider { + + @DataProvider(name = "boxPrimitiveDataProvider") + public static Object[][] boxPrimitiveDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + // Boolean testing + cfgSet.add( + new Object[]{JavaConstant.forBoolean(true), CONSTANT_REFLECTION_PROVIDER.forObject((Boolean) true)}); + cfgSet.add(new Object[]{JavaConstant.forBoolean(false), + CONSTANT_REFLECTION_PROVIDER.forObject((Boolean) false)}); + // Boxed boolean testing (returns null) + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject((Boolean) true), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject((Boolean) false), null}); + for (byte number : new byte[]{-128, 0, 1, 127}) { + // Integer primitives testing + cfgSet.add(new Object[]{JavaConstant.forByte(number), + CONSTANT_REFLECTION_PROVIDER.forObject(Byte.valueOf(number))}); + cfgSet.add(new Object[]{JavaConstant.forShort(number), + CONSTANT_REFLECTION_PROVIDER.forObject(Short.valueOf(number))}); + cfgSet.add(new Object[]{JavaConstant.forInt(number), + CONSTANT_REFLECTION_PROVIDER.forObject(Integer.valueOf(number))}); + cfgSet.add(new Object[]{JavaConstant.forLong(number), + CONSTANT_REFLECTION_PROVIDER.forObject(Long.valueOf(number))}); + if (number >= 0) { + cfgSet.add(new Object[]{JavaConstant.forChar((char) number), + CONSTANT_REFLECTION_PROVIDER.forObject(Character.valueOf((char) number))}); + } + // Float and Double variables are not cached, + // so the tested method returns "null" on them + cfgSet.add(new Object[]{JavaConstant.forFloat((float) number), null}); + cfgSet.add(new Object[]{JavaConstant.forDouble((double) number), null}); + // Boxed primitives testing (return null) + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Byte.valueOf(number)), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Short.valueOf(number)), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Integer.valueOf(number)), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Long.valueOf(number)), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Character.valueOf((char) number)), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Float.valueOf(number)), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Double.valueOf(number)), null}); + } + // Integer primitives testing with big non-cached values (returns null) + cfgSet.add(new Object[]{JavaConstant.forShort(Short.MAX_VALUE), null}); + cfgSet.add(new Object[]{JavaConstant.forInt(Integer.MAX_VALUE), null}); + cfgSet.add(new Object[]{JavaConstant.forLong(Long.MAX_VALUE), null}); + cfgSet.add(new Object[]{JavaConstant.forChar(Character.MAX_VALUE), null}); + // Non-primitives testing + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayWithValues), + null}); + // Null testing + cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, null}); + cfgSet.add(new Object[]{null, null}); + return cfgSet.toArray(new Object[0][0]); + } +} diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ConstantEqualsDataProvider.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ConstantEqualsDataProvider.java new file mode 100644 index 00000000000..93fa1e024a4 --- /dev/null +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ConstantEqualsDataProvider.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 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. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Objects; +import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class ConstantEqualsDataProvider { + @DataProvider(name = "constantEqualsDataProvider") + public static Object[][] constantEqualsDataProvider() { + HashMap constMap = new HashMap<>(); + constMap.put(DUMMY_CLASS_INSTANCE.booleanField, JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultBooleanField, + JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.stableDefaultBooleanField)); + constMap.put(DUMMY_CLASS_INSTANCE.byteField, JavaConstant.forByte(DUMMY_CLASS_INSTANCE.byteField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalByteField, JavaConstant.forByte(DUMMY_CLASS_INSTANCE.finalByteField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultByteField, + JavaConstant.forByte(DUMMY_CLASS_INSTANCE.stableDefaultByteField)); + constMap.put(DUMMY_CLASS_INSTANCE.shortField, JavaConstant.forShort(DUMMY_CLASS_INSTANCE.shortField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalShortField, JavaConstant.forShort(DUMMY_CLASS_INSTANCE.finalShortField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultShortField, + JavaConstant.forShort(DUMMY_CLASS_INSTANCE.stableDefaultShortField)); + constMap.put(DUMMY_CLASS_INSTANCE.intField, JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalIntField, JavaConstant.forInt(DUMMY_CLASS_INSTANCE.finalIntField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultIntField, + JavaConstant.forInt(DUMMY_CLASS_INSTANCE.stableDefaultIntField)); + constMap.put(DUMMY_CLASS_INSTANCE.longField, JavaConstant.forLong(DUMMY_CLASS_INSTANCE.longField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalLongField, JavaConstant.forLong(DUMMY_CLASS_INSTANCE.finalLongField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultLongField, + JavaConstant.forLong(DUMMY_CLASS_INSTANCE.stableDefaultLongField)); + constMap.put(DUMMY_CLASS_INSTANCE.doubleField, JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.doubleField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalDoubleField, + JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.finalDoubleField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultDoubleField, + JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.stableDefaultDoubleField)); + constMap.put(DUMMY_CLASS_INSTANCE.floatField, JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.floatField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalFloatField, JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.finalFloatField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultFloatField, + JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.stableDefaultFloatField)); + constMap.put(DUMMY_CLASS_INSTANCE.charField, JavaConstant.forChar(DUMMY_CLASS_INSTANCE.charField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalCharField, JavaConstant.forChar(DUMMY_CLASS_INSTANCE.finalCharField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultCharField, + JavaConstant.forChar(DUMMY_CLASS_INSTANCE.stableDefaultCharField)); + constMap.put(DUMMY_CLASS_INSTANCE.stringField, + CONSTANT_REFLECTION_PROVIDER.forString(DUMMY_CLASS_INSTANCE.stringField)); + constMap.put(DUMMY_CLASS_INSTANCE.stringField2, + CONSTANT_REFLECTION_PROVIDER.forString(DUMMY_CLASS_INSTANCE.stringField2)); + constMap.put(DUMMY_CLASS_INSTANCE.objectField, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalObjectField, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.finalObjectField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultObjectField, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.stableDefaultObjectField)); + constMap.put(null, null); + constMap.put(JavaConstant.NULL_POINTER, JavaConstant.NULL_POINTER); + LinkedList cfgSet = new LinkedList<>(); + constMap.entrySet().stream().forEach((obj1) -> { + constMap.entrySet().stream().forEach((obj2) -> { + cfgSet.add(new Object[]{obj1.getValue(), obj2.getValue(), + Objects.equals(obj1.getKey(), obj2.getKey())}); + }); + }); + return cfgSet.toArray(new Object[0][0]); + } +} diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/DummyClass.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/DummyClass.java new file mode 100644 index 00000000000..29b3a5c7bcf --- /dev/null +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/DummyClass.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 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. + */ + +package jdk.vm.ci.hotspot.test; + +import jdk.internal.vm.annotation.Stable; + +public class DummyClass { + + public boolean booleanField = true; + public byte byteField = 2; + public short shortField = 3; + public char charField = 'a'; + public int intField = 4; + public long longField = 5L; + public float floatField = 4.5f; + public double doubleField = 53.2; + public Object objectField = new Object(); + + public final boolean finalBooleanField = true; + public final byte finalByteField = -2; + public final short finalShortField = -3; + public final char finalCharField = 'b'; + public final int finalIntField = 8; + public final long finalLongField = 888L; + public final float finalFloatField = 77.8f; + public final double finalDoubleField = -234.2; + public final Object finalObjectField = new Object(); + + @Stable public boolean stableBooleanField = true; + @Stable public byte stableByteField = -2; + @Stable public short stableShortField = -3; + @Stable public char stableCharField = 'c'; + @Stable public int stableIntField = 8; + @Stable public long stableLongField = 888L; + @Stable public float stableFloatField = 77.8f; + @Stable public double stableDoubleField = -234.2; + @Stable public Object stableObjectField = new Object(); + + @Stable public boolean stableDefaultBooleanField; + @Stable public byte stableDefaultByteField; + @Stable public short stableDefaultShortField; + @Stable public char stableDefaultCharField; + @Stable public int stableDefaultIntField; + @Stable public long stableDefaultLongField; + @Stable public float stableDefaultFloatField; + @Stable public double stableDefaultDoubleField; + @Stable public Object stableDefaultObjectField; + + public final boolean finalDefaultBooleanField = false; + public final byte finalDefaultByteField = 0; + public final short finalDefaultShortField = 0; + public final char finalDefaultCharField = 0; + public final int finalDefaultIntField = 0; + public final long finalDefaultLongField = 0L; + public final float finalDefaultFloatField = 0.0f; + public final double finalDefaultDoubleField = 0.0; + public final Object finalDefaultObjectField = null; + + public static boolean staticBooleanField = true; + public static byte staticByteField = -1; + public static short staticShortField = 11; + public static char staticCharField = 'e'; + public static int staticIntField = 344; + public static long staticLongField = 34231212L; + public static float staticFloatField = -4.5f; + public static double staticDoubleField = 453.2; + public static Object staticObjectField = new Object(); + + public static final boolean staticFinalBooleanField = true; + public static final byte staticFinalByteField = -51; + public static final short staticFinalShortField = 911; + public static final char staticFinalCharField = 'g'; + public static final int staticFinalIntField = 9344; + public static final long staticFinalLongField = 54231212L; + public static final float staticFinalFloatField = -42.5f; + public static final double staticFinalDoubleField = 5453.2; + public static final Object staticFinalObjectField = new Object(); + + @Stable public static boolean staticStableBooleanField = true; + @Stable public static byte staticStableByteField = -61; + @Stable public static short staticStableShortField = 661; + @Stable public static char staticStableCharField = 'y'; + @Stable public static int staticStableIntField = 6574; + @Stable public static long staticStableLongField = -2342L; + @Stable public static float staticStableFloatField = -466.5f; + @Stable public static double staticStableDoubleField = 4563.2; + @Stable public static Object staticStableObjectField = new Object(); + + @Stable public static boolean staticStableDefaultBooleanField; + @Stable public static byte staticStableDefaultByteField; + @Stable public static short staticStableDefaultShortField; + @Stable public static char staticStableDefaultCharField; + @Stable public static int staticStableDefaultIntField; + @Stable public static long staticStableDefaultLongField; + @Stable public static float staticStableDefaultFloatField; + @Stable public static double staticStableDefaultDoubleField; + @Stable public static Object staticStableDefaultObjectField; + + public boolean[] booleanArrayWithValues = new boolean[]{true, false}; + public byte[] byteArrayWithValues = new byte[]{43, 0}; + public short[] shortArrayWithValues = new short[]{9, 0}; + public char[] charArrayWithValues = new char[]{'a', 0}; + public int[] intArrayWithValues = new int[]{99, 0}; + public long[] longArrayWithValues = new long[]{868L, 0L}; + public float[] floatArrayWithValues = new float[]{75.8f, 0f}; + public double[] doubleArrayWithValues = new double[]{-294.66, 0.0}; + public Object[] objectArrayWithValues = new Object[]{new Object(), null}; + + @Stable public boolean[] stableBooleanArrayWithValues = new boolean[]{true, false}; + @Stable public byte[] stableByteArrayWithValues = new byte[]{-2, 0}; + @Stable public short[] stableShortArrayWithValues = new short[]{-3, 0}; + @Stable public char[] stableCharArrayWithValues = new char[]{'c', 0}; + @Stable public int[] stableIntArrayWithValues = new int[]{8, 0}; + @Stable public long[] stableLongArrayWithValues = new long[]{888L, 0L}; + @Stable public float[] stableFloatArrayWithValues = new float[]{77.8f, 0f}; + @Stable public double[] stableDoubleArrayWithValues = new double[]{-234.2, 0.0}; + @Stable public Object[] stableObjectArrayWithValues = new Object[]{new Object(), null}; + + public boolean[][] booleanArrayArrayWithValues = new boolean[][]{{true}, null}; + public byte[][] byteArrayArrayWithValues = new byte[][]{{43, 0}, null}; + public short[][] shortArrayArrayWithValues = new short[][]{{9, 0}, null}; + public char[][] charArrayArrayWithValues = new char[][]{{'a', 0}, null}; + public int[][] intArrayArrayWithValues = new int[][]{{99, 0}, null}; + public long[][] longArrayArrayWithValues = new long[][]{{868L, 0L}, null}; + public float[][] floatArrayArrayWithValues = new float[][]{{75.8f, 0f}, null}; + public double[][] doubleArrayArrayWithValues = new double[][]{{-294.66, 0.0}, null}; + public Object[][] objectArrayArrayWithValues = new Object[][]{{new Object(), null}, null}; + + @Stable public boolean[][] stableBooleanArrayArrayWithValues = new boolean[][]{{true, false}, null}; + @Stable public byte[][] stableByteArrayArrayWithValues = new byte[][]{{-2, 0}, null}; + @Stable public short[][] stableShortArrayArrayWithValues = new short[][]{{-3, 0}, null}; + @Stable public char[][] stableCharArrayArrayWithValues = new char[][]{{'c', 0}, null}; + @Stable public int[][] stableIntArrayArrayWithValues = new int[][]{{8, 0}, null}; + @Stable public long[][] stableLongArrayArrayWithValues = new long[][]{{888L, 0L}, null}; + @Stable public float[][] stableFloatArrayArrayWithValues = new float[][]{{77.8f, 0f}, null}; + @Stable public double[][] stableDoubleArrayArrayWithValues = new double[][]{{-234.2, 0.0}, null}; + @Stable public Object[][] stableObjectArrayArrayWithValues = new Object[][]{{new Object(), null}, null}; + + // Strings for testing "forString" method + public final String stringField = "abc"; + public final String stringField2 = "xyz"; + public final String stringEmptyField = ""; +} diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ForObjectDataProvider.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ForObjectDataProvider.java new file mode 100644 index 00000000000..f6305e41d1d --- /dev/null +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ForObjectDataProvider.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 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. + */ + +package jdk.vm.ci.hotspot.test; + +import org.testng.annotations.DataProvider; + +public class ForObjectDataProvider { + @DataProvider(name = "forObjectDataProvider") + public static Object[][] forObjectDataProvider() { + return new Object[][]{ + {TestHelper.DUMMY_CLASS_INSTANCE.objectField, + "Object[Object@" + TestHelper.DUMMY_CLASS_INSTANCE.objectField.hashCode() + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.stringField, + "Object[String:\"" + TestHelper.DUMMY_CLASS_INSTANCE.stringField + "\"]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.booleanField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.booleanField + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.byteField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.byteField + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.charField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.charField + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.shortField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.shortField + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.intField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.intField + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.longField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.longField + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.floatField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.floatField + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.doubleField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.doubleField + "]"}, + {new Object[0], "Object[Object[" + 0 + "]{}]"}, {new Object[1], "Object[Object[" + 1 + "]{null}]"}, + {null, "Object[null]"}}; + } +} diff --git a/jdk/test/java/net/Inet4Address/DummyNameService.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ForStringDataProvider.java similarity index 60% rename from jdk/test/java/net/Inet4Address/DummyNameService.java rename to hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ForStringDataProvider.java index 8d813ac4003..5c753557ae8 100644 --- a/jdk/test/java/net/Inet4Address/DummyNameService.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ForStringDataProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -21,25 +21,18 @@ * questions. */ -/* - * A simple name service which throws an exception when invoked - */ +package jdk.vm.ci.hotspot.test; -import java.net.UnknownHostException; -import java.net.InetAddress; -import sun.net.spi.nameservice.*; -import java.util.*; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; -public final class DummyNameService implements NameService { +import org.testng.annotations.DataProvider; - public DummyNameService() throws Exception { - } - - public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException { - throw new UnknownHostException("Dummy name service"); - } - - public String getHostByAddr(byte[] addr) throws UnknownHostException { - throw new UnknownHostException("Dummy name service"); +public class ForStringDataProvider { + @DataProvider(name = "forStringDataProvider") + public static Object[][] forStringDataProvider() { + return new Object[][]{ + {DUMMY_CLASS_INSTANCE.stringField, "Object[String:\"" + DUMMY_CLASS_INSTANCE.stringField + "\"]"}, + {DUMMY_CLASS_INSTANCE.stringEmptyField, "Object[String:\"\"]"}, + {null, "Object[null]"}}; } } diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java new file mode 100644 index 00000000000..879a1c0c833 --- /dev/null +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java @@ -0,0 +1,226 @@ +/* + * Copyright (c) 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 jdk.vm.ci.hotspot.test.HotSpotConstantReflectionProviderTest + * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64") + * @modules jdk.vm.ci/jdk.vm.ci.runtime + * jdk.vm.ci/jdk.vm.ci.meta + * jdk.vm.ci/jdk.vm.ci.hotspot + * java.base/jdk.internal.vm.annotation + * java.base/jdk.internal.misc + * @library /testlibrary /test/lib /compiler/jvmci/jdk.vm.ci.hotspot.test/src + * @build jdk.vm.ci.hotspot.test.DummyClass + * @run driver ClassFileInstaller jdk.vm.ci.hotspot.test.DummyClass + * @run testng/othervm/timeout=300 -Xbootclasspath/a:. + * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * jdk.vm.ci.hotspot.test.HotSpotConstantReflectionProviderTest + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; + +import java.lang.reflect.Method; +import jdk.vm.ci.hotspot.HotSpotResolvedJavaField; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.MemoryAccessProvider; +import jdk.vm.ci.meta.MethodHandleAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaType; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class HotSpotConstantReflectionProviderTest { + + @Test(dataProvider = "forObjectDataProvider", dataProviderClass = ForObjectDataProvider.class) + public void testForObject(Object obj, String expected) { + JavaConstant jConst = TestHelper.CONSTANT_REFLECTION_PROVIDER.forObject(obj); + Assert.assertNotNull(jConst, + "An instance of JavaConstant returned by" + " \"forObject\" method should not be null"); + Assert.assertEquals(jConst.toString(), expected, "Unexpected result:"); + } + + @Test(dataProvider = "forStringDataProvider", dataProviderClass = ForStringDataProvider.class) + public void testForString(String string, String expected) { + JavaConstant jConst = CONSTANT_REFLECTION_PROVIDER.forString(string); + Assert.assertNotNull(jConst, + "An instance of JavaConstant returned by" + " \"forString\" method should not be null"); + Assert.assertEquals(jConst.toString(), expected, "Unexpected result:"); + } + + @Test(dataProvider = "constantEqualsDataProvider", dataProviderClass = ConstantEqualsDataProvider.class) + public void testConstantEquals(Constant const1, Constant const2, Boolean expected) { + Assert.assertEquals(CONSTANT_REFLECTION_PROVIDER.constantEquals(const1, const2), expected, + "Unexpected result:"); + } + + @Test(dataProvider = "readArrayLengthDataProvider", dataProviderClass = ReadArrayLengthDataProvider.class) + public void testReadArrayLength(JavaConstant array, Integer expected) { + Assert.assertEquals(CONSTANT_REFLECTION_PROVIDER.readArrayLength(array), expected, + "Unexpected result:"); + } + + @Test(dataProvider = "readArrayElementDataProvider", dataProviderClass = ReadArrayElementDataProvider.class) + public void testReadArrayElement(JavaConstant array, int index, Object expected) { + Assert.assertEquals(CONSTANT_REFLECTION_PROVIDER.readArrayElement(array, index), expected, + "Unexpected result:"); + } + + @Test(dataProvider = "readFieldValueDataProvider", dataProviderClass = ReadFieldValueDataProvider.class) + public void testReadFieldValue(ResolvedJavaField field, JavaConstant receiver, JavaConstant expected) { + JavaConstant actual = CONSTANT_REFLECTION_PROVIDER.readFieldValue(field, receiver); + Assert.assertEquals(actual == null ? "null" : actual.toString(), + expected == null ? "null" : expected.toString(), "Unexpected result:"); + } + + @Test(dataProvider = "readFieldValueNegativeDataProvider", + dataProviderClass = ReadFieldValueDataProvider.class, + expectedExceptions = {NullPointerException.class}) + public void testNegativeReadFieldValue(ResolvedJavaField field, JavaConstant receiver) { + CONSTANT_REFLECTION_PROVIDER.readFieldValue(field, receiver); + } + + @Test(dataProvider = "readStableFieldValueDataProvider", + dataProviderClass = ReadStableFieldValueDataProvider.class) + public void testReadStableFieldValue(ResolvedJavaField field, JavaConstant receiver, boolean isDefStab, + JavaConstant expected) { + Assert.assertEquals( + CONSTANT_REFLECTION_PROVIDER.readStableFieldValue(field, receiver, isDefStab), + expected, + "Unexpected result:"); + } + + @Test(dataProvider = "readStableFieldValueArrayDataProvider", + dataProviderClass = ReadStableFieldValueDataProvider.class) + public void testReadStableFieldValueForArray(ResolvedJavaField field, JavaConstant receiver, boolean isDefStab, + int arrayDim, JavaConstant expected) { + JavaConstant result = CONSTANT_REFLECTION_PROVIDER.readStableFieldValue(field, receiver, + isDefStab); + boolean resultDefStab = false; + int resultStableDim = -1; + try { + Class hotSpotObjectConstantImplClass = Class.forName( + "jdk.vm.ci.hotspot.HotSpotObjectConstantImpl"); + Method getStableDimensionMethod = hotSpotObjectConstantImplClass.getDeclaredMethod( + "getStableDimension"); + Method isDefaultStableMethod = hotSpotObjectConstantImplClass.getDeclaredMethod( + "isDefaultStable"); + getStableDimensionMethod.setAccessible(true); + isDefaultStableMethod.setAccessible(true); + resultDefStab = (boolean) isDefaultStableMethod.invoke(result); + resultStableDim = (int) getStableDimensionMethod.invoke(result); + } catch (ReflectiveOperationException e) { + throw new Error("Unexpected error: " + e, e); + } + Assert.assertEquals(resultDefStab, isDefStab, + "Wrong default stable value for " + result.toString()); + Assert.assertEquals(resultStableDim, arrayDim, + "Wrong array dimension for " + result.toString()); + Assert.assertEquals(result.toString(), expected.toString(), "Unexpected result:"); + } + + @Test(dataProvider = "readStableFieldValueNegativeDataProvider", + dataProviderClass = ReadStableFieldValueDataProvider.class, + expectedExceptions = {NullPointerException.class}) + public void testNegativeReadStableFieldValue(ResolvedJavaField field, JavaConstant receiver, boolean isDefStab) { + CONSTANT_REFLECTION_PROVIDER.readStableFieldValue(field, receiver, isDefStab); + } + + @Test(dataProvider = "readConstantFieldValueDataProvider", + dataProviderClass = ReadConstantFieldValueDataProvider.class) + public void testReadConstantFieldValue(ResolvedJavaField field, JavaConstant receiver, JavaConstant expected, + String testInfo) { + String msg = String.format("Unexpected result for %s. Field is stable = %s.", testInfo, + ((HotSpotResolvedJavaField) field).isStable()); + Assert.assertEquals(CONSTANT_REFLECTION_PROVIDER.readConstantFieldValue(field, receiver), + expected, msg); + } + + @Test(dataProvider = "readConstantFieldValueNegativeDataProvider", + dataProviderClass = ReadConstantFieldValueDataProvider.class, + expectedExceptions = {NullPointerException.class}) + public void testNegativeReadConstantFieldValue(ResolvedJavaField field, JavaConstant receiver) { + CONSTANT_REFLECTION_PROVIDER.readConstantFieldValue(field, receiver); + } + + @Test(dataProvider = "readConstantArrayElementDataProvider", + dataProviderClass = ReadConstantArrayElementDataProvider.class) + public void testReadConstantArrayElement(JavaConstant array, int index, JavaConstant expected, String testInfo) { + JavaConstant actual = CONSTANT_REFLECTION_PROVIDER.readConstantArrayElement(array, index); + Assert.assertEquals(actual == null ? "null" : actual.toString(), + expected == null ? "null" : expected.toString(), + String.format("Unexpected result while testing %s:", testInfo)); + } + + @Test(dataProvider = "readConstantArrayElementForOffsetDataProvider", + dataProviderClass = ReadConstantArrayElementDataProvider.class) + public void testReadConstantArrayElementForOffset(JavaConstant array, long offset, JavaConstant expected, + String testInfo) { + JavaConstant actual = CONSTANT_REFLECTION_PROVIDER.readConstantArrayElementForOffset(array, + offset); + Assert.assertEquals(actual == null ? "null" : actual.toString(), + expected == null ? "null" : expected.toString(), + String.format("Unexpected result while testing %s:", testInfo)); + } + + @Test(dataProvider = "asJavaTypeDataProvider", dataProviderClass = AsJavaTypeDataProvider.class) + public void testAsJavaType(JavaConstant constant, String expected) { + ResolvedJavaType actual = CONSTANT_REFLECTION_PROVIDER.asJavaType(constant); + Assert.assertEquals(actual == null ? "null" : actual.toJavaName(), + expected == null ? "null" : expected, + "Unexpected result, wrong type returned:"); + } + + @Test(dataProvider = "boxPrimitiveDataProvider", dataProviderClass = BoxPrimitiveDataProvider.class) + public void testBoxPrimitive(JavaConstant constant, JavaConstant expected) { + JavaConstant actual = CONSTANT_REFLECTION_PROVIDER.boxPrimitive(constant); + Assert.assertEquals(actual, expected, "Unexpected result:"); + } + + @Test(dataProvider = "unboxPrimitiveDataProvider", dataProviderClass = UnboxPrimitiveDataProvider.class) + public void testUnboxPrimitive(JavaConstant constant, JavaConstant expected) { + JavaConstant actual = CONSTANT_REFLECTION_PROVIDER.unboxPrimitive(constant); + Assert.assertEquals(actual, expected, "Unexpected result:"); + } + + @Test(dataProvider = "isEmbeddableDataProvider", dataProviderClass = IsEmbeddableDataProvider.class) + public void testIsEmbeddable(JavaConstant constant, boolean expected) { + boolean actual = CONSTANT_REFLECTION_PROVIDER.isEmbeddable(constant); + Assert.assertEquals(actual, expected, "Unexpected result:"); + } + + @Test + public void testGetMemoryAccessProvider() { + MemoryAccessProvider actual = CONSTANT_REFLECTION_PROVIDER.getMemoryAccessProvider(); + Assert.assertNotNull(actual, "Returned MemoryAccessProvider instance should not be null"); + } + + @Test + public void testGetMethodHandleAccess() { + MethodHandleAccessProvider actual = CONSTANT_REFLECTION_PROVIDER.getMethodHandleAccess(); + Assert.assertNotNull(actual, + "Returned MethodHandleAccessProvider instance should not be null"); + } +} diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/IsEmbeddableDataProvider.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/IsEmbeddableDataProvider.java new file mode 100644 index 00000000000..b586a65e952 --- /dev/null +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/IsEmbeddableDataProvider.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 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. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; + +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class IsEmbeddableDataProvider { + @DataProvider(name = "isEmbeddableDataProvider") + public static Object[][] isEmbeddableDataProvider() { + return new Object[][]{{JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanField), true}, + {JavaConstant.forByte(DUMMY_CLASS_INSTANCE.byteField), true}, + {JavaConstant.forShort(DUMMY_CLASS_INSTANCE.shortField), true}, + {JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intField), true}, + {JavaConstant.forLong(DUMMY_CLASS_INSTANCE.longField), true}, + {JavaConstant.forChar(DUMMY_CLASS_INSTANCE.charField), true}, + {JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.floatField), true}, + {JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.doubleField), true}, + {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField), true}, + {JavaConstant.NULL_POINTER, true}, {null, true}}; + } +} diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadArrayElementDataProvider.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadArrayElementDataProvider.java new file mode 100644 index 00000000000..1e4bb40e6db --- /dev/null +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadArrayElementDataProvider.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 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. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAY_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FIELDS_MAP; + +import java.util.LinkedList; +import java.util.stream.Stream; + +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class ReadArrayElementDataProvider { + + @DataProvider(name = "readArrayElementDataProvider") + public static Object[][] readArrayElementDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + for (int i : new int[]{0, 1}) { + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayWithValues), + i, JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.byteArrayWithValues), + i, JavaConstant.forByte(DUMMY_CLASS_INSTANCE.byteArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.shortArrayWithValues), + i, JavaConstant.forShort(DUMMY_CLASS_INSTANCE.shortArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.charArrayWithValues), + i, JavaConstant.forChar(DUMMY_CLASS_INSTANCE.charArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.intArrayWithValues), + i, JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.longArrayWithValues), + i, JavaConstant.forLong(DUMMY_CLASS_INSTANCE.longArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.floatArrayWithValues), + i, JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.floatArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.doubleArrayWithValues), + i, JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.doubleArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectArrayWithValues), + i, CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.byteArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.byteArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.shortArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.shortArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.charArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.charArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.intArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.intArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.longArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.longArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.floatArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.floatArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.doubleArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.doubleArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectArrayArrayWithValues[i])}); + } + Stream.concat(ARRAYS_MAP.values().stream(), ARRAY_ARRAYS_MAP.values().stream()).forEach((array) -> { + for (int i : new int[]{-1, 2}) { + cfgSet.add(new Object[]{array, i, null}); + } + }); + cfgSet.add(new Object[]{null, 0, null}); + cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, 0, null}); + INSTANCE_FIELDS_MAP.values().forEach((constant) -> { + cfgSet.add(new Object[]{constant, 0, null}); + }); + return cfgSet.toArray(new Object[0][0]); + } +} diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadArrayLengthDataProvider.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadArrayLengthDataProvider.java new file mode 100644 index 00000000000..ad877ac799c --- /dev/null +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadArrayLengthDataProvider.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 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. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; + +import java.util.LinkedList; +import java.util.List; +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class ReadArrayLengthDataProvider { + + public static List createListOfDummyArrays(int length) { + List arrays = new LinkedList<>(); + arrays.add(new boolean[length]); + arrays.add(new byte[length]); + arrays.add(new short[length]); + arrays.add(new char[length]); + arrays.add(new int[length]); + arrays.add(new long[length]); + arrays.add(new float[length]); + arrays.add(new double[length]); + arrays.add(new Object[length]); + arrays.add(new boolean[length][2]); + arrays.add(new byte[length][2]); + arrays.add(new short[length][2]); + arrays.add(new char[length][2]); + arrays.add(new int[length][2]); + arrays.add(new long[length][2]); + arrays.add(new float[length][2]); + arrays.add(new double[length][2]); + arrays.add(new Object[length][2]); + return arrays; + } + + @DataProvider(name = "readArrayLengthDataProvider") + public static Object[][] readArrayLengthDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + for (int i : new int[]{0, 1, 42}) { + createListOfDummyArrays(i).stream().forEach((array) -> { + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(array), i}); + }); + } + cfgSet.add(new Object[]{null, null}); + cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.intField), null}); + cfgSet.add(new Object[]{JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intField), null}); + return cfgSet.toArray(new Object[0][0]); + } +} diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadConstantArrayElementDataProvider.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadConstantArrayElementDataProvider.java new file mode 100644 index 00000000000..f67cec8080c --- /dev/null +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadConstantArrayElementDataProvider.java @@ -0,0 +1,290 @@ +/* + * Copyright (c) 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. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAY_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_CONSTANT; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; +import static jdk.vm.ci.hotspot.test.TestHelper.getResolvedJavaField; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_STABLE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAY_ARRAYS_MAP; + +import java.lang.reflect.Field; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; +import jdk.internal.misc.Unsafe; +import jdk.vm.ci.meta.ResolvedJavaField; + +public class ReadConstantArrayElementDataProvider { + + // Non-stable array fields names mapped to their base offsets and index scale + private static final List NON_STABLE_ARRAY_NAMES + = new LinkedList<>(); + + static { + NON_STABLE_ARRAY_NAMES.add( + new ArrayFieldParams("booleanArrayWithValues", Unsafe.ARRAY_BOOLEAN_BASE_OFFSET, + Unsafe.ARRAY_BOOLEAN_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("byteArrayWithValues", + Unsafe.ARRAY_BYTE_BASE_OFFSET, + Unsafe.ARRAY_BYTE_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("shortArrayWithValues", + Unsafe.ARRAY_SHORT_BASE_OFFSET, + Unsafe.ARRAY_SHORT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("charArrayWithValues", + Unsafe.ARRAY_CHAR_BASE_OFFSET, + Unsafe.ARRAY_CHAR_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("intArrayWithValues", + Unsafe.ARRAY_INT_BASE_OFFSET, + Unsafe.ARRAY_INT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("longArrayWithValues", + Unsafe.ARRAY_LONG_BASE_OFFSET, + Unsafe.ARRAY_LONG_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("floatArrayWithValues", + Unsafe.ARRAY_FLOAT_BASE_OFFSET, + Unsafe.ARRAY_FLOAT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("doubleArrayWithValues", + Unsafe.ARRAY_DOUBLE_BASE_OFFSET, + Unsafe.ARRAY_DOUBLE_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("objectArrayWithValues", + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET, + Unsafe.ARRAY_BOOLEAN_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("booleanArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("byteArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("shortArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("charArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("intArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("longArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("floatArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("doubleArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("objectArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + } + + // Stable array fields names mapped to their base offsets and index scale + private static final List STABLE_ARRAY_NAMES + = new LinkedList<>(); + + static { + NON_STABLE_ARRAY_NAMES.stream().forEach((entry) -> { + String nsFieldName = entry.name; + char firstChar = nsFieldName.charAt(0); + char newFirstChar = Character.toUpperCase(firstChar); + String sFieldName = nsFieldName.replaceFirst("" + firstChar, + "" + newFirstChar); + sFieldName = "stable" + sFieldName; + STABLE_ARRAY_NAMES.add(new ArrayFieldParams(sFieldName, entry.offsetBase, entry.scale)); + }); + } + + @DataProvider(name = "readConstantArrayElementDataProvider") + public static Object[][] readConstantArrayElementDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + for (int i : new int[]{0, 1}) { + NON_STABLE_ARRAY_NAMES.stream().forEach((entry) -> { + String fieldName = entry.name; + cfgSet.add(new Object[]{ + readFieldValue(fieldName), + i, + null, + "array field \"" + fieldName + "\" for index " + i}); + }); + STABLE_ARRAY_NAMES.stream().forEach((entry) -> { + String fieldName = entry.name; + cfgSet.add(new Object[]{ + readFieldValue(fieldName), + i, + i == 0 ? getJavaConstant(fieldName) : null, + "array field \"" + fieldName + "\" for index " + i}); + }); + } + Stream> arraysStream1 + = Stream.concat(ARRAYS_MAP.entrySet().stream(), + ARRAY_ARRAYS_MAP.entrySet().stream()); + Stream> arraysStream2 + = Stream.concat(STABLE_ARRAYS_MAP.entrySet().stream(), + STABLE_ARRAY_ARRAYS_MAP.entrySet().stream()); + Stream.concat(arraysStream1, arraysStream2).forEach((array) -> { + for (int i : new int[]{-1, 2}) { + cfgSet.add(new Object[]{ + array.getValue(), + i, + null, + "array field \"" + array.getKey() + "\" for index " + i}); + } + }); + cfgSet.add(new Object[]{null, 0, null, "null"}); + cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, 0, null, "JavaConstant.NULL_POINTER"}); + INSTANCE_FIELDS_MAP.values().forEach((constant) -> { + cfgSet.add(new Object[]{constant, 0, null, "non-stable non-array field"}); + }); + INSTANCE_STABLE_FIELDS_MAP.values().forEach((constant) -> { + cfgSet.add(new Object[]{constant, 0, null, "stable non-array field"}); + }); + return cfgSet.toArray(new Object[0][0]); + } + + @DataProvider(name = "readConstantArrayElementForOffsetDataProvider") + public static Object[][] readConstantArrayElementForOffsetDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + // Testing non-stable arrays. Result should be null in all cases + for (double i : new double[]{-1, 0, 0.5, 1, 1.5, 2}) { + NON_STABLE_ARRAY_NAMES.stream().forEach(entry -> { + String fieldName = entry.name; + long offset = (long) (entry.offsetBase + i * entry.scale); + cfgSet.add(new Object[]{ + readFieldValue(fieldName), + offset, + null, + "array field \"" + fieldName + "\" for offset " + offset}); + }); + } + // Testing stable arrays. Result should be null in all cases except "offset = base + 0" + for (double i : new double[]{-1, 0.5, 1, 1.5, 2}) { + STABLE_ARRAY_NAMES.stream().forEach(entry -> { + String fieldName = entry.name; + long offset = (long) Math.ceil(entry.offsetBase + i * entry.scale); + cfgSet.add(new Object[]{ + readFieldValue(fieldName), + offset, + null, + "array field \"" + fieldName + "\" for offset " + offset}); + }); + } + // Testing stable arrays "offset = base + 0". Result should be non-null + STABLE_ARRAY_NAMES.stream().forEach(entry -> { + String fieldName = entry.name; + long offset = (long) entry.offsetBase; + cfgSet.add(new Object[]{ + readFieldValue(fieldName), + offset, + getJavaConstant(fieldName), + "array field \"" + fieldName + "\" for offset " + offset}); + }); + // Testing null as array + cfgSet.add(new Object[]{null, 0, null, "null"}); + // Testing JavaConstant.NULL_POINTER as array + cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, 0, null, "JavaConstant.NULL_POINTER"}); + // Testing non-stable non-array fields + INSTANCE_FIELDS_MAP.values().forEach((constant) -> { + cfgSet.add(new Object[]{constant, 0, null, "non-stable non-array field"}); + }); + // Testing stable non-array fields + INSTANCE_STABLE_FIELDS_MAP.values().forEach((constant) -> { + cfgSet.add(new Object[]{constant, 0, null, "stable non-array field"}); + }); + return cfgSet.toArray(new Object[0][0]); + } + + private static JavaConstant readFieldValue(String fieldName) { + return CONSTANT_REFLECTION_PROVIDER.readFieldValue(getResolvedJavaField(DummyClass.class, fieldName), + DUMMY_CLASS_CONSTANT); + } + + private static JavaConstant getJavaConstant(String fieldName) { + Class dummyClass = DummyClass.class; + Field arrayField; + try { + arrayField = dummyClass.getDeclaredField(fieldName); + } catch (NoSuchFieldException ex) { + throw new Error("Test bug: wrong field name " + ex, ex); + } catch (SecurityException ex) { + throw new Error("Unexpected error: " + ex, ex); + } + arrayField.setAccessible(true); + Class componentType = arrayField.getType().getComponentType(); + if (componentType == null) { + throw new Error("Test error: field is not an array"); + } + Object value; + try { + value = arrayField.get(DUMMY_CLASS_INSTANCE); + } catch (IllegalArgumentException | IllegalAccessException ex) { + throw new Error("Unexpected error: " + ex, ex); + } + if (componentType == boolean.class) { + return JavaConstant.forBoolean(((boolean[]) value)[0]); + } + if (componentType == byte.class) { + return JavaConstant.forByte(((byte[]) value)[0]); + } + if (componentType == short.class) { + return JavaConstant.forShort(((short[]) value)[0]); + } + if (componentType == char.class) { + return JavaConstant.forChar(((char[]) value)[0]); + } + if (componentType == int.class) { + return JavaConstant.forInt(((int[]) value)[0]); + } + if (componentType == long.class) { + return JavaConstant.forLong(((long[]) value)[0]); + } + if (componentType == float.class) { + return JavaConstant.forFloat(((float[]) value)[0]); + } + if (componentType == double.class) { + return JavaConstant.forDouble(((double[]) value)[0]); + } + return CONSTANT_REFLECTION_PROVIDER.forObject(((Object[]) value)[0]); + } + + private static class ArrayFieldParams { + public final String name; + public final int offsetBase; + public final int scale; + + ArrayFieldParams(String name, int offsetBase, int scale) { + this.name = name; + this.offsetBase = offsetBase; + this.scale = scale; + } + } +} diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadConstantFieldValueDataProvider.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadConstantFieldValueDataProvider.java new file mode 100644 index 00000000000..c22afec8792 --- /dev/null +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadConstantFieldValueDataProvider.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 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. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_CONSTANT; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_STABLE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FINAL_DEFAULT_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FINAL_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_STABLE_DEFAULT_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_FINAL_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_STABLE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_STABLE_DEFAULT_FIELDS_MAP; + +import java.util.LinkedList; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + + +public class ReadConstantFieldValueDataProvider { + + @DataProvider(name = "readConstantFieldValueDataProvider") + public static Object[][] readConstantFieldValueDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + // Testing static final fields + STATIC_FINAL_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), null, field.getValue(), "static final field"}); + }); + // Testing static stable fields + STATIC_STABLE_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), null, field.getValue(), "static stable field"}); + }); + // Testing instance final non-default fields + INSTANCE_FINAL_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), + DUMMY_CLASS_CONSTANT, + field.getValue(), + "instance final field"}); + }); + // Testing instance final default fields. + boolean trustDefFinal = HotSpotJVMCIRuntime.Option.TrustFinalDefaultFields.getBoolean(); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.entrySet().stream().forEach((field) -> { + JavaConstant expected = trustDefFinal ? field.getValue() : null; + cfgSet.add(new Object[]{field.getKey(), + DUMMY_CLASS_CONSTANT, + expected, + "instance final default field"}); + }); + // Testing instance stable non-default fields + INSTANCE_STABLE_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), + DUMMY_CLASS_CONSTANT, + field.getValue(), + "instance stable field"}); + }); + // Testing instance stable default fields + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), + DUMMY_CLASS_CONSTANT, + null, + "instance stable default field"}); + }); + // Testing regular instance fields + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), DUMMY_CLASS_CONSTANT, null, "instance field"}); + }); + // Testing regular static fields + STATIC_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), null, null, "static field"}); + }); + // Testing static stable fields + STATIC_STABLE_DEFAULT_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), null, null, "static stable default field"}); + }); + return cfgSet.toArray(new Object[0][0]); + } + + @DataProvider(name = "readConstantFieldValueNegativeDataProvider") + public static Object[][] readConstantFieldValueNegativeDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + // Testing instance fields with null as receiver + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), null}); + }); + // Testing null as a field argument + cfgSet.add(new Object[]{null, null}); + return cfgSet.toArray(new Object[0][0]); + } +} diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadFieldValueDataProvider.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadFieldValueDataProvider.java new file mode 100644 index 00000000000..c3872352ee8 --- /dev/null +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadFieldValueDataProvider.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 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. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAY_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_CONSTANT; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; +import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAY_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_STABLE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_STABLE_FIELDS_MAP; + +import java.util.LinkedList; +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + + +public class ReadFieldValueDataProvider { + + @DataProvider(name = "readFieldValueDataProvider") + public static Object[][] readFieldValueDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + // Testing instance non-stable fields + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + instanceField.getValue()}); + }); + // Testing static non-stable fields with null as receiver + STATIC_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), null, staticField.getValue()}); + }); + // Testing static non-stable fields with JavaConstant.NULL_POINTER as receiver + STATIC_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), + JavaConstant.NULL_POINTER, + staticField.getValue()}); + }); + // Testing instance stable fields + INSTANCE_STABLE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + instanceField.getValue()}); + }); + // Testing static stable fields with null as receiver + STATIC_STABLE_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), null, staticField.getValue()}); + }); + // Testing static stable fields with JavaConstant.NULL_POINTER as receiver + STATIC_STABLE_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), + JavaConstant.NULL_POINTER, + staticField.getValue()}); + }); + // Testing instance non-stable array fields + ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + instanceField.getValue()}); + }); + // Testing instance stable array fields + STABLE_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + instanceField.getValue()}); + }); + // Testing instance non-stable array-of-array fields + ARRAY_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + instanceField.getValue()}); + }); + // Testing instance stable array-of-array fields + STABLE_ARRAY_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + instanceField.getValue()}); + }); + // Testing instance fields with JavaConstant.NULL_POINTER as receiver + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), JavaConstant.NULL_POINTER, null}); + }); + // Testing instance fields with an object that does not have the field + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField), + null}); + }); + return cfgSet.toArray(new Object[0][0]); + } + + @DataProvider(name = "readFieldValueNegativeDataProvider") + public static Object[][] readFieldValueNegativeDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + // Testing instance fields with null as receiver + INSTANCE_FIELDS_MAP.keySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField, null}); + }); + // Testing null as a field argument + cfgSet.add(new Object[]{null, null}); + return cfgSet.toArray(new Object[0][0]); + } +} diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadStableFieldValueDataProvider.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadStableFieldValueDataProvider.java new file mode 100644 index 00000000000..5a62a15a18c --- /dev/null +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadStableFieldValueDataProvider.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 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. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAY_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_CONSTANT; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; +import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAY_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_STABLE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_STABLE_FIELDS_MAP; + +import java.util.LinkedList; +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class ReadStableFieldValueDataProvider { + + @DataProvider(name = "readStableFieldValueDataProvider") + public static Object[][] readStableFieldValueDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + for (boolean isDefStab : new boolean[]{true, false}) { + // Testing instance non-stable fields + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + isDefStab, + instanceField.getValue()}); + }); + // Testing static non-stable fields with null as receiver + STATIC_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), + null, + isDefStab, + staticField.getValue()}); + }); + // Testing static non-stable fields with JavaConstant.NULL_POINTER as receiver + STATIC_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), + JavaConstant.NULL_POINTER, + isDefStab, + staticField.getValue()}); + }); + // Testing instance stable fields + INSTANCE_STABLE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + isDefStab, + instanceField.getValue()}); + }); + // Testing static stable fields with null as receiver + STATIC_STABLE_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), + null, + isDefStab, + staticField.getValue()}); + }); + // Testing static stable fields with JavaConstant.NULL_POINTER as receiver + STATIC_STABLE_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), + JavaConstant.NULL_POINTER, + isDefStab, + staticField.getValue()}); + }); + // Testing instance fields with JavaConstant.NULL_POINTER as receiver + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + JavaConstant.NULL_POINTER, + isDefStab, + null}); + }); + // Testing instance fields with an object that does not have the field + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField), + isDefStab, + null}); + }); + } + return cfgSet.toArray(new Object[0][0]); + } + + @DataProvider(name = "readStableFieldValueArrayDataProvider") + public static Object[][] readStableFieldValueArrayDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + for (boolean isDefStab : new boolean[]{true, false}) { + // Testing instance non-stable array fields + ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + isDefStab, + TestHelper.ARRAY_DIMENSION, + instanceField.getValue()}); + }); + // Testing instance stable array fields + STABLE_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + isDefStab, + TestHelper.ARRAY_DIMENSION, + instanceField.getValue()}); + }); + // Testing instance non-stable array-of-array fields + ARRAY_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + isDefStab, + TestHelper.ARRAY_OF_ARRAYS_DIMENSION, + instanceField.getValue()}); + }); + // Testing instance stable array-of-array fields + STABLE_ARRAY_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + isDefStab, + TestHelper.ARRAY_OF_ARRAYS_DIMENSION, + instanceField.getValue()}); + }); + } + return cfgSet.toArray(new Object[0][0]); + } + + @DataProvider(name = "readStableFieldValueNegativeDataProvider") + public static Object[][] readStableFieldValueNegativeDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + for (boolean isDefStab : new boolean[]{true, false}) { + // Testing instance fields with null as receiver + INSTANCE_FIELDS_MAP.keySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField, null, isDefStab}); + }); + // Testing null as a field argument + cfgSet.add(new Object[]{null, null, isDefStab}); + } + return cfgSet.toArray(new Object[0][0]); + } +} diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHelper.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHelper.java new file mode 100644 index 00000000000..bb2c977e582 --- /dev/null +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHelper.java @@ -0,0 +1,486 @@ +/* + * Copyright (c) 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. + */ + +package jdk.vm.ci.hotspot.test; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; +import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.runtime.JVMCI; + +public class TestHelper { + + public static final DummyClass DUMMY_CLASS_INSTANCE = new DummyClass(); + public static final HotSpotConstantReflectionProvider CONSTANT_REFLECTION_PROVIDER + = (HotSpotConstantReflectionProvider) JVMCI.getRuntime().getHostJVMCIBackend().getConstantReflection(); + public static final JavaConstant DUMMY_CLASS_CONSTANT + = CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE); + + public static final Map INSTANCE_FIELDS_MAP + = new HashMap<>(); + + static { + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "booleanField"), + JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "byteField"), + JavaConstant.forByte(DUMMY_CLASS_INSTANCE.byteField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "shortField"), + JavaConstant.forShort(DUMMY_CLASS_INSTANCE.shortField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "charField"), + JavaConstant.forChar(DUMMY_CLASS_INSTANCE.charField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "intField"), + JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "longField"), + JavaConstant.forLong(DUMMY_CLASS_INSTANCE.longField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "floatField"), + JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.floatField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "doubleField"), + JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.doubleField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "objectField"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.objectField)); + } + + public static final Map INSTANCE_FINAL_FIELDS_MAP + = new HashMap<>(); + + static { + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalBooleanField"), + JavaConstant.forBoolean( + DUMMY_CLASS_INSTANCE.finalBooleanField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalByteField"), + JavaConstant.forByte(DUMMY_CLASS_INSTANCE.finalByteField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalShortField"), + JavaConstant.forShort(DUMMY_CLASS_INSTANCE.finalShortField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalCharField"), + JavaConstant.forChar(DUMMY_CLASS_INSTANCE.finalCharField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalIntField"), + JavaConstant.forInt(DUMMY_CLASS_INSTANCE.finalIntField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalLongField"), + JavaConstant.forLong(DUMMY_CLASS_INSTANCE.finalLongField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalFloatField"), + JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.finalFloatField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalDoubleField"), + JavaConstant.forDouble( + DUMMY_CLASS_INSTANCE.finalDoubleField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.finalObjectField)); + } + + public static final Map INSTANCE_FINAL_DEFAULT_FIELDS_MAP + = new HashMap<>(); + + static { + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultBooleanField"), + JavaConstant.forBoolean( + DUMMY_CLASS_INSTANCE.finalDefaultBooleanField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultByteField"), + JavaConstant.forByte( + DUMMY_CLASS_INSTANCE.finalDefaultByteField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultShortField"), + JavaConstant.forShort( + DUMMY_CLASS_INSTANCE.finalDefaultShortField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultCharField"), + JavaConstant.forChar( + DUMMY_CLASS_INSTANCE.finalDefaultCharField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultIntField"), + JavaConstant.forInt( + DUMMY_CLASS_INSTANCE.finalDefaultIntField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultLongField"), + JavaConstant.forLong( + DUMMY_CLASS_INSTANCE.finalDefaultLongField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultFloatField"), + JavaConstant.forFloat( + DUMMY_CLASS_INSTANCE.finalDefaultFloatField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultDoubleField"), + JavaConstant.forDouble( + DUMMY_CLASS_INSTANCE.finalDefaultDoubleField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.finalDefaultObjectField)); + } + + public static final Map INSTANCE_STABLE_FIELDS_MAP + = new HashMap<>(); + + static { + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableBooleanField"), + JavaConstant.forBoolean( + DUMMY_CLASS_INSTANCE.stableBooleanField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableByteField"), + JavaConstant.forByte(DUMMY_CLASS_INSTANCE.stableByteField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableShortField"), + JavaConstant.forShort( + DUMMY_CLASS_INSTANCE.stableShortField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableCharField"), + JavaConstant.forChar(DUMMY_CLASS_INSTANCE.stableCharField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableIntField"), + JavaConstant.forInt(DUMMY_CLASS_INSTANCE.stableIntField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableLongField"), + JavaConstant.forLong(DUMMY_CLASS_INSTANCE.stableLongField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableFloatField"), + JavaConstant.forFloat( + DUMMY_CLASS_INSTANCE.stableFloatField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableDoubleField"), + JavaConstant.forDouble( + DUMMY_CLASS_INSTANCE.stableDoubleField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableObjectField)); + } + + public static final Map INSTANCE_STABLE_DEFAULT_FIELDS_MAP + = new HashMap<>(); + + static { + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultBooleanField"), + JavaConstant.forBoolean( + DUMMY_CLASS_INSTANCE.stableDefaultBooleanField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultByteField"), + JavaConstant.forByte( + DUMMY_CLASS_INSTANCE.stableDefaultByteField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultShortField"), + JavaConstant.forShort( + DUMMY_CLASS_INSTANCE.stableDefaultShortField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultCharField"), + JavaConstant.forChar( + DUMMY_CLASS_INSTANCE.stableDefaultCharField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultIntField"), + JavaConstant.forInt( + DUMMY_CLASS_INSTANCE.stableDefaultIntField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultLongField"), + JavaConstant.forLong( + DUMMY_CLASS_INSTANCE.stableDefaultLongField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultFloatField"), + JavaConstant.forFloat( + DUMMY_CLASS_INSTANCE.stableDefaultFloatField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultDoubleField"), + JavaConstant.forDouble( + DUMMY_CLASS_INSTANCE.stableDefaultDoubleField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableDefaultObjectField)); + } + + public static final Map STATIC_FIELDS_MAP = new HashMap<>(); + + static { + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticBooleanField"), + JavaConstant.forBoolean(DummyClass.staticBooleanField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticByteField"), + JavaConstant.forByte(DummyClass.staticByteField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticShortField"), + JavaConstant.forShort(DummyClass.staticShortField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticCharField"), + JavaConstant.forChar(DummyClass.staticCharField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticIntField"), + JavaConstant.forInt(DummyClass.staticIntField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticLongField"), + JavaConstant.forLong(DummyClass.staticLongField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFloatField"), + JavaConstant.forFloat(DummyClass.staticFloatField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticDoubleField"), + JavaConstant.forDouble(DummyClass.staticDoubleField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.staticObjectField)); + } + + public static final Map STATIC_FINAL_FIELDS_MAP + = new HashMap<>(); + + static { + STATIC_FINAL_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticFinalBooleanField"), + JavaConstant.forBoolean(DummyClass.staticFinalBooleanField)); + STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalByteField"), + JavaConstant.forByte(DummyClass.staticFinalByteField)); + STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalShortField"), + JavaConstant.forShort(DummyClass.staticFinalShortField)); + STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalCharField"), + JavaConstant.forChar(DummyClass.staticFinalCharField)); + STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalIntField"), + JavaConstant.forInt(DummyClass.staticFinalIntField)); + STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalLongField"), + JavaConstant.forLong(DummyClass.staticFinalLongField)); + STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalFloatField"), + JavaConstant.forFloat(DummyClass.staticFinalFloatField)); + STATIC_FINAL_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticFinalDoubleField"), + JavaConstant.forDouble(DummyClass.staticFinalDoubleField)); + STATIC_FINAL_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticFinalObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.staticFinalObjectField)); + } + + public static final Map STATIC_STABLE_FIELDS_MAP + = new HashMap<>(); + + static { + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableBooleanField"), + JavaConstant.forBoolean(DummyClass.staticStableBooleanField)); + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableByteField"), + JavaConstant.forByte(DummyClass.staticStableByteField)); + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableShortField"), + JavaConstant.forShort(DummyClass.staticStableShortField)); + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableCharField"), + JavaConstant.forChar(DummyClass.staticStableCharField)); + STATIC_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticStableIntField"), + JavaConstant.forInt(DummyClass.staticStableIntField)); + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableLongField"), + JavaConstant.forLong(DummyClass.staticStableLongField)); + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableFloatField"), + JavaConstant.forFloat(DummyClass.staticStableFloatField)); + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableDoubleField"), + JavaConstant.forDouble(DummyClass.staticStableDoubleField)); + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.staticStableObjectField)); + } + + public static final Map STATIC_STABLE_DEFAULT_FIELDS_MAP + = new HashMap<>(); + + static { + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultBooleanField"), + JavaConstant.forBoolean( + DummyClass.staticStableDefaultBooleanField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultByteField"), + JavaConstant.forByte( + DummyClass.staticStableDefaultByteField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultShortField"), + JavaConstant.forShort( + DummyClass.staticStableDefaultShortField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultCharField"), + JavaConstant.forChar( + DummyClass.staticStableDefaultCharField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultIntField"), + JavaConstant.forInt( + DummyClass.staticStableDefaultIntField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultLongField"), + JavaConstant.forLong( + DummyClass.staticStableDefaultLongField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultFloatField"), + JavaConstant.forFloat( + DummyClass.staticStableDefaultFloatField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultDoubleField"), + JavaConstant.forDouble( + DummyClass.staticStableDefaultDoubleField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DummyClass.staticStableDefaultObjectField)); + } + + public static final int ARRAY_DIMENSION = 1; + public static final int ARRAY_OF_ARRAYS_DIMENSION = 2; + + public static final Map ARRAYS_MAP = new HashMap<>(); + + static { + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "booleanArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.booleanArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "byteArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.byteArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "shortArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.shortArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "charArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.charArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "intArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.intArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "longArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.longArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "floatArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.floatArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "doubleArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.doubleArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "objectArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.objectArrayWithValues)); + } + + public static final Map STABLE_ARRAYS_MAP = new HashMap<>(); + + static { + STABLE_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableBooleanArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableBooleanArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableByteArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableByteArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableShortArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableShortArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableCharArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableCharArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableIntArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableIntArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableLongArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableLongArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableFloatArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableFloatArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableDoubleArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableDoubleArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableObjectArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableObjectArrayWithValues)); + } + + public static final Map ARRAY_ARRAYS_MAP = new HashMap<>(); + + static { + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "booleanArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "byteArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.byteArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "shortArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.shortArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "charArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.charArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "intArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.intArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "longArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.longArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "floatArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.floatArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "doubleArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.doubleArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "objectArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.objectArrayArrayWithValues)); + } + + public static final Map STABLE_ARRAY_ARRAYS_MAP = new HashMap<>(); + + static { + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableBooleanArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableBooleanArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableByteArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableByteArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableShortArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableShortArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableCharArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableCharArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableIntArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableIntArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableLongArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableLongArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableFloatArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableFloatArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableDoubleArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableDoubleArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableObjectArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableObjectArrayArrayWithValues)); + } + + public static ResolvedJavaField getResolvedJavaField(Class clazz, String fieldName) { + Field reflectionField = null; + try { + reflectionField = clazz.getDeclaredField(fieldName); + reflectionField.setAccessible(true); + } catch (NoSuchFieldException ex) { + throw new Error("Test bug: Invalid field name: " + ex, ex); + } catch (SecurityException ex) { + throw new Error("Unexpected error: " + ex, ex); + } + MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess(); + return metaAccess.lookupJavaField(reflectionField); + } +} diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/UnboxPrimitiveDataProvider.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/UnboxPrimitiveDataProvider.java new file mode 100644 index 00000000000..122ad426600 --- /dev/null +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/UnboxPrimitiveDataProvider.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 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. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; + +import java.util.LinkedList; + +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class UnboxPrimitiveDataProvider { + + @DataProvider(name = "unboxPrimitiveDataProvider") + public static Object[][] unboxPrimitiveDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + // Testing boolean + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject( + (Boolean) true), JavaConstant.forBoolean(true)}); + cfgSet.add(new Object[]{JavaConstant.forBoolean(true), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject((Boolean) false), + JavaConstant.forBoolean(false)}); + cfgSet.add(new Object[]{JavaConstant.forBoolean(false), null}); + for (byte number : new byte[]{-128, 0, 1, 127}) { + // Testing boxed primitives + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Byte.valueOf(number)), + JavaConstant.forByte(number)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Short.valueOf(number)), + JavaConstant.forShort(number)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Integer.valueOf(number)), + JavaConstant.forInt(number)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Long.valueOf(number)), + JavaConstant.forLong(number)}); + if (number >= 0) { + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject( + Character.valueOf((char) number)), + JavaConstant.forChar((char) number)}); + } + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject( + Float.valueOf(number * 1.1f)), + JavaConstant.forFloat(number * 1.1f)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject( + Double.valueOf(number * 1.1)), + JavaConstant.forDouble(number * 1.1)}); + // Testing non-boxed primitives (should result in returning of "null") + cfgSet.add(new Object[]{JavaConstant.forByte(number), null}); + cfgSet.add(new Object[]{JavaConstant.forShort(number), null}); + cfgSet.add(new Object[]{JavaConstant.forInt(number), null}); + cfgSet.add(new Object[]{JavaConstant.forLong(number), null}); + cfgSet.add(new Object[]{JavaConstant.forChar((char) number), null}); + cfgSet.add(new Object[]{JavaConstant.forFloat(number), null}); + cfgSet.add(new Object[]{JavaConstant.forDouble(number), null}); + } + // Testing boxed primitives with max values + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Short.MAX_VALUE), + JavaConstant.forShort(Short.MAX_VALUE)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Integer.MAX_VALUE), + JavaConstant.forInt(Integer.MAX_VALUE)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Long.MAX_VALUE), + JavaConstant.forLong(Long.MAX_VALUE)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Character.MAX_VALUE), + JavaConstant.forChar(Character.MAX_VALUE)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Float.MAX_VALUE), + JavaConstant.forFloat(Float.MAX_VALUE)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Double.MAX_VALUE), + JavaConstant.forDouble(Double.MAX_VALUE)}); + // Non-primitives testing + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.objectField), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.booleanArrayWithValues), + null}); + // Null testing + cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, null}); + cfgSet.add(new Object[]{null, null}); + return cfgSet.toArray(new Object[0][0]); + } +} diff --git a/hotspot/test/compiler/oracle/CheckCompileCommandOption.java b/hotspot/test/compiler/oracle/CheckCompileCommandOption.java index 978aad4178f..6489df5cba4 100644 --- a/hotspot/test/compiler/oracle/CheckCompileCommandOption.java +++ b/hotspot/test/compiler/oracle/CheckCompileCommandOption.java @@ -31,7 +31,7 @@ import jdk.test.lib.*; * @bug 8055286 8056964 8059847 8069035 * @summary "Checks parsing of -XX:CompileCommand=option" * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main CheckCompileCommandOption */ diff --git a/hotspot/test/compiler/oracle/TestCompileCommand.java b/hotspot/test/compiler/oracle/TestCompileCommand.java index cff8ed4e91b..6ec02ac6e81 100644 --- a/hotspot/test/compiler/oracle/TestCompileCommand.java +++ b/hotspot/test/compiler/oracle/TestCompileCommand.java @@ -31,7 +31,7 @@ import jdk.test.lib.*; * @bug 8069389 * @summary "Regression tests of -XX:CompileCommand" * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main TestCompileCommand */ diff --git a/hotspot/test/compiler/patches/java.base/java/lang/Helper.java b/hotspot/test/compiler/patches/java.base/java/lang/Helper.java new file mode 100644 index 00000000000..f0b285c5c07 --- /dev/null +++ b/hotspot/test/compiler/patches/java.base/java/lang/Helper.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang; + +/** + * A helper class to get access to package-private members + */ +public class Helper { + @jdk.internal.vm.annotation.ForceInline + public static boolean StringCodingHasNegatives(byte[] ba, int off, int len) { + return StringCoding.hasNegatives(ba, off, len); + } +} diff --git a/hotspot/test/compiler/profiling/spectrapredefineclass/Launcher.java b/hotspot/test/compiler/profiling/spectrapredefineclass/Launcher.java index 8ed81a52046..312734eafe5 100644 --- a/hotspot/test/compiler/profiling/spectrapredefineclass/Launcher.java +++ b/hotspot/test/compiler/profiling/spectrapredefineclass/Launcher.java @@ -27,7 +27,7 @@ import jdk.test.lib.*; * @test * @bug 8038636 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.instrument * java.management * @build Agent diff --git a/hotspot/test/compiler/profiling/spectrapredefineclass_classloaders/Launcher.java b/hotspot/test/compiler/profiling/spectrapredefineclass_classloaders/Launcher.java index f66da7e6049..66f155d845e 100644 --- a/hotspot/test/compiler/profiling/spectrapredefineclass_classloaders/Launcher.java +++ b/hotspot/test/compiler/profiling/spectrapredefineclass_classloaders/Launcher.java @@ -27,7 +27,7 @@ import jdk.test.lib.*; * @test * @bug 8040237 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.instrument * java.management * @build Agent Test A B diff --git a/hotspot/test/compiler/rangechecks/TestRangeCheckSmearing.java b/hotspot/test/compiler/rangechecks/TestRangeCheckSmearing.java index 4a8f067852d..72b78738288 100644 --- a/hotspot/test/compiler/rangechecks/TestRangeCheckSmearing.java +++ b/hotspot/test/compiler/rangechecks/TestRangeCheckSmearing.java @@ -26,7 +26,7 @@ * @bug 8066103 * @summary C2's range check smearing allows out of bound array accesses * @library /testlibrary /test/lib /compiler/whitebox / - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRangeCheckSmearing * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java index 1ef29fa3593..c4eacf5f111 100644 --- a/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java @@ -28,7 +28,7 @@ * @summary Verify PrintPreciseRTMLockingStatistics on CPUs with * rtm support and on VM with rtm locking support, * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java index 389141fe016..29cbee10771 100644 --- a/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java @@ -28,7 +28,7 @@ * @summary Verify PrintPreciseRTMLockingStatistics on CPUs without * rtm support and/or unsupported VM. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnSupportedConfig.java index 7e6b3960d03..aa5fc122a64 100644 --- a/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnSupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnSupportedConfig.java @@ -28,7 +28,7 @@ * @summary Verify RTMAbortRatio option processing on CPU with rtm * support and on VM with rtm locking support. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMAbortRatioOptionOnSupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java index 17a66529deb..5c97ade4ce2 100644 --- a/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java @@ -28,7 +28,7 @@ * @summary Verify RTMAbortRatio option processing on CPU without rtm * support or on VM that does not support rtm locking. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMAbortRatioOptionOnUnsupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/cli/TestRTMAbortThresholdOption.java b/hotspot/test/compiler/rtm/cli/TestRTMAbortThresholdOption.java index d43e7c26eae..3edec234295 100644 --- a/hotspot/test/compiler/rtm/cli/TestRTMAbortThresholdOption.java +++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortThresholdOption.java @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify processing of RTMAbortThreshold option. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMAbortThresholdOption * @run main/othervm TestRTMAbortThresholdOption diff --git a/hotspot/test/compiler/rtm/cli/TestRTMLockingCalculationDelayOption.java b/hotspot/test/compiler/rtm/cli/TestRTMLockingCalculationDelayOption.java index 7a059c1d6cc..9a70f7c15c9 100644 --- a/hotspot/test/compiler/rtm/cli/TestRTMLockingCalculationDelayOption.java +++ b/hotspot/test/compiler/rtm/cli/TestRTMLockingCalculationDelayOption.java @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify processing of RTMLockingCalculationDelay option. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMLockingCalculationDelayOption * @run main/othervm TestRTMLockingCalculationDelayOption diff --git a/hotspot/test/compiler/rtm/cli/TestRTMLockingThresholdOption.java b/hotspot/test/compiler/rtm/cli/TestRTMLockingThresholdOption.java index 9f13b74dd98..f9c202a37ac 100644 --- a/hotspot/test/compiler/rtm/cli/TestRTMLockingThresholdOption.java +++ b/hotspot/test/compiler/rtm/cli/TestRTMLockingThresholdOption.java @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify processing of RTMLockingThreshold option. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMLockingThresholdOption * @run main/othervm TestRTMLockingThresholdOption diff --git a/hotspot/test/compiler/rtm/cli/TestRTMRetryCountOption.java b/hotspot/test/compiler/rtm/cli/TestRTMRetryCountOption.java index f0832480f1d..baaf4a7e058 100644 --- a/hotspot/test/compiler/rtm/cli/TestRTMRetryCountOption.java +++ b/hotspot/test/compiler/rtm/cli/TestRTMRetryCountOption.java @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify processing of RTMRetryCount option. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMRetryCountOption * @run main/othervm TestRTMRetryCountOption diff --git a/hotspot/test/compiler/rtm/cli/TestRTMSpinLoopCountOption.java b/hotspot/test/compiler/rtm/cli/TestRTMSpinLoopCountOption.java index ec59cdbe58c..23d0f054872 100644 --- a/hotspot/test/compiler/rtm/cli/TestRTMSpinLoopCountOption.java +++ b/hotspot/test/compiler/rtm/cli/TestRTMSpinLoopCountOption.java @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify processing of RTMSpinLoopCount option. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMSpinLoopCountOption * @run main/othervm TestRTMSpinLoopCountOption diff --git a/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnSupportedConfig.java index cde17b4482c..b76fc6f7408 100644 --- a/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnSupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnSupportedConfig.java @@ -28,7 +28,7 @@ * @summary Verify RTMTotalCountIncrRate option processing on CPU with * rtm support and on VM with rtm locking support. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMTotalCountIncrRateOptionOnSupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java index 222ffa25793..c1d26ccd3a3 100644 --- a/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java @@ -33,7 +33,7 @@ import rtm.predicate.SupportedVM; * @summary Verify RTMTotalCountIncrRate option processing on CPU without * rtm support and/or on VM without rtm locking support. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMTotalCountIncrRateOptionOnUnsupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java index af702f6520a..07431f3e91f 100644 --- a/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java @@ -28,7 +28,7 @@ * @summary Verify UseRTMDeopt option processing on CPUs with rtm support * when rtm locking is supported by VM. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseRTMDeoptOptionOnSupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java index ba9970d077a..59b87002aa7 100644 --- a/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java @@ -28,7 +28,7 @@ * @summary Verify UseRTMDeopt option processing on CPUs without rtm support * or on VMs without rtm locking support. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseRTMDeoptOptionOnUnsupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java index 128b0efc06c..a6520551d52 100644 --- a/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java @@ -28,7 +28,7 @@ * @summary Verify UseRTMForStackLocks option processing on CPU with * rtm support when VM supports rtm locking. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseRTMForStackLocksOptionOnSupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java index 3e22b07a744..54bc3e94ba4 100644 --- a/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java @@ -28,7 +28,7 @@ * @summary Verify UseRTMForStackLocks option processing on CPUs without * rtm support and/or on VMs without rtm locking support. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseRTMForStackLocksOptionOnUnsupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java index 6939d13f8fc..8a923eb5b7c 100644 --- a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java @@ -28,7 +28,7 @@ * @summary Verify UseRTMLocking option processing on CPU with rtm support and * on VM with rtm-locking support. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseRTMLockingOptionOnSupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java index dd6ac2d406b..fa77a22d164 100644 --- a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java @@ -28,7 +28,7 @@ * @summary Verify UseRTMLocking option processing on CPU without * rtm support. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseRTMLockingOptionOnUnsupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java index e257f3451a1..69c5d1580e7 100644 --- a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java @@ -28,7 +28,7 @@ * @summary Verify UseRTMLocking option processing on CPU with rtm support * in case when VM should not support this option. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseRTMLockingOptionOnUnsupportedVM * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java index f6128654509..33a39468dd0 100644 --- a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java @@ -28,7 +28,7 @@ * @summary Verify processing of UseRTMLocking and UseBiasedLocking * options combination on CPU and VM with rtm support. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseRTMLockingOptionWithBiasedLocking * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMXendForLockBusyOption.java b/hotspot/test/compiler/rtm/cli/TestUseRTMXendForLockBusyOption.java index af76b83a9c6..9683da33187 100644 --- a/hotspot/test/compiler/rtm/cli/TestUseRTMXendForLockBusyOption.java +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMXendForLockBusyOption.java @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify processing of UseRTMXendForLockBusy option. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseRTMXendForLockBusyOption * @run main/othervm TestUseRTMXendForLockBusyOption diff --git a/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java index a03ba37ace1..90a9f14cc3a 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java @@ -28,7 +28,7 @@ * @summary Verify that RTMAbortRatio affects amount of aborts before * deoptimization. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMAbortRatio * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java b/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java index d76e812530d..3597c8362bf 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java @@ -28,7 +28,7 @@ * @summary Verify that RTMAbortThreshold option affects * amount of aborts after which abort ratio is calculated. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMAbortThreshold * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java index 91b7bafe142..605f7953ff7 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java @@ -30,7 +30,7 @@ * method's RTM state. And if we don't use RTMDeopt, then * RTM state remain the same after such deoptimization. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMAfterNonRTMDeopt * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java index 3dccdd911af..eddc3cc3200 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java @@ -28,7 +28,7 @@ * @summary Verify that on high abort ratio method will be recompiled * without rtm locking. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMDeoptOnHighAbortRatio * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java index 1a62cfd5149..b531aac5946 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify that on low abort ratio method will be recompiled. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMDeoptOnLowAbortRatio * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java b/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java index 56ab0937c0b..9cbcea733c8 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java @@ -28,7 +28,7 @@ * @summary Verify that RTMLockingCalculationDelay affect when * abort ratio calculation is started. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMLockingCalculationDelay * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java index 56fb6bef993..8b1ee985095 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java @@ -28,7 +28,7 @@ * @summary Verify that RTMLockingThreshold affects rtm state transition * ProfileRTM => UseRTM. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMLockingThreshold * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java b/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java index 4a51463e01d..35d5b62cc62 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify that RTMRetryCount affects actual amount of retries. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMRetryCount * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java b/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java index 30abc3b187a..b3d15716630 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java @@ -28,7 +28,7 @@ * @summary Verify that RTMSpinLoopCount affects time spent * between locking attempts. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMSpinLoopCount * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java index 3b9b9fcea65..4056dc9a50c 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java @@ -28,7 +28,7 @@ * @summary Verify that RTMTotalCountIncrRate option affects * RTM locking statistics. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestRTMTotalCountIncrRate * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java b/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java index a41535c7f75..4916d29bd1c 100644 --- a/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java @@ -28,7 +28,7 @@ * @summary Verify that rtm locking is used for stack locks before * inflation and after it used for inflated locks. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseRTMAfterLockInflation * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java b/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java index b7cd4bf83f3..93c630ce654 100644 --- a/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java @@ -28,7 +28,7 @@ * @summary Verify that UseRTMDeopt affects uncommon trap installation in * copmpiled methods with synchronized block. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseRTMDeopt * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java b/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java index 727e165cdac..9f433479b06 100644 --- a/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify that rtm locking is used for inflated locks. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseRTMForInflatedLocks * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java b/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java index b6f301dc1de..0f2cf7641e5 100644 --- a/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify that rtm locking is used for stack locks. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseRTMForStackLocks * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java b/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java index 0d7e788c72f..4be6f198c7d 100644 --- a/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java @@ -28,7 +28,7 @@ * @summary Verify that UseRTMXendForLockBusy option affects * method behaviour if lock is busy. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseRTMXendForLockBusy * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java b/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java index a14aa9d882e..a63cc0f88f0 100644 --- a/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java +++ b/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java @@ -28,7 +28,7 @@ * @summary Verify that NoRTMLockEliding option could be applied to * specified method and that such method will not use rtm. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestNoRTMLockElidingOption * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java b/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java index acb03abd104..c8edc9b053e 100644 --- a/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java +++ b/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java @@ -29,7 +29,7 @@ * specified method and that such method will not be deoptimized * on high abort ratio. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestUseRTMLockElidingOption * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java b/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java index 6accb0cb607..f94ed5ee8bc 100644 --- a/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java +++ b/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java @@ -30,7 +30,7 @@ * different types. Test also verify that VM output does not * contain rtm locking statistics when it should not. * @library /testlibrary /test/lib /compiler/testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestPrintPreciseRTMLockingStatistics * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/runtime/6859338/Test6859338.java b/hotspot/test/compiler/runtime/6859338/Test6859338.java index 03d68126f66..73576840db1 100644 --- a/hotspot/test/compiler/runtime/6859338/Test6859338.java +++ b/hotspot/test/compiler/runtime/6859338/Test6859338.java @@ -27,7 +27,7 @@ * @bug 6859338 * @summary Assertion failure in sharedRuntime.cpp * - * @run main/othervm -Xcomp -XX:+IgnoreUnrecognizedVMOptions -XX:-InlineObjectHash -Xbatch -XX:-ProfileInterpreter Test6859338 + * @run main/othervm -Xcomp -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:-InlineObjectHash -Xbatch -XX:-ProfileInterpreter Test6859338 */ public class Test6859338 { diff --git a/hotspot/test/compiler/runtime/8010927/Test8010927.java b/hotspot/test/compiler/runtime/8010927/Test8010927.java index 35317801f7f..127e80b9a5f 100644 --- a/hotspot/test/compiler/runtime/8010927/Test8010927.java +++ b/hotspot/test/compiler/runtime/8010927/Test8010927.java @@ -26,7 +26,7 @@ * @bug 8010927 * @summary Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy * @library /test/lib /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @build Test8010927 * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff --git a/hotspot/test/compiler/stable/TestStableUByte.java b/hotspot/test/compiler/stable/TestStableUByte.java new file mode 100644 index 00000000000..285b0274588 --- /dev/null +++ b/hotspot/test/compiler/stable/TestStableUByte.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 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. 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. + */ + +/* + * @test TestStableUByte + * @summary tests on stable fields and arrays + * @library /testlibrary /test/lib / + * @modules java.base/jdk.internal.vm.annotation + * @build sun.hotspot.WhiteBox + * @build compiler.stable.TestStableUByte + * + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:-TieredCompilation + * -XX:+FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUByte + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:-TieredCompilation + * -XX:-FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUByte + * + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:+TieredCompilation -XX:TieredStopAtLevel=1 + * -XX:+FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUByte + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:+TieredCompilation -XX:TieredStopAtLevel=1 + * -XX:-FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUByte + * + */ +package compiler.stable; + +import jdk.internal.vm.annotation.Stable; + +import java.lang.reflect.InvocationTargetException; + +public class TestStableUByte { + static final boolean isStableEnabled = StableConfiguration.isStableEnabled; + + public static void main(String[] args) throws Exception { + run(UByteStable.class); + run(UByteArrayDim1.class); + + if (failed) { + throw new Error("TEST FAILED"); + } + } + + /* ==================================================== */ + + static class UByteStable { + public @Stable byte v; + + public static final UByteStable c = new UByteStable(); + + public static int get() { return c.v & 0xFF; } + + public static void test() throws Exception { + byte v1 = -1, v2 = 1; + + c.v = v1; int r1 = get(); + c.v = v2; int r2 = get(); + + assertEquals(r1, v1 & 0xFF); + assertEquals(r2, (isStableEnabled ? v1 : v2) & 0xFF); + } + } + + /* ==================================================== */ + + static class UByteArrayDim1 { + public @Stable byte[] v; + + public static final UByteArrayDim1 c = new UByteArrayDim1(); + + public static byte[] get() { return c.v; } + public static int get1() { return get()[0] & 0xFF; } + + public static void test() throws Exception { + byte v1 = -1, v2 = 1; + + c.v = new byte[1]; + c.v[0] = v1; int r1 = get1(); + c.v[0] = v2; int r2 = get1(); + + assertEquals(r1, v1 & 0xFF); + assertEquals(r2, (isStableEnabled ? v1 : v2) & 0xFF); + } + } + + /* ==================================================== */ + // Auxiliary methods + static void assertEquals(int i, int j) { if (i != j) throw new AssertionError(i + " != " + j); } + static void assertTrue(boolean b) { if (!b) throw new AssertionError(); } + + static boolean failed = false; + + public static void run(Class test) { + Throwable ex = null; + System.out.print(test.getName()+": "); + try { + test.getMethod("test").invoke(null); + } catch (InvocationTargetException e) { + ex = e.getCause(); + } catch (Throwable e) { + ex = e; + } finally { + if (ex == null) { + System.out.println("PASSED"); + } else { + failed = true; + System.out.println("FAILED"); + ex.printStackTrace(System.out); + } + } + } +} diff --git a/hotspot/test/compiler/stable/TestStableUShort.java b/hotspot/test/compiler/stable/TestStableUShort.java new file mode 100644 index 00000000000..b450582f854 --- /dev/null +++ b/hotspot/test/compiler/stable/TestStableUShort.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 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. 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. + */ + +/* + * @test TestStableUShort + * @summary tests on stable fields and arrays + * @library /testlibrary /test/lib / + * @modules java.base/jdk.internal.vm.annotation + * @build sun.hotspot.WhiteBox + * @build compiler.stable.TestStableUShort + * + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:-TieredCompilation + * -XX:+FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUShort + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:-TieredCompilation + * -XX:-FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUShort + * + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:+TieredCompilation -XX:TieredStopAtLevel=1 + * -XX:+FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUShort + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:+TieredCompilation -XX:TieredStopAtLevel=1 + * -XX:-FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUShort + * + */ +package compiler.stable; + +import jdk.internal.vm.annotation.Stable; + +import java.lang.reflect.InvocationTargetException; + +public class TestStableUShort { + static final boolean isStableEnabled = StableConfiguration.isStableEnabled; + + public static void main(String[] args) throws Exception { + run(UShortStable.class); + run(UShortArrayDim1.class); + + if (failed) { + throw new Error("TEST FAILED"); + } + } + + /* ==================================================== */ + + static class UShortStable { + public @Stable short v; + + public static final UShortStable c = new UShortStable(); + + public static int get() { return c.v & 0xFFFF; } + + public static void test() throws Exception { + short v1 = -1, v2 = 1; + + c.v = v1; int r1 = get(); + c.v = v2; int r2 = get(); + + assertEquals(r1, v1 & 0xFFFF); + assertEquals(r2, (isStableEnabled ? v1 : v2) & 0xFFFF); + } + } + + /* ==================================================== */ + + static class UShortArrayDim1 { + public @Stable short[] v; + + public static final UShortArrayDim1 c = new UShortArrayDim1(); + + public static short[] get() { return c.v; } + public static int get1() { return get()[0] & 0xFFFF; } + + public static void test() throws Exception { + short v1 = -1, v2 = 1; + + c.v = new short[1]; + c.v[0] = v1; int r1 = get1(); + c.v[0] = v2; int r2 = get1(); + + assertEquals(r1, v1 & 0xFFFF); + assertEquals(r2, (isStableEnabled ? v1 : v2) & 0xFFFF); + } + } + + /* ==================================================== */ + // Auxiliary methods + static void assertEquals(int i, int j) { if (i != j) throw new AssertionError(i + " != " + j); } + static void assertTrue(boolean b) { if (!b) throw new AssertionError(); } + + static boolean failed = false; + + public static void run(Class test) { + Throwable ex = null; + System.out.print(test.getName()+": "); + try { + test.getMethod("test").invoke(null); + } catch (InvocationTargetException e) { + ex = e.getCause(); + } catch (Throwable e) { + ex = e; + } finally { + if (ex == null) { + System.out.println("PASSED"); + } else { + failed = true; + System.out.println("FAILED"); + ex.printStackTrace(System.out); + } + } + } +} diff --git a/hotspot/test/compiler/startup/NumCompilerThreadsCheck.java b/hotspot/test/compiler/startup/NumCompilerThreadsCheck.java index ecc305cf8e6..1eebffc1893 100644 --- a/hotspot/test/compiler/startup/NumCompilerThreadsCheck.java +++ b/hotspot/test/compiler/startup/NumCompilerThreadsCheck.java @@ -26,7 +26,7 @@ * @bug 8034775 * @summary Ensures correct minimal number of compiler threads (provided by -XX:CICompilerCount=) * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ import jdk.test.lib.*; diff --git a/hotspot/test/compiler/startup/SmallCodeCacheStartup.java b/hotspot/test/compiler/startup/SmallCodeCacheStartup.java index 89c0c841aae..fbab26221e8 100644 --- a/hotspot/test/compiler/startup/SmallCodeCacheStartup.java +++ b/hotspot/test/compiler/startup/SmallCodeCacheStartup.java @@ -29,7 +29,7 @@ * to initialize all compiler threads. The option -Xcomp gives the VM more time to * trigger the old bug. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ import jdk.test.lib.*; diff --git a/hotspot/test/compiler/startup/StartupOutput.java b/hotspot/test/compiler/startup/StartupOutput.java index 599902079d5..5d15e404921 100644 --- a/hotspot/test/compiler/startup/StartupOutput.java +++ b/hotspot/test/compiler/startup/StartupOutput.java @@ -26,7 +26,7 @@ * @bug 8026949 * @summary Test ensures correct VM output during startup * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ import jdk.test.lib.*; diff --git a/hotspot/test/compiler/tiered/ConstantGettersTransitionsTest.java b/hotspot/test/compiler/tiered/ConstantGettersTransitionsTest.java index 180848ab275..4eb086aef3c 100644 --- a/hotspot/test/compiler/tiered/ConstantGettersTransitionsTest.java +++ b/hotspot/test/compiler/tiered/ConstantGettersTransitionsTest.java @@ -28,7 +28,7 @@ import compiler.whitebox.CompilerWhiteBoxTest; /** * @test ConstantGettersTransitionsTest * @library /testlibrary /test/lib /compiler/whitebox / - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TransitionsTestExecutor ConstantGettersTransitionsTest * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission diff --git a/hotspot/test/compiler/tiered/LevelTransitionTest.java b/hotspot/test/compiler/tiered/LevelTransitionTest.java index c3b80504619..c011ba414ba 100644 --- a/hotspot/test/compiler/tiered/LevelTransitionTest.java +++ b/hotspot/test/compiler/tiered/LevelTransitionTest.java @@ -31,7 +31,7 @@ import compiler.whitebox.SimpleTestCase; /** * @test LevelTransitionTest * @library /testlibrary /test/lib /compiler/whitebox / - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @ignore 8067651 * @build TransitionsTestExecutor LevelTransitionTest diff --git a/hotspot/test/compiler/types/TestMeetIncompatibleInterfaceArrays.java b/hotspot/test/compiler/types/TestMeetIncompatibleInterfaceArrays.java index dbd4fef01df..9769afccc81 100644 --- a/hotspot/test/compiler/types/TestMeetIncompatibleInterfaceArrays.java +++ b/hotspot/test/compiler/types/TestMeetIncompatibleInterfaceArrays.java @@ -26,7 +26,7 @@ * @bug 8141551 * @summary C2 can not handle returns with inccompatible interface arrays * @modules java.base/jdk.internal.org.objectweb.asm - * java.base/sun.misc + * java.base/jdk.internal.misc * @library /testlibrary /test/lib * @build sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/compiler/types/correctness/CorrectnessTest.java b/hotspot/test/compiler/types/correctness/CorrectnessTest.java index 448e974b875..7add6555e4b 100644 --- a/hotspot/test/compiler/types/correctness/CorrectnessTest.java +++ b/hotspot/test/compiler/types/correctness/CorrectnessTest.java @@ -25,7 +25,7 @@ * @test CorrectnessTest * @bug 8038418 * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @ignore 8066173 * @compile execution/TypeConflict.java execution/TypeProfile.java diff --git a/hotspot/test/compiler/types/correctness/OffTest.java b/hotspot/test/compiler/types/correctness/OffTest.java index b0ee53542ad..ecab6e8a6e1 100644 --- a/hotspot/test/compiler/types/correctness/OffTest.java +++ b/hotspot/test/compiler/types/correctness/OffTest.java @@ -25,7 +25,7 @@ * @test CorrectnessTest * @bug 8038418 * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @ignore 8066173 * @compile execution/TypeConflict.java execution/TypeProfile.java diff --git a/hotspot/test/compiler/uncommontrap/TestUnstableIfTrap.java b/hotspot/test/compiler/uncommontrap/TestUnstableIfTrap.java index 14e46af1e19..aaf4d33f91a 100644 --- a/hotspot/test/compiler/uncommontrap/TestUnstableIfTrap.java +++ b/hotspot/test/compiler/uncommontrap/TestUnstableIfTrap.java @@ -42,7 +42,7 @@ import uncommontrap.Verifier; * @bug 8030976 8059226 * @library /testlibrary /compiler/testlibrary /test/lib * @modules java.base/jdk.internal.org.objectweb.asm - * java.base/sun.misc + * java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/compiler/unsafe/GetUnsafeObjectG1PreBarrier.java b/hotspot/test/compiler/unsafe/GetUnsafeObjectG1PreBarrier.java index a32769f4603..c7dc5cabab8 100644 --- a/hotspot/test/compiler/unsafe/GetUnsafeObjectG1PreBarrier.java +++ b/hotspot/test/compiler/unsafe/GetUnsafeObjectG1PreBarrier.java @@ -25,7 +25,7 @@ * @test * @bug 8016474 * @summary The bug only happens with C1 and G1 using a different ObjectAlignmentInBytes than KlassAlignmentInBytes (which is 8) - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=32 GetUnsafeObjectG1PreBarrier */ diff --git a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java index f8b82d21549..58fe9296be8 100644 --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java @@ -147,3 +147,5 @@ public class JdkInternalMiscUnsafeAccessTestBoolean { } } + + diff --git a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java index edc6f9ad859..12ae3c31a4e 100644 --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java @@ -184,3 +184,5 @@ public class JdkInternalMiscUnsafeAccessTestByte { } } } + + diff --git a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java index b63b1716ffa..f912b7fd86d 100644 --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java @@ -202,3 +202,5 @@ public class JdkInternalMiscUnsafeAccessTestChar { } } } + + diff --git a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java index 2309269f473..adbe249bafc 100644 --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java @@ -184,3 +184,5 @@ public class JdkInternalMiscUnsafeAccessTestDouble { } } } + + diff --git a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java index 07f537f4c5e..6e08a213f7f 100644 --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java @@ -184,3 +184,5 @@ public class JdkInternalMiscUnsafeAccessTestFloat { } } } + + diff --git a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java index 0d8bc7e4291..47bfd7da01f 100644 --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java @@ -156,12 +156,6 @@ public class JdkInternalMiscUnsafeAccessTestInt { assertEquals(x, 2, "putVolatile int value"); } - // Lazy - { - UNSAFE.putOrderedInt(base, offset, 1); - int x = UNSAFE.getIntVolatile(base, offset); - assertEquals(x, 1, "putRelease int value"); - } // Lazy { @@ -305,3 +299,5 @@ public class JdkInternalMiscUnsafeAccessTestInt { } } } + + diff --git a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java index 4460b4452e4..9ed8b8710bc 100644 --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java @@ -156,12 +156,6 @@ public class JdkInternalMiscUnsafeAccessTestLong { assertEquals(x, 2L, "putVolatile long value"); } - // Lazy - { - UNSAFE.putOrderedLong(base, offset, 1L); - long x = UNSAFE.getLongVolatile(base, offset); - assertEquals(x, 1L, "putRelease long value"); - } // Lazy { @@ -305,3 +299,5 @@ public class JdkInternalMiscUnsafeAccessTestLong { } } } + + diff --git a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java index 98afe49f6fa..2db2efa9932 100644 --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java @@ -127,12 +127,6 @@ public class JdkInternalMiscUnsafeAccessTestObject { assertEquals(x, "bar", "putVolatile Object value"); } - // Lazy - { - UNSAFE.putOrderedObject(base, offset, "foo"); - Object x = UNSAFE.getObjectVolatile(base, offset); - assertEquals(x, "foo", "putRelease Object value"); - } // Lazy { @@ -241,3 +235,5 @@ public class JdkInternalMiscUnsafeAccessTestObject { } } + + diff --git a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java index 600425dc913..814e0367bf0 100644 --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java @@ -202,3 +202,5 @@ public class JdkInternalMiscUnsafeAccessTestShort { } } } + + diff --git a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java index 976691c6735..7288954612b 100644 --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java @@ -25,7 +25,7 @@ * @test * @bug 8143628 * @summary Test unsafe access for boolean - * @modules java.base/sun.misc + * @modules jdk.unsupported/sun.misc * @run testng/othervm -Diters=100 -Xint SunMiscUnsafeAccessTestBoolean * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 SunMiscUnsafeAccessTestBoolean * @run testng/othervm -Diters=20000 -XX:-TieredCompilation SunMiscUnsafeAccessTestBoolean @@ -130,6 +130,10 @@ public class SunMiscUnsafeAccessTestBoolean { + + } } + + diff --git a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestByte.java b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestByte.java index bdcab491316..928f51790e6 100644 --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestByte.java +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestByte.java @@ -25,7 +25,7 @@ * @test * @bug 8143628 * @summary Test unsafe access for byte - * @modules java.base/sun.misc + * @modules jdk.unsupported/sun.misc * @run testng/othervm -Diters=100 -Xint SunMiscUnsafeAccessTestByte * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 SunMiscUnsafeAccessTestByte * @run testng/othervm -Diters=20000 -XX:-TieredCompilation SunMiscUnsafeAccessTestByte @@ -159,6 +159,8 @@ public class SunMiscUnsafeAccessTestByte { + + } static void testAccess(long address) { @@ -170,3 +172,5 @@ public class SunMiscUnsafeAccessTestByte { } } } + + diff --git a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestChar.java b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestChar.java index d7f56e31648..48aa82f9a53 100644 --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestChar.java +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestChar.java @@ -25,7 +25,7 @@ * @test * @bug 8143628 * @summary Test unsafe access for char - * @modules java.base/sun.misc + * @modules jdk.unsupported/sun.misc * @run testng/othervm -Diters=100 -Xint SunMiscUnsafeAccessTestChar * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 SunMiscUnsafeAccessTestChar * @run testng/othervm -Diters=20000 -XX:-TieredCompilation SunMiscUnsafeAccessTestChar @@ -159,6 +159,8 @@ public class SunMiscUnsafeAccessTestChar { + + } static void testAccess(long address) { @@ -170,3 +172,5 @@ public class SunMiscUnsafeAccessTestChar { } } } + + diff --git a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java index e9c5624afe6..0902911046d 100644 --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java @@ -25,7 +25,7 @@ * @test * @bug 8143628 * @summary Test unsafe access for double - * @modules java.base/sun.misc + * @modules jdk.unsupported/sun.misc * @run testng/othervm -Diters=100 -Xint SunMiscUnsafeAccessTestDouble * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 SunMiscUnsafeAccessTestDouble * @run testng/othervm -Diters=20000 -XX:-TieredCompilation SunMiscUnsafeAccessTestDouble @@ -159,6 +159,8 @@ public class SunMiscUnsafeAccessTestDouble { + + } static void testAccess(long address) { @@ -170,3 +172,5 @@ public class SunMiscUnsafeAccessTestDouble { } } } + + diff --git a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java index 993c63339d8..41056dc3b2e 100644 --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java @@ -25,7 +25,7 @@ * @test * @bug 8143628 * @summary Test unsafe access for float - * @modules java.base/sun.misc + * @modules jdk.unsupported/sun.misc * @run testng/othervm -Diters=100 -Xint SunMiscUnsafeAccessTestFloat * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 SunMiscUnsafeAccessTestFloat * @run testng/othervm -Diters=20000 -XX:-TieredCompilation SunMiscUnsafeAccessTestFloat @@ -159,6 +159,8 @@ public class SunMiscUnsafeAccessTestFloat { + + } static void testAccess(long address) { @@ -170,3 +172,5 @@ public class SunMiscUnsafeAccessTestFloat { } } } + + diff --git a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestInt.java b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestInt.java index 8924cc168cd..ecf79ee392e 100644 --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestInt.java +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestInt.java @@ -25,7 +25,7 @@ * @test * @bug 8143628 * @summary Test unsafe access for int - * @modules java.base/sun.misc + * @modules jdk.unsupported/sun.misc * @run testng/othervm -Diters=100 -Xint SunMiscUnsafeAccessTestInt * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 SunMiscUnsafeAccessTestInt * @run testng/othervm -Diters=20000 -XX:-TieredCompilation SunMiscUnsafeAccessTestInt @@ -164,6 +164,8 @@ public class SunMiscUnsafeAccessTestInt { } + + UNSAFE.putInt(base, offset, 1); // Compare @@ -181,6 +183,8 @@ public class SunMiscUnsafeAccessTestInt { assertEquals(x, 2, "failing compareAndSwap int value"); } + + // Compare set and get { int o = UNSAFE.getAndSetInt(base, offset, 1); @@ -209,3 +213,5 @@ public class SunMiscUnsafeAccessTestInt { } } } + + diff --git a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestLong.java b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestLong.java index 5999073a425..4a9b4805fc7 100644 --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestLong.java +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestLong.java @@ -25,7 +25,7 @@ * @test * @bug 8143628 * @summary Test unsafe access for long - * @modules java.base/sun.misc + * @modules jdk.unsupported/sun.misc * @run testng/othervm -Diters=100 -Xint SunMiscUnsafeAccessTestLong * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 SunMiscUnsafeAccessTestLong * @run testng/othervm -Diters=20000 -XX:-TieredCompilation SunMiscUnsafeAccessTestLong @@ -164,6 +164,8 @@ public class SunMiscUnsafeAccessTestLong { } + + UNSAFE.putLong(base, offset, 1L); // Compare @@ -181,6 +183,8 @@ public class SunMiscUnsafeAccessTestLong { assertEquals(x, 2L, "failing compareAndSwap long value"); } + + // Compare set and get { long o = UNSAFE.getAndSetLong(base, offset, 1L); @@ -209,3 +213,5 @@ public class SunMiscUnsafeAccessTestLong { } } } + + diff --git a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestObject.java b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestObject.java index 75fb599340b..efb15090f0e 100644 --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestObject.java +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestObject.java @@ -25,7 +25,7 @@ * @test * @bug 8143628 * @summary Test unsafe access for Object - * @modules java.base/sun.misc + * @modules jdk.unsupported/sun.misc * @run testng/othervm -Diters=100 -Xint SunMiscUnsafeAccessTestObject * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 SunMiscUnsafeAccessTestObject * @run testng/othervm -Diters=20000 -XX:-TieredCompilation SunMiscUnsafeAccessTestObject @@ -135,6 +135,8 @@ public class SunMiscUnsafeAccessTestObject { } + + UNSAFE.putObject(base, offset, "foo"); // Compare @@ -152,6 +154,8 @@ public class SunMiscUnsafeAccessTestObject { assertEquals(x, "bar", "failing compareAndSwap Object value"); } + + // Compare set and get { Object o = UNSAFE.getAndSetObject(base, offset, "foo"); @@ -163,3 +167,5 @@ public class SunMiscUnsafeAccessTestObject { } } + + diff --git a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestShort.java b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestShort.java index ef4311483a6..4e4cda0458c 100644 --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestShort.java +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestShort.java @@ -25,7 +25,7 @@ * @test * @bug 8143628 * @summary Test unsafe access for short - * @modules java.base/sun.misc + * @modules jdk.unsupported/sun.misc * @run testng/othervm -Diters=100 -Xint SunMiscUnsafeAccessTestShort * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 SunMiscUnsafeAccessTestShort * @run testng/othervm -Diters=20000 -XX:-TieredCompilation SunMiscUnsafeAccessTestShort @@ -159,6 +159,8 @@ public class SunMiscUnsafeAccessTestShort { + + } static void testAccess(long address) { @@ -170,3 +172,5 @@ public class SunMiscUnsafeAccessTestShort { } } } + + diff --git a/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java b/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java index 40725e431db..fead52fd530 100644 --- a/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java +++ b/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java @@ -46,6 +46,7 @@ * -XX:+FoldStableValues * -XX:CompileCommand=dontinline,UnsafeGetConstantField.checkGetAddress() * -XX:CompileCommand=dontinline,*.test* + * -XX:CompileCommand=inline,*Unsafe.get* * -XX:-UseUnalignedAccesses * compiler.unsafe.UnsafeGetConstantField */ diff --git a/hotspot/test/compiler/unsafe/UnsafeRaw.java b/hotspot/test/compiler/unsafe/UnsafeRaw.java index 907548a9d81..80ffd837c73 100644 --- a/hotspot/test/compiler/unsafe/UnsafeRaw.java +++ b/hotspot/test/compiler/unsafe/UnsafeRaw.java @@ -26,7 +26,7 @@ * @bug 8058744 * @summary Invalid pattern-matching of address computations in raw unsafe * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm -Xbatch UnsafeRaw */ diff --git a/hotspot/test/compiler/unsafe/X-UnsafeAccessTest.java.template b/hotspot/test/compiler/unsafe/X-UnsafeAccessTest.java.template index 4553635a158..e1957e00a83 100644 --- a/hotspot/test/compiler/unsafe/X-UnsafeAccessTest.java.template +++ b/hotspot/test/compiler/unsafe/X-UnsafeAccessTest.java.template @@ -25,7 +25,7 @@ * @test * @bug 8143628 * @summary Test unsafe access for $type$ - * @modules java.base/$package$ + * @modules $module$/$package$ * @run testng/othervm -Diters=100 -Xint $Qualifier$UnsafeAccessTest$Type$ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 $Qualifier$UnsafeAccessTest$Type$ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation $Qualifier$UnsafeAccessTest$Type$ @@ -160,6 +160,7 @@ public class $Qualifier$UnsafeAccessTest$Type$ { assertEquals(x, $value2$, "putVolatile $type$ value"); } +#if[!JdkInternalMisc] #if[Ordered] // Lazy { @@ -168,6 +169,7 @@ public class $Qualifier$UnsafeAccessTest$Type$ { assertEquals(x, $value1$, "putRelease $type$ value"); } #end[Ordered] +#end[!JdkInternalMisc] #if[JdkInternalMisc] // Lazy diff --git a/hotspot/test/compiler/unsafe/generate-unsafe-access-tests.sh b/hotspot/test/compiler/unsafe/generate-unsafe-access-tests.sh index fc4f7f47ee1..100283f245b 100644 --- a/hotspot/test/compiler/unsafe/generate-unsafe-access-tests.sh +++ b/hotspot/test/compiler/unsafe/generate-unsafe-access-tests.sh @@ -30,9 +30,11 @@ SPP=build.tools.spp.Spp # Generates unsafe access tests for objects and all primitive types # $1 = package name to Unsafe, sun.misc | jdk.internal.misc # $2 = test class qualifier name, SunMisc | JdkInternalMisc +# $3 = module name containing the Unsafe class, for @modules function generate { package=$1 Qualifier=$2 + module=$3 for type in boolean byte short char int long float double Object do @@ -108,12 +110,12 @@ function generate { args="$args -Dvalue1=$value1 -Dvalue2=$value2 -Dvalue3=$value3" echo $args - java $SPP -nel -K$Qualifier -Dpackage=$package -DQualifier=$Qualifier \ + java $SPP -nel -K$Qualifier -Dpackage=$package -DQualifier=$Qualifier -Dmodule=$module \ $args < X-UnsafeAccessTest.java.template > ${Qualifier}UnsafeAccessTest${Type}.java done } -generate sun.misc SunMisc -generate jdk.internal.misc JdkInternalMisc +generate sun.misc SunMisc jdk.unsupported +generate jdk.internal.misc JdkInternalMisc java.base -rm -fr build \ No newline at end of file +rm -fr build diff --git a/hotspot/test/compiler/whitebox/ForceNMethodSweepTest.java b/hotspot/test/compiler/whitebox/ForceNMethodSweepTest.java index b37838b4922..8661b32126f 100644 --- a/hotspot/test/compiler/whitebox/ForceNMethodSweepTest.java +++ b/hotspot/test/compiler/whitebox/ForceNMethodSweepTest.java @@ -90,7 +90,7 @@ public class ForceNMethodSweepTest extends CompilerWhiteBoxTest { return usage; } private void guaranteedSweep() { - // not entrant -> ++stack_traversal_mark -> zombie -> reclamation -> flushed + // not entrant -> ++stack_traversal_mark -> zombie -> flushed for (int i = 0; i < 5; ++i) { WHITE_BOX.fullGC(); WHITE_BOX.forceNMethodSweep(); diff --git a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java index 2178acf4028..a733bc96392 100644 --- a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java +++ b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java @@ -25,7 +25,7 @@ * @test IsMethodCompilableTest * @bug 8007270 8006683 8007288 8022832 * @library /testlibrary /test/lib / - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.* sun.hotspot.WhiteBox * @build IsMethodCompilableTest diff --git a/hotspot/test/compiler/whitebox/LockCompilationTest.java b/hotspot/test/compiler/whitebox/LockCompilationTest.java index 3efe08edf8f..4ba039699e4 100644 --- a/hotspot/test/compiler/whitebox/LockCompilationTest.java +++ b/hotspot/test/compiler/whitebox/LockCompilationTest.java @@ -23,12 +23,12 @@ /* * @test LockCompilationTest - * @bug 8059624 + * @bug 8059624 8152169 * @library /testlibrary /test/lib / * @modules java.management * @build LockCompilationTest - * @run main ClassFileInstaller sun.hotspot.WhiteBox - * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI LockCompilationTest * @summary testing of WB::lock/unlockCompilation() */ @@ -42,10 +42,25 @@ import compiler.whitebox.CompilerWhiteBoxTest; import jdk.test.lib.Asserts; public class LockCompilationTest extends CompilerWhiteBoxTest { + public static void main(String[] args) throws Exception { - // This case waits for 10 seconds and verifies that the method hasn't been + // This case waits for 5 seconds and verifies that the method hasn't been // compiled during that time. Only do that for one of the test cases. - CompilerWhiteBoxTest.main(LockCompilationTest::new, new String[] {"METHOD_TEST"}); + + // Only compile SimpleTestCase$Helper.method and exclude all other to ensure no + // contention on the compile queue causes problems. + String directive = + "[{ match:\"*SimpleTestCase$Helper.method\", Exclude:false}, " + + " { match:\"*.*\", Exclude:true}]"; + if (WHITE_BOX.addCompilerDirective(directive) != 2) { + throw new RuntimeException("Could not add directive"); + } + try { + CompilerWhiteBoxTest.main(LockCompilationTest::new, new String[] {"METHOD_TEST"}); + } finally { + WHITE_BOX.removeCompilerDirective(2); + } + } private LockCompilationTest(TestCase testCase) { @@ -66,7 +81,9 @@ public class LockCompilationTest extends CompilerWhiteBoxTest { // to check if it works correctly w/ safepoints System.out.println("going to safepoint"); WHITE_BOX.fullGC(); - waitBackgroundCompilation(); + // Sleep a while and then make sure the compile is still waiting + Thread.sleep(5000); + Asserts.assertTrue( WHITE_BOX.isMethodQueuedForCompilation(method), method + " must be in queue"); diff --git a/hotspot/test/gc/TestCardTablePageCommits.java b/hotspot/test/gc/TestCardTablePageCommits.java index 5c105e087ea..b3b4e13a898 100644 --- a/hotspot/test/gc/TestCardTablePageCommits.java +++ b/hotspot/test/gc/TestCardTablePageCommits.java @@ -33,7 +33,7 @@ import jdk.test.lib.Platform; * @summary Tests that the card table does not commit the same page twice * @requires vm.gc=="Parallel" | vm.gc=="null" * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run driver TestCardTablePageCommits */ diff --git a/hotspot/test/gc/TestObjectAlignment.java b/hotspot/test/gc/TestObjectAlignment.java index d46958c198a..2feaf63ba2b 100644 --- a/hotspot/test/gc/TestObjectAlignment.java +++ b/hotspot/test/gc/TestObjectAlignment.java @@ -27,7 +27,7 @@ * @bug 8021823 * @summary G1: Concurrent marking crashes with -XX:ObjectAlignmentInBytes>=32 in 64bit VMs * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=8 * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=16 diff --git a/hotspot/test/gc/TestSoftReferencesBehaviorOnOOME.java b/hotspot/test/gc/TestSoftReferencesBehaviorOnOOME.java index 75ab30f0453..380c9b882d4 100644 --- a/hotspot/test/gc/TestSoftReferencesBehaviorOnOOME.java +++ b/hotspot/test/gc/TestSoftReferencesBehaviorOnOOME.java @@ -26,7 +26,7 @@ * @key gc * @summary Tests that all SoftReferences has been cleared at time of OOM. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestSoftReferencesBehaviorOnOOME * @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 512 2k diff --git a/hotspot/test/gc/TestVerifyDuringStartup.java b/hotspot/test/gc/TestVerifyDuringStartup.java index 69466673a16..3ac4cddb35e 100644 --- a/hotspot/test/gc/TestVerifyDuringStartup.java +++ b/hotspot/test/gc/TestVerifyDuringStartup.java @@ -26,7 +26,7 @@ * @bug 8010463 8011343 8011898 * @summary Simple test run with -XX:+VerifyDuringStartup -XX:-UseTLAB to verify 8010463 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/TestVerifySilently.java b/hotspot/test/gc/TestVerifySilently.java index 3694f2f027b..864a1ef8d03 100644 --- a/hotspot/test/gc/TestVerifySilently.java +++ b/hotspot/test/gc/TestVerifySilently.java @@ -26,7 +26,7 @@ * @bug 8032771 * @summary Test silent verification. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/TestVerifySubSet.java b/hotspot/test/gc/TestVerifySubSet.java index ca201633bba..7126b9658b5 100644 --- a/hotspot/test/gc/TestVerifySubSet.java +++ b/hotspot/test/gc/TestVerifySubSet.java @@ -26,7 +26,7 @@ * @bug 8072725 * @summary Test VerifySubSet option * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/arguments/TestArrayAllocatorMallocLimit.java b/hotspot/test/gc/arguments/TestArrayAllocatorMallocLimit.java index 99e46d2095a..d06d3eec51c 100644 --- a/hotspot/test/gc/arguments/TestArrayAllocatorMallocLimit.java +++ b/hotspot/test/gc/arguments/TestArrayAllocatorMallocLimit.java @@ -28,7 +28,7 @@ * @bug 8054823 * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run driver TestArrayAllocatorMallocLimit */ diff --git a/hotspot/test/gc/arguments/TestCMSHeapSizeFlags.java b/hotspot/test/gc/arguments/TestCMSHeapSizeFlags.java index afc49710514..2e9e329f9d4 100644 --- a/hotspot/test/gc/arguments/TestCMSHeapSizeFlags.java +++ b/hotspot/test/gc/arguments/TestCMSHeapSizeFlags.java @@ -28,7 +28,7 @@ * @requires vm.gc=="ConcMarkSweep" | vm.gc=="null" * @summary Tests argument processing for initial and maximum heap size for the CMS collector * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestCMSHeapSizeFlags TestMaxHeapSizeTools * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/arguments/TestCompressedClassFlags.java b/hotspot/test/gc/arguments/TestCompressedClassFlags.java index 047974cffd2..3cc50ad5741 100644 --- a/hotspot/test/gc/arguments/TestCompressedClassFlags.java +++ b/hotspot/test/gc/arguments/TestCompressedClassFlags.java @@ -29,7 +29,7 @@ import jdk.test.lib.*; * @summary Tests that VM prints a warning when -XX:CompressedClassSpaceSize * is used together with -XX:-UseCompressedClassPointers * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ public class TestCompressedClassFlags { diff --git a/hotspot/test/gc/arguments/TestG1ConcMarkStepDurationMillis.java b/hotspot/test/gc/arguments/TestG1ConcMarkStepDurationMillis.java index baf362f9b6f..9a1eb442905 100644 --- a/hotspot/test/gc/arguments/TestG1ConcMarkStepDurationMillis.java +++ b/hotspot/test/gc/arguments/TestG1ConcMarkStepDurationMillis.java @@ -27,7 +27,7 @@ * @requires vm.gc=="null" | vm.gc=="G1" * @summary Tests argument processing for double type flag, G1ConcMarkStepDurationMillis * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/arguments/TestG1ConcRefinementThreads.java b/hotspot/test/gc/arguments/TestG1ConcRefinementThreads.java index 5d09738d9c2..0a470191560 100644 --- a/hotspot/test/gc/arguments/TestG1ConcRefinementThreads.java +++ b/hotspot/test/gc/arguments/TestG1ConcRefinementThreads.java @@ -28,7 +28,7 @@ * @requires vm.gc=="G1" | vm.gc=="null" * @summary Tests argument processing for G1ConcRefinementThreads * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/arguments/TestG1HeapSizeFlags.java b/hotspot/test/gc/arguments/TestG1HeapSizeFlags.java index 127f9ffbc91..440a963f318 100644 --- a/hotspot/test/gc/arguments/TestG1HeapSizeFlags.java +++ b/hotspot/test/gc/arguments/TestG1HeapSizeFlags.java @@ -28,7 +28,7 @@ * @requires vm.gc=="G1" | vm.gc=="null" * @summary Tests argument processing for initial and maximum heap size for the G1 collector * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestG1HeapSizeFlags TestMaxHeapSizeTools * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/arguments/TestG1PercentageOptions.java b/hotspot/test/gc/arguments/TestG1PercentageOptions.java index 9834f4dd603..27d1e0b9cf3 100644 --- a/hotspot/test/gc/arguments/TestG1PercentageOptions.java +++ b/hotspot/test/gc/arguments/TestG1PercentageOptions.java @@ -28,7 +28,7 @@ * @requires vm.gc=="G1" | vm.gc=="null" * @summary Test argument processing of various percentage options * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run driver TestG1PercentageOptions */ diff --git a/hotspot/test/gc/arguments/TestHeapFreeRatio.java b/hotspot/test/gc/arguments/TestHeapFreeRatio.java index e3cb7ba6a57..4f97a7ce383 100644 --- a/hotspot/test/gc/arguments/TestHeapFreeRatio.java +++ b/hotspot/test/gc/arguments/TestHeapFreeRatio.java @@ -27,7 +27,7 @@ * @bug 8025661 * @summary Test parsing of -Xminf and -Xmaxf * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm TestHeapFreeRatio */ diff --git a/hotspot/test/gc/arguments/TestInitialTenuringThreshold.java b/hotspot/test/gc/arguments/TestInitialTenuringThreshold.java index e9abbf7563c..82a4dca1456 100644 --- a/hotspot/test/gc/arguments/TestInitialTenuringThreshold.java +++ b/hotspot/test/gc/arguments/TestInitialTenuringThreshold.java @@ -28,7 +28,7 @@ * @requires vm.gc=="Parallel" | vm.gc=="null" * @summary Tests argument processing for initial tenuring threshold * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm TestInitialTenuringThreshold * @author thomas.schatzl@oracle.com diff --git a/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java b/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java index d512e40ccd9..a9f0f89a697 100644 --- a/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java +++ b/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java @@ -26,7 +26,7 @@ * @key gc * @summary Verify that heap size changes according to max and min heap free ratios. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestMaxMinHeapFreeRatioFlags * @run driver/timeout=240 TestMaxMinHeapFreeRatioFlags diff --git a/hotspot/test/gc/arguments/TestMaxNewSize.java b/hotspot/test/gc/arguments/TestMaxNewSize.java index 85aa530d27f..25eb279f455 100644 --- a/hotspot/test/gc/arguments/TestMaxNewSize.java +++ b/hotspot/test/gc/arguments/TestMaxNewSize.java @@ -28,7 +28,7 @@ * @summary Make sure that MaxNewSize always has a useful value after argument * processing. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestMaxNewSize * @run main TestMaxNewSize -XX:+UseSerialGC diff --git a/hotspot/test/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java b/hotspot/test/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java index 9ae68929c2e..d58040bca0a 100644 --- a/hotspot/test/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java +++ b/hotspot/test/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java @@ -26,7 +26,7 @@ * @key gc * @summary Verify that MinSurvivorRatio and InitialSurvivorRatio flags work * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestMinAndInitialSurvivorRatioFlags * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/arguments/TestMinInitialErgonomics.java b/hotspot/test/gc/arguments/TestMinInitialErgonomics.java index 680887c1d00..784860a834d 100644 --- a/hotspot/test/gc/arguments/TestMinInitialErgonomics.java +++ b/hotspot/test/gc/arguments/TestMinInitialErgonomics.java @@ -27,7 +27,7 @@ * @bug 8006088 * @summary Test ergonomics decisions related to minimum and initial heap size. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestMinInitialErgonomics TestMaxHeapSizeTools * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/arguments/TestNewRatioFlag.java b/hotspot/test/gc/arguments/TestNewRatioFlag.java index 4bcfce02e1b..1f8cfb8dd4e 100644 --- a/hotspot/test/gc/arguments/TestNewRatioFlag.java +++ b/hotspot/test/gc/arguments/TestNewRatioFlag.java @@ -27,7 +27,7 @@ * @bug 8025166 * @summary Verify that heap devided among generations according to NewRatio * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestNewRatioFlag * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/arguments/TestNewSizeFlags.java b/hotspot/test/gc/arguments/TestNewSizeFlags.java index 84c027e6275..4762afbf1cb 100644 --- a/hotspot/test/gc/arguments/TestNewSizeFlags.java +++ b/hotspot/test/gc/arguments/TestNewSizeFlags.java @@ -27,7 +27,7 @@ * @bug 8025166 * @summary Verify that young gen size conforms values specified by NewSize, MaxNewSize and Xmn options * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestNewSizeFlags * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/arguments/TestNewSizeThreadIncrease.java b/hotspot/test/gc/arguments/TestNewSizeThreadIncrease.java index 2422baec386..ce5aa179e79 100644 --- a/hotspot/test/gc/arguments/TestNewSizeThreadIncrease.java +++ b/hotspot/test/gc/arguments/TestNewSizeThreadIncrease.java @@ -28,7 +28,7 @@ * @summary Tests argument processing for NewSizeThreadIncrease * @library /testlibrary * @requires vm.gc=="Serial" | vm.gc=="null" - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/arguments/TestObjectTenuringFlags.java b/hotspot/test/gc/arguments/TestObjectTenuringFlags.java index 11c1c69e26d..fde3e607177 100644 --- a/hotspot/test/gc/arguments/TestObjectTenuringFlags.java +++ b/hotspot/test/gc/arguments/TestObjectTenuringFlags.java @@ -29,7 +29,7 @@ * @summary Tests argument processing for NeverTenure, AlwaysTenure, * and MaxTenuringThreshold * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestObjectTenuringFlags FlagsValue * @run main/othervm TestObjectTenuringFlags diff --git a/hotspot/test/gc/arguments/TestParallelGCThreads.java b/hotspot/test/gc/arguments/TestParallelGCThreads.java index 1059aed23c5..44d24171128 100644 --- a/hotspot/test/gc/arguments/TestParallelGCThreads.java +++ b/hotspot/test/gc/arguments/TestParallelGCThreads.java @@ -27,7 +27,7 @@ * @bug 8059527 8081382 * @summary Tests argument processing for ParallelGCThreads * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run driver TestParallelGCThreads */ diff --git a/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java b/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java index 0966e790fe0..af0b2a7922c 100644 --- a/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java +++ b/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java @@ -29,7 +29,7 @@ * parallel collectors. * @requires vm.gc=="null" * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestParallelHeapSizeFlags TestMaxHeapSizeTools * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/arguments/TestSelectDefaultGC.java b/hotspot/test/gc/arguments/TestSelectDefaultGC.java index be8ffbcb304..689f86c85b4 100644 --- a/hotspot/test/gc/arguments/TestSelectDefaultGC.java +++ b/hotspot/test/gc/arguments/TestSelectDefaultGC.java @@ -27,7 +27,7 @@ * @bug 8068582 * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @ignore 8148239 * @run driver TestSelectDefaultGC diff --git a/hotspot/test/gc/arguments/TestSerialHeapSizeFlags.java b/hotspot/test/gc/arguments/TestSerialHeapSizeFlags.java index b52b08c6cc4..3ffd729d5cb 100644 --- a/hotspot/test/gc/arguments/TestSerialHeapSizeFlags.java +++ b/hotspot/test/gc/arguments/TestSerialHeapSizeFlags.java @@ -27,7 +27,7 @@ * @bug 8006088 * @summary Tests argument processing for initial and maximum heap size for the Serial collector * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestSerialHeapSizeFlags TestMaxHeapSizeTools * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/arguments/TestSurvivorAlignmentInBytesOption.java b/hotspot/test/gc/arguments/TestSurvivorAlignmentInBytesOption.java index d61f797c85e..e275e6b8799 100644 --- a/hotspot/test/gc/arguments/TestSurvivorAlignmentInBytesOption.java +++ b/hotspot/test/gc/arguments/TestSurvivorAlignmentInBytesOption.java @@ -34,7 +34,7 @@ import jdk.test.lib.cli.CommandLineOptionTest; * & vm.opt.UnlockExperimentalVMOptions == null * & (vm.opt.IgnoreUnrecognizedVMOptions == null * | vm.opt.IgnoreUnrecognizedVMOptions == "false") - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main TestSurvivorAlignmentInBytesOption */ diff --git a/hotspot/test/gc/arguments/TestSurvivorRatioFlag.java b/hotspot/test/gc/arguments/TestSurvivorRatioFlag.java index ce20f3db9a3..2e386c2f6d2 100644 --- a/hotspot/test/gc/arguments/TestSurvivorRatioFlag.java +++ b/hotspot/test/gc/arguments/TestSurvivorRatioFlag.java @@ -26,7 +26,7 @@ * @key gc * @summary Verify that actual survivor ratio is equal to specified SurvivorRatio value * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestSurvivorRatioFlag * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java b/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java index 3dc2980a9ee..b1198e77251 100644 --- a/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java +++ b/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java @@ -26,7 +26,7 @@ * @key gc * @summary Verify that option TargetSurvivorRatio affects survivor space occupancy after minor GC. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestTargetSurvivorRatioFlag * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/arguments/TestUnrecognizedVMOptionsHandling.java b/hotspot/test/gc/arguments/TestUnrecognizedVMOptionsHandling.java index 787e23e8156..3b33466ee96 100644 --- a/hotspot/test/gc/arguments/TestUnrecognizedVMOptionsHandling.java +++ b/hotspot/test/gc/arguments/TestUnrecognizedVMOptionsHandling.java @@ -27,7 +27,7 @@ * @bug 8017611 * @summary Tests handling unrecognized VM options * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm TestUnrecognizedVMOptionsHandling */ diff --git a/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java b/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java index 64b5129122c..effbfa5cbe5 100644 --- a/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java +++ b/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java @@ -27,7 +27,7 @@ * @bug 8010722 * @summary Tests ergonomics for UseCompressedOops. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management/sun.management * @build TestUseCompressedOopsErgo TestUseCompressedOopsErgoTools * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/arguments/TestUseNUMAInterleaving.java b/hotspot/test/gc/arguments/TestUseNUMAInterleaving.java index 12fb9e47f16..85bb1de4cac 100644 --- a/hotspot/test/gc/arguments/TestUseNUMAInterleaving.java +++ b/hotspot/test/gc/arguments/TestUseNUMAInterleaving.java @@ -28,7 +28,7 @@ * @bug 8059614 * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run driver TestUseNUMAInterleaving */ diff --git a/hotspot/test/gc/class_unloading/TestCMSClassUnloadingEnabledHWM.java b/hotspot/test/gc/class_unloading/TestCMSClassUnloadingEnabledHWM.java index 12acc0fe0a9..732f0a74a3d 100644 --- a/hotspot/test/gc/class_unloading/TestCMSClassUnloadingEnabledHWM.java +++ b/hotspot/test/gc/class_unloading/TestCMSClassUnloadingEnabledHWM.java @@ -26,7 +26,7 @@ * @key gc * @bug 8049831 * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestCMSClassUnloadingEnabledHWM * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/class_unloading/TestG1ClassUnloadingHWM.java b/hotspot/test/gc/class_unloading/TestG1ClassUnloadingHWM.java index 3d382c91c25..6b99caf7531 100644 --- a/hotspot/test/gc/class_unloading/TestG1ClassUnloadingHWM.java +++ b/hotspot/test/gc/class_unloading/TestG1ClassUnloadingHWM.java @@ -26,7 +26,7 @@ * @key gc * @bug 8049831 * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestG1ClassUnloadingHWM * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/cms/GuardShrinkWarning.java b/hotspot/test/gc/cms/GuardShrinkWarning.java index 0b5ded01f84..58182678159 100644 --- a/hotspot/test/gc/cms/GuardShrinkWarning.java +++ b/hotspot/test/gc/cms/GuardShrinkWarning.java @@ -28,7 +28,7 @@ * @key gc * @key regression * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm GuardShrinkWarning * @author jon.masamitsu@oracle.com diff --git a/hotspot/test/gc/g1/Test2GbHeap.java b/hotspot/test/gc/g1/Test2GbHeap.java index 74a27f88022..8baa3199e18 100644 --- a/hotspot/test/gc/g1/Test2GbHeap.java +++ b/hotspot/test/gc/g1/Test2GbHeap.java @@ -28,7 +28,7 @@ * @key gc * @key regression * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegions.java b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegions.java index 487a4b10c43..b29d9328cbd 100644 --- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegions.java +++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegions.java @@ -28,7 +28,7 @@ * up the heap with humongous objects that should be eagerly reclaimable to avoid Full GC. * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java index 5dde4f48b9f..3e835bb49b7 100644 --- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java +++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java @@ -28,7 +28,7 @@ * mark bitmaps at reclaim. * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java index eacc9454701..ecd016451ac 100644 --- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java +++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java @@ -31,7 +31,7 @@ * should still be eagerly reclaimable to avoid Full GC. * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java b/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java index a4a17be430c..57fcf2ce7a3 100644 --- a/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java +++ b/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java @@ -28,7 +28,7 @@ * includes the expected necessary messages. * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/g1/TestGCLogMessages.java b/hotspot/test/gc/g1/TestGCLogMessages.java index 81526644c59..90e4b71d8ed 100644 --- a/hotspot/test/gc/g1/TestGCLogMessages.java +++ b/hotspot/test/gc/g1/TestGCLogMessages.java @@ -28,7 +28,7 @@ * includes the expected necessary messages. * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java b/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java index ef0109679ef..cd43193c3a1 100644 --- a/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java +++ b/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java @@ -26,7 +26,7 @@ * @bug 7168848 * @summary G1: humongous object allocations should initiate marking cycles when necessary * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java b/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java index 5f2e6fb918a..00950cc188d 100644 --- a/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java +++ b/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java @@ -27,7 +27,7 @@ * @key gc * @bug 8027756 * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestHumongousCodeCacheRoots * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/g1/TestNoEagerReclaimOfHumongousRegions.java b/hotspot/test/gc/g1/TestNoEagerReclaimOfHumongousRegions.java index 5090309c7f9..2fd5f6cba2f 100644 --- a/hotspot/test/gc/g1/TestNoEagerReclaimOfHumongousRegions.java +++ b/hotspot/test/gc/g1/TestNoEagerReclaimOfHumongousRegions.java @@ -30,7 +30,7 @@ * @requires vm.gc=="G1" | vm.gc=="null" * @key gc * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @build TestNoEagerReclaimOfHumongousRegions * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff --git a/hotspot/test/gc/g1/TestPLABSizeBounds.java b/hotspot/test/gc/g1/TestPLABSizeBounds.java index 4a4c6f80f50..df1c05e8888 100644 --- a/hotspot/test/gc/g1/TestPLABSizeBounds.java +++ b/hotspot/test/gc/g1/TestPLABSizeBounds.java @@ -28,7 +28,7 @@ * @requires vm.gc=="G1" | vm.gc=="null" * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java b/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java index 7d51fb6a97b..b0482083628 100644 --- a/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java +++ b/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java @@ -27,7 +27,7 @@ * @bug 8014240 * @summary Test output of G1PrintRegionRememberedSetInfo * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main TestPrintRegionRememberedSetInfo * @author thomas.schatzl@oracle.com diff --git a/hotspot/test/gc/g1/TestRemsetLogging.java b/hotspot/test/gc/g1/TestRemsetLogging.java index 54186bf568c..77d8b492386 100644 --- a/hotspot/test/gc/g1/TestRemsetLogging.java +++ b/hotspot/test/gc/g1/TestRemsetLogging.java @@ -26,7 +26,7 @@ * @requires vm.gc=="G1" | vm.gc =="null" * @bug 8013895 8129977 8145534 * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management/sun.management * @build TestRemsetLoggingTools TestRemsetLogging * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/g1/TestRemsetLoggingPerRegion.java b/hotspot/test/gc/g1/TestRemsetLoggingPerRegion.java index a19f7aeb719..7567caf8e44 100644 --- a/hotspot/test/gc/g1/TestRemsetLoggingPerRegion.java +++ b/hotspot/test/gc/g1/TestRemsetLoggingPerRegion.java @@ -26,7 +26,7 @@ * @requires vm.gc=="G1" | vm.gc =="null" * @bug 8014078 8129977 8145534 * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management/sun.management * @build TestRemsetLoggingTools TestRemsetLoggingPerRegion * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/g1/TestRemsetLoggingThreads.java b/hotspot/test/gc/g1/TestRemsetLoggingThreads.java index a654548ddeb..c26727f9d83 100644 --- a/hotspot/test/gc/g1/TestRemsetLoggingThreads.java +++ b/hotspot/test/gc/g1/TestRemsetLoggingThreads.java @@ -27,7 +27,7 @@ * @bug 8025441 8145534 * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management/sun.management * @summary Ensure that various values of worker threads/concurrent * refinement threads do not crash the VM. diff --git a/hotspot/test/gc/g1/TestShrinkAuxiliaryData00.java b/hotspot/test/gc/g1/TestShrinkAuxiliaryData00.java index 0babdc73cb7..e4149b4b7c1 100644 --- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData00.java +++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData00.java @@ -29,7 +29,7 @@ * @requires vm.gc=="G1" | vm.gc=="null" * @requires vm.opt.AggressiveOpts=="false" | vm.opt.AggressiveOpts=="null" * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.* sun.hotspot.WhiteBox * TestShrinkAuxiliaryData TestShrinkAuxiliaryData00 diff --git a/hotspot/test/gc/g1/TestShrinkAuxiliaryData05.java b/hotspot/test/gc/g1/TestShrinkAuxiliaryData05.java index 169686fa82e..db611f6ac09 100644 --- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData05.java +++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData05.java @@ -29,7 +29,7 @@ * @requires vm.gc=="G1" | vm.gc=="null" * @requires vm.opt.AggressiveOpts=="false" | vm.opt.AggressiveOpts=="null" * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.* sun.hotspot.WhiteBox * TestShrinkAuxiliaryData TestShrinkAuxiliaryData05 diff --git a/hotspot/test/gc/g1/TestShrinkAuxiliaryData10.java b/hotspot/test/gc/g1/TestShrinkAuxiliaryData10.java index 600b782479c..8e645ed5b7e 100644 --- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData10.java +++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData10.java @@ -29,7 +29,7 @@ * @requires vm.gc=="G1" | vm.gc=="null" * @requires vm.opt.AggressiveOpts=="false" | vm.opt.AggressiveOpts=="null" * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.* sun.hotspot.WhiteBox * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData10 diff --git a/hotspot/test/gc/g1/TestShrinkAuxiliaryData15.java b/hotspot/test/gc/g1/TestShrinkAuxiliaryData15.java index 09c2a073a68..2b4401fa46b 100644 --- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData15.java +++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData15.java @@ -29,7 +29,7 @@ * @requires vm.gc=="G1" | vm.gc=="null" * @requires vm.opt.AggressiveOpts=="false" | vm.opt.AggressiveOpts=="null" * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.* sun.hotspot.WhiteBox * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData15 diff --git a/hotspot/test/gc/g1/TestShrinkAuxiliaryData20.java b/hotspot/test/gc/g1/TestShrinkAuxiliaryData20.java index 4b464689b5c..b0854ea2a10 100644 --- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData20.java +++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData20.java @@ -29,7 +29,7 @@ * @requires vm.gc=="G1" | vm.gc=="null" * @requires vm.opt.AggressiveOpts=="false" | vm.opt.AggressiveOpts=="null" * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.* sun.hotspot.WhiteBox * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData20 diff --git a/hotspot/test/gc/g1/TestShrinkAuxiliaryData25.java b/hotspot/test/gc/g1/TestShrinkAuxiliaryData25.java index 2ee907488e4..60f6e5037c5 100644 --- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData25.java +++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData25.java @@ -29,7 +29,7 @@ * @requires vm.gc=="G1" | vm.gc=="null" * @requires vm.opt.AggressiveOpts=="false" | vm.opt.AggressiveOpts=="null" * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.* sun.hotspot.WhiteBox * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData25 diff --git a/hotspot/test/gc/g1/TestShrinkAuxiliaryData30.java b/hotspot/test/gc/g1/TestShrinkAuxiliaryData30.java index d1304b07033..6b73629b70a 100644 --- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData30.java +++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData30.java @@ -29,7 +29,7 @@ * @requires vm.gc=="G1" | vm.gc=="null" * @requires vm.opt.AggressiveOpts=="false" | vm.opt.AggressiveOpts=="null" * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.* sun.hotspot.WhiteBox * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData30 diff --git a/hotspot/test/gc/g1/TestShrinkDefragmentedHeap.java b/hotspot/test/gc/g1/TestShrinkDefragmentedHeap.java index c53eb6170fc..34948e9797e 100644 --- a/hotspot/test/gc/g1/TestShrinkDefragmentedHeap.java +++ b/hotspot/test/gc/g1/TestShrinkDefragmentedHeap.java @@ -32,7 +32,7 @@ * 3. invoke gc and check that memory returned to the system (amount of committed memory got down) * * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management/sun.management */ import java.lang.management.ManagementFactory; diff --git a/hotspot/test/gc/g1/TestStringDeduplicationAgeThreshold.java b/hotspot/test/gc/g1/TestStringDeduplicationAgeThreshold.java index cfa4b1f0931..b09a32a6956 100644 --- a/hotspot/test/gc/g1/TestStringDeduplicationAgeThreshold.java +++ b/hotspot/test/gc/g1/TestStringDeduplicationAgeThreshold.java @@ -27,7 +27,7 @@ * @bug 8029075 * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/g1/TestStringDeduplicationFullGC.java b/hotspot/test/gc/g1/TestStringDeduplicationFullGC.java index 8265f30d6e3..b725acbf8de 100644 --- a/hotspot/test/gc/g1/TestStringDeduplicationFullGC.java +++ b/hotspot/test/gc/g1/TestStringDeduplicationFullGC.java @@ -27,7 +27,7 @@ * @bug 8029075 * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/g1/TestStringDeduplicationInterned.java b/hotspot/test/gc/g1/TestStringDeduplicationInterned.java index 24fcb718793..3abe32d80ec 100644 --- a/hotspot/test/gc/g1/TestStringDeduplicationInterned.java +++ b/hotspot/test/gc/g1/TestStringDeduplicationInterned.java @@ -27,7 +27,7 @@ * @bug 8029075 * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/g1/TestStringDeduplicationPrintOptions.java b/hotspot/test/gc/g1/TestStringDeduplicationPrintOptions.java index 83401a47da2..62146e176d8 100644 --- a/hotspot/test/gc/g1/TestStringDeduplicationPrintOptions.java +++ b/hotspot/test/gc/g1/TestStringDeduplicationPrintOptions.java @@ -27,7 +27,7 @@ * @bug 8029075 * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/g1/TestStringDeduplicationTableRehash.java b/hotspot/test/gc/g1/TestStringDeduplicationTableRehash.java index 0a37b95d522..d7c2f12c77b 100644 --- a/hotspot/test/gc/g1/TestStringDeduplicationTableRehash.java +++ b/hotspot/test/gc/g1/TestStringDeduplicationTableRehash.java @@ -27,7 +27,7 @@ * @bug 8029075 * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/g1/TestStringDeduplicationTableResize.java b/hotspot/test/gc/g1/TestStringDeduplicationTableResize.java index 7106527ac15..204efb5a4ce 100644 --- a/hotspot/test/gc/g1/TestStringDeduplicationTableResize.java +++ b/hotspot/test/gc/g1/TestStringDeduplicationTableResize.java @@ -27,7 +27,7 @@ * @bug 8029075 * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/g1/TestStringDeduplicationYoungGC.java b/hotspot/test/gc/g1/TestStringDeduplicationYoungGC.java index 66c6ee42324..15ab52f67e5 100644 --- a/hotspot/test/gc/g1/TestStringDeduplicationYoungGC.java +++ b/hotspot/test/gc/g1/TestStringDeduplicationYoungGC.java @@ -27,7 +27,7 @@ * @bug 8029075 * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/g1/TestStringSymbolTableStats.java b/hotspot/test/gc/g1/TestStringSymbolTableStats.java index f50bcf3e73f..b5c9d0f7018 100644 --- a/hotspot/test/gc/g1/TestStringSymbolTableStats.java +++ b/hotspot/test/gc/g1/TestStringSymbolTableStats.java @@ -27,7 +27,7 @@ * @summary Ensure that the G1TraceStringSymbolTableScrubbing prints the expected message. * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/logging/TestDeprecatedPrintFlags.java b/hotspot/test/gc/logging/TestDeprecatedPrintFlags.java index aaf4d5cff8d..fe2a8d71041 100644 --- a/hotspot/test/gc/logging/TestDeprecatedPrintFlags.java +++ b/hotspot/test/gc/logging/TestDeprecatedPrintFlags.java @@ -27,7 +27,7 @@ * @summary Verify PrintGC, PrintGCDetails and -Xloggc * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/logging/TestGCId.java b/hotspot/test/gc/logging/TestGCId.java index 38354b153f3..1f89a33a0df 100644 --- a/hotspot/test/gc/logging/TestGCId.java +++ b/hotspot/test/gc/logging/TestGCId.java @@ -28,7 +28,7 @@ * @requires vm.gc=="null" * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/logging/TestPrintReferences.java b/hotspot/test/gc/logging/TestPrintReferences.java index b8b94cd04be..8181e0ca3aa 100644 --- a/hotspot/test/gc/logging/TestPrintReferences.java +++ b/hotspot/test/gc/logging/TestPrintReferences.java @@ -27,7 +27,7 @@ * @summary Validate the reference processing logging * @key gc * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java b/hotspot/test/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java index e7ab96f1448..57fb611fd73 100644 --- a/hotspot/test/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java +++ b/hotspot/test/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java @@ -26,7 +26,7 @@ * @bug 8004924 * @summary Checks that jmap -heap contains the flag CompressedClassSpaceSize * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:CompressedClassSpaceSize=50m CompressedClassSpaceSizeInJmapHeap */ diff --git a/hotspot/test/gc/metaspace/TestCapacityUntilGCWrapAround.java b/hotspot/test/gc/metaspace/TestCapacityUntilGCWrapAround.java index be4ad861253..827aff5946e 100644 --- a/hotspot/test/gc/metaspace/TestCapacityUntilGCWrapAround.java +++ b/hotspot/test/gc/metaspace/TestCapacityUntilGCWrapAround.java @@ -26,7 +26,7 @@ * @key gc * @bug 8049831 * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestCapacityUntilGCWrapAround * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java b/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java index 11d8901ea40..64066ee2b62 100644 --- a/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java +++ b/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java @@ -31,7 +31,7 @@ import static jdk.test.lib.Asserts.*; * @summary Tests that a MemoryPoolMXBeans is created for metaspace and that a * MemoryManagerMXBean is created. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops TestMetaspaceMemoryPool * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:MaxMetaspaceSize=60m TestMetaspaceMemoryPool diff --git a/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java index 6c0c48a239b..042f7660657 100644 --- a/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java +++ b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java @@ -33,10 +33,11 @@ import static jdk.test.lib.Asserts.*; * @library /testlibrary * @summary Tests that performance counters for metaspace and compressed class * space exists and works. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor + * @ignore 8151460 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters diff --git a/hotspot/test/gc/metaspace/TestMetaspaceSizeFlags.java b/hotspot/test/gc/metaspace/TestMetaspaceSizeFlags.java index 4fc599509e6..bb76ae4bd7b 100644 --- a/hotspot/test/gc/metaspace/TestMetaspaceSizeFlags.java +++ b/hotspot/test/gc/metaspace/TestMetaspaceSizeFlags.java @@ -31,7 +31,7 @@ import jdk.test.lib.ProcessTools; * @bug 8024650 * @summary Test that metaspace size flags can be set correctly * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ public class TestMetaspaceSizeFlags { diff --git a/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java b/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java index 5d7d3852f43..e85b172190f 100644 --- a/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java +++ b/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java @@ -33,9 +33,10 @@ import static jdk.test.lib.Asserts.*; * @requires vm.gc=="Serial" | vm.gc=="null" * @summary Tests that a MemoryPoolMXBeans and PerfCounters for metaspace * report the same data. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * jdk.jvmstat/sun.jvmstat.monitor + * @ignore 8151460 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData -Xint TestPerfCountersAndMemoryPools * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData -Xint TestPerfCountersAndMemoryPools */ diff --git a/hotspot/test/gc/parallel/AdaptiveGCBoundary.java b/hotspot/test/gc/parallel/AdaptiveGCBoundary.java index 64e4f7135c9..91ad282f1ea 100644 --- a/hotspot/test/gc/parallel/AdaptiveGCBoundary.java +++ b/hotspot/test/gc/parallel/AdaptiveGCBoundary.java @@ -28,7 +28,7 @@ * @key gc * @key regression * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm AdaptiveGCBoundary * @author jon.masamitsu@oracle.com diff --git a/hotspot/test/gc/serial/HeapChangeLogging.java b/hotspot/test/gc/serial/HeapChangeLogging.java index 27823a320ec..f3d0c0180a3 100644 --- a/hotspot/test/gc/serial/HeapChangeLogging.java +++ b/hotspot/test/gc/serial/HeapChangeLogging.java @@ -25,7 +25,7 @@ * @test HeapChangeLogging.java * @bug 8027440 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build HeapChangeLogging * @summary Allocate to get a promotion failure and verify that that heap change logging is present. diff --git a/hotspot/test/gc/startup_warnings/TestCMS.java b/hotspot/test/gc/startup_warnings/TestCMS.java index eb48b408bd6..23e0c85e4d4 100644 --- a/hotspot/test/gc/startup_warnings/TestCMS.java +++ b/hotspot/test/gc/startup_warnings/TestCMS.java @@ -27,7 +27,7 @@ * @bug 8006398 * @summary Test that CMS does not print a warning message * @library /testlibrary -* @modules java.base/sun.misc +* @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/startup_warnings/TestDefNewCMS.java b/hotspot/test/gc/startup_warnings/TestDefNewCMS.java index 6b684accb85..1821464ce2f 100644 --- a/hotspot/test/gc/startup_warnings/TestDefNewCMS.java +++ b/hotspot/test/gc/startup_warnings/TestDefNewCMS.java @@ -27,7 +27,7 @@ * @bug 8065972 * @summary Test that the unsupported DefNew+CMS combination does not start * @library /testlibrary -* @modules java.base/sun.misc +* @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/startup_warnings/TestG1.java b/hotspot/test/gc/startup_warnings/TestG1.java index e4505f9cf33..68bd4796166 100644 --- a/hotspot/test/gc/startup_warnings/TestG1.java +++ b/hotspot/test/gc/startup_warnings/TestG1.java @@ -27,7 +27,7 @@ * @bug 8006398 * @summary Test that the G1 collector does not print a warning message * @library /testlibrary -* @modules java.base/sun.misc +* @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/startup_warnings/TestParNewCMS.java b/hotspot/test/gc/startup_warnings/TestParNewCMS.java index 6fc0b332e51..7a332d985b0 100644 --- a/hotspot/test/gc/startup_warnings/TestParNewCMS.java +++ b/hotspot/test/gc/startup_warnings/TestParNewCMS.java @@ -27,7 +27,7 @@ * @bug 8065972 * @summary Test that specifying -XX:+UseParNewGC on the command line logs a warning message * @library /testlibrary -* @modules java.base/sun.misc +* @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/startup_warnings/TestParNewSerialOld.java b/hotspot/test/gc/startup_warnings/TestParNewSerialOld.java index 504eefd19e9..18455c7f9ea 100644 --- a/hotspot/test/gc/startup_warnings/TestParNewSerialOld.java +++ b/hotspot/test/gc/startup_warnings/TestParNewSerialOld.java @@ -27,7 +27,7 @@ * @bug 8065972 * @summary Test that the unsupported ParNew+SerialOld combination does not start * @library /testlibrary -* @modules java.base/sun.misc +* @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/startup_warnings/TestParallelGC.java b/hotspot/test/gc/startup_warnings/TestParallelGC.java index 444c7cf6d16..6af5f762ddc 100644 --- a/hotspot/test/gc/startup_warnings/TestParallelGC.java +++ b/hotspot/test/gc/startup_warnings/TestParallelGC.java @@ -27,7 +27,7 @@ * @bug 8006398 * @summary Test that ParallelGC does not print a warning message * @library /testlibrary -* @modules java.base/sun.misc +* @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/startup_warnings/TestParallelScavengeSerialOld.java b/hotspot/test/gc/startup_warnings/TestParallelScavengeSerialOld.java index bb1f641bc8d..e748b0ef7e1 100644 --- a/hotspot/test/gc/startup_warnings/TestParallelScavengeSerialOld.java +++ b/hotspot/test/gc/startup_warnings/TestParallelScavengeSerialOld.java @@ -27,7 +27,7 @@ * @bug 8006398 * @summary Test that the ParallelScavenge+SerialOld combination does not print a warning message * @library /testlibrary -* @modules java.base/sun.misc +* @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/startup_warnings/TestSerialGC.java b/hotspot/test/gc/startup_warnings/TestSerialGC.java index 5219f4cb7c1..2010980699a 100644 --- a/hotspot/test/gc/startup_warnings/TestSerialGC.java +++ b/hotspot/test/gc/startup_warnings/TestSerialGC.java @@ -27,7 +27,7 @@ * @bug 8006398 * @summary Test that SerialGC does not print a warning message * @library /testlibrary -* @modules java.base/sun.misc +* @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/gc/survivorAlignment/TestAllocationInEden.java b/hotspot/test/gc/survivorAlignment/TestAllocationInEden.java index 5cc7efaeb95..4ba5ae2c749 100644 --- a/hotspot/test/gc/survivorAlignment/TestAllocationInEden.java +++ b/hotspot/test/gc/survivorAlignment/TestAllocationInEden.java @@ -27,7 +27,7 @@ * @summary Verify that object's alignment in eden space is not affected by * SurvivorAlignmentInBytes option. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestAllocationInEden SurvivorAlignmentTestMain AlignmentHelper * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/gc/survivorAlignment/TestPromotionFromEdenToTenured.java b/hotspot/test/gc/survivorAlignment/TestPromotionFromEdenToTenured.java index b8d276367eb..92dcacd488c 100644 --- a/hotspot/test/gc/survivorAlignment/TestPromotionFromEdenToTenured.java +++ b/hotspot/test/gc/survivorAlignment/TestPromotionFromEdenToTenured.java @@ -27,7 +27,7 @@ * @summary Verify that objects promoted from eden space to tenured space during * full GC are not aligned to SurvivorAlignmentInBytes value. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestPromotionFromEdenToTenured SurvivorAlignmentTestMain * AlignmentHelper diff --git a/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java b/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java index 06aaf43c027..0fec465cade 100644 --- a/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java +++ b/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java @@ -27,7 +27,7 @@ * @summary Verify that objects promoted from survivor space to tenured space * during full GC are not aligned to SurvivorAlignmentInBytes value. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestPromotionFromSurvivorToTenuredAfterFullGC * SurvivorAlignmentTestMain AlignmentHelper diff --git a/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java b/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java index c0ce4d65701..488207d18e3 100644 --- a/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java +++ b/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java @@ -28,7 +28,7 @@ * when their age exceeded tenuring threshold are not aligned to * SurvivorAlignmentInBytes value. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestPromotionFromSurvivorToTenuredAfterMinorGC * SurvivorAlignmentTestMain AlignmentHelper diff --git a/hotspot/test/gc/survivorAlignment/TestPromotionToSurvivor.java b/hotspot/test/gc/survivorAlignment/TestPromotionToSurvivor.java index 42e70dccc84..f5b2dc293f8 100644 --- a/hotspot/test/gc/survivorAlignment/TestPromotionToSurvivor.java +++ b/hotspot/test/gc/survivorAlignment/TestPromotionToSurvivor.java @@ -27,7 +27,7 @@ * @summary Verify that objects promoted from eden space to survivor space after * minor GC are aligned to SurvivorAlignmentInBytes. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestPromotionToSurvivor * SurvivorAlignmentTestMain AlignmentHelper diff --git a/hotspot/test/gc/whitebox/TestConcMarkCycleWB.java b/hotspot/test/gc/whitebox/TestConcMarkCycleWB.java index fe2e64c17ea..4c76852f25b 100644 --- a/hotspot/test/gc/whitebox/TestConcMarkCycleWB.java +++ b/hotspot/test/gc/whitebox/TestConcMarkCycleWB.java @@ -26,7 +26,7 @@ * @bug 8065579 * @requires vm.gc=="null" | vm.gc=="G1" * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/gc/whitebox/TestWBGC.java b/hotspot/test/gc/whitebox/TestWBGC.java index 509456a2860..56eae949b63 100644 --- a/hotspot/test/gc/whitebox/TestWBGC.java +++ b/hotspot/test/gc/whitebox/TestWBGC.java @@ -26,7 +26,7 @@ * @bug 8055098 * @summary Test verify that WB methods isObjectInOldGen and youngGC works correctly. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestWBGC * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/8003720/Test8003720.java b/hotspot/test/runtime/8003720/Test8003720.java index 0fd5ef3e4ab..4abe0f807c1 100644 --- a/hotspot/test/runtime/8003720/Test8003720.java +++ b/hotspot/test/runtime/8003720/Test8003720.java @@ -27,7 +27,7 @@ * @bug 8003720 * @summary Method in interpreter stack frame can be deallocated * @modules java.base/jdk.internal.org.objectweb.asm - * java.base/sun.misc + * java.base/jdk.internal.misc * @compile -XDignore.symbol.file Victim.java * @run main/othervm -Xverify:all -Xint Test8003720 */ diff --git a/hotspot/test/runtime/8026365/InvokeSpecialAnonTest.java b/hotspot/test/runtime/8026365/InvokeSpecialAnonTest.java index 4dd6657412d..c84bf5c1806 100644 --- a/hotspot/test/runtime/8026365/InvokeSpecialAnonTest.java +++ b/hotspot/test/runtime/8026365/InvokeSpecialAnonTest.java @@ -28,7 +28,7 @@ * @author Robert Field * @library /testlibrary * @modules java.base/jdk.internal.org.objectweb.asm - * java.base/sun.misc + * java.base/jdk.internal.misc * @compile -XDignore.symbol.file InvokeSpecialAnonTest.java * @run main ClassFileInstaller InvokeSpecialAnonTest AnonTester * @run main/othervm -Xbootclasspath/a:. -Xverify:all InvokeSpecialAnonTest diff --git a/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java b/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java index bed5f7c510f..71ce6643bbc 100644 --- a/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java +++ b/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java @@ -26,7 +26,7 @@ * @bug 6583051 * @summary Give error if java.lang.Object has been incompatibly overridden on the bootpath * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main BootstrapRedefine */ diff --git a/hotspot/test/runtime/BootClassAppendProp/BootClassPathAppend.java b/hotspot/test/runtime/BootClassAppendProp/BootClassPathAppend.java index 5dba459c4b7..28371979be0 100644 --- a/hotspot/test/runtime/BootClassAppendProp/BootClassPathAppend.java +++ b/hotspot/test/runtime/BootClassAppendProp/BootClassPathAppend.java @@ -26,7 +26,7 @@ * @bug 8087154 * @summary Uninitialized system property jdk.boot.class.path.append causes SIGSEGV * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc */ import jdk.test.lib.*; diff --git a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java index 6a5a0b18ef6..34a417e54bc 100644 --- a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java +++ b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java @@ -26,7 +26,7 @@ * @bug 8003424 * @summary Testing UseCompressedClassPointers with CDS * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main CDSCompressedKPtrs */ diff --git a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java index 589046c673d..b9242e17e75 100644 --- a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java +++ b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java @@ -26,7 +26,7 @@ * @bug 8003424 * @summary Test that cannot use CDS if UseCompressedClassPointers is turned off. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main CDSCompressedKPtrsError */ diff --git a/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java b/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java index 19163043c14..db3b5f6e173 100644 --- a/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java +++ b/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java @@ -26,7 +26,7 @@ * @bug 8005933 * @summary Test that -Xshare:auto uses CDS when explicitly specified with -server. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main XShareAuto */ diff --git a/hotspot/test/runtime/ClassFile/JsrRewriting.java b/hotspot/test/runtime/ClassFile/JsrRewriting.java index 51cad1ef7d8..4d9a3e6238f 100644 --- a/hotspot/test/runtime/ClassFile/JsrRewriting.java +++ b/hotspot/test/runtime/ClassFile/JsrRewriting.java @@ -34,7 +34,7 @@ * @bug 7149464 * @key cte_test * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.desktop * java.management * @run main JsrRewriting diff --git a/hotspot/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java b/hotspot/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java index 0c565b558dc..9ab684a4b4b 100644 --- a/hotspot/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java +++ b/hotspot/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java @@ -34,7 +34,7 @@ * @bug 7123945 * @bug 8016029 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.desktop * java.management * @run main OomWhileParsingRepeatedJsr diff --git a/hotspot/test/runtime/ClassFile/UnsupportedClassFileVersion.java b/hotspot/test/runtime/ClassFile/UnsupportedClassFileVersion.java index 84be8356779..c3ca4676582 100644 --- a/hotspot/test/runtime/ClassFile/UnsupportedClassFileVersion.java +++ b/hotspot/test/runtime/ClassFile/UnsupportedClassFileVersion.java @@ -25,7 +25,7 @@ * @test * @library /testlibrary * @modules java.base/jdk.internal.org.objectweb.asm - * java.base/sun.misc + * java.base/jdk.internal.misc * java.management * @compile -XDignore.symbol.file UnsupportedClassFileVersion.java * @run main UnsupportedClassFileVersion diff --git a/hotspot/test/runtime/CommandLine/BooleanFlagWithInvalidValue.java b/hotspot/test/runtime/CommandLine/BooleanFlagWithInvalidValue.java index 8994b174ba3..218b014e3ea 100644 --- a/hotspot/test/runtime/CommandLine/BooleanFlagWithInvalidValue.java +++ b/hotspot/test/runtime/CommandLine/BooleanFlagWithInvalidValue.java @@ -26,7 +26,7 @@ * @bug 8006298 * @summary Setting an invalid value for a bool argument should result in a useful error message * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java b/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java index 9d92cf549be..de46967d7e5 100644 --- a/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java +++ b/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java @@ -26,7 +26,7 @@ * @bug 7167142 * @summary Warn if unused .hotspot_compiler file is present * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/CommandLine/ConfigFileParsing.java b/hotspot/test/runtime/CommandLine/ConfigFileParsing.java index ce18610a2a4..870240a1876 100644 --- a/hotspot/test/runtime/CommandLine/ConfigFileParsing.java +++ b/hotspot/test/runtime/CommandLine/ConfigFileParsing.java @@ -26,7 +26,7 @@ * @bug 7158804 * @summary Improve config file parsing * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/CommandLine/ConfigFileWarning.java b/hotspot/test/runtime/CommandLine/ConfigFileWarning.java index 20da6dea9a7..6fcbde3651c 100644 --- a/hotspot/test/runtime/CommandLine/ConfigFileWarning.java +++ b/hotspot/test/runtime/CommandLine/ConfigFileWarning.java @@ -26,7 +26,7 @@ * @bug 7167142 * @summary Warn if unused .hotspot_rc file is present * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/CommandLine/FlagWithInvalidValue.java b/hotspot/test/runtime/CommandLine/FlagWithInvalidValue.java index 7058ff734b2..336ebaf98ef 100644 --- a/hotspot/test/runtime/CommandLine/FlagWithInvalidValue.java +++ b/hotspot/test/runtime/CommandLine/FlagWithInvalidValue.java @@ -26,7 +26,7 @@ * @bug 8006298 * @summary Setting a flag to an invalid value should print a useful error message * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/CommandLine/IgnoreUnrecognizedVMOptions.java b/hotspot/test/runtime/CommandLine/IgnoreUnrecognizedVMOptions.java index 10f68c675f9..20766a2db03 100644 --- a/hotspot/test/runtime/CommandLine/IgnoreUnrecognizedVMOptions.java +++ b/hotspot/test/runtime/CommandLine/IgnoreUnrecognizedVMOptions.java @@ -29,7 +29,7 @@ import jdk.test.lib.*; * @summary -XX:+IgnoreUnrecognizedVMOptions should work according to the spec from JDK-8129855 * * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main IgnoreUnrecognizedVMOptions */ diff --git a/hotspot/test/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java b/hotspot/test/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java index 9f21b95d5ac..1f0ed1539ec 100644 --- a/hotspot/test/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java +++ b/hotspot/test/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java @@ -26,7 +26,7 @@ * @bug 8006298 * @summary Using a bool (+/-) prefix on non-bool flag should result in a useful error message * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/CommandLine/OptionsValidation/TestJcmdOutput.java b/hotspot/test/runtime/CommandLine/OptionsValidation/TestJcmdOutput.java index f03455f26c8..b1ff1eabedf 100644 --- a/hotspot/test/runtime/CommandLine/OptionsValidation/TestJcmdOutput.java +++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestJcmdOutput.java @@ -27,7 +27,7 @@ * value which is not allowed by constraint. Also check that * jcmd does not print an error message to the target process output. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * jdk.management * @run main TestJcmdOutput diff --git a/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java index f9dbbda1698..a67ff42e46c 100644 --- a/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java +++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java @@ -25,7 +25,7 @@ * @test * @summary Test VM Options with ranges * @library /testlibrary /runtime/CommandLine/OptionsValidation/common - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * jdk.attach/sun.tools.attach * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRangesDynamic.java b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRangesDynamic.java index 66c84a20bb4..3c8453c7ab2 100644 --- a/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRangesDynamic.java +++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRangesDynamic.java @@ -25,7 +25,7 @@ * @test * @summary Test writeable VM Options with ranges. * @library /testlibrary /runtime/CommandLine/OptionsValidation/common - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * jdk.attach/sun.tools.attach * java.management * @run main/othervm -XX:MinHeapFreeRatio=0 -XX:MaxHeapFreeRatio=100 TestOptionsWithRangesDynamic diff --git a/hotspot/test/runtime/CommandLine/PrintTouchedMethods.java b/hotspot/test/runtime/CommandLine/PrintTouchedMethods.java index 7bae35ee714..f0661cd7431 100644 --- a/hotspot/test/runtime/CommandLine/PrintTouchedMethods.java +++ b/hotspot/test/runtime/CommandLine/PrintTouchedMethods.java @@ -24,7 +24,7 @@ /* * @test * @bug 8025692 - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @library /testlibrary * @compile TestLogTouchedMethods.java PrintTouchedMethods.java diff --git a/hotspot/test/runtime/CommandLine/TestHexArguments.java b/hotspot/test/runtime/CommandLine/TestHexArguments.java index bf53c045c3e..43f63c8c0f5 100644 --- a/hotspot/test/runtime/CommandLine/TestHexArguments.java +++ b/hotspot/test/runtime/CommandLine/TestHexArguments.java @@ -27,7 +27,7 @@ * @summary Make sure there is no error using hexadecimal format in vm options * @author Yumin Qi * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/CommandLine/TestNullTerminatedFlags.java b/hotspot/test/runtime/CommandLine/TestNullTerminatedFlags.java index 313f0cfc26f..f40f941fedd 100644 --- a/hotspot/test/runtime/CommandLine/TestNullTerminatedFlags.java +++ b/hotspot/test/runtime/CommandLine/TestNullTerminatedFlags.java @@ -28,7 +28,7 @@ import jdk.test.lib.*; * @bug 6522873 * @summary Test that the VM don't allow random junk characters at the end of valid command line flags. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run driver TestNullTerminatedFlags */ diff --git a/hotspot/test/runtime/CommandLine/TestVMOptions.java b/hotspot/test/runtime/CommandLine/TestVMOptions.java index a725fa7704d..f16e744d9f5 100644 --- a/hotspot/test/runtime/CommandLine/TestVMOptions.java +++ b/hotspot/test/runtime/CommandLine/TestVMOptions.java @@ -26,7 +26,7 @@ * @bug 8060256 * @summary Test various command line options * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main TestVMOptions */ diff --git a/hotspot/test/runtime/CommandLine/TraceExceptionsTest.java b/hotspot/test/runtime/CommandLine/TraceExceptionsTest.java index cbfc33f30e3..04f7a57af3c 100644 --- a/hotspot/test/runtime/CommandLine/TraceExceptionsTest.java +++ b/hotspot/test/runtime/CommandLine/TraceExceptionsTest.java @@ -26,7 +26,7 @@ * @bug 8048933 * @summary TraceExceptions output should have the exception message - useful for ClassNotFoundExceptions especially * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/CommandLine/UnrecognizedVMOption.java b/hotspot/test/runtime/CommandLine/UnrecognizedVMOption.java index eb2cf74eb24..62477aaa0b2 100644 --- a/hotspot/test/runtime/CommandLine/UnrecognizedVMOption.java +++ b/hotspot/test/runtime/CommandLine/UnrecognizedVMOption.java @@ -26,7 +26,7 @@ * @bug 8006298 * @summary Using an unrecognized VM option should print the name of the option * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/CommandLine/VMOptionWarning.java b/hotspot/test/runtime/CommandLine/VMOptionWarning.java index 1d81ff18060..08d762de219 100644 --- a/hotspot/test/runtime/CommandLine/VMOptionWarning.java +++ b/hotspot/test/runtime/CommandLine/VMOptionWarning.java @@ -26,7 +26,7 @@ * @bug 8027314 * @summary Warn if diagnostic or experimental vm option is used and -XX:+UnlockDiagnosticVMOptions or -XX:+UnlockExperimentalVMOptions, respectively, isn't specified. Warn if develop or notproduct vm option is used with product version of VM. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java b/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java index 54616e4b176..62a2cc2dd48 100644 --- a/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java +++ b/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java @@ -26,7 +26,7 @@ * @bug 8024927 * @summary Testing address of compressed class pointer space as best as possible. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/CompressedOops/CompressedClassSpaceSize.java b/hotspot/test/runtime/CompressedOops/CompressedClassSpaceSize.java index 5192c3b4c99..d53672091b2 100644 --- a/hotspot/test/runtime/CompressedOops/CompressedClassSpaceSize.java +++ b/hotspot/test/runtime/CompressedOops/CompressedClassSpaceSize.java @@ -26,7 +26,7 @@ * @bug 8022865 * @summary Tests for the -XX:CompressedClassSpaceSize command line option * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main CompressedClassSpaceSize */ diff --git a/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java b/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java index 04805db9658..2ff8b27f87f 100644 --- a/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java +++ b/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java @@ -27,7 +27,7 @@ * @key regression * @summary NPG: UseCompressedClassPointers asserts with ObjectAlignmentInBytes=32 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/CompressedOops/ObjectAlignment.java b/hotspot/test/runtime/CompressedOops/ObjectAlignment.java index 80644202f77..00cc071a497 100644 --- a/hotspot/test/runtime/CompressedOops/ObjectAlignment.java +++ b/hotspot/test/runtime/CompressedOops/ObjectAlignment.java @@ -26,7 +26,7 @@ * @bug 8022865 * @summary Tests for the -XX:ObjectAlignmentInBytes command line option * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main ObjectAlignment */ diff --git a/hotspot/test/runtime/CompressedOops/UseCompressedOops.java b/hotspot/test/runtime/CompressedOops/UseCompressedOops.java index ac60e764e75..b0aa61ce105 100644 --- a/hotspot/test/runtime/CompressedOops/UseCompressedOops.java +++ b/hotspot/test/runtime/CompressedOops/UseCompressedOops.java @@ -27,7 +27,7 @@ * @summary Tests for different combination of UseCompressedOops options * @library /testlibrary * @ignore 8079353 - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main UseCompressedOops */ diff --git a/hotspot/test/runtime/EnclosingMethodAttr/EnclMethodAttr.java b/hotspot/test/runtime/EnclosingMethodAttr/EnclMethodAttr.java index 47dc26f70d7..ccd0bd420d7 100644 --- a/hotspot/test/runtime/EnclosingMethodAttr/EnclMethodAttr.java +++ b/hotspot/test/runtime/EnclosingMethodAttr/EnclMethodAttr.java @@ -26,7 +26,7 @@ * @bug 8044738 * @library /testlibrary * @summary Check attribute_length of EnclosingMethod attribute - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main EnclMethodAttr */ diff --git a/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java b/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java index d6ce8380a32..299444ffba3 100644 --- a/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java +++ b/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java b/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java index 56ae291bc7c..85a0749bd7a 100644 --- a/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java +++ b/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java @@ -26,7 +26,7 @@ * @bug 8050167 * @summary Test that error is not occurred during printing problematic frame * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/runtime/ErrorHandling/SecondaryErrorTest.java b/hotspot/test/runtime/ErrorHandling/SecondaryErrorTest.java index 37fac08130c..d82274ab3f2 100644 --- a/hotspot/test/runtime/ErrorHandling/SecondaryErrorTest.java +++ b/hotspot/test/runtime/ErrorHandling/SecondaryErrorTest.java @@ -28,7 +28,7 @@ * @summary Synchronous signals during error reporting may terminate or hang VM process * @library /testlibrary * @author Thomas Stuefe (SAP) - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/LoadClass/LoadClassNegative.java b/hotspot/test/runtime/LoadClass/LoadClassNegative.java index 7cf729779ab..08bd4dad6b5 100644 --- a/hotspot/test/runtime/LoadClass/LoadClassNegative.java +++ b/hotspot/test/runtime/LoadClass/LoadClassNegative.java @@ -27,7 +27,7 @@ * @bug 8020675 * @summary make sure there is no fatal error if a class is loaded from an invalid jar file which is in the bootclasspath * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestForName * @build LoadClassNegative diff --git a/hotspot/test/runtime/LocalVariableTable/TestLVT.java b/hotspot/test/runtime/LocalVariableTable/TestLVT.java index e704f63b2ac..42ad0b777c7 100644 --- a/hotspot/test/runtime/LocalVariableTable/TestLVT.java +++ b/hotspot/test/runtime/LocalVariableTable/TestLVT.java @@ -26,7 +26,7 @@ * @bug 8049632 * @summary Test ClassFileParser::copy_localvariable_table cases * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile -g -XDignore.symbol.file TestLVT.java * @run main TestLVT diff --git a/hotspot/test/runtime/NMT/AutoshutdownNMT.java b/hotspot/test/runtime/NMT/AutoshutdownNMT.java index c7bba5e63da..90a02ff2bd3 100644 --- a/hotspot/test/runtime/NMT/AutoshutdownNMT.java +++ b/hotspot/test/runtime/NMT/AutoshutdownNMT.java @@ -26,7 +26,7 @@ * @key nmt * @summary Test for deprecated message if -XX:-AutoShutdownNMT is specified * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/NMT/BaselineWithParameter.java b/hotspot/test/runtime/NMT/BaselineWithParameter.java index dcb8f82adb6..38d31ffcfee 100644 --- a/hotspot/test/runtime/NMT/BaselineWithParameter.java +++ b/hotspot/test/runtime/NMT/BaselineWithParameter.java @@ -27,7 +27,7 @@ * @key nmt jcmd regression * @summary Regression test for invoking a jcmd with baseline=false, result was that the target VM crashed * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm -XX:NativeMemoryTracking=detail BaselineWithParameter */ diff --git a/hotspot/test/runtime/NMT/CommandLineDetail.java b/hotspot/test/runtime/NMT/CommandLineDetail.java index 4464a23d63c..70d914a53b2 100644 --- a/hotspot/test/runtime/NMT/CommandLineDetail.java +++ b/hotspot/test/runtime/NMT/CommandLineDetail.java @@ -26,7 +26,7 @@ * @key nmt * @summary Running with NMT detail should not result in an error * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/NMT/CommandLineEmptyArgument.java b/hotspot/test/runtime/NMT/CommandLineEmptyArgument.java index 7b4407c6da5..510c0024f29 100644 --- a/hotspot/test/runtime/NMT/CommandLineEmptyArgument.java +++ b/hotspot/test/runtime/NMT/CommandLineEmptyArgument.java @@ -26,7 +26,7 @@ * @key nmt * @summary Empty argument to NMT should result in an informative error message * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/NMT/CommandLineInvalidArgument.java b/hotspot/test/runtime/NMT/CommandLineInvalidArgument.java index f5b30d6ee39..985e8e49dd1 100644 --- a/hotspot/test/runtime/NMT/CommandLineInvalidArgument.java +++ b/hotspot/test/runtime/NMT/CommandLineInvalidArgument.java @@ -26,7 +26,7 @@ * @key nmt * @summary Invalid argument to NMT should result in an informative error message * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/NMT/CommandLineSummary.java b/hotspot/test/runtime/NMT/CommandLineSummary.java index 8e60777b25d..67198395657 100644 --- a/hotspot/test/runtime/NMT/CommandLineSummary.java +++ b/hotspot/test/runtime/NMT/CommandLineSummary.java @@ -26,7 +26,7 @@ * @key nmt * @summary Running with NMT summary should not result in an error * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/NMT/CommandLineTurnOffNMT.java b/hotspot/test/runtime/NMT/CommandLineTurnOffNMT.java index 024ae32ae55..33893080957 100644 --- a/hotspot/test/runtime/NMT/CommandLineTurnOffNMT.java +++ b/hotspot/test/runtime/NMT/CommandLineTurnOffNMT.java @@ -26,7 +26,7 @@ * @key nmt * @summary Turning off NMT should not result in an error * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/NMT/JcmdBaselineDetail.java b/hotspot/test/runtime/NMT/JcmdBaselineDetail.java index a8117975e84..ce99b202742 100644 --- a/hotspot/test/runtime/NMT/JcmdBaselineDetail.java +++ b/hotspot/test/runtime/NMT/JcmdBaselineDetail.java @@ -26,7 +26,7 @@ * @key nmt jcmd * @summary Verify that jcmd correctly reports that baseline succeeds with NMT enabled with detailed tracking. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm -XX:NativeMemoryTracking=detail JcmdBaselineDetail */ diff --git a/hotspot/test/runtime/NMT/JcmdDetailDiff.java b/hotspot/test/runtime/NMT/JcmdDetailDiff.java index 4baeeb31e06..694d47edb66 100644 --- a/hotspot/test/runtime/NMT/JcmdDetailDiff.java +++ b/hotspot/test/runtime/NMT/JcmdDetailDiff.java @@ -26,7 +26,7 @@ * @summary run NMT baseline, allocate memory and verify output from detail.diff * @key nmt jcmd * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build JcmdDetailDiff * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/NMT/JcmdScale.java b/hotspot/test/runtime/NMT/JcmdScale.java index c3d10085760..13cb50abd22 100644 --- a/hotspot/test/runtime/NMT/JcmdScale.java +++ b/hotspot/test/runtime/NMT/JcmdScale.java @@ -26,7 +26,7 @@ * @key nmt jcmd * @summary Test the NMT scale parameter * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm -XX:NativeMemoryTracking=summary JcmdScale */ diff --git a/hotspot/test/runtime/NMT/JcmdScaleDetail.java b/hotspot/test/runtime/NMT/JcmdScaleDetail.java index 4f19f116897..0379e234dce 100644 --- a/hotspot/test/runtime/NMT/JcmdScaleDetail.java +++ b/hotspot/test/runtime/NMT/JcmdScaleDetail.java @@ -26,7 +26,7 @@ * @key nmt jcmd * @summary Test the NMT scale parameter with detail tracking level * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm -XX:NativeMemoryTracking=detail JcmdScaleDetail */ diff --git a/hotspot/test/runtime/NMT/JcmdSummaryDiff.java b/hotspot/test/runtime/NMT/JcmdSummaryDiff.java index f74b523c838..a53d75f999a 100644 --- a/hotspot/test/runtime/NMT/JcmdSummaryDiff.java +++ b/hotspot/test/runtime/NMT/JcmdSummaryDiff.java @@ -26,7 +26,7 @@ * @summary run NMT baseline, allocate memory and verify output from summary.diff * @key nmt jcmd * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build JcmdSummaryDiff * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/NMT/JcmdWithNMTDisabled.java b/hotspot/test/runtime/NMT/JcmdWithNMTDisabled.java index e479891cee7..b9c506be5d1 100644 --- a/hotspot/test/runtime/NMT/JcmdWithNMTDisabled.java +++ b/hotspot/test/runtime/NMT/JcmdWithNMTDisabled.java @@ -26,7 +26,7 @@ * @key nmt jcmd * @summary Verify that jcmd correctly reports that NMT is not enabled * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main JcmdWithNMTDisabled 1 */ diff --git a/hotspot/test/runtime/NMT/MallocRoundingReportTest.java b/hotspot/test/runtime/NMT/MallocRoundingReportTest.java index 2e9a9de68e8..b823679c486 100644 --- a/hotspot/test/runtime/NMT/MallocRoundingReportTest.java +++ b/hotspot/test/runtime/NMT/MallocRoundingReportTest.java @@ -26,7 +26,7 @@ * @summary Test consistency of NMT by creating allocations of the Test type with various sizes and verifying visibility with jcmd * @key nmt jcmd * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build MallocRoundingReportTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/NMT/MallocStressTest.java b/hotspot/test/runtime/NMT/MallocStressTest.java index a798f71f9f4..af7f97f5d1f 100644 --- a/hotspot/test/runtime/NMT/MallocStressTest.java +++ b/hotspot/test/runtime/NMT/MallocStressTest.java @@ -26,7 +26,7 @@ * @summary Stress test for malloc tracking * @key nmt jcmd stress * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build MallocStressTest * @ignore - This test is disabled since it will stress NMT and timeout during normal testing diff --git a/hotspot/test/runtime/NMT/MallocTestType.java b/hotspot/test/runtime/NMT/MallocTestType.java index 4cc00ac1813..abd04a799e4 100644 --- a/hotspot/test/runtime/NMT/MallocTestType.java +++ b/hotspot/test/runtime/NMT/MallocTestType.java @@ -26,7 +26,7 @@ * @summary Test consistency of NMT by leaking a few select allocations of the Test type and then verify visibility with jcmd * @key nmt jcmd * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build MallocTestType * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/NMT/MallocTrackingVerify.java b/hotspot/test/runtime/NMT/MallocTrackingVerify.java index 8cbc497c1d6..cefbcd9a012 100644 --- a/hotspot/test/runtime/NMT/MallocTrackingVerify.java +++ b/hotspot/test/runtime/NMT/MallocTrackingVerify.java @@ -27,7 +27,7 @@ * @summary Test to verify correctness of malloc tracking * @key nmt jcmd * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build MallocTrackingVerify * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/NMT/NMTWithCDS.java b/hotspot/test/runtime/NMT/NMTWithCDS.java index 628c596da54..a4a409a0dd5 100644 --- a/hotspot/test/runtime/NMT/NMTWithCDS.java +++ b/hotspot/test/runtime/NMT/NMTWithCDS.java @@ -26,7 +26,7 @@ * @bug 8055061 * @key nmt * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main NMTWithCDS */ diff --git a/hotspot/test/runtime/NMT/PrintNMTStatisticsWithNMTDisabled.java b/hotspot/test/runtime/NMT/PrintNMTStatisticsWithNMTDisabled.java index 9f06a5437a4..311d834bb4c 100644 --- a/hotspot/test/runtime/NMT/PrintNMTStatisticsWithNMTDisabled.java +++ b/hotspot/test/runtime/NMT/PrintNMTStatisticsWithNMTDisabled.java @@ -26,7 +26,7 @@ * @key nmt * @summary Trying to enable PrintNMTStatistics should result in a warning * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/NMT/ReleaseNoCommit.java b/hotspot/test/runtime/NMT/ReleaseNoCommit.java index a16d3ecdc66..7499d608c13 100644 --- a/hotspot/test/runtime/NMT/ReleaseNoCommit.java +++ b/hotspot/test/runtime/NMT/ReleaseNoCommit.java @@ -26,7 +26,7 @@ * @summary Release uncommitted memory and make sure NMT handles it correctly * @key nmt regression * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build ReleaseNoCommit * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/NMT/ShutdownTwice.java b/hotspot/test/runtime/NMT/ShutdownTwice.java index 8e6cdfc6b96..1d354168fe7 100644 --- a/hotspot/test/runtime/NMT/ShutdownTwice.java +++ b/hotspot/test/runtime/NMT/ShutdownTwice.java @@ -26,7 +26,7 @@ * @key nmt jcmd * @summary Run shutdown twice * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm -XX:NativeMemoryTracking=detail ShutdownTwice */ diff --git a/hotspot/test/runtime/NMT/SummaryAfterShutdown.java b/hotspot/test/runtime/NMT/SummaryAfterShutdown.java index 3d54c43b225..66921152b76 100644 --- a/hotspot/test/runtime/NMT/SummaryAfterShutdown.java +++ b/hotspot/test/runtime/NMT/SummaryAfterShutdown.java @@ -26,7 +26,7 @@ * @key nmt jcmd * @summary Verify that jcmd correctly reports that NMT is not enabled after a shutdown * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm -XX:NativeMemoryTracking=detail SummaryAfterShutdown */ diff --git a/hotspot/test/runtime/NMT/SummarySanityCheck.java b/hotspot/test/runtime/NMT/SummarySanityCheck.java index b21ae9d7032..d322fa649a3 100644 --- a/hotspot/test/runtime/NMT/SummarySanityCheck.java +++ b/hotspot/test/runtime/NMT/SummarySanityCheck.java @@ -26,7 +26,7 @@ * @key nmt jcmd * @summary Sanity check the output of NMT * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build SummarySanityCheck * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/NMT/ThreadedMallocTestType.java b/hotspot/test/runtime/NMT/ThreadedMallocTestType.java index 53d1b5513a9..a0e29fca618 100644 --- a/hotspot/test/runtime/NMT/ThreadedMallocTestType.java +++ b/hotspot/test/runtime/NMT/ThreadedMallocTestType.java @@ -25,7 +25,7 @@ * @test * @key nmt jcmd * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build ThreadedMallocTestType * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/NMT/ThreadedVirtualAllocTestType.java b/hotspot/test/runtime/NMT/ThreadedVirtualAllocTestType.java index c28df0a4eec..8ba7e7c53cd 100644 --- a/hotspot/test/runtime/NMT/ThreadedVirtualAllocTestType.java +++ b/hotspot/test/runtime/NMT/ThreadedVirtualAllocTestType.java @@ -25,7 +25,7 @@ * @test * @key nmt jcmd * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build ThreadedVirtualAllocTestType * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/NMT/VirtualAllocCommitUncommitRecommit.java b/hotspot/test/runtime/NMT/VirtualAllocCommitUncommitRecommit.java index 4c71c11f396..fbc5fe9032b 100644 --- a/hotspot/test/runtime/NMT/VirtualAllocCommitUncommitRecommit.java +++ b/hotspot/test/runtime/NMT/VirtualAllocCommitUncommitRecommit.java @@ -26,7 +26,7 @@ * @summary Test reserve/commit/uncommit/release of virtual memory and that we track it correctly * @key nmt jcmd * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build VirtualAllocCommitUncommitRecommit * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/NMT/VirtualAllocTestType.java b/hotspot/test/runtime/NMT/VirtualAllocTestType.java index 02a7923af66..b8bd3be77a6 100644 --- a/hotspot/test/runtime/NMT/VirtualAllocTestType.java +++ b/hotspot/test/runtime/NMT/VirtualAllocTestType.java @@ -26,7 +26,7 @@ * @summary Test Reserve/Commit/Uncommit/Release of virtual memory and that we track it correctly * @key nmt jcmd * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build VirtualAllocTestType * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/PerfMemDestroy/PerfMemDestroy.java b/hotspot/test/runtime/PerfMemDestroy/PerfMemDestroy.java index a43da341404..512dbc9914e 100644 --- a/hotspot/test/runtime/PerfMemDestroy/PerfMemDestroy.java +++ b/hotspot/test/runtime/PerfMemDestroy/PerfMemDestroy.java @@ -26,7 +26,7 @@ * @bug 8030955 * @summary Allow multiple calls to PerfMemory::destroy() without asserting. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main PerfMemDestroy */ diff --git a/hotspot/test/runtime/RedefineObject/TestRedefineObject.java b/hotspot/test/runtime/RedefineObject/TestRedefineObject.java index c06583f112e..9ebee649217 100644 --- a/hotspot/test/runtime/RedefineObject/TestRedefineObject.java +++ b/hotspot/test/runtime/RedefineObject/TestRedefineObject.java @@ -33,7 +33,7 @@ import jdk.test.lib.*; * @bug 8005056 * @bug 8009728 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.instrument * java.management * @build Agent diff --git a/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency1.java b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency1.java index 947f36ee8a6..c05da6b0476 100644 --- a/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency1.java +++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency1.java @@ -26,7 +26,7 @@ * @bug 8047290 * @summary Ensure that a Monitor::lock_without_safepoint_check fires an assert when it incorrectly acquires a lock which must always have safepoint checks. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build AssertSafepointCheckConsistency1 * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency2.java b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency2.java index 6e24d0d17a1..8fc54bd36cb 100644 --- a/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency2.java +++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency2.java @@ -26,7 +26,7 @@ * @bug 8047290 * @summary Ensure that a Monitor::lock fires an assert when it incorrectly acquires a lock which must never have safepoint checks. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build AssertSafepointCheckConsistency2 * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency3.java b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency3.java index c1395e0519a..f8bf4973910 100644 --- a/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency3.java +++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency3.java @@ -26,7 +26,7 @@ * @bug 8047290 * @summary Ensure that Monitor::lock_without_safepoint_check does not assert when it correctly acquires a lock which must never have safepoint checks. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build AssertSafepointCheckConsistency3 * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency4.java b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency4.java index 5d5449a28ac..383174e0514 100644 --- a/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency4.java +++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency4.java @@ -26,7 +26,7 @@ * @bug 8047290 * @summary Ensure that Monitor::lock does not assert when it correctly acquires a lock which must always have safepoint checks. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build AssertSafepointCheckConsistency4 * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/SharedArchiveFile/ArchiveDoesNotExist.java b/hotspot/test/runtime/SharedArchiveFile/ArchiveDoesNotExist.java index 076248409a7..009f8f4147a 100644 --- a/hotspot/test/runtime/SharedArchiveFile/ArchiveDoesNotExist.java +++ b/hotspot/test/runtime/SharedArchiveFile/ArchiveDoesNotExist.java @@ -28,7 +28,7 @@ * when sharing mode is ON, and continue w/o sharing if sharing * mode is AUTO. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main ArchiveDoesNotExist */ diff --git a/hotspot/test/runtime/SharedArchiveFile/CdsDifferentCompactStrings.java b/hotspot/test/runtime/SharedArchiveFile/CdsDifferentCompactStrings.java index 3f8669241c0..90422d294ab 100644 --- a/hotspot/test/runtime/SharedArchiveFile/CdsDifferentCompactStrings.java +++ b/hotspot/test/runtime/SharedArchiveFile/CdsDifferentCompactStrings.java @@ -26,7 +26,7 @@ * @summary CDS (class data sharing) requires the same -XX:[+-]CompactStrings * setting between archive creation time and load time. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java b/hotspot/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java index 082e607a50d..7be3968b28a 100644 --- a/hotspot/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java +++ b/hotspot/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java @@ -30,7 +30,7 @@ * should fail when loading. * @library /testlibrary * @bug 8025642 - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java b/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java index 6ec1c9279c2..6dc33f90ceb 100644 --- a/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java +++ b/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java @@ -26,7 +26,7 @@ * @summary Testing CDS (class data sharing) using varying object alignment. * Using same object alignment for each dump/load pair * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/SharedArchiveFile/DefaultUseWithClient.java b/hotspot/test/runtime/SharedArchiveFile/DefaultUseWithClient.java index cdd6f0535ec..050b0ff6f27 100644 --- a/hotspot/test/runtime/SharedArchiveFile/DefaultUseWithClient.java +++ b/hotspot/test/runtime/SharedArchiveFile/DefaultUseWithClient.java @@ -25,7 +25,7 @@ * @test DefaultUseWithClient * @summary Test default behavior of sharing with -client * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main DefaultUseWithClient * @bug 8032224 diff --git a/hotspot/test/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java b/hotspot/test/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java index c7f9813a439..1d30fd6b963 100644 --- a/hotspot/test/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java +++ b/hotspot/test/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java @@ -26,7 +26,7 @@ * @bug 8059510 * @summary Test jcmd VM.symboltable and VM.stringtable options * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm -XX:+UnlockDiagnosticVMOptions DumpSymbolAndStringTable */ diff --git a/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java b/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java index c774111f210..32dfb2a2445 100644 --- a/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java +++ b/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java @@ -24,7 +24,7 @@ /* @test LimitSharedSizes * @summary Test handling of limits on shared space size * @library /testlibrary /runtime/CommandLine/OptionsValidation/common - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * jdk.attach/sun.tools.attach * @run main LimitSharedSizes diff --git a/hotspot/test/runtime/SharedArchiveFile/MaxMetaspaceSize.java b/hotspot/test/runtime/SharedArchiveFile/MaxMetaspaceSize.java index d44d50396bc..7de1521cc07 100644 --- a/hotspot/test/runtime/SharedArchiveFile/MaxMetaspaceSize.java +++ b/hotspot/test/runtime/SharedArchiveFile/MaxMetaspaceSize.java @@ -26,7 +26,7 @@ * @bug 8067187 * @summary Testing CDS dumping with the -XX:MaxMetaspaceSize= option * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/SharedArchiveFile/PrintSharedArchiveAndExit.java b/hotspot/test/runtime/SharedArchiveFile/PrintSharedArchiveAndExit.java index 45f74515339..24bea75ea6f 100644 --- a/hotspot/test/runtime/SharedArchiveFile/PrintSharedArchiveAndExit.java +++ b/hotspot/test/runtime/SharedArchiveFile/PrintSharedArchiveAndExit.java @@ -26,7 +26,7 @@ * @bug 8066670 * @summary Testing -XX:+PrintSharedArchiveAndExit option * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/SharedArchiveFile/SharedArchiveFile.java b/hotspot/test/runtime/SharedArchiveFile/SharedArchiveFile.java index 901f38debe4..2b1f03392e3 100644 --- a/hotspot/test/runtime/SharedArchiveFile/SharedArchiveFile.java +++ b/hotspot/test/runtime/SharedArchiveFile/SharedArchiveFile.java @@ -26,7 +26,7 @@ * @bug 8014138 * @summary Testing new -XX:SharedArchiveFile= option * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/SharedArchiveFile/SharedBaseAddress.java b/hotspot/test/runtime/SharedArchiveFile/SharedBaseAddress.java index 8386a55ca98..e5fee961c0f 100644 --- a/hotspot/test/runtime/SharedArchiveFile/SharedBaseAddress.java +++ b/hotspot/test/runtime/SharedArchiveFile/SharedBaseAddress.java @@ -26,7 +26,7 @@ * @summary Test variety of values for SharedBaseAddress, making sure * VM handles normal values as well as edge values w/o a crash. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main SharedBaseAddress */ diff --git a/hotspot/test/runtime/SharedArchiveFile/SharedStrings.java b/hotspot/test/runtime/SharedArchiveFile/SharedStrings.java index 67059bf5715..96036ec3629 100644 --- a/hotspot/test/runtime/SharedArchiveFile/SharedStrings.java +++ b/hotspot/test/runtime/SharedArchiveFile/SharedStrings.java @@ -30,7 +30,7 @@ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true) * @requires (vm.gc=="G1" | vm.gc=="null") * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * jdk.jartool/sun.tools.jar * @build SharedStringsWb SharedStrings BasicJarBuilder sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/SharedArchiveFile/SharedStringsRunAuto.java b/hotspot/test/runtime/SharedArchiveFile/SharedStringsRunAuto.java index 6df71d57bba..1f90fd02931 100644 --- a/hotspot/test/runtime/SharedArchiveFile/SharedStringsRunAuto.java +++ b/hotspot/test/runtime/SharedArchiveFile/SharedStringsRunAuto.java @@ -29,7 +29,7 @@ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true) * @requires (vm.gc=="G1" | vm.gc=="null") * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main SharedStringsRunAuto */ diff --git a/hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java b/hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java index 3ba63062f0c..e99f218ec86 100644 --- a/hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java +++ b/hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java @@ -26,7 +26,7 @@ * @bug 8059510 * @summary Test SharedSymbolTableBucketSize option * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/SharedArchiveFile/SpaceUtilizationCheck.java b/hotspot/test/runtime/SharedArchiveFile/SpaceUtilizationCheck.java index 3d493e60bf6..665a3aeef94 100644 --- a/hotspot/test/runtime/SharedArchiveFile/SpaceUtilizationCheck.java +++ b/hotspot/test/runtime/SharedArchiveFile/SpaceUtilizationCheck.java @@ -25,7 +25,7 @@ * @test SpaceUtilizationCheck * @summary Check if the space utilization for shared spaces is adequate * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main SpaceUtilizationCheck */ diff --git a/hotspot/test/runtime/Thread/TestThreadDumpMonitorContention.java b/hotspot/test/runtime/Thread/TestThreadDumpMonitorContention.java index 21f08b2138b..36f351da560 100644 --- a/hotspot/test/runtime/Thread/TestThreadDumpMonitorContention.java +++ b/hotspot/test/runtime/Thread/TestThreadDumpMonitorContention.java @@ -29,7 +29,7 @@ * whether jstack reports "locked" by more than one thread. * * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm TestThreadDumpMonitorContention */ diff --git a/hotspot/test/runtime/Thread/ThreadPriorities.java b/hotspot/test/runtime/Thread/ThreadPriorities.java index 99f41d19407..a03d5d4a199 100644 --- a/hotspot/test/runtime/Thread/ThreadPriorities.java +++ b/hotspot/test/runtime/Thread/ThreadPriorities.java @@ -28,7 +28,7 @@ * whether jstack reports correct priorities for them. * * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main ThreadPriorities */ diff --git a/hotspot/test/runtime/Unsafe/AllocateInstance.java b/hotspot/test/runtime/Unsafe/AllocateInstance.java index 4393a081de4..e9748e539db 100644 --- a/hotspot/test/runtime/Unsafe/AllocateInstance.java +++ b/hotspot/test/runtime/Unsafe/AllocateInstance.java @@ -25,7 +25,7 @@ * @test * @summary Verifies the behaviour of Unsafe.allocateInstance * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main AllocateInstance */ diff --git a/hotspot/test/runtime/Unsafe/AllocateMemory.java b/hotspot/test/runtime/Unsafe/AllocateMemory.java index 0bc26727b51..0af6fcbf014 100644 --- a/hotspot/test/runtime/Unsafe/AllocateMemory.java +++ b/hotspot/test/runtime/Unsafe/AllocateMemory.java @@ -26,7 +26,7 @@ * @requires vm.compMode != "Xcomp" * @summary Verifies behaviour of Unsafe.allocateMemory * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=100m AllocateMemory */ diff --git a/hotspot/test/runtime/Unsafe/CopyMemory.java b/hotspot/test/runtime/Unsafe/CopyMemory.java index b70528206fb..ef67517c2a2 100644 --- a/hotspot/test/runtime/Unsafe/CopyMemory.java +++ b/hotspot/test/runtime/Unsafe/CopyMemory.java @@ -25,7 +25,7 @@ * @test * @summary Verifies behaviour of Unsafe.copyMemory * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main CopyMemory */ diff --git a/hotspot/test/runtime/Unsafe/DefineClass.java b/hotspot/test/runtime/Unsafe/DefineClass.java index 87858fb4d2b..bf10a393d0e 100644 --- a/hotspot/test/runtime/Unsafe/DefineClass.java +++ b/hotspot/test/runtime/Unsafe/DefineClass.java @@ -25,7 +25,7 @@ * @test * @summary Verifies the behaviour of Unsafe.defineClass * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * @run main DefineClass diff --git a/hotspot/test/runtime/Unsafe/FieldOffset.java b/hotspot/test/runtime/Unsafe/FieldOffset.java index e96bd7f1313..6bbd785019b 100644 --- a/hotspot/test/runtime/Unsafe/FieldOffset.java +++ b/hotspot/test/runtime/Unsafe/FieldOffset.java @@ -25,7 +25,7 @@ * @test * @summary Verifies the behaviour of Unsafe.fieldOffset * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main FieldOffset */ diff --git a/hotspot/test/runtime/Unsafe/GetField.java b/hotspot/test/runtime/Unsafe/GetField.java index f9b5677756a..48e71b58b02 100644 --- a/hotspot/test/runtime/Unsafe/GetField.java +++ b/hotspot/test/runtime/Unsafe/GetField.java @@ -25,7 +25,7 @@ * @test * @summary Verifies behaviour of Unsafe.getField * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main GetField */ diff --git a/hotspot/test/runtime/Unsafe/GetKlassPointerGetJavaMirror.java b/hotspot/test/runtime/Unsafe/GetKlassPointerGetJavaMirror.java index 9f7071628ed..f1fc7d52331 100644 --- a/hotspot/test/runtime/Unsafe/GetKlassPointerGetJavaMirror.java +++ b/hotspot/test/runtime/Unsafe/GetKlassPointerGetJavaMirror.java @@ -24,7 +24,7 @@ /* @test * @bug 8022853 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @build jdk.test.lib.* * @run main GetKlassPointerGetJavaMirror */ diff --git a/hotspot/test/runtime/Unsafe/GetPutAddress.java b/hotspot/test/runtime/Unsafe/GetPutAddress.java index 17d270c02f8..9650d040c72 100644 --- a/hotspot/test/runtime/Unsafe/GetPutAddress.java +++ b/hotspot/test/runtime/Unsafe/GetPutAddress.java @@ -25,7 +25,7 @@ * @test * Verify behaviour of Unsafe.get/putAddress and Unsafe.addressSize * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main GetPutAddress */ diff --git a/hotspot/test/runtime/Unsafe/GetPutBoolean.java b/hotspot/test/runtime/Unsafe/GetPutBoolean.java index e5c89922bca..eddbc6c23ac 100644 --- a/hotspot/test/runtime/Unsafe/GetPutBoolean.java +++ b/hotspot/test/runtime/Unsafe/GetPutBoolean.java @@ -25,7 +25,7 @@ * @test * @summary Verify behaviour of Unsafe.get/putBoolean * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main GetPutBoolean */ diff --git a/hotspot/test/runtime/Unsafe/GetPutByte.java b/hotspot/test/runtime/Unsafe/GetPutByte.java index 73f365bec6d..ec08dd2ad85 100644 --- a/hotspot/test/runtime/Unsafe/GetPutByte.java +++ b/hotspot/test/runtime/Unsafe/GetPutByte.java @@ -25,7 +25,7 @@ * @test * @summary Verify behaviour of Unsafe.get/putByte * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main GetPutByte */ diff --git a/hotspot/test/runtime/Unsafe/GetPutChar.java b/hotspot/test/runtime/Unsafe/GetPutChar.java index 9bf911685c5..79e94f0a6de 100644 --- a/hotspot/test/runtime/Unsafe/GetPutChar.java +++ b/hotspot/test/runtime/Unsafe/GetPutChar.java @@ -25,7 +25,7 @@ * @test * @summary Verify behaviour of Unsafe.get/putChar * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main GetPutChar */ diff --git a/hotspot/test/runtime/Unsafe/GetPutDouble.java b/hotspot/test/runtime/Unsafe/GetPutDouble.java index 5518d26ed3e..b1d7431e3b1 100644 --- a/hotspot/test/runtime/Unsafe/GetPutDouble.java +++ b/hotspot/test/runtime/Unsafe/GetPutDouble.java @@ -25,7 +25,7 @@ * @test * @summary Verify behaviour of Unsafe.get/putDouble * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main GetPutDouble */ diff --git a/hotspot/test/runtime/Unsafe/GetPutFloat.java b/hotspot/test/runtime/Unsafe/GetPutFloat.java index 47770d7d8d5..16de792dac6 100644 --- a/hotspot/test/runtime/Unsafe/GetPutFloat.java +++ b/hotspot/test/runtime/Unsafe/GetPutFloat.java @@ -25,7 +25,7 @@ * @test * @summary Verify behaviour of Unsafe.get/putFloat * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main GetPutFloat */ diff --git a/hotspot/test/runtime/Unsafe/GetPutInt.java b/hotspot/test/runtime/Unsafe/GetPutInt.java index 048865ad5bc..0a4403668aa 100644 --- a/hotspot/test/runtime/Unsafe/GetPutInt.java +++ b/hotspot/test/runtime/Unsafe/GetPutInt.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main GetPutInt */ diff --git a/hotspot/test/runtime/Unsafe/GetPutLong.java b/hotspot/test/runtime/Unsafe/GetPutLong.java index fb020bb4af3..2c524e2e516 100644 --- a/hotspot/test/runtime/Unsafe/GetPutLong.java +++ b/hotspot/test/runtime/Unsafe/GetPutLong.java @@ -25,7 +25,7 @@ * @test * @summary Verify behaviour of Unsafe.get/putLong * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main GetPutLong */ diff --git a/hotspot/test/runtime/Unsafe/GetPutObject.java b/hotspot/test/runtime/Unsafe/GetPutObject.java index fc725b1c9d4..e4add8f9e76 100644 --- a/hotspot/test/runtime/Unsafe/GetPutObject.java +++ b/hotspot/test/runtime/Unsafe/GetPutObject.java @@ -25,7 +25,7 @@ * @test * @summary Verify behaviour of Unsafe.get/putObject * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main GetPutObject */ diff --git a/hotspot/test/runtime/Unsafe/GetPutShort.java b/hotspot/test/runtime/Unsafe/GetPutShort.java index 63a94451c09..f7b94fb0e54 100644 --- a/hotspot/test/runtime/Unsafe/GetPutShort.java +++ b/hotspot/test/runtime/Unsafe/GetPutShort.java @@ -25,7 +25,7 @@ * @test * @summary Verify behaviour of Unsafe.get/putShort * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main GetPutShort */ diff --git a/hotspot/test/runtime/Unsafe/GetUncompressedObject.java b/hotspot/test/runtime/Unsafe/GetUncompressedObject.java index 215a3646fcf..9673c75aea9 100644 --- a/hotspot/test/runtime/Unsafe/GetUncompressedObject.java +++ b/hotspot/test/runtime/Unsafe/GetUncompressedObject.java @@ -24,7 +24,7 @@ /* @test * @bug 8022853 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @build jdk.test.lib.* * @run main GetUncompressedObject */ diff --git a/hotspot/test/runtime/Unsafe/GetUnsafe.java b/hotspot/test/runtime/Unsafe/GetUnsafe.java index 796291c2ae3..8cb95f54eae 100644 --- a/hotspot/test/runtime/Unsafe/GetUnsafe.java +++ b/hotspot/test/runtime/Unsafe/GetUnsafe.java @@ -25,7 +25,7 @@ * @test * @summary Verifies that getUnsafe() actually throws SecurityException when unsafeAccess is prohibited. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @run main GetUnsafe */ diff --git a/hotspot/test/runtime/Unsafe/PageSize.java b/hotspot/test/runtime/Unsafe/PageSize.java index 771f5e5f5a4..6b29f6dcca5 100644 --- a/hotspot/test/runtime/Unsafe/PageSize.java +++ b/hotspot/test/runtime/Unsafe/PageSize.java @@ -25,7 +25,7 @@ * @test * @summary Make sure pageSize() returns a value that is a power of two * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main PageSize */ diff --git a/hotspot/test/runtime/Unsafe/RangeCheck.java b/hotspot/test/runtime/Unsafe/RangeCheck.java index 778b9017196..ecd413c3bc4 100644 --- a/hotspot/test/runtime/Unsafe/RangeCheck.java +++ b/hotspot/test/runtime/Unsafe/RangeCheck.java @@ -26,7 +26,7 @@ * @bug 8001071 * @summary Add simple range check into VM implemenation of Unsafe access methods * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/runtime/Unsafe/Reallocate.java b/hotspot/test/runtime/Unsafe/Reallocate.java index 4f441586486..10992fca115 100644 --- a/hotspot/test/runtime/Unsafe/Reallocate.java +++ b/hotspot/test/runtime/Unsafe/Reallocate.java @@ -26,7 +26,7 @@ * @requires vm.compMode != "Xcomp" * @bug 8058897 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=100m Reallocate */ diff --git a/hotspot/test/runtime/Unsafe/SetMemory.java b/hotspot/test/runtime/Unsafe/SetMemory.java index 4cce397c899..e1991968429 100644 --- a/hotspot/test/runtime/Unsafe/SetMemory.java +++ b/hotspot/test/runtime/Unsafe/SetMemory.java @@ -25,7 +25,7 @@ * @test * @summary Verifies that setMemory works correctly * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main SetMemory */ diff --git a/hotspot/test/runtime/Unsafe/ThrowException.java b/hotspot/test/runtime/Unsafe/ThrowException.java index 602852b4384..957be3c1db8 100644 --- a/hotspot/test/runtime/Unsafe/ThrowException.java +++ b/hotspot/test/runtime/Unsafe/ThrowException.java @@ -25,7 +25,7 @@ * @test * @summary Verify that throwException() can throw an exception * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main ThrowException */ diff --git a/hotspot/test/runtime/XCheckJniJsig/XCheckJSig.java b/hotspot/test/runtime/XCheckJniJsig/XCheckJSig.java index a56923c99d1..1cc20a1ef24 100644 --- a/hotspot/test/runtime/XCheckJniJsig/XCheckJSig.java +++ b/hotspot/test/runtime/XCheckJniJsig/XCheckJSig.java @@ -26,7 +26,7 @@ * @bug 7051189 8023393 * @summary Need to suppress info message if -Xcheck:jni is used with libjsig.so * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main XCheckJSig */ diff --git a/hotspot/test/runtime/classFileParserBug/ClassFileParserBug.java b/hotspot/test/runtime/classFileParserBug/ClassFileParserBug.java index e7945d04002..2415cc22029 100644 --- a/hotspot/test/runtime/classFileParserBug/ClassFileParserBug.java +++ b/hotspot/test/runtime/classFileParserBug/ClassFileParserBug.java @@ -26,7 +26,7 @@ * @bug 8040018 * @library /testlibrary * @summary Check for exception instead of assert. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main ClassFileParserBug */ diff --git a/hotspot/test/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java b/hotspot/test/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java index 81773ef6823..be0dc53dee9 100644 --- a/hotspot/test/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java +++ b/hotspot/test/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java @@ -26,7 +26,7 @@ * @bug 8041918 * @library /testlibrary * @summary Test empty bootstrap_methods table within BootstrapMethods attribute - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @compile TestEmptyBootstrapMethodsAttr.java * @run main TestEmptyBootstrapMethodsAttr diff --git a/hotspot/test/runtime/contended/Options.java b/hotspot/test/runtime/contended/Options.java index 642743c5612..cd11d8230f8 100644 --- a/hotspot/test/runtime/contended/Options.java +++ b/hotspot/test/runtime/contended/Options.java @@ -29,7 +29,7 @@ import jdk.test.lib.*; * @summary ContendedPaddingWidth should be range-checked * * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main Options */ diff --git a/hotspot/test/runtime/duplAttributes/DuplAttributesTest.java b/hotspot/test/runtime/duplAttributes/DuplAttributesTest.java index 13e011f9341..8d1ddab89df 100644 --- a/hotspot/test/runtime/duplAttributes/DuplAttributesTest.java +++ b/hotspot/test/runtime/duplAttributes/DuplAttributesTest.java @@ -26,7 +26,7 @@ * @bug 8040292 * @library /testlibrary * @summary Throw exceptions when duplicate attributes are detected. - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main DuplAttributesTest */ diff --git a/hotspot/test/runtime/logging/BiasedLockingTest.java b/hotspot/test/runtime/logging/BiasedLockingTest.java index 36afcea3c75..365f31934b0 100644 --- a/hotspot/test/runtime/logging/BiasedLockingTest.java +++ b/hotspot/test/runtime/logging/BiasedLockingTest.java @@ -26,7 +26,7 @@ * @bug 8149383 * @summary -Xlog:biasedlocking should have logging from statements in the source code * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.ProcessTools * @run driver BiasedLockingTest diff --git a/hotspot/test/runtime/logging/DefaultMethodsTest.java b/hotspot/test/runtime/logging/DefaultMethodsTest.java index c1ac868906e..e910bbb920c 100644 --- a/hotspot/test/runtime/logging/DefaultMethodsTest.java +++ b/hotspot/test/runtime/logging/DefaultMethodsTest.java @@ -26,7 +26,7 @@ * @bug 8139564 * @summary defaultmethods=debug should have logging from each of the statements in the code * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.ProcessTools * @run driver DefaultMethodsTest diff --git a/hotspot/test/runtime/logging/ExceptionsTest.java b/hotspot/test/runtime/logging/ExceptionsTest.java index 3dfaec82d1e..1f12e31efd4 100644 --- a/hotspot/test/runtime/logging/ExceptionsTest.java +++ b/hotspot/test/runtime/logging/ExceptionsTest.java @@ -26,7 +26,7 @@ * @bug 8141211 8147477 * @summary exceptions=info output should have an exception message for interpreter methods * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.ProcessTools * @run driver ExceptionsTest diff --git a/hotspot/test/runtime/logging/ItablesTest.java b/hotspot/test/runtime/logging/ItablesTest.java index 0fe9d84213c..44fb7b486e2 100644 --- a/hotspot/test/runtime/logging/ItablesTest.java +++ b/hotspot/test/runtime/logging/ItablesTest.java @@ -29,7 +29,7 @@ * @library /testlibrary * @compile ClassB.java * ItablesVtableTest.java - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run driver ItablesTest */ diff --git a/hotspot/test/runtime/logging/ModulesTest.java b/hotspot/test/runtime/logging/ModulesTest.java index 3547a06062a..e1689fb41aa 100644 --- a/hotspot/test/runtime/logging/ModulesTest.java +++ b/hotspot/test/runtime/logging/ModulesTest.java @@ -25,7 +25,7 @@ * @test * @summary modules=debug should have logging from statements in the code * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.ProcessTools * @run main ModulesTest diff --git a/hotspot/test/runtime/logging/MonitorInflationTest.java b/hotspot/test/runtime/logging/MonitorInflationTest.java index 781ee83c6cd..dca42b223f0 100644 --- a/hotspot/test/runtime/logging/MonitorInflationTest.java +++ b/hotspot/test/runtime/logging/MonitorInflationTest.java @@ -26,7 +26,7 @@ * @bug 8133885 * @summary monitorinflation=debug should have logging from each of the statements in the code * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.ProcessTools * @run driver MonitorInflationTest diff --git a/hotspot/test/runtime/logging/SafepointTest.java b/hotspot/test/runtime/logging/SafepointTest.java index a57eaa811a5..184706b9516 100644 --- a/hotspot/test/runtime/logging/SafepointTest.java +++ b/hotspot/test/runtime/logging/SafepointTest.java @@ -26,7 +26,7 @@ * @bug 8140348 * @summary safepoint=trace should have output from each log statement in the code * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.ProcessTools * @run driver SafepointTest diff --git a/hotspot/test/runtime/logging/StartupTimeTest.java b/hotspot/test/runtime/logging/StartupTimeTest.java index 1c8c0a0f87f..3e65b1d9510 100644 --- a/hotspot/test/runtime/logging/StartupTimeTest.java +++ b/hotspot/test/runtime/logging/StartupTimeTest.java @@ -26,7 +26,7 @@ * @bug 8148630 * @summary -Xlog:startuptime should produce logging from the source code * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.ProcessTools * @run driver StartupTimeTest diff --git a/hotspot/test/runtime/logging/ThreadLoggingTest.java b/hotspot/test/runtime/logging/ThreadLoggingTest.java index a5cde9c845c..e3cc0695ec0 100644 --- a/hotspot/test/runtime/logging/ThreadLoggingTest.java +++ b/hotspot/test/runtime/logging/ThreadLoggingTest.java @@ -27,7 +27,7 @@ * @bug 8149036 8150619 * @summary os+thread output should contain logging calls for thread start stop attaches detaches * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.ProcessTools * @run driver ThreadLoggingTest diff --git a/hotspot/test/runtime/logging/VMOperationTest.java b/hotspot/test/runtime/logging/VMOperationTest.java index 13570d6af6d..9ffe8632d58 100644 --- a/hotspot/test/runtime/logging/VMOperationTest.java +++ b/hotspot/test/runtime/logging/VMOperationTest.java @@ -26,7 +26,7 @@ * @bug 8143157 * @summary vmoperation=debug should have logging output * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.ProcessTools * @run driver VMOperationTest diff --git a/hotspot/test/runtime/logging/VtablesTest.java b/hotspot/test/runtime/logging/VtablesTest.java index 9df4c595069..b23fec00b3a 100644 --- a/hotspot/test/runtime/logging/VtablesTest.java +++ b/hotspot/test/runtime/logging/VtablesTest.java @@ -31,7 +31,7 @@ * p2/B.jcod * p1/C.java * p2/D.java - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run driver VtablesTest */ diff --git a/hotspot/test/runtime/memory/LargePages/TestLargePageSizeInBytes.java b/hotspot/test/runtime/memory/LargePages/TestLargePageSizeInBytes.java index e91f06d72ac..0b86e9d11a8 100644 --- a/hotspot/test/runtime/memory/LargePages/TestLargePageSizeInBytes.java +++ b/hotspot/test/runtime/memory/LargePages/TestLargePageSizeInBytes.java @@ -25,7 +25,7 @@ * @summary Tests that the flag -XX:LargePageSizeInBytes does not cause warnings on Solaris * @bug 8049536 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run driver TestLargePageSizeInBytes */ diff --git a/hotspot/test/runtime/memory/LargePages/TestLargePagesFlags.java b/hotspot/test/runtime/memory/LargePages/TestLargePagesFlags.java index 7c499cb1368..2cfb5a70ace 100644 --- a/hotspot/test/runtime/memory/LargePages/TestLargePagesFlags.java +++ b/hotspot/test/runtime/memory/LargePages/TestLargePagesFlags.java @@ -24,7 +24,7 @@ /* @test TestLargePagesFlags * @summary Tests how large pages are choosen depending on the given large pages flag combinations. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main TestLargePagesFlags */ diff --git a/hotspot/test/runtime/memory/ReadFromNoaccessArea.java b/hotspot/test/runtime/memory/ReadFromNoaccessArea.java index 61227c5aa4a..e47aa48ea2f 100644 --- a/hotspot/test/runtime/memory/ReadFromNoaccessArea.java +++ b/hotspot/test/runtime/memory/ReadFromNoaccessArea.java @@ -25,7 +25,7 @@ * @test * @summary Test that touching noaccess area in class ReservedHeapSpace results in SIGSEGV/ACCESS_VIOLATION * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build ReadFromNoaccessArea * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/memory/ReserveMemory.java b/hotspot/test/runtime/memory/ReserveMemory.java index bcc8fb1a7ef..b6fadfd0bcf 100644 --- a/hotspot/test/runtime/memory/ReserveMemory.java +++ b/hotspot/test/runtime/memory/ReserveMemory.java @@ -27,7 +27,7 @@ * @bug 8012015 * @summary Make sure reserved (but uncommitted) memory is not accessible * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build ReserveMemory * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/memory/RunUnitTestsConcurrently.java b/hotspot/test/runtime/memory/RunUnitTestsConcurrently.java index 27a05560988..c03cf8afa9c 100644 --- a/hotspot/test/runtime/memory/RunUnitTestsConcurrently.java +++ b/hotspot/test/runtime/memory/RunUnitTestsConcurrently.java @@ -25,7 +25,7 @@ * @test * @summary Test launches unit tests inside vm concurrently * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build RunUnitTestsConcurrently * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/runtime/modules/AccModuleTest.java b/hotspot/test/runtime/modules/AccModuleTest.java index f1f8ab0bc60..45d9bb394ad 100644 --- a/hotspot/test/runtime/modules/AccModuleTest.java +++ b/hotspot/test/runtime/modules/AccModuleTest.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @compile acc_module.jcod * @build AccModuleTest * @run main AccModuleTest diff --git a/hotspot/test/runtime/modules/Visibility/XbootcpNoVisibility.java b/hotspot/test/runtime/modules/Visibility/XbootcpNoVisibility.java index 3dd36caaa03..70cfa71f25a 100644 --- a/hotspot/test/runtime/modules/Visibility/XbootcpNoVisibility.java +++ b/hotspot/test/runtime/modules/Visibility/XbootcpNoVisibility.java @@ -26,7 +26,7 @@ * @summary Ensure that a class defined within a java.base package can not * be located via -Xbootclasspath/a * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm XbootcpNoVisibility */ diff --git a/hotspot/test/runtime/modules/Visibility/XbootcpVisibility.java b/hotspot/test/runtime/modules/Visibility/XbootcpVisibility.java index 5eb8882e870..c58ff0b606d 100644 --- a/hotspot/test/runtime/modules/Visibility/XbootcpVisibility.java +++ b/hotspot/test/runtime/modules/Visibility/XbootcpVisibility.java @@ -27,7 +27,7 @@ * is correctly located with -Xbootclasspath/a * @requires !(os.family == "windows") * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm XbootcpVisibility */ diff --git a/hotspot/test/runtime/modules/Visibility/XpatchVisibility.java b/hotspot/test/runtime/modules/Visibility/XpatchVisibility.java index 1fe53d19b74..0b38f7727ad 100644 --- a/hotspot/test/runtime/modules/Visibility/XpatchVisibility.java +++ b/hotspot/test/runtime/modules/Visibility/XpatchVisibility.java @@ -27,7 +27,7 @@ * is considered part of the boot loader's visibility boundary * @requires !(os.family == "windows") * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm XpatchVisibility */ diff --git a/hotspot/test/runtime/modules/XpatchCDS.java b/hotspot/test/runtime/modules/XpatchCDS.java index 4c80beca9fb..eda178759cb 100644 --- a/hotspot/test/runtime/modules/XpatchCDS.java +++ b/hotspot/test/runtime/modules/XpatchCDS.java @@ -24,7 +24,7 @@ /* * @test * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @run main XpatchCDS */ diff --git a/hotspot/test/runtime/verifier/OverriderMsg.java b/hotspot/test/runtime/verifier/OverriderMsg.java index 12a01bfdda7..dffa43885e6 100644 --- a/hotspot/test/runtime/verifier/OverriderMsg.java +++ b/hotspot/test/runtime/verifier/OverriderMsg.java @@ -33,7 +33,7 @@ import jdk.test.lib.*; * @bug 8026894 * @library /testlibrary * @modules java.base/jdk.internal.org.objectweb.asm - * java.base/sun.misc + * java.base/jdk.internal.misc * java.management * @compile -XDignore.symbol.file OverriderMsg.java * @run main/othervm OverriderMsg diff --git a/hotspot/test/runtime/verifier/TestANewArray.java b/hotspot/test/runtime/verifier/TestANewArray.java index 4adb160cd19..4414e88f80a 100644 --- a/hotspot/test/runtime/verifier/TestANewArray.java +++ b/hotspot/test/runtime/verifier/TestANewArray.java @@ -35,7 +35,7 @@ import jdk.test.lib.*; * @summary Test that anewarray bytecode is valid only if it specifies 255 or fewer dimensions. * @library /testlibrary * @modules java.base/jdk.internal.org.objectweb.asm - * java.base/sun.misc + * java.base/jdk.internal.misc * java.management * @compile -XDignore.symbol.file TestANewArray.java * @run main/othervm TestANewArray 49 diff --git a/hotspot/test/runtime/verifier/TestMultiANewArray.java b/hotspot/test/runtime/verifier/TestMultiANewArray.java index 35de2ada075..96e22064cde 100644 --- a/hotspot/test/runtime/verifier/TestMultiANewArray.java +++ b/hotspot/test/runtime/verifier/TestMultiANewArray.java @@ -33,7 +33,7 @@ import jdk.test.lib.*; * @bug 8038076 * @library /testlibrary * @modules java.base/jdk.internal.org.objectweb.asm - * java.base/sun.misc + * java.base/jdk.internal.misc * java.management * @compile -XDignore.symbol.file TestMultiANewArray.java * @run main/othervm TestMultiANewArray 49 diff --git a/hotspot/test/serviceability/attach/AttachSetGetFlag.java b/hotspot/test/serviceability/attach/AttachSetGetFlag.java index a78edaafff1..81e3a01fccb 100644 --- a/hotspot/test/serviceability/attach/AttachSetGetFlag.java +++ b/hotspot/test/serviceability/attach/AttachSetGetFlag.java @@ -26,7 +26,7 @@ * @bug 8054823 * @summary Tests the setFlag and printFlag attach command * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.attach/sun.tools.attach diff --git a/hotspot/test/serviceability/dcmd/compiler/CodeCacheTest.java b/hotspot/test/serviceability/dcmd/compiler/CodeCacheTest.java index 136f2599388..4bbf6b1d0b8 100644 --- a/hotspot/test/serviceability/dcmd/compiler/CodeCacheTest.java +++ b/hotspot/test/serviceability/dcmd/compiler/CodeCacheTest.java @@ -25,7 +25,7 @@ * @test CodeCacheTest * @bug 8054889 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/compiler/CodelistTest.java b/hotspot/test/serviceability/dcmd/compiler/CodelistTest.java index d5360de229d..7125a57f9bb 100644 --- a/hotspot/test/serviceability/dcmd/compiler/CodelistTest.java +++ b/hotspot/test/serviceability/dcmd/compiler/CodelistTest.java @@ -25,7 +25,7 @@ * @test CodelistTest * @bug 8054889 * @library /testlibrary /test/lib / - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/compiler/CompilerDirectivesDCMDTest.java b/hotspot/test/serviceability/dcmd/compiler/CompilerDirectivesDCMDTest.java index 770373e3f82..7851431ba7e 100644 --- a/hotspot/test/serviceability/dcmd/compiler/CompilerDirectivesDCMDTest.java +++ b/hotspot/test/serviceability/dcmd/compiler/CompilerDirectivesDCMDTest.java @@ -25,7 +25,7 @@ * @test CompilerDirectivesDCMDTest * @bug 8137167 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * @build jdk.test.lib.* diff --git a/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java b/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java index 321be8257f5..708ee0bf005 100644 --- a/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java +++ b/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java @@ -25,7 +25,7 @@ * @test CompilerQueueTest * @bug 8054889 * @library /testlibrary /test/lib / - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/framework/HelpTest.java b/hotspot/test/serviceability/dcmd/framework/HelpTest.java index 2b55e1c49c3..d03091ef27d 100644 --- a/hotspot/test/serviceability/dcmd/framework/HelpTest.java +++ b/hotspot/test/serviceability/dcmd/framework/HelpTest.java @@ -33,7 +33,7 @@ import org.testng.annotations.Test; * @test * @summary Test of diagnostic command help (tests all DCMD executors) * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/framework/InvalidCommandTest.java b/hotspot/test/serviceability/dcmd/framework/InvalidCommandTest.java index 8bbbf96eb00..e05da42c499 100644 --- a/hotspot/test/serviceability/dcmd/framework/InvalidCommandTest.java +++ b/hotspot/test/serviceability/dcmd/framework/InvalidCommandTest.java @@ -33,7 +33,7 @@ import org.testng.annotations.Test; * @test * @summary Test of invalid diagnostic command (tests all DCMD executors) * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/framework/VMVersionTest.java b/hotspot/test/serviceability/dcmd/framework/VMVersionTest.java index 8a8d242c6d0..63a3fa73399 100644 --- a/hotspot/test/serviceability/dcmd/framework/VMVersionTest.java +++ b/hotspot/test/serviceability/dcmd/framework/VMVersionTest.java @@ -34,7 +34,7 @@ import org.testng.annotations.Test; * @test * @summary Test of diagnostic command VM.version (tests all DCMD executors) * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/gc/ClassHistogramAllTest.java b/hotspot/test/serviceability/dcmd/gc/ClassHistogramAllTest.java index 5bddabdb2a8..331421af297 100644 --- a/hotspot/test/serviceability/dcmd/gc/ClassHistogramAllTest.java +++ b/hotspot/test/serviceability/dcmd/gc/ClassHistogramAllTest.java @@ -25,7 +25,7 @@ * @test * @summary Test of diagnostic command GC.class_histogram -all=true * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/gc/ClassHistogramTest.java b/hotspot/test/serviceability/dcmd/gc/ClassHistogramTest.java index 009a6e78403..6434bb0f918 100644 --- a/hotspot/test/serviceability/dcmd/gc/ClassHistogramTest.java +++ b/hotspot/test/serviceability/dcmd/gc/ClassHistogramTest.java @@ -33,7 +33,7 @@ import jdk.test.lib.dcmd.JMXExecutor; * @test * @summary Test of diagnostic command GC.class_histogram * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/gc/HeapDumpAllTest.java b/hotspot/test/serviceability/dcmd/gc/HeapDumpAllTest.java index 6b7cc7608e1..ca38cbb5332 100644 --- a/hotspot/test/serviceability/dcmd/gc/HeapDumpAllTest.java +++ b/hotspot/test/serviceability/dcmd/gc/HeapDumpAllTest.java @@ -26,7 +26,7 @@ * @summary Test of diagnostic command GC.heap_dump -all=true * @library /testlibrary * @library /test/lib/share/classes - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/gc/HeapDumpTest.java b/hotspot/test/serviceability/dcmd/gc/HeapDumpTest.java index 16dfdee007a..0329cb625aa 100644 --- a/hotspot/test/serviceability/dcmd/gc/HeapDumpTest.java +++ b/hotspot/test/serviceability/dcmd/gc/HeapDumpTest.java @@ -42,7 +42,7 @@ import jdk.test.lib.dcmd.PidJcmdExecutor; * @summary Test of diagnostic command GC.heap_dump * @library /testlibrary * @library /test/lib/share/classes - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/gc/RunFinalizationTest.java b/hotspot/test/serviceability/dcmd/gc/RunFinalizationTest.java index 485ecc65ba8..9e22ada4602 100644 --- a/hotspot/test/serviceability/dcmd/gc/RunFinalizationTest.java +++ b/hotspot/test/serviceability/dcmd/gc/RunFinalizationTest.java @@ -32,7 +32,7 @@ import jdk.test.lib.process.ProcessTools; * @summary Test of diagnostic command GC.run_finalization * @library /testlibrary * @library /test/lib/share/classes - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/gc/RunGCTest.java b/hotspot/test/serviceability/dcmd/gc/RunGCTest.java index acb1f9c57d4..7813605933c 100644 --- a/hotspot/test/serviceability/dcmd/gc/RunGCTest.java +++ b/hotspot/test/serviceability/dcmd/gc/RunGCTest.java @@ -37,7 +37,7 @@ import jdk.test.lib.dcmd.JMXExecutor; * @test * @summary Test of diagnostic command GC.run * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/jvmti/LoadAgentDcmdTest.java b/hotspot/test/serviceability/dcmd/jvmti/LoadAgentDcmdTest.java index da7224583e0..f27bd3aaca6 100644 --- a/hotspot/test/serviceability/dcmd/jvmti/LoadAgentDcmdTest.java +++ b/hotspot/test/serviceability/dcmd/jvmti/LoadAgentDcmdTest.java @@ -36,7 +36,7 @@ import org.testng.annotations.Test; * @test * @bug 8147388 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.instrument * java.management diff --git a/hotspot/test/serviceability/dcmd/thread/PrintConcurrentLocksTest.java b/hotspot/test/serviceability/dcmd/thread/PrintConcurrentLocksTest.java index c551b2f0750..55e0728e030 100644 --- a/hotspot/test/serviceability/dcmd/thread/PrintConcurrentLocksTest.java +++ b/hotspot/test/serviceability/dcmd/thread/PrintConcurrentLocksTest.java @@ -25,7 +25,7 @@ * @test * @summary Test of diagnostic command Thread.print -l=true * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/thread/PrintTest.java b/hotspot/test/serviceability/dcmd/thread/PrintTest.java index 75a1db904da..79f9b04fa77 100644 --- a/hotspot/test/serviceability/dcmd/thread/PrintTest.java +++ b/hotspot/test/serviceability/dcmd/thread/PrintTest.java @@ -38,7 +38,7 @@ import java.util.regex.Pattern; * @test * @summary Test of diagnostic command Thread.print * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/vm/ClassHierarchyTest.java b/hotspot/test/serviceability/dcmd/vm/ClassHierarchyTest.java index 19ffcf25def..63c509d935c 100644 --- a/hotspot/test/serviceability/dcmd/vm/ClassHierarchyTest.java +++ b/hotspot/test/serviceability/dcmd/vm/ClassHierarchyTest.java @@ -25,7 +25,7 @@ * @test * @summary Test of diagnostic command VM.class_hierarchy * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/vm/ClassLoaderStatsTest.java b/hotspot/test/serviceability/dcmd/vm/ClassLoaderStatsTest.java index d1e1cf38870..fcabb137ed0 100644 --- a/hotspot/test/serviceability/dcmd/vm/ClassLoaderStatsTest.java +++ b/hotspot/test/serviceability/dcmd/vm/ClassLoaderStatsTest.java @@ -25,7 +25,7 @@ * @test * @summary Test of diagnostic command VM.classloader_stats * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/vm/CommandLineTest.java b/hotspot/test/serviceability/dcmd/vm/CommandLineTest.java index 5bebfc0dfad..6d8c174544a 100644 --- a/hotspot/test/serviceability/dcmd/vm/CommandLineTest.java +++ b/hotspot/test/serviceability/dcmd/vm/CommandLineTest.java @@ -31,7 +31,7 @@ import jdk.test.lib.dcmd.JMXExecutor; * @test * @summary Test of diagnostic command VM.command_line * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/vm/DynLibsTest.java b/hotspot/test/serviceability/dcmd/vm/DynLibsTest.java index 68843ea95f7..b8c2fbe8cd0 100644 --- a/hotspot/test/serviceability/dcmd/vm/DynLibsTest.java +++ b/hotspot/test/serviceability/dcmd/vm/DynLibsTest.java @@ -33,7 +33,7 @@ import jdk.test.lib.dcmd.JMXExecutor; * @test * @summary Test of VM.dynlib diagnostic command via MBean * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/vm/FlagsTest.java b/hotspot/test/serviceability/dcmd/vm/FlagsTest.java index 69d2771f2eb..1ed2da18436 100644 --- a/hotspot/test/serviceability/dcmd/vm/FlagsTest.java +++ b/hotspot/test/serviceability/dcmd/vm/FlagsTest.java @@ -30,7 +30,7 @@ import org.testng.annotations.Test; * @test * @summary Test of diagnostic command VM.flags * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/vm/SystemPropertiesTest.java b/hotspot/test/serviceability/dcmd/vm/SystemPropertiesTest.java index 2a9ff664557..ae3d6ae6370 100644 --- a/hotspot/test/serviceability/dcmd/vm/SystemPropertiesTest.java +++ b/hotspot/test/serviceability/dcmd/vm/SystemPropertiesTest.java @@ -31,7 +31,7 @@ import jdk.test.lib.dcmd.JMXExecutor; * @test * @summary Test of diagnostic command VM.system_properties * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/dcmd/vm/UptimeTest.java b/hotspot/test/serviceability/dcmd/vm/UptimeTest.java index 75912c8f72e..02783bfdb73 100644 --- a/hotspot/test/serviceability/dcmd/vm/UptimeTest.java +++ b/hotspot/test/serviceability/dcmd/vm/UptimeTest.java @@ -35,7 +35,7 @@ import java.text.ParseException; * @test * @summary Test of diagnostic command VM.uptime * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/jvmti/GetObjectSizeOverflow.java b/hotspot/test/serviceability/jvmti/GetObjectSizeOverflow.java index 6617e89a902..562dda8d4f5 100644 --- a/hotspot/test/serviceability/jvmti/GetObjectSizeOverflow.java +++ b/hotspot/test/serviceability/jvmti/GetObjectSizeOverflow.java @@ -29,7 +29,7 @@ import jdk.test.lib.*; * @test * @bug 8027230 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.instrument * java.management diff --git a/hotspot/test/serviceability/jvmti/TestLambdaFormRetransformation.java b/hotspot/test/serviceability/jvmti/TestLambdaFormRetransformation.java index 01bf98917fb..aeda7a1db69 100644 --- a/hotspot/test/serviceability/jvmti/TestLambdaFormRetransformation.java +++ b/hotspot/test/serviceability/jvmti/TestLambdaFormRetransformation.java @@ -27,7 +27,7 @@ * @bug 8008678 * @summary JSR 292: constant pool reconstitution must support pseudo strings * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.instrument * java.management * jdk.jartool/sun.tools.jar diff --git a/hotspot/test/serviceability/jvmti/TestRedefineWithUnresolvedClass.java b/hotspot/test/serviceability/jvmti/TestRedefineWithUnresolvedClass.java index 1a978db9ab0..85840996a29 100644 --- a/hotspot/test/serviceability/jvmti/TestRedefineWithUnresolvedClass.java +++ b/hotspot/test/serviceability/jvmti/TestRedefineWithUnresolvedClass.java @@ -26,7 +26,7 @@ * @summary Redefine a class with an UnresolvedClass reference in the constant pool. * @bug 8035150 * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.instrument * java.management diff --git a/hotspot/test/serviceability/logging/TestLogRotation.java b/hotspot/test/serviceability/logging/TestLogRotation.java index cd056dec1fe..6ad0b1dad79 100644 --- a/hotspot/test/serviceability/logging/TestLogRotation.java +++ b/hotspot/test/serviceability/logging/TestLogRotation.java @@ -25,7 +25,7 @@ * @test TestLogRotation.java * @summary test flags for log rotation * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main/othervm/timeout=600 TestLogRotation * diff --git a/hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java b/hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java index e19eb046835..ac0ef6dca94 100644 --- a/hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java +++ b/hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java @@ -33,7 +33,7 @@ import java.io.File; * @bug 8028623 * @summary Test hashing of extended characters in Serviceability Agent. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java b/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java index 4e2abad9078..c1b6e955ef8 100644 --- a/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java +++ b/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java @@ -44,7 +44,7 @@ import jdk.test.lib.ProcessTools; * @key regression * @summary Regression test for hprof export issue due to large heaps (>2G) * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management/sun.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/stress/gc/TestStressRSetCoarsening.java b/hotspot/test/stress/gc/TestStressRSetCoarsening.java index 10ac597facc..e7ce522c9e2 100644 --- a/hotspot/test/stress/gc/TestStressRSetCoarsening.java +++ b/hotspot/test/stress/gc/TestStressRSetCoarsening.java @@ -32,7 +32,7 @@ import sun.hotspot.WhiteBox; * @requires os.maxMemory > 3G * * @summary Stress G1 Remembered Set by creating a lot of cross region links - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * @library /testlibrary /test/lib * @build sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/testlibrary_tests/OutputAnalyzerReportingTest.java b/hotspot/test/testlibrary_tests/OutputAnalyzerReportingTest.java index c863e90f750..d708ebb829a 100644 --- a/hotspot/test/testlibrary_tests/OutputAnalyzerReportingTest.java +++ b/hotspot/test/testlibrary_tests/OutputAnalyzerReportingTest.java @@ -28,7 +28,7 @@ * such as printing additional diagnostic info * (exit code, stdout, stderr, command line, etc.) * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/testlibrary_tests/OutputAnalyzerTest.java b/hotspot/test/testlibrary_tests/OutputAnalyzerTest.java index 132eb700770..7f64529610b 100644 --- a/hotspot/test/testlibrary_tests/OutputAnalyzerTest.java +++ b/hotspot/test/testlibrary_tests/OutputAnalyzerTest.java @@ -25,7 +25,7 @@ * @test * @summary Test the OutputAnalyzer utility class * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management */ diff --git a/hotspot/test/testlibrary_tests/RandomGeneratorTest.java b/hotspot/test/testlibrary_tests/RandomGeneratorTest.java index 4344f1d2d44..f242d2f7d28 100644 --- a/hotspot/test/testlibrary_tests/RandomGeneratorTest.java +++ b/hotspot/test/testlibrary_tests/RandomGeneratorTest.java @@ -25,7 +25,7 @@ * @test * @summary Verify correctnes of the random generator from Utility.java * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run driver RandomGeneratorTest SAME_SEED * @run driver RandomGeneratorTest NO_SEED diff --git a/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java b/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java index ecd9ec08469..4f20576be77 100644 --- a/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java +++ b/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java @@ -39,7 +39,7 @@ import java.util.Set; * in jdk.test.lib.Platform one and only one predicate * evaluates to true. * @library /testlibrary - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @run main TestMutuallyExclusivePlatformPredicates */ diff --git a/hotspot/test/testlibrary_tests/TestPlatformIsTieredSupported.java b/hotspot/test/testlibrary_tests/TestPlatformIsTieredSupported.java index 235aa3a5223..c9a5beabbcb 100644 --- a/hotspot/test/testlibrary_tests/TestPlatformIsTieredSupported.java +++ b/hotspot/test/testlibrary_tests/TestPlatformIsTieredSupported.java @@ -29,7 +29,7 @@ import sun.hotspot.WhiteBox; * @test * @summary Verifies that Platform::isTieredSupported returns correct value. * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @build TestPlatformIsTieredSupported * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/testlibrary_tests/whitebox/vm_flags/BooleanTest.java b/hotspot/test/testlibrary_tests/whitebox/vm_flags/BooleanTest.java index 7ba6f72088b..23e6afd02bd 100644 --- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/BooleanTest.java +++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/BooleanTest.java @@ -25,7 +25,7 @@ * @test BooleanTest * @bug 8028756 * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.compiler * java.management/sun.management * jdk.jvmstat/sun.jvmstat.monitor diff --git a/hotspot/test/testlibrary_tests/whitebox/vm_flags/SizeTTest.java b/hotspot/test/testlibrary_tests/whitebox/vm_flags/SizeTTest.java index fcc18eb4251..22886802363 100644 --- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/SizeTTest.java +++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/SizeTTest.java @@ -25,7 +25,7 @@ * @test SizeTTest * @bug 8054823 * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management/sun.management * @build SizeTTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/hotspot/test/testlibrary_tests/whitebox/vm_flags/UintxTest.java b/hotspot/test/testlibrary_tests/whitebox/vm_flags/UintxTest.java index 683a9c3339c..97149afd248 100644 --- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/UintxTest.java +++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/UintxTest.java @@ -25,7 +25,7 @@ * @test UintxTest * @bug 8028756 * @library /testlibrary /test/lib - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management/sun.management * @build UintxTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff --git a/jdk/.hgtags b/jdk/.hgtags index 2a4ecef2d92..b4a3e0be60b 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -355,3 +355,4 @@ eee1ced1d8e78293f2a004af818ca474387dbebf jdk-9+103 9417e1bcded6af5532c3b26235437ab227758877 jdk-9+110 b2a69d66dc65ad1d3aeb3bd362cf5bb0deba040e jdk-9+111 1565a0efe6f0ca411a6df277df1e069431c60988 jdk-9+112 +68f8be44b6a6b33dfa841ec671c0ba6e4056b372 jdk-9+113 diff --git a/jdk/make/data/swingbeaninfo/SwingBeanInfo.template b/jdk/make/data/swingbeaninfo/SwingBeanInfo.template deleted file mode 100644 index e0c83c0e2cf..00000000000 --- a/jdk/make/data/swingbeaninfo/SwingBeanInfo.template +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 1998, 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. 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 @(BeanPackageName); - -import java.beans.BeanDescriptor; -import java.beans.PropertyDescriptor; -import java.awt.Image; - -import sun.swing.BeanInfoUtils; - -/** - * Descriptive information about the @(BeanClassName) class for Java - * Beans application builders. This BeanInfo class provides descriptions - * of each property, of the bean itself, it indicates which - * @(BeanClassName) properties are bound, and it provides other - * information and icons useful to builders. - * - * @author Auto-Generated Source Code - */ - -public class @(BeanClassName)BeanInfo extends javax.swing.SwingBeanInfoBase { - private static final Class class@(BeanClassName) = @(BeanClassObject); - - /** - * @return a @(BeanClassName) BeanDescriptor - */ - public BeanDescriptor getBeanDescriptor() { - return BeanInfoUtils.createBeanDescriptor(class@(BeanClassName), - new Object[] { - BeanInfoUtils.PREFERRED, Boolean.TRUE, - @(ClassDescriptors) - BeanInfoUtils.SHORTDESCRIPTION, "@(BeanDescription)" - }); - } - - - /** - * Create a @(BeanClassName) PropertyDescriptor. This is just an internal - * convenience method that allows one to leave the @(BeanClassName).class - * argument out of the createPropertyDescriptor() class in the - * getPropertyDescriptors() method below. - * - * @param name the name of the property - * @param args an array java.beans.PropertyDescriptor property names and values - * @return a @(BeanClassName) PropertyDescriptor. - * @see BeanInfoUtils#createPropertyDescriptor - */ - private PropertyDescriptor createPropertyDescriptor(String name, Object[] args) { - return BeanInfoUtils.createPropertyDescriptor(class@(BeanClassName), name, args); - } - - - /** - * This method returns a list of bean PropertyDescriptors, one for each public - * property in @(BeanClassName). The first property is the "default" property. - * - * @return a complete list of bean PropertyDescriptors for @(BeanClassName) - * @see SwingBeanInfo - * @see java.beans.BeanInfo#getDefaultPropertyIndex - */ - public PropertyDescriptor[] getPropertyDescriptors() { - @(EnumVariables) - return new PropertyDescriptor[] { - @(BeanPropertyDescriptors) - }; - } - - - /** - * @return an icon of the specified kind for @(BeanClassName) - */ - public Image getIcon(final int kind) { - Image i; - switch (kind){ - case ICON_COLOR_32x32: - i = loadStandardImage("beaninfo/images/@(BeanClassName)Color32.gif"); - return ((i == null) ? loadStandardImage("beaninfo/images/JComponentColor32.gif") : i); - case ICON_COLOR_16x16: - i = loadStandardImage("beaninfo/images/@(BeanClassName)Color16.gif"); - return ((i == null) ? loadStandardImage("beaninfo/images/JComponentColor16.gif") : i); - case ICON_MONO_32x32: - i = loadStandardImage("beaninfo/images/@(BeanClassName)Mono32.gif"); - return ((i == null) ? loadStandardImage("beaninfo/images/JComponentMono32.gif") : i); - case ICON_MONO_16x16: - i = loadStandardImage("beaninfo/images/@(BeanClassName)Mono16.gif"); - return ((i == null) ? loadStandardImage("beaninfo/images/JComponentMono16.gif") : i); - default: - return super.getIcon(kind); - } - } - - /** - * This is a utility method to help in loading standard icon images. - * - * @param resourceName A pathname relative to the directory holding the - * class file of the current class - * @return an image object. May be null if the load failed. - * @see java.beans.SimpleBeanInfo#loadImage(String) - */ - private Image loadStandardImage(final String resourceName) { - return java.security.AccessController.doPrivileged( - (java.security.PrivilegedAction) () -> loadImage(resourceName)); - } -} - - diff --git a/jdk/make/data/swingbeaninfo/javax/swing/SwingBeanInfoBase.java b/jdk/make/data/swingbeaninfo/javax/swing/SwingBeanInfoBase.java deleted file mode 100644 index d6167b448e5..00000000000 --- a/jdk/make/data/swingbeaninfo/javax/swing/SwingBeanInfoBase.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package javax.swing; - -import java.beans.*; -import java.lang.reflect.*; -import java.awt.Image; - -/** - * The superclass for all Swing BeanInfo classes. It provides - * default implementations of getIcon and - * getDefaultPropertyIndex as well as utility - * methods, like createPropertyDescriptor, for writing BeanInfo - * implementations. This classes is intended to be used along - * with GenSwingBeanInfo a BeanInfo class code generator. - * - * @see GenSwingBeanInfo - * @author Hans Muller - */ -public class SwingBeanInfoBase extends SimpleBeanInfo -{ - /** - * The default index is always 0. In other words the first property - * listed in the getPropertyDescriptors() method is the one - * to show a (JFC builder) user in a situation where just a single - * property will be shown. - */ - public int getDefaultPropertyIndex() { - return 0; - } - - /** - * Returns a generic Swing icon, all icon "kinds" are supported. - * Subclasses should defer to this method when they don't have - * a particular beans icon kind. - */ - public Image getIcon(int kind) { - // PENDING(hmuller) need generic swing icon images. - return null; - } - - /** - * Returns the BeanInfo for the superclass of our bean, so that - * its PropertyDescriptors will be included. - */ - public BeanInfo[] getAdditionalBeanInfo() { - Class superClass = getBeanDescriptor().getBeanClass().getSuperclass(); - BeanInfo superBeanInfo = null; - try { - superBeanInfo = Introspector.getBeanInfo(superClass); - } catch (IntrospectionException ie) {} - if (superBeanInfo != null) { - BeanInfo[] ret = new BeanInfo[1]; - ret[0] = superBeanInfo; - return ret; - } - return null; - } -} diff --git a/jdk/make/data/swingbeaninfo/manifest.mf b/jdk/make/data/swingbeaninfo/manifest.mf deleted file mode 100644 index 228fcb78814..00000000000 --- a/jdk/make/data/swingbeaninfo/manifest.mf +++ /dev/null @@ -1,111 +0,0 @@ -Name: javax/swing/JApplet.class -Java-Bean: True - -Name: javax/swing/JButton.class -Java-Bean: True - -Name: javax/swing/JCheckBox.class -Java-Bean: True - -Name: javax/swing/JCheckBoxMenuItem.class -Java-Bean: True - -Name: javax/swing/JComboBox.class -Java-Bean: True - -Name: javax/swing/JDialog.class -Java-Bean: True - -Name: javax/swing/JEditorPane.class -Java-Bean: True - -Name: javax/swing/JFormattedTextField.class -Java-Bean: True - -Name: javax/swing/JInternalFrame.class -Java-Bean: True - -Name: javax/swing/JFrame.class -Java-Bean: True - -Name: javax/swing/JLabel.class -Java-Bean: True - -Name: javax/swing/JList.class -Java-Bean: True - -Name: javax/swing/JMenu.class -Java-Bean: True - -Name: javax/swing/JMenuBar.class -Java-Bean: True - -Name: javax/swing/JMenuItem.class -Java-Bean: True - -Name: javax/swing/JOptionPane.class -Java-Bean: True - -Name: javax/swing/JPanel.class -Java-Bean: True - -Name: javax/swing/JPasswordField.class -Java-Bean: True - -Name: javax/swing/JPopupMenu.class -Java-Bean: True - -Name: javax/swing/JProgressBar.class -Java-Bean: True - -Name: javax/swing/JRadioButton.class -Java-Bean: True - -Name: javax/swing/JRadioButtonMenuItem.class -Java-Bean: True - -Name: javax/swing/JScrollBar.class -Java-Bean: True - -Name: javax/swing/JScrollPane.class -Java-Bean: True - -Name: javax/swing/JSeparator.class -Java-Bean: True - -Name: javax/swing/JSlider.class -Java-Bean: True - -Name: javax/swing/JSpinner.class -Java-Bean: True - -Name: javax/swing/JSplitPane.class -Java-Bean: True - -Name: javax/swing/JTabbedPane.class -Java-Bean: True - -Name: javax/swing/JTextArea.class -Java-Bean: True - -Name: javax/swing/JTextField.class -Java-Bean: True - -Name: javax/swing/JTextPane.class -Java-Bean: True - -Name: javax/swing/JToolBar.class -Java-Bean: True - -Name: javax/swing/JTree.class -Java-Bean: True - -Name: javax/swing/JTable.class -Java-Bean: True - -Name: javax/swing/JToggleButton.class -Java-Bean: True - -Name: javax/swing/JWindow.class -Java-Bean: True - diff --git a/jdk/make/data/swingbeaninfo/sun/swing/BeanInfoUtils.java b/jdk/make/data/swingbeaninfo/sun/swing/BeanInfoUtils.java deleted file mode 100644 index 037615ad63a..00000000000 --- a/jdk/make/data/swingbeaninfo/sun/swing/BeanInfoUtils.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * 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.swing; - -import java.beans.*; -import java.lang.reflect.Method; - -public class BeanInfoUtils -{ - /* The values of these createPropertyDescriptor() and - * createBeanDescriptor() keywords are the names of the - * properties they're used to set. - */ - public static final String BOUND = "bound"; - public static final String CONSTRAINED = "constrained"; - public static final String PROPERTYEDITORCLASS = "propertyEditorClass"; - public static final String READMETHOD = "readMethod"; - public static final String WRITEMETHOD = "writeMethod"; - public static final String DISPLAYNAME = "displayName"; - public static final String EXPERT = "expert"; - public static final String HIDDEN = "hidden"; - public static final String PREFERRED = "preferred"; - public static final String SHORTDESCRIPTION = "shortDescription"; - public static final String CUSTOMIZERCLASS = "customizerClass"; - - static private void initFeatureDescriptor(FeatureDescriptor fd, String key, Object value) - { - if (DISPLAYNAME.equals(key)) { - fd.setDisplayName((String)value); - } - - if (EXPERT.equals(key)) { - fd.setExpert(((Boolean)value).booleanValue()); - } - - if (HIDDEN.equals(key)) { - fd.setHidden(((Boolean)value).booleanValue()); - } - - if (PREFERRED.equals(key)) { - fd.setPreferred(((Boolean)value).booleanValue()); - } - - else if (SHORTDESCRIPTION.equals(key)) { - fd.setShortDescription((String)value); - } - - /* Otherwise assume that we have an arbitrary FeatureDescriptor - * "attribute". - */ - else { - fd.setValue(key, value); - } - } - - /** - * Create a beans PropertyDescriptor given an of keyword/value - * arguments. The following sample call shows all of the supported - * keywords: - *
-     *      createPropertyDescriptor("contentPane", new Object[] {
-     *                     BOUND, Boolean.TRUE,
-     *               CONSTRAINED, Boolean.TRUE,
-     *       PROPERTYEDITORCLASS, package.MyEditor.class,
-     *                READMETHOD, "getContentPane",
-     *               WRITEMETHOD, "setContentPane",
-     *               DISPLAYNAME, "contentPane",
-     *                    EXPERT, Boolean.FALSE,
-     *                    HIDDEN, Boolean.FALSE,
-     *                 PREFERRED, Boolean.TRUE,
-     *          SHORTDESCRIPTION, "A top level window with a window manager border",
-     *         "random attribute","random object value"
-     *        }
-     *     );
-     * 
- * The keywords correspond to java.beans.PropertyDescriptor and - * java.beans.FeatureDescriptor properties, e.g. providing a value - * for displayName is comparable to FeatureDescriptor.setDisplayName(). - * Using createPropertyDescriptor instead of the PropertyDescriptor - * constructor and set methods is preferrable in that it regularizes - * the code in a java.beans.BeanInfo.getPropertyDescriptors() - * method implementation. One can use createPropertyDescriptor - * to set FeatureDescriptor attributes, as in "random attribute" - * "random object value". - *

- * All properties should provide a reasonable value for the - * SHORTDESCRIPTION keyword and should set BOUND - * to Boolean.TRUE if neccessary. The remaining keywords - * are optional. There's no need to provide values for keywords like - * READMETHOD if the correct value can be computed, i.e. if the properties - * get/is method follows the standard beans pattern. - *

- * The PREFERRED keyword is not supported by the JDK1.1 java.beans package. - * It's still worth setting it to true for properties that are most - * likely to be interested to the average developer, e.g. AbstractButton.title - * is a preferred property, AbstractButton.focusPainted is not. - * - * @see java.beans#BeanInfo - * @see java.beans#PropertyDescriptor - * @see java.beans#FeatureDescriptor - */ - public static PropertyDescriptor createPropertyDescriptor(Class cls, String name, Object[] args) - { - PropertyDescriptor pd = null; - try { - pd = new PropertyDescriptor(name, cls); - } catch (IntrospectionException e) { - // Try creating a read-only property, in case setter isn't defined. - try { - pd = createReadOnlyPropertyDescriptor(name, cls); - } catch (IntrospectionException ie) { - throwError(ie, "Can't create PropertyDescriptor for " + name + " "); - } - } - - for(int i = 0; i < args.length; i += 2) { - String key = (String)args[i]; - Object value = args[i + 1]; - - if (BOUND.equals(key)) { - pd.setBound(((Boolean)value).booleanValue()); - } - - else if (CONSTRAINED.equals(key)) { - pd.setConstrained(((Boolean)value).booleanValue()); - } - - else if (PROPERTYEDITORCLASS.equals(key)) { - pd.setPropertyEditorClass((Class)value); - } - - else if (READMETHOD.equals(key)) { - String methodName = (String)value; - Method method; - try { - method = cls.getMethod(methodName, new Class[0]); - pd.setReadMethod(method); - } - catch(Exception e) { - throwError(e, cls + " no such method as \"" + methodName + "\""); - } - } - - else if (WRITEMETHOD.equals(key)) { - String methodName = (String)value; - Method method; - try { - Class type = pd.getPropertyType(); - method = cls.getMethod(methodName, new Class[]{type}); - pd.setWriteMethod(method); - } - catch(Exception e) { - throwError(e, cls + " no such method as \"" + methodName + "\""); - } - } - - else { - initFeatureDescriptor(pd, key, value); - } - } - - return pd; - } - - - /** - * Create a BeanDescriptor object given an of keyword/value - * arguments. The following sample call shows all of the supported - * keywords: - *

-     *      createBeanDescriptor(JWindow..class, new Object[] {
-     *           CUSTOMIZERCLASS, package.MyCustomizer.class,
-     *               DISPLAYNAME, "JFrame",
-     *                    EXPERT, Boolean.FALSE,
-     *                    HIDDEN, Boolean.FALSE,
-     *                 PREFERRED, Boolean.TRUE,
-     *          SHORTDESCRIPTION, "A top level window with a window manager border",
-     *         "random attribute","random object value"
-     *        }
-     *     );
-     * 
- * The keywords correspond to java.beans.BeanDescriptor and - * java.beans.FeatureDescriptor properties, e.g. providing a value - * for displayName is comparable to FeatureDescriptor.setDisplayName(). - * Using createBeanDescriptor instead of the BeanDescriptor - * constructor and set methods is preferrable in that it regularizes - * the code in a java.beans.BeanInfo.getBeanDescriptor() - * method implementation. One can use createBeanDescriptor - * to set FeatureDescriptor attributes, as in "random attribute" - * "random object value". - * - * @see java.beans#BeanInfo - * @see java.beans#PropertyDescriptor - */ - public static BeanDescriptor createBeanDescriptor(Class cls, Object[] args) - { - Class customizerClass = null; - - /* For reasons I don't understand, customizerClass is a - * readOnly property. So we have to find it and pass it - * to the constructor here. - */ - for(int i = 0; i < args.length; i += 2) { - if (CUSTOMIZERCLASS.equals((String)args[i])) { - customizerClass = (Class)args[i + 1]; - break; - } - } - - BeanDescriptor bd = new BeanDescriptor(cls, customizerClass); - - for(int i = 0; i < args.length; i += 2) { - String key = (String)args[i]; - Object value = args[i + 1]; - initFeatureDescriptor(bd, key, value); - } - - return bd; - } - - static private PropertyDescriptor createReadOnlyPropertyDescriptor( - String name, Class cls) throws IntrospectionException { - - Method readMethod = null; - String base = capitalize(name); - Class[] parameters = new Class[0]; - - // Is it a boolean? - try { - readMethod = cls.getMethod("is" + base, parameters); - } catch (Exception ex) {} - if (readMethod == null) { - try { - // Try normal accessor pattern. - readMethod = cls.getMethod("get" + base, parameters); - } catch (Exception ex2) {} - } - if (readMethod != null) { - return new PropertyDescriptor(name, readMethod, null); - } - - try { - // Try indexed accessor pattern. - parameters = new Class[1]; - parameters[0] = int.class; - readMethod = cls.getMethod("get" + base, parameters); - } catch (NoSuchMethodException nsme) { - throw new IntrospectionException( - "cannot find accessor method for " + name + " property."); - } - return new IndexedPropertyDescriptor(name, null, null, readMethod, null); - } - - // Modified methods from java.beans.Introspector - private static String capitalize(String s) { - if (s.length() == 0) { - return s; - } - char chars[] = s.toCharArray(); - chars[0] = Character.toUpperCase(chars[0]); - return new String(chars); - } - - /** - * Fatal errors are handled by calling this method. - */ - public static void throwError(Exception e, String s) { - throw new Error(e.toString() + " " + s); - } -} diff --git a/jdk/make/gensrc/Gensrc-java.base.gmk b/jdk/make/gensrc/Gensrc-java.base.gmk index 9d3e3cf486e..66e41feb5e1 100644 --- a/jdk/make/gensrc/Gensrc-java.base.gmk +++ b/jdk/make/gensrc/Gensrc-java.base.gmk @@ -33,6 +33,7 @@ include GensrcCharsetMapping.gmk include GensrcCharsetCoder.gmk include GensrcBuffer.gmk include GensrcExceptions.gmk +include GensrcVarHandles.gmk include GensrcModuleLoaderMap.gmk ################################################################################ diff --git a/jdk/make/gensrc/Gensrc-java.desktop.gmk b/jdk/make/gensrc/Gensrc-java.desktop.gmk index 05e93c66e3f..42eb1a2fda0 100644 --- a/jdk/make/gensrc/Gensrc-java.desktop.gmk +++ b/jdk/make/gensrc/Gensrc-java.desktop.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -62,7 +62,9 @@ endif ifeq ($(OPENJDK_TARGET_OS), windows) PROP_SRC_DIRS += $(JDK_TOPDIR)/src/java.desktop/windows/classes/sun/awt/windows -else +endif + +ifeq ($(filter $(OPENJDK_TARGET_OS), windows macosx), ) PROP_SRC_DIRS += $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/resources endif diff --git a/jdk/make/gensrc/GensrcVarHandles.gmk b/jdk/make/gensrc/GensrcVarHandles.gmk new file mode 100644 index 00000000000..5d90deb1304 --- /dev/null +++ b/jdk/make/gensrc/GensrcVarHandles.gmk @@ -0,0 +1,162 @@ +# +# Copyright (c) 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. 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. +# + +GENSRC_VARHANDLES := + +VARHANDLES_GENSRC_DIR := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/java/lang/invoke +VARHANDLES_SRC_DIR := $(JDK_TOPDIR)/src/java.base/share/classes/java/lang/invoke + +################################################################################ +# Setup a rule for generating a VarHandle java class +# Param 1 - Variable declaration prefix +# Param 2 - Type with first letter capitalized +define GenerateVarHandle + + $1_Type := $2 + + $1_FILENAME := $(VARHANDLES_GENSRC_DIR)/VarHandle$$($1_Type)s.java + + ifneq ($$(findstring $$($1_Type), Object Int Long), ) + $1_ARGS += -KCAS + endif + + ifneq ($$(findstring $$($1_Type), Int Long), ) + $1_ARGS += -KAtomicAdd + endif + + $$($1_FILENAME): $(VARHANDLES_SRC_DIR)/X-VarHandle.java.template $(BUILD_TOOLS_JDK) + ifeq ($$($1_Type), Object) + $$(eval $1_type := $$($1_Type)) + else + $$(eval $1_type := $$$$(shell $(TR) '[:upper:]' '[:lower:]' <<< $$$$($1_Type))) + endif + $$(call MakeDir, $$(@D)) + $(TOOL_SPP) -nel -K$$($1_type) -Dtype=$$($1_type) -DType=$$($1_Type) \ + $$($1_ARGS) < $$< > $$@ + + GENSRC_VARHANDLES += $$($1_FILENAME) +endef + +################################################################################ + +################################################################################ +# Setup a rule for generating a VarHandleByteArray java class +# Param 1 - Variable declaration prefix +# Param 2 - Type with first letter capitalized +define GenerateVarHandleByteArray + + $1_Type := $2 + + $1_FILENAME := $(VARHANDLES_GENSRC_DIR)/VarHandleByteArrayAs$$($1_Type)s.java + + ifeq ($$($1_Type), Short) + $1_type := short + $1_BoxType := $$($1_Type) + + $1_rawType := $$($1_type) + $1_RawType := $$($1_Type) + $1_RawBoxType := $$($1_BoxType) + endif + + ifeq ($$($1_Type), Char) + $1_type := char + $1_BoxType := Character + + $1_rawType := $$($1_type) + $1_RawType := $$($1_Type) + $1_RawBoxType := $$($1_BoxType) + endif + + ifeq ($$($1_Type), Int) + $1_type := int + $1_BoxType := Integer + + $1_rawType := $$($1_type) + $1_RawType := $$($1_Type) + $1_RawBoxType := $$($1_BoxType) + + $1_ARGS += -KCAS + $1_ARGS += -KAtomicAdd + endif + + ifeq ($$($1_Type), Long) + $1_type := long + $1_BoxType := $$($1_Type) + + $1_rawType := $$($1_type) + $1_RawType := $$($1_Type) + $1_RawBoxType := $$($1_BoxType) + + $1_ARGS += -KCAS + $1_ARGS += -KAtomicAdd + endif + + ifeq ($$($1_Type), Float) + $1_type := float + $1_BoxType := $$($1_Type) + + $1_rawType := int + $1_RawType := Int + $1_RawBoxType := Integer + + $1_ARGS += -KCAS + $1_ARGS += -KfloatingPoint + endif + + ifeq ($$($1_Type), Double) + $1_type := double + $1_BoxType := $$($1_Type) + + $1_rawType := long + $1_RawType := Long + $1_RawBoxType := Long + + $1_ARGS += -KCAS + $1_ARGS += -KfloatingPoint + endif + + $$($1_FILENAME): $(VARHANDLES_SRC_DIR)/X-VarHandleByteArrayView.java.template $(BUILD_TOOLS_JDK) + $$(call MakeDir, $$(@D)) + $(TOOL_SPP) -nel -K$$($1_type) \ + -Dtype=$$($1_type) -DType=$$($1_Type) -DBoxType=$$($1_BoxType) \ + -DrawType=$$($1_rawType) -DRawType=$$($1_RawType) -DRawBoxType=$$($1_RawBoxType) \ + $$($1_ARGS) < $$< > $$@ + + GENSRC_VARHANDLES += $$($1_FILENAME) +endef + +################################################################################ + +# List the types to generate source for, with capitalized first letter +VARHANDLES_TYPES := Boolean Byte Short Char Int Long Float Double Object +$(foreach t, $(VARHANDLES_TYPES), \ + $(eval $(call GenerateVarHandle,VAR_HANDLE_$t,$t))) + +# List the types to generate source for, with capitalized first letter +VARHANDLES_BYTE_ARRAY_TYPES := Short Char Int Long Float Double +$(foreach t, $(VARHANDLES_BYTE_ARRAY_TYPES), \ + $(eval $(call GenerateVarHandleByteArray,VAR_HANDLE_BYTE_ARRAY_$t,$t))) + +GENSRC_JAVA_BASE += $(GENSRC_VARHANDLES) diff --git a/jdk/make/lib/Awt2dLibraries.gmk b/jdk/make/lib/Awt2dLibraries.gmk index d6ba6443bf2..d563935683c 100644 --- a/jdk/make/lib/Awt2dLibraries.gmk +++ b/jdk/make/lib/Awt2dLibraries.gmk @@ -204,6 +204,7 @@ endif ifeq ($(OPENJDK_TARGET_OS), windows) LIBAWT_DIRS += $(JDK_TOPDIR)/src/java.desktop/share/native/common/font \ $(JDK_TOPDIR)/src/java.desktop/share/native/common/java2d/opengl \ + $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/awt/systemscale \ # Why does libawt need java.base headers? LIBAWT_CFLAGS += -I$(JDK_TOPDIR)/src/java.desktop/share/native/common/font \ -I$(JDK_TOPDIR)/src/java.desktop/share/native/common/java2d/opengl \ @@ -311,6 +312,10 @@ ifeq ($(findstring $(OPENJDK_TARGET_OS),windows macosx),) $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/awt \ # + ifneq ($(filter $(OPENJDK_TARGET_OS),linux solaris aix), ) + LIBAWT_XAWT_DIRS += $(JDK_TOPDIR)/src/java.desktop/unix/native/common/awt/systemscale + endif + LIBAWT_XAWT_EXCLUDES := medialib LIBAWT_XAWT_CFLAGS := $(addprefix -I, $(shell $(FIND) $(LIBAWT_XAWT_DIRS) -type d)) \ @@ -883,6 +888,13 @@ ifndef BUILD_HEADLESS_ONLY LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/java.desktop/macosx/native/libsplashscreen endif + ifneq ($(filter $(OPENJDK_TARGET_OS),linux solaris aix), ) + LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/java.desktop/unix/native/common/awt/systemscale + endif + + ifeq ($(OPENJDK_TARGET_OS), windows) + LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/java.desktop/windows/native/common/awt/systemscale + endif LIBSPLASHSCREEN_CFLAGS += -DSPLASHSCREEN -DPNG_NO_MMX_CODE -DPNG_ARM_NEON_OPT=0 \ $(addprefix -I, $(LIBSPLASHSCREEN_DIRS)) \ $(LIBJAVA_HEADER_FLAGS) \ @@ -923,7 +935,7 @@ ifndef BUILD_HEADLESS_ONLY -framework JavaNativeFoundation else ifeq ($(OPENJDK_TARGET_OS), windows) LIBSPLASHSCREEN_LDFLAGS := -delayload:user32.dll - LIBSPLASHSCREEN_LIBS += kernel32.lib user32.lib gdi32.lib delayimp.lib + LIBSPLASHSCREEN_LIBS += kernel32.lib user32.lib gdi32.lib delayimp.lib $(WIN_JAVA_LIB) jvm.lib else LIBSPLASHSCREEN_LIBS += $(X_LIBS) -lX11 -lXext $(LIBM) -lpthread endif diff --git a/jdk/make/lib/Lib-java.rmi.gmk b/jdk/make/lib/Lib-java.rmi.gmk new file mode 100644 index 00000000000..c01e2f888fe --- /dev/null +++ b/jdk/make/lib/Lib-java.rmi.gmk @@ -0,0 +1,53 @@ +# +# Copyright (c) 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +include LibCommon.gmk + +################################################################################ + +$(eval $(call SetupNativeCompilation,BUILD_LIBRMI, \ + LIBRARY := rmi, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/java.rmi/share/native/librmi, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/java.rmi, \ + MAPFILE := $(JDK_TOPDIR)/make/mapfiles/librmi/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS_unix := -ljvm, \ + LIBS_windows := jvm.lib, \ + VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=rmi.dll" \ + -D "JDK_INTERNAL_NAME=rmi" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/librmi, \ +)) + +$(BUILD_LIBRMI): $(call FindLib, java.base, java) + +TARGETS += $(BUILD_LIBRMI) + +################################################################################ diff --git a/jdk/make/mapfiles/libawt_xawt/mapfile-vers b/jdk/make/mapfiles/libawt_xawt/mapfile-vers index 42ef24d90a1..2b18bd42e6f 100644 --- a/jdk/make/mapfiles/libawt_xawt/mapfile-vers +++ b/jdk/make/mapfiles/libawt_xawt/mapfile-vers @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 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 @@ -150,6 +150,12 @@ SUNWprivate_1.1 { Java_sun_awt_X11_XlibWrapper_XdbeEndIdiom; Java_sun_awt_X11_XDesktopPeer_init; Java_sun_awt_X11_XDesktopPeer_gnome_1url_1show; + Java_sun_awt_X11_XTaskbarPeer_init; + Java_sun_awt_X11_XTaskbarPeer_runloop; + Java_sun_awt_X11_XTaskbarPeer_setBadge; + Java_sun_awt_X11_XTaskbarPeer_setUrgent; + Java_sun_awt_X11_XTaskbarPeer_updateProgress; + Java_sun_awt_X11_XTaskbarPeer_setNativeMenu; Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl; Java_sun_awt_X11_XRobotPeer_keyPressImpl; Java_sun_awt_X11_XRobotPeer_keyReleaseImpl; diff --git a/jdk/make/mapfiles/libjava/mapfile-vers b/jdk/make/mapfiles/libjava/mapfile-vers index 82fd583e48e..b3659227988 100644 --- a/jdk/make/mapfiles/libjava/mapfile-vers +++ b/jdk/make/mapfiles/libjava/mapfile-vers @@ -259,7 +259,6 @@ SUNWprivate_1.1 { Java_java_io_Console_istty; Java_java_io_Console_encoding; Java_java_io_Console_echo; - Java_sun_misc_GC_maxObjectInspectionAge; Java_sun_reflect_NativeConstructorAccessorImpl_newInstance0; Java_sun_reflect_NativeMethodAccessorImpl_invoke0; Java_sun_reflect_Reflection_getCallerClass__; @@ -283,8 +282,8 @@ SUNWprivate_1.1 { Java_jdk_internal_loader_BootLoader_getSystemPackageNames; Java_jdk_internal_loader_BootLoader_setBootLoaderUnnamedModule0; - Java_sun_misc_VMSupport_initAgentProperties; - Java_sun_misc_VMSupport_getVMTemporaryDirectory; + Java_jdk_internal_vm_VMSupport_initAgentProperties; + Java_jdk_internal_vm_VMSupport_getVMTemporaryDirectory; # ZipFile.c needs this one throwFileNotFoundException; diff --git a/jdk/test/java/net/Inet4Address/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor b/jdk/make/mapfiles/librmi/mapfile-vers similarity index 71% rename from jdk/test/java/net/Inet4Address/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor rename to jdk/make/mapfiles/librmi/mapfile-vers index e12414994d3..af060c62331 100644 --- a/jdk/test/java/net/Inet4Address/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor +++ b/jdk/make/mapfiles/librmi/mapfile-vers @@ -1,9 +1,12 @@ -# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# +# Copyright (c) 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. +# 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 @@ -18,5 +21,11 @@ # 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. +# -DummyNameServiceDescriptor # name service provider descriptor +SUNWprivate_1.1 { + global: + Java_sun_rmi_transport_GC_maxObjectInspectionAge; + local: + *; +}; diff --git a/jdk/make/mapfiles/libsplashscreen/mapfile-vers b/jdk/make/mapfiles/libsplashscreen/mapfile-vers index 2be756be1e5..fec7b037f0d 100644 --- a/jdk/make/mapfiles/libsplashscreen/mapfile-vers +++ b/jdk/make/mapfiles/libsplashscreen/mapfile-vers @@ -42,6 +42,8 @@ SUNWprivate_1.1 { SplashInit; SplashClose; SplashSetFileJarName; + SplashSetScaleFactor; + SplashGetScaledImageName; local: *; }; diff --git a/jdk/make/src/classes/build/tools/cldrconverter/LDMLParseHandler.java b/jdk/make/src/classes/build/tools/cldrconverter/LDMLParseHandler.java index 49f35854a20..c95c730c860 100644 --- a/jdk/make/src/classes/build/tools/cldrconverter/LDMLParseHandler.java +++ b/jdk/make/src/classes/build/tools/cldrconverter/LDMLParseHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -786,10 +786,10 @@ class LDMLParseHandler extends AbstractLDMLHandler { return keyName; } - private String getTarget(String qName, String path, String calType, String context, String width) { - // qName + private String getTarget(String path, String calType, String context, String width) { + // Target qName int lastSlash = path.lastIndexOf('/'); - qName = path.substring(lastSlash+1); + String qName = path.substring(lastSlash+1); int bracket = qName.indexOf('['); if (bracket != -1) { qName = qName.substring(0, bracket); @@ -885,7 +885,7 @@ class LDMLParseHandler extends AbstractLDMLHandler { String[] tmp = keyName.split(",", 3); String calType = currentCalendarType.lname(); String src = calType+"."+tmp[0]; - String target = getTarget(containerqName, + String target = getTarget( entry.getKey(), calType, tmp[1].length()>0 ? tmp[1] : currentContext, diff --git a/jdk/make/src/classes/build/tools/swingbeaninfo/DocBeanInfo.java b/jdk/make/src/classes/build/tools/swingbeaninfo/DocBeanInfo.java deleted file mode 100644 index b30d79b7ee5..00000000000 --- a/jdk/make/src/classes/build/tools/swingbeaninfo/DocBeanInfo.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 1998, 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. 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 build.tools.swingbeaninfo; - -import java.util.HashMap; - -/** - * Class that holds information for populating a FeatureDescriptor. For the class, - * This information represents the BeanDescriptor, for a property, it represents - * a PropertyDescriptor. - */ -public class DocBeanInfo { - - // Values of the BeanFlags - public static final int BOUND = 1; - public static final int EXPERT = 2; - public static final int CONSTRAINED = 4; - public static final int HIDDEN = 8; - public static final int PREFERRED = 16 ; - - public String name; - public int beanflags; - public String desc; - public String displayname; - public String propertyeditorclass; - public String customizerclass; - - public HashMap attribs; - public HashMap enums; - - public DocBeanInfo(){} - - public DocBeanInfo(String p, int flags, String d, - String displayname, String pec, String cc, - HashMap attribs, HashMap enums) { - this.name = p; - this.beanflags = flags; - this.desc = d; - this.displayname = displayname; - this.propertyeditorclass = pec; - this.customizerclass = cc; - - this.attribs = attribs; - this.enums = enums; - } - - public String toString() { - StringBuffer buffer = new StringBuffer("*****"); - buffer.append("\nProperty: " + name); - buffer.append("\tDescription: " + desc); - buffer.append("\nDisplayname: " + displayname); - buffer.append("\nPropertyEditorClass: " + propertyeditorclass); - buffer.append("\nCustomizerClass: " + customizerclass); - - if ((beanflags & BOUND) != 0) - buffer.append("\nBound: true"); - - if ((beanflags & EXPERT) != 0) - buffer.append("\nExpert: true"); - - if ((beanflags & CONSTRAINED) != 0) - buffer.append("\nConstrained: true"); - - if ((beanflags & HIDDEN) !=0) - buffer.append("\nHidden: true"); - - if ((beanflags & PREFERRED) !=0) - - if (attribs != null) - buffer.append(attribs.toString()); - - if (enums != null) - buffer.append(enums.toString()); - - return buffer.toString(); - } - -} diff --git a/jdk/make/src/classes/build/tools/swingbeaninfo/GenDocletBeanInfo.java b/jdk/make/src/classes/build/tools/swingbeaninfo/GenDocletBeanInfo.java deleted file mode 100644 index ce7b9afd15b..00000000000 --- a/jdk/make/src/classes/build/tools/swingbeaninfo/GenDocletBeanInfo.java +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright (c) 1998, 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. 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 build.tools.swingbeaninfo; - -import com.sun.javadoc.ClassDoc; -import com.sun.javadoc.MethodDoc; -import com.sun.javadoc.RootDoc; -import com.sun.javadoc.Tag; - -import java.beans.Introspector; - -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.HashMap; -import java.util.StringTokenizer; - -/** - * Properties supported and tag syntax: - * - * @beaninfo - * bound: flag - * constrained: flag - * expert: flag - * hidden: flag - * preferred: flag - * description: string - * displayname: string - * propertyeditorclass: string (with dots: foo.bar.MyPropertyEditor - * customizerclass: string (w/dots: foo.bar.MyCustomizer) - * attribute: key1 value1 - * attribute: key2 value2 - * - * TODO: getValue and genDocletInfo needs some cleaning. - * - * @author Hans Muller - * @author Rich Schiavi - * @author Mark Davidson - */ -public class GenDocletBeanInfo { - - static String[] ATTRIBUTE_NAMES = { "bound", - "constrained", - "expert", - "hidden", - "preferred", - "displayname", - "propertyeditorclass", - "customizerclass", - "displayname", - "description", - "enum", - "attribute" }; - private static boolean DEBUG = false; - - private static String fileDir = ""; - private static String templateDir = ""; - - public static final String TRUE = "true"; - public static final String FALSE = "false"; - - /** - * Method called from the javadoc environment to determint the options length. - * Doclet options: - * -t template location - * -d outputdir - * -x true Enable debug output. - */ - public static int optionLength(String option) { - // remind: this needs to be cleaned up - if (option.equals("-t")) - return 2; - if (option.equals("-d")) - return 2; - if (option.equals("-x")) - return 2; - return 0; - } - - /** @beaninfo - * bound:true - * constrained:false - * expert:true - * hidden:true - * preferred:false - * description: the description of this method can - * do all sorts of funky things. if it \n - * is indented like this, we have to remove - * all char spaces greater than 2 and also any hard-coded \n - * newline characters and all newlines - * displayname: theString - * propertyeditorclass: foo.bar.MyPropertyEditorClass - * customizerclass: foo.bar.MyCustomizerClass - * attribute:key1 value1 - * attribute: key2 value2 - * - */ - public static boolean start(RootDoc doc) { - readOptions(doc.options()); - - if (templateDir.length() == 0) { - System.err.println("-t option not specified"); - return false; - } - if (fileDir.length() == 0) { - System.err.println("-d option not specified"); - return false; - } - - GenSwingBeanInfo generator = new GenSwingBeanInfo(fileDir, templateDir, DEBUG); - Hashtable dochash = new Hashtable(); - DocBeanInfo dbi; - - /* "javadoc Foo.java Bar.java" will return: - * "Foo Foo.I1 Foo.I2 Bar Bar.I1 Bar.I2" - * i.e., with all the innerclasses of classes specified in the command - * line. We don't want to generate BeanInfo for any of these inner - * classes, so we ignore these by remembering what the last outer - * class was. A hack, I admit, but makes the build faster. - */ - String previousClass = null; - - ClassDoc[] classes = doc.classes(); - - for (int cnt = 0; cnt < classes.length; cnt++) { - String className = classes[cnt].qualifiedName(); - if (previousClass != null && - className.startsWith(previousClass) && - className.charAt(previousClass.length()) == '.') { - continue; - } - previousClass = className; - - // XXX - debug - System.out.println("\n>>> Generating beaninfo for " + className + "..."); - - // Examine the javadoc tags and look for the the @beaninfo tag - // This first block looks at the javadoc for the class - Tag[] tags = classes[cnt].tags(); - for (int i = 0; i < tags.length; i++) { - if (tags[i].kind().equalsIgnoreCase("@beaninfo")) { - if (DEBUG) - System.out.println("GenDocletBeanInfo: found @beaninfo tagged Class: " + tags[i].text()); - dbi = genDocletInfo(tags[i].text(), classes[cnt].name()); - dochash.put(dbi.name, dbi); - break; - } - } - - // This block looks at the javadoc for the class methods. - int startPos = -1; - MethodDoc[] methods = classes[cnt].methods(); - for (int j = 0; j < methods.length; j++) { - // actually don't "introspect" - look for all - // methods with a @beaninfo tag - tags = methods[j].tags(); - for (int x = 0; x < tags.length; x++){ - if (tags[x].kind().equalsIgnoreCase("@beaninfo")){ - if ((methods[j].name().startsWith("get")) || - (methods[j].name().startsWith("set"))) - startPos = 3; - else if (methods[j].name().startsWith("is")) - startPos = 2; - else - startPos = 0; - String propDesc = - Introspector.decapitalize((methods[j].name()).substring(startPos)); - if (DEBUG) - System.out.println("GenDocletBeanInfo: found @beaninfo tagged Method: " + tags[x].text()); - dbi = genDocletInfo(tags[x].text(), propDesc); - dochash.put(dbi.name, dbi); - break; - } - } - } - if (DEBUG) { - // dump our classes doc beaninfo - System.out.println(">>>>DocletBeanInfo for class: " + classes[cnt].name()); - Enumeration e = dochash.elements(); - while (e.hasMoreElements()) { - DocBeanInfo db = (DocBeanInfo)e.nextElement(); - System.out.println(db.toString()); - } - } - - // Use the generator to create the beaninfo code for the class. - generator.genBeanInfo(classes[cnt].containingPackage().name(), - classes[cnt].name(), dochash); - // reset the values! - dochash.clear(); - } // end for loop - return true; - } - - /** - * Reads the command line options. - * Side Effect, sets class variables templateDir, fileDir and DEBUG - */ - private static void readOptions(String[][] options) { - // Parse the command line args - for (int i = 0; i < options.length; i++){ - if (options[i][0].equals("-t")) { - templateDir = options[i][1]; - } else if (options[i][0].equals("-d")) { - fileDir = options[i][1]; - } else if (options[i][0].equals("-x")){ - if (options[i][1].equals("true")) - DEBUG=true; - else - DEBUG=false; - } - } - } - - /** - * Create a "BeanInfo" data structure from the tag. This is a data structure - * which contains all beaninfo data for a method or a class. - * - * @param text All the text after the @beaninfo tag. - * @param name Name of the property i.e., mnemonic for setMnemonic - */ - private static DocBeanInfo genDocletInfo(String text, String name) { - int beanflags = 0; - String desc = "null"; - String displayname = "null"; - String propertyeditorclass = "null"; - String customizerclass = "null"; - String value = "null"; - HashMap attribs = null; - HashMap enums = null; - - int index; - - for (int j = 0; j < ATTRIBUTE_NAMES.length; j++){ - index = 0; - if ((index = text.indexOf(ATTRIBUTE_NAMES[j])) != -1){ - value = getValue((text).substring(index),ATTRIBUTE_NAMES[j]); - - if (ATTRIBUTE_NAMES[j].equalsIgnoreCase("attribute")) { - attribs = getAttributeMap(value, " "); - } - if (ATTRIBUTE_NAMES[j].equalsIgnoreCase("enum")) { - enums = getAttributeMap(value, " \n"); - } - else if (ATTRIBUTE_NAMES[j].equals("displayname")){ - displayname = value; - } - else if (ATTRIBUTE_NAMES[j].equalsIgnoreCase("propertyeditorclass")) { - propertyeditorclass = value; - } - else if (ATTRIBUTE_NAMES[j].equalsIgnoreCase("customizerclass")){ - customizerclass = value; - } - else if ((ATTRIBUTE_NAMES[j].equalsIgnoreCase("bound")) - && (value.equalsIgnoreCase(TRUE))) - beanflags = beanflags | DocBeanInfo.BOUND; - else if ((ATTRIBUTE_NAMES[j].equalsIgnoreCase("expert")) - && (value.equalsIgnoreCase(TRUE))) - beanflags = beanflags | DocBeanInfo.EXPERT; - else if ((ATTRIBUTE_NAMES[j].equalsIgnoreCase("constrained")) - && (value.equalsIgnoreCase(TRUE))) - beanflags = beanflags | DocBeanInfo.CONSTRAINED; - else if ((ATTRIBUTE_NAMES[j].equalsIgnoreCase("hidden")) - && (value.equalsIgnoreCase(TRUE))) - beanflags = beanflags | DocBeanInfo.HIDDEN; - else if ((ATTRIBUTE_NAMES[j].equalsIgnoreCase("preferred")) - && (value.equalsIgnoreCase(TRUE))) - beanflags = beanflags | DocBeanInfo.PREFERRED; - else if (ATTRIBUTE_NAMES[j].equalsIgnoreCase("description")){ - desc = value; - } - } - } - /** here we create our doclet-beaninfo data structure, which we read in - * later if it has anything worthwhile - */ - - // Construct a new Descriptor class - return new DocBeanInfo(name, beanflags, desc,displayname, - propertyeditorclass, customizerclass, - attribs, enums); - } - - /** - * Parses the substring and returns the cleaned up value for the attribute. - * @param substring Full String of the attrib tag. - * i.e., "attribute: visualUpdate true" will return "visualUpdate true"; - */ - private static String getValue(String substring, String prop) { - StringTokenizer t; - String value = "null"; - - try { - /** if the ATTRIBUTE_NAMES is NOT the description, then we - * parse until newline - * if it is the description we read until the next token - * and then look for a match in the last MAXMATCH index - * and truncate the description - * if it is the attribute we wead until no more - */ - if (prop.equalsIgnoreCase("attribute")){ - StringBuffer tmp = new StringBuffer(); - try { - t = new StringTokenizer(substring, " :\n"); - t.nextToken().trim();//the prop - // we want to return : key1 value1 key2 value2 - while (t.hasMoreTokens()){ - tmp.append(t.nextToken().trim()).append(" "); - tmp.append(t.nextToken().trim()).append(" "); - String test = t.nextToken().trim(); - if (!(test.equalsIgnoreCase("attribute"))) - break; - } - } catch (Exception e){ - } - value = tmp.toString(); - } - else if (prop.equalsIgnoreCase("enum")){ - t = new StringTokenizer(substring, ":"); - t.nextToken().trim(); // the prop we already know - StringBuffer tmp = new StringBuffer(t.nextToken().trim()); - for (int i = 0; i < ATTRIBUTE_NAMES.length; i++){ - if (tmp.toString().endsWith(ATTRIBUTE_NAMES[i])){ - int len = ATTRIBUTE_NAMES[i].length(); - // trim off that - tmp.setLength(tmp.length() - len); - break; - } - } - value = tmp.toString(); - } - else if (prop.equalsIgnoreCase("description")){ - t = new StringTokenizer(substring, ":"); - t.nextToken().trim(); // the prop we already know - StringBuffer tmp = new StringBuffer(t.nextToken().trim()); - for (int i = 0; i < ATTRIBUTE_NAMES.length; i++){ - if (tmp.toString().endsWith(ATTRIBUTE_NAMES[i])){ - int len = ATTRIBUTE_NAMES[i].length(); - // trim off that - tmp.setLength(tmp.length() - len); - break; - } - } - value = hansalizeIt(tmp.toString()); - } - else { - // Single value properties like bound: true - t = new StringTokenizer(substring, ":\n"); - t.nextToken().trim(); // the prop we already know - value = t.nextToken().trim(); - } - - // now we need to look for a match of any of the - // property - - return value; - } - catch (Exception e){ - return "invalidValue"; - } - } - - /** - * Creates a HashMap containing the key value pair for the parsed values - * of the "attributes" and "enum" tags. - * ie. For attribute value: visualUpdate true - * The HashMap will have key: visualUpdate, value: true - */ - private static HashMap getAttributeMap(String str, String delim) { - StringTokenizer t = new StringTokenizer(str, delim); - HashMap map = null; - String key; - String value; - - int num = t.countTokens()/2; - if (num > 0) { - map = new HashMap(); - for (int i = 0; i < num; i++) { - key = t.nextToken().trim(); - value = t.nextToken().trim(); - map.put(key, value); - } - } - return map; - } - - // looks for extra spaces, \n hard-coded and invisible,etc - private static String hansalizeIt(String from){ - char [] chars = from.toCharArray(); - int len = chars.length; - int toss = 0; - - // remove double spaces - for (int i = 0; i < len; i++){ - if ((chars[i] == ' ')) { - if (i+1 < len) { - if ((chars[i+1] == ' ' ) || (chars[i+1] == '\n')) - { - --len; - System.arraycopy(chars,i+1,chars,i,len-i); - --i; - } - } - } - - if (chars[i] == '\n'){ - chars[i] = ' '; - i -= 2; - } - - if (chars[i] == '\\') { - if (i+1 < len) { - if (chars[i+1] == 'n'){ - chars[i+1] = ' '; - --len; - System.arraycopy(chars,i+1, chars,i, len-i); - --i; - } - } - } - } - return new String(chars,0,len); - } - -} diff --git a/jdk/make/src/classes/build/tools/swingbeaninfo/GenSwingBeanInfo.java b/jdk/make/src/classes/build/tools/swingbeaninfo/GenSwingBeanInfo.java deleted file mode 100644 index 0a8a6866b05..00000000000 --- a/jdk/make/src/classes/build/tools/swingbeaninfo/GenSwingBeanInfo.java +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Copyright (c) 1998, 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. 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 build.tools.swingbeaninfo; - -import java.beans.BeanInfo; -import java.beans.BeanDescriptor; -import java.beans.Introspector; -import java.beans.IntrospectionException; -import java.beans.PropertyDescriptor; - -import java.io.*; - -import java.util.Hashtable; -import java.util.HashMap; -import java.util.Iterator; - -/** - * A utlity for generating a BeanInfo source file from a template and a - * Hashtable with hints that were generated from a doclet. - * it's neccessary to write things like the per property descriptions - * by hand. To run the application: - *
- * java GenSwingBeanInfo 
- * 
- * Code for a bean info class is written to out. If the class is - * swing package, you don't need to fully specify its name. - * - * @author Hans Muller - * @author Rich Schiavi - * @author Mark Davidson - */ -public class GenSwingBeanInfo { - private final static String BEANINFO_SUFFIX = "BeanInfo.java"; - - // Tokens in @(...) - private final static String TOK_BEANPACKAGE = "BeanPackageName"; - private final static String TOK_BEANCLASS = "BeanClassName"; - private final static String TOK_BEANOBJECT = "BeanClassObject"; - private final static String TOK_CLASSDESC = "ClassDescriptors"; - private final static String TOK_BEANDESC = "BeanDescription"; - private final static String TOK_PROPDESC = "BeanPropertyDescriptors"; - private final static String TOK_ENUMVARS = "EnumVariables"; - - private String enumcode; // Generated code for enumerated properties. - - private boolean DEBUG = false; - - private String fileDir; - private String templateFilename; - - /** - * Public constructor - * @param fileDir Location to put the generated source files. - * @param templateFilename Location of the BeanInfo template - * @param debug Flag to turn on debugging - */ - public GenSwingBeanInfo(String fileDir, String templateFilename, boolean debug) { - this.fileDir = fileDir; - this.templateFilename = templateFilename; - this.DEBUG = debug; - } - - /** - * Opens a BeanInfo PrintStream for the class. - */ - private PrintStream initOutputFile(String classname) { - try { - OutputStream out = new FileOutputStream(fileDir + File.separator + classname + BEANINFO_SUFFIX); - BufferedOutputStream bout = new BufferedOutputStream(out); - return new PrintStream(out); - } catch (IOException e){ - // System.err.println("GenSwingBeanInfo: " + e.toString()); - } - return null; - } - - private static void messageAndExit(String msg) { - System.err.println("\n" + msg); - System.exit(1); - } - - - /** - * Load the contents of the BeanInfo template into a string and - * return the string. - */ - private String loadTemplate() { - String template = ""; - - try { - File file = new File(templateFilename); - DataInputStream stream = new DataInputStream(new FileInputStream(file)); - BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); - StringBuffer buffer = new StringBuffer(); - - int c; - while((c = reader.read()) != -1) { - buffer.append((char)c); - } - - template = buffer.toString(); - reader.close(); - } catch (IOException e) { - System.out.println(e.getMessage()); - messageAndExit("GenSwingBeanInfo: Couldn't load template: " + templateFilename + e); - } - return template; - } - - - /** - * Generates a string for the BeanDescriptor - */ - private String genBeanDescriptor(DocBeanInfo dbi) { - String code = ""; - int beanflags = dbi.beanflags; - - // we support export, hidden, preferred - if ((beanflags & DocBeanInfo.EXPERT) != 0) - code += " sun.swing.BeanInfoUtils.EXPERT, Boolean.TRUE,\n"; - if ((beanflags & DocBeanInfo.HIDDEN) !=0) - code += " sun.swing.BeanInfoUtils.HIDDEN, Boolean.TRUE,\n"; - /* 1.2 only - make sure build flag build using 1.2 */ - if ((beanflags & DocBeanInfo.PREFERRED) !=0) - code += " sun.swing.BeanInfoUtils.PREFERRED, Boolean.TRUE,\n"; - if (!(dbi.customizerclass.equals("null"))) - code += " sun.swing.BeanInfoUtils.CUSTOMIZERCLASS, " + dbi.customizerclass + ".class,\n"; - - if (dbi.attribs != null) { - code += genAttributes(dbi.attribs); - } - - return code; - } - - /** - * Generates the code for the attributes table. - */ - private String genAttributes(HashMap attribs) { - StringBuffer code = new StringBuffer(); - String key; - String value; - - Iterator iterator = attribs.keySet().iterator(); - while(iterator.hasNext()) { - key = (String)iterator.next(); - value = (String)attribs.get(key); - - if (value.equals("true") || value.equals("false")) { - // Substitute the "true" and "false" for codegen Boolean values. - if(value.equals("true")) - value = "Boolean.TRUE"; - else - value = "Boolean.FALSE"; - - code.append(" \"").append(key).append("\", ").append(value).append(",\n"); - } else { - code.append(" \"").append(key).append("\", \"").append(value).append("\",\n"); - } - } - return code.toString(); - } - - /** - * Generates the code for the enumeration. - * XXX - side effect: Modifies the enumcode field variable. - */ - private String genEnumeration(String propName, HashMap enums) { - String objectName = propName + "Enumeration"; - String key; - String value; - - StringBuffer code = new StringBuffer("\n\t\tObject[] "); - code.append(objectName).append(" = new Object[] { \n"); - - Iterator iterator = enums.keySet().iterator(); - while(iterator.hasNext()) { - key = (String)iterator.next(); - value = (String)enums.get(key); - - code.append("\t\t\t\"").append(key).append("\" , new Integer("); - code.append(value).append("), \"").append(value).append("\",\n"); - } - // Close the statically initialized Object[] - code.replace(code.length() - 2, code.length(), "\n\t\t};\n"); - - // Add this string to the enumeration code. - enumcode += code.toString(); - - // Return the PropertyDescriptor init string; - return " \"enumerationValues\", " + objectName + ",\n"; - } - - /** - * Generate the createPropertyDescriptor() calls, one per property. - * A fully specified createPropertyDescriptor() call looks like this: - *
-     *      createPropertyDescriptor("contentPane", new Object[] {
-     *                           BOUND, Boolean.TRUE,
-     *               CONSTRAINED, Boolean.TRUE,
-     *             PROPERTYEDITORCLASS, package.MyEditor.cl
-     *               WRITEMETHOD, "setContentPane",
-     *               DISPLAYNAME, "contentPane",
-     *                          EXPERT, Boolean.FALSE,
-     *                          HIDDEN, Boolean.FALSE,
-     *                       PREFERRED, Boolean.TRUE,
-     *                SHORTDESCRIPTION, "A top level window with a window manager border",
-     *               "random attribute","random value"
-     *              }
-     *           );
-     * 
- * - * @param info The actual BeanInfo class generated from from the Intospector. - * @param dochash Set of DocBeanInfo pairs for each property. This information - * is used to suplement the instrospected properties. - * @return A snippet of source code which would construct all the PropertyDescriptors. - */ - private String genPropertyDescriptors(BeanInfo info, Hashtable dochash) { - String code = ""; - enumcode = " "; // code for enumerated properties. - PropertyDescriptor[] pds = info.getPropertyDescriptors(); - boolean hash_match = false; - DocBeanInfo dbi = null; - - for(int i = 0; i < pds.length; i++) { - if (pds[i].getReadMethod() != null) { - code += "\ncreatePropertyDescriptor(\"" + pds[i].getName() + "\", new Object[] {\n"; - - if (DEBUG) - System.out.println("Introspected propertyDescriptor: " + pds[i].getName()); - - if (dochash.size() > 0 && dochash.containsKey(pds[i].getName())) { - dbi = (DocBeanInfo)dochash.remove(pds[i].getName()); - // override/set properties on this *introspected* - // BeanInfo pds using our DocBeanInfo class values - setDocInfoProps(dbi, pds[i]); - hash_match = true; - if (DEBUG) - System.out.println("DocBeanInfo class exists for propertyDescriptor: " + pds[i].getName() + "\n"); - } else { - hash_match = false; - } - - // Do I need to do anything with this property descriptor - if (hash_match) { - if ((dbi.beanflags & DocBeanInfo.BOUND) != 0) { - code += " sun.swing.BeanInfoUtils.BOUND, Boolean.TRUE,\n"; - } else { - code += " sun.swing.BeanInfoUtils.BOUND, Boolean.FALSE,\n"; - } - } - - if (pds[i].isConstrained()) { - code += " sun.swing.BeanInfoUtils.CONSTRAINED, Boolean.TRUE,\n"; - } - - if (pds[i].getPropertyEditorClass() != null) { - String className = pds[i].getPropertyEditorClass().getName(); - code += " sun.swing.BeanInfoUtils.PROPERTYEDITORCLASS, " + className + ".class,\n"; - } else if ((hash_match) && (!(dbi.propertyeditorclass.equals("null")))) { - code += " sun.swing.BeanInfoUtils.PROPERTYEDITORCLASS, " + dbi.propertyeditorclass + ".class,\n"; - } - - if ((hash_match) && (!(dbi.customizerclass.equals("null")))) { - code += " sun.swing.BeanInfoUtils.CUSTOMIZERCLASS, " + dbi.customizerclass + ".class,\n"; - } - - if ((hash_match) && (dbi.enums != null)) { - code += genEnumeration(pds[i].getName(), dbi.enums); - } - - if (!pds[i].getDisplayName().equals(pds[i].getName())) { - code += " sun.swing.BeanInfoUtils.DISPLAYNAME, \"" + pds[i].getDisplayName() + "\",\n"; - } - - if (pds[i].isExpert()) { - code += " sun.swing.BeanInfoUtils.EXPERT, Boolean.TRUE,\n"; - } - - if (pds[i].isHidden()) { - code += " sun.swing.BeanInfoUtils.HIDDEN, Boolean.TRUE,\n"; - } - - if (pds[i].isPreferred()) { - code += " sun.swing.BeanInfoUtils.PREFERRED, Boolean.TRUE,\n"; - } - - // user attributes - if (hash_match) { - if (dbi.attribs != null) { - code += genAttributes(dbi.attribs); - } - } - code += " sun.swing.BeanInfoUtils.SHORTDESCRIPTION, \"" + pds[i].getShortDescription() + "\",\n"; - - // Print the closing brackets. If this is the last array initializer, - // don't print the trailing comma. - if (i == (pds.length - 1)) { - code += " }\n)\n"; - } else { - code += " }\n),\n"; - } - - } // end if ( readMethod != null ) - } // end for - return code; - } - - /** - * Sets properties from the BeanInfo supplement on the - * introspected PropertyDescriptor - */ - private void setDocInfoProps(DocBeanInfo dbi, PropertyDescriptor pds) { - int beanflags = dbi.beanflags; - - if ((beanflags & DocBeanInfo.BOUND) != 0) - pds.setBound(true); - if ((beanflags & DocBeanInfo.EXPERT) != 0) - pds.setExpert(true); - if ((beanflags & DocBeanInfo.CONSTRAINED) != 0) - pds.setConstrained(true); - if ((beanflags & DocBeanInfo.HIDDEN) !=0) - pds.setHidden(true); - if ((beanflags & DocBeanInfo.PREFERRED) !=0) - pds.setPreferred(true); - - if (!(dbi.desc.equals("null"))){ - pds.setShortDescription(dbi.desc); - } - if (!(dbi.displayname.equals("null"))){ - pds.setDisplayName(dbi.displayname); - } - } - - /** - * Generates the BeanInfo source file using instrospection and a - * Hashtable full of hints. This the only public method in this class. - * - * @param classname Root name of the class. i.e., JButton - * @param dochash A hashtable containing the DocBeanInfo. - */ - public void genBeanInfo(String packageName, String classname, Hashtable dochash) { - // The following initial values are just examples. All of these - // fields are initialized below. - String beanClassName = "JInternalFrame"; - String beanClassObject = "javax.swing.JInternalFrame.class"; - String beanDescription = "."; - String beanPropertyDescriptors = ""; - String classPropertyDescriptors = ""; - - Class cls = getClass(packageName, classname); - if (cls == null){ - messageAndExit("Can't find class: " + classname); - } - - // Get the output stream. - PrintStream out = initOutputFile(classname); - - // Run the Introspector and initialize the variables - - BeanInfo beanInfo = null; - BeanDescriptor beanDescriptor = null; - - try { - if (cls == javax.swing.JComponent.class) { - // Go all the way up the heirarchy for JComponent - beanInfo = Introspector.getBeanInfo(cls); - } else { - beanInfo = Introspector.getBeanInfo(cls, cls.getSuperclass()); - } - beanDescriptor = beanInfo.getBeanDescriptor(); - beanDescription = beanDescriptor.getShortDescription(); - } catch (IntrospectionException e) { - messageAndExit("Introspection failed for " + cls.getName() + " " + e); - } - - beanClassName = beanDescriptor.getName(); - beanClassObject = cls.getName() + ".class"; - - if (DEBUG){ - System.out.println(">>>>GenSwingBeanInfo class: " + beanClassName); - } - // Generate the Class BeanDescriptor information first - if (dochash.size() > 0) { - if (dochash.containsKey(beanClassName)) { - DocBeanInfo dbi = (DocBeanInfo)dochash.remove(beanClassName); - classPropertyDescriptors = genBeanDescriptor(dbi); - if (DEBUG) - System.out.println("ClassPropertyDescriptors: " + classPropertyDescriptors); - if (!(dbi.desc.equals("null"))) - beanDescription = dbi.desc; - } else - beanDescription = beanDescriptor.getShortDescription(); - } else - beanDescription = beanDescriptor.getShortDescription(); - - // Generate the Property descriptors - beanPropertyDescriptors = genPropertyDescriptors(beanInfo,dochash); - - // Dump the template to out, substituting values for - // @(token) tokens as they're encountered. - - int currentIndex = 0; - // not loading this to get around build issue for now - String template = loadTemplate(); - - // This loop substitutes the "@(...)" tags in the template with the ones for the - // current class. - while (currentIndex < template.length()) { - // Find the Token - int tokenStart = template.indexOf("@(", currentIndex); - if (tokenStart != -1) { - out.print(template.substring(currentIndex, tokenStart)); - - int tokenEnd = template.indexOf(")", tokenStart); - if (tokenEnd == -1) { - messageAndExit("Bad @() beginning at " + tokenStart); - } - String token = template.substring(tokenStart+2, tokenEnd); - - if (token.equals(TOK_BEANCLASS)) { - out.print(beanClassName); - } else if (token.equals(TOK_CLASSDESC)) { - if (!(classPropertyDescriptors.equals(""))) { - printDescriptors(out, classPropertyDescriptors, template, tokenStart); - } - } else if (token.equals(TOK_BEANPACKAGE)){ - out.print(packageName); - } else if (token.equals(TOK_BEANOBJECT)) { - out.print(beanClassObject); - } else if (token.equals(TOK_BEANDESC)) { - out.print(beanDescription); - } else if (token.equals(TOK_ENUMVARS)){ - out.print(enumcode); - } else if (token.equals(TOK_PROPDESC)) { - printDescriptors(out, beanPropertyDescriptors, template, tokenStart); - } else if (token.equals("#")) { - // Ignore the @(#) Version Control tag if it exists. - } else { - messageAndExit("Unrecognized token @(" + token + ")"); - } - currentIndex = tokenEnd + 1; - } else { - // tokenStart == -1 - We are finsihed. - out.print(template.substring(currentIndex, template.length())); - break; - } - } - out.close(); - } - - /** - * Returns the class from the package name and the class root name. - * - * @param packageName The name of the package of the containing class. - * @param rootname The root name of the class. i.e, JButton - * @return The class instance or null. - */ - private Class getClass(String packageName, String rootname) { - Class cls = null; - String classname = rootname; - - if (packageName != null || !packageName.equals("")) { - classname = packageName + "." + rootname; - } - - try { - cls = Class.forName(classname); - } catch (ClassNotFoundException e) { - // Fail silently. - } - return cls; - } - - /** - * Prints the formated descriptors to the PrintStream - * @param out Open PrintStream - * @param s String descriptor - * @param template Template - * @param tokenStart Index into the template - */ - private void printDescriptors(PrintStream out, String s, - String template, int tokenStart) { - String indent = ""; - - // Find the newline that preceeds @(BeanPropertyDescriptors) to - // calculate the indent. - for (int i = tokenStart; i >= 0; i--) { - if (template.charAt(i) == '\n') { - char[] chars = new char[tokenStart - i]; - for (int j = 0; j < chars.length; j++) { - chars[j] = ' '; - } - indent = new String(chars); - break; - } - } - - int i = 0; - while(i < s.length()) { - int nlIndex = s.indexOf('\n', i); - out.print(s.substring(i, nlIndex+1)); - out.print(indent); - i = nlIndex + 1; - } - } - - -} diff --git a/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java b/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java index b6475b85a24..2aa3fbcbaa2 100644 --- a/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java +++ b/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java @@ -31,7 +31,6 @@ package sun.nio.ch; -import sun.misc.*; import java.io.IOException; import java.io.FileDescriptor; import java.util.Iterator; diff --git a/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java b/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java index 352ab7ebd4d..ae6bfbcc59e 100644 --- a/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java +++ b/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java @@ -36,7 +36,6 @@ import java.io.FileDescriptor; import java.nio.channels.*; import java.nio.channels.spi.*; import java.util.*; -import sun.misc.*; class KQueueSelectorImpl extends SelectorImpl diff --git a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java index fa6a652067b..9fe76558c82 100644 --- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java +++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java @@ -2625,6 +2625,25 @@ public abstract class ClassLoader { // the ServiceCatalog for modules associated with this class loader. private volatile ServicesCatalog servicesCatalog; + /** + * Returns the ConcurrentHashMap used as a storage for ClassLoaderValue(s) + * associated with this ClassLoader, creating it if it doesn't already exist. + */ + ConcurrentHashMap createOrGetClassLoaderValueMap() { + ConcurrentHashMap map = classLoaderValueMap; + if (map == null) { + map = new ConcurrentHashMap<>(); + boolean set = trySetObjectField("classLoaderValueMap", map); + if (!set) { + // beaten by someone else + map = classLoaderValueMap; + } + } + return map; + } + + // the storage for ClassLoaderValue(s) associated with this ClassLoader + private volatile ConcurrentHashMap classLoaderValueMap; /** * Attempts to atomically set a volatile field in this object. Returns diff --git a/jdk/src/java.base/share/classes/java/lang/StringCoding.java b/jdk/src/java.base/share/classes/java/lang/StringCoding.java index fe875372218..ccbe6f24b43 100644 --- a/jdk/src/java.base/share/classes/java/lang/StringCoding.java +++ b/jdk/src/java.base/share/classes/java/lang/StringCoding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -146,7 +146,7 @@ class StringCoding { } @HotSpotIntrinsicCandidate - private static boolean hasNegatives(byte[] ba, int off, int len) { + public static boolean hasNegatives(byte[] ba, int off, int len) { for (int i = off; i < off + len; i++) { if (ba[i] < 0) { return true; diff --git a/jdk/src/java.base/share/classes/java/lang/System.java b/jdk/src/java.base/share/classes/java/lang/System.java index 92fee1a4337..5bbaff28335 100644 --- a/jdk/src/java.base/share/classes/java/lang/System.java +++ b/jdk/src/java.base/share/classes/java/lang/System.java @@ -49,6 +49,7 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.nio.channels.Channel; import java.nio.channels.spi.SelectorProvider; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Stream; import java.util.Objects; @@ -2026,6 +2027,9 @@ public final class System { public ServicesCatalog createOrGetServicesCatalog(ClassLoader cl) { return cl.createOrGetServicesCatalog(); } + public ConcurrentHashMap createOrGetClassLoaderValueMap(ClassLoader cl) { + return cl.createOrGetClassLoaderValueMap(); + } public Class findBootstrapClassOrNull(ClassLoader cl, String name) { return cl.findBootstrapClassOrNull(name); } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/InfoFromMemberName.java b/jdk/src/java.base/share/classes/java/lang/invoke/InfoFromMemberName.java index 6e9e1de81ee..8ee5f19809d 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/InfoFromMemberName.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InfoFromMemberName.java @@ -41,7 +41,7 @@ class InfoFromMemberName implements MethodHandleInfo { private final int referenceKind; InfoFromMemberName(Lookup lookup, MemberName member, byte referenceKind) { - assert(member.isResolved() || member.isMethodHandleInvoke()); + assert(member.isResolved() || member.isMethodHandleInvoke() || member.isVarHandleMethodInvoke()); assert(member.referenceKindIsConsistentWith(referenceKind)); this.member = member; this.referenceKind = referenceKind; @@ -79,7 +79,8 @@ class InfoFromMemberName implements MethodHandleInfo { @Override public T reflectAs(Class expected, Lookup lookup) { - if (member.isMethodHandleInvoke() && !member.isVarargs()) { + if ((member.isMethodHandleInvoke() || member.isVarHandleMethodInvoke()) + && !member.isVarargs()) { // This member is an instance of a signature-polymorphic method, which cannot be reflected // A method handle invoker can come in either of two forms: // A generic placeholder (present in the source code, and varargs) diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java index 277cac28a44..6c2b134c31c 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java @@ -93,6 +93,16 @@ class Invokers { return setCachedInvoker(INV_BASIC, invoker); } + /*non-public*/ MethodHandle varHandleMethodInvoker(VarHandle.AccessMode ak) { + // TODO cache invoker + return makeVarHandleMethodInvoker(ak); + } + + /*non-public*/ MethodHandle varHandleMethodExactInvoker(VarHandle.AccessMode ak) { + // TODO cache invoker + return makeVarHandleMethodExactInvoker(ak); + } + private MethodHandle cachedInvoker(int idx) { return invokers[idx]; } @@ -117,6 +127,36 @@ class Invokers { return invoker; } + private MethodHandle makeVarHandleMethodInvoker(VarHandle.AccessMode ak) { + MethodType mtype = targetType; + MethodType invokerType = mtype.insertParameterTypes(0, VarHandle.class); + + LambdaForm lform = varHandleMethodGenericInvokerHandleForm(ak.name(), mtype); + VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal()); + MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, ad); + + invoker = invoker.withInternalMemberName(MemberName.makeVarHandleMethodInvoke(ak.name(), mtype), false); + assert(checkVarHandleInvoker(invoker)); + + maybeCompileToBytecode(invoker); + return invoker; + } + + private MethodHandle makeVarHandleMethodExactInvoker(VarHandle.AccessMode ak) { + MethodType mtype = targetType; + MethodType invokerType = mtype.insertParameterTypes(0, VarHandle.class); + + LambdaForm lform = varHandleMethodExactInvokerHandleForm(ak.name(), mtype); + VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal()); + MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, ad); + + invoker = invoker.withInternalMemberName(MemberName.makeVarHandleMethodInvoke(ak.name(), mtype), false); + assert(checkVarHandleInvoker(invoker)); + + maybeCompileToBytecode(invoker); + return invoker; + } + /** If the target type seems to be common enough, eagerly compile the invoker to bytecodes. */ private void maybeCompileToBytecode(MethodHandle invoker) { final int EAGER_COMPILE_ARITY_LIMIT = 10; @@ -146,6 +186,16 @@ class Invokers { return true; } + private boolean checkVarHandleInvoker(MethodHandle invoker) { + MethodType invokerType = targetType.insertParameterTypes(0, VarHandle.class); + assert(invokerType.equals(invoker.type())) + : java.util.Arrays.asList(targetType, invokerType, invoker); + assert(invoker.internalMemberName() == null || + invoker.internalMemberName().getMethodType().equals(targetType)); + assert(!invoker.isVarargsCollector()); + return true; + } + /** * Find or create an invoker which passes unchanged a given number of arguments * and spreads the rest from a trailing array argument. @@ -193,9 +243,9 @@ class Invokers { Object[] appendixResult) { int which; switch (name) { - case "invokeExact": which = MethodTypeForm.LF_EX_LINKER; break; - case "invoke": which = MethodTypeForm.LF_GEN_LINKER; break; - default: throw new InternalError("not invoker: "+name); + case "invokeExact": which = MethodTypeForm.LF_EX_LINKER; break; + case "invoke": which = MethodTypeForm.LF_GEN_LINKER; break; + default: throw new InternalError("not invoker: "+name); } LambdaForm lform; if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) { @@ -296,6 +346,199 @@ class Invokers { return lform; } + + static MemberName varHandleInvokeLinkerMethod(String name, + MethodType mtype) { + LambdaForm lform; + if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) { + lform = varHandleMethodGenericLinkerHandleForm(name, mtype); + } else { + // TODO + throw newInternalError("Unsupported parameter slot count " + mtype.parameterSlotCount()); + } + return lform.vmentry; + } + + private static LambdaForm varHandleMethodGenericLinkerHandleForm(String name, MethodType mtype) { + // TODO Cache form? + + final int THIS_VH = 0; + final int ARG_BASE = THIS_VH + 1; + final int ARG_LIMIT = ARG_BASE + mtype.parameterCount(); + int nameCursor = ARG_LIMIT; + final int VAD_ARG = nameCursor++; + final int CHECK_TYPE = nameCursor++; + final int CHECK_CUSTOM = (CUSTOMIZE_THRESHOLD >= 0) ? nameCursor++ : -1; + final int LINKER_CALL = nameCursor++; + + Name[] names = new Name[LINKER_CALL + 1]; + names[THIS_VH] = argument(THIS_VH, BasicType.basicType(Object.class)); + for (int i = 0; i < mtype.parameterCount(); i++) { + names[ARG_BASE + i] = argument(ARG_BASE + i, BasicType.basicType(mtype.parameterType(i))); + } + names[VAD_ARG] = new Name(ARG_LIMIT, BasicType.basicType(Object.class)); + + names[CHECK_TYPE] = new Name(NF_checkVarHandleGenericType, names[THIS_VH], names[VAD_ARG]); + + Object[] outArgs = new Object[ARG_LIMIT + 1]; + outArgs[0] = names[CHECK_TYPE]; + for (int i = 0; i < ARG_LIMIT; i++) { + outArgs[i + 1] = names[i]; + } + + if (CHECK_CUSTOM != -1) { + names[CHECK_CUSTOM] = new Name(NF_checkCustomized, outArgs[0]); + } + + MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class) + .basicType(); + names[LINKER_CALL] = new Name(outCallType, outArgs); + LambdaForm lform = new LambdaForm(name + ":VarHandle_invoke_MT_" + shortenSignature(basicTypeSignature(mtype)), + ARG_LIMIT + 1, names); + + lform.prepare(); + return lform; + } + + private static LambdaForm varHandleMethodExactInvokerHandleForm(String name, MethodType mtype) { + // TODO Cache form? + + final int THIS_MH = 0; + final int CALL_VH = THIS_MH + 1; + final int ARG_BASE = CALL_VH + 1; + final int ARG_LIMIT = ARG_BASE + mtype.parameterCount(); + int nameCursor = ARG_LIMIT; + final int VAD_ARG = nameCursor++; + final int CHECK_TYPE = nameCursor++; + final int GET_MEMBER = nameCursor++; + final int LINKER_CALL = nameCursor++; + + MethodType invokerFormType = mtype.insertParameterTypes(0, VarHandle.class) + .basicType() + .appendParameterTypes(MemberName.class); + + MemberName linker = new MemberName(MethodHandle.class, "linkToStatic", invokerFormType, REF_invokeStatic); + try { + linker = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class); + } catch (ReflectiveOperationException ex) { + throw newInternalError(ex); + } + + Name[] names = new Name[LINKER_CALL + 1]; + names[THIS_MH] = argument(THIS_MH, BasicType.basicType(Object.class)); + names[CALL_VH] = argument(CALL_VH, BasicType.basicType(Object.class)); + for (int i = 0; i < mtype.parameterCount(); i++) { + names[ARG_BASE + i] = argument(ARG_BASE + i, BasicType.basicType(mtype.parameterType(i))); + } + + BoundMethodHandle.SpeciesData speciesData = BoundMethodHandle.speciesData_L(); + names[THIS_MH] = names[THIS_MH].withConstraint(speciesData); + + NamedFunction getter = speciesData.getterFunction(0); + names[VAD_ARG] = new Name(getter, names[THIS_MH]); + + Object[] outArgs = Arrays.copyOfRange(names, CALL_VH, ARG_LIMIT + 1, Object[].class); + + names[CHECK_TYPE] = new Name(NF_checkVarHandleExactType, names[CALL_VH], names[VAD_ARG]); + + names[GET_MEMBER] = new Name(NF_getVarHandleMemberName, names[CALL_VH], names[VAD_ARG]); + outArgs[outArgs.length - 1] = names[GET_MEMBER]; + + names[LINKER_CALL] = new Name(linker, outArgs); + LambdaForm lform = new LambdaForm(name + ":VarHandle_exactInvoker" + shortenSignature(basicTypeSignature(mtype)), + ARG_LIMIT, names); + + lform.prepare(); + return lform; + } + + private static LambdaForm varHandleMethodGenericInvokerHandleForm(String name, MethodType mtype) { + // TODO Cache form? + + final int THIS_MH = 0; + final int CALL_VH = THIS_MH + 1; + final int ARG_BASE = CALL_VH + 1; + final int ARG_LIMIT = ARG_BASE + mtype.parameterCount(); + int nameCursor = ARG_LIMIT; + final int VAD_ARG = nameCursor++; + final int CHECK_TYPE = nameCursor++; + final int LINKER_CALL = nameCursor++; + + Name[] names = new Name[LINKER_CALL + 1]; + names[THIS_MH] = argument(THIS_MH, BasicType.basicType(Object.class)); + names[CALL_VH] = argument(CALL_VH, BasicType.basicType(Object.class)); + for (int i = 0; i < mtype.parameterCount(); i++) { + names[ARG_BASE + i] = argument(ARG_BASE + i, BasicType.basicType(mtype.parameterType(i))); + } + + BoundMethodHandle.SpeciesData speciesData = BoundMethodHandle.speciesData_L(); + names[THIS_MH] = names[THIS_MH].withConstraint(speciesData); + + NamedFunction getter = speciesData.getterFunction(0); + names[VAD_ARG] = new Name(getter, names[THIS_MH]); + + names[CHECK_TYPE] = new Name(NF_checkVarHandleGenericType, names[CALL_VH], names[VAD_ARG]); + + Object[] outArgs = new Object[ARG_LIMIT]; + outArgs[0] = names[CHECK_TYPE]; + for (int i = 1; i < ARG_LIMIT; i++) { + outArgs[i] = names[i]; + } + + MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class) + .basicType(); + names[LINKER_CALL] = new Name(outCallType, outArgs); + LambdaForm lform = new LambdaForm(name + ":VarHandle_invoker" + shortenSignature(basicTypeSignature(mtype)), + ARG_LIMIT, names); + + lform.prepare(); + return lform; + } + + /*non-public*/ static + @ForceInline + MethodHandle checkVarHandleGenericType(VarHandle vh, VarHandle.AccessDescriptor vad) { + MethodType expected = vad.symbolicMethodType; + MethodType actual = VarHandle.AccessType.getMethodType(vad.type, vh); + + MemberName mn = VarHandle.AccessMode.getMemberName(vad.mode, vh.vform); + if (mn == null) + throw vh.unsupported(); + // TODO the following MH is not constant, cache in stable field array + // on VarForm? + MethodHandle mh = DirectMethodHandle.make(mn); + if (actual == expected) { + return mh; + } + else { + // Adapt to the actual (which should never fail since mh's method + // type is in the basic form), then to the expected (which my fail + // if the symbolic type descriptor does not match) + // TODO optimize for the case of actual.erased() == expected.erased() + return mh.asType(actual.insertParameterTypes(0, VarHandle.class)). + asType(expected.insertParameterTypes(0, VarHandle.class)); + } + } + + /*non-public*/ static + @ForceInline + void checkVarHandleExactType(VarHandle vh, VarHandle.AccessDescriptor vad) { + MethodType expected = vad.symbolicMethodType; + MethodType actual = VarHandle.AccessType.getMethodType(vad.type, vh); + if (actual != expected) + throw newWrongMethodTypeException(expected, actual); + } + + /*non-public*/ static + @ForceInline + MemberName getVarHandleMemberName(VarHandle vh, VarHandle.AccessDescriptor vad) { + MemberName mn = VarHandle.AccessMode.getMemberName(vad.mode, vh.vform); + if (mn == null) { + throw vh.unsupported(); + } + return mn; + } + /*non-public*/ static WrongMethodTypeException newWrongMethodTypeException(MethodType actual, MethodType expected) { // FIXME: merge with JVM logic for throwing WMTE @@ -415,7 +658,10 @@ class Invokers { NF_checkExactType, NF_checkGenericType, NF_getCallSiteTarget, - NF_checkCustomized; + NF_checkCustomized, + NF_checkVarHandleGenericType, + NF_checkVarHandleExactType, + NF_getVarHandleMemberName; static { try { NamedFunction nfs[] = { @@ -426,7 +672,13 @@ class Invokers { NF_getCallSiteTarget = new NamedFunction(Invokers.class .getDeclaredMethod("getCallSiteTarget", CallSite.class)), NF_checkCustomized = new NamedFunction(Invokers.class - .getDeclaredMethod("checkCustomized", MethodHandle.class)) + .getDeclaredMethod("checkCustomized", MethodHandle.class)), + NF_checkVarHandleGenericType = new NamedFunction(Invokers.class + .getDeclaredMethod("checkVarHandleGenericType", VarHandle.class, VarHandle.AccessDescriptor.class)), + NF_checkVarHandleExactType = new NamedFunction(Invokers.class + .getDeclaredMethod("checkVarHandleExactType", VarHandle.class, VarHandle.AccessDescriptor.class)), + NF_getVarHandleMemberName = new NamedFunction(Invokers.class + .getDeclaredMethod("getVarHandleMemberName", VarHandle.class, VarHandle.AccessDescriptor.class)) }; // Each nf must be statically invocable or we get tied up in our bootstraps. assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs)); diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java index 3c6b0d14d50..da91db90da3 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java @@ -363,6 +363,23 @@ import java.util.Objects; return false; } } + public boolean isVarHandleMethodInvoke() { + final int bits = MH_INVOKE_MODS &~ Modifier.PUBLIC; + final int negs = Modifier.STATIC; + if (testFlags(bits | negs, bits) && + clazz == VarHandle.class) { + return isVarHandleMethodInvokeName(name); + } + return false; + } + public static boolean isVarHandleMethodInvokeName(String name) { + try { + VarHandle.AccessMode.valueOf(name); + return true; + } catch (IllegalArgumentException e) { + return false; + } + } private static final int MH_INVOKE_MODS = Modifier.NATIVE | Modifier.FINAL | Modifier.PUBLIC; /** Utility method to query the modifier flags of this member. */ @@ -538,6 +555,17 @@ import java.util.Objects; if (isMethodHandleInvoke()) return; } + if (m.getDeclaringClass() == VarHandle.class && + isVarHandleMethodInvokeName(m.getName())) { + // The JVM did not reify this signature-polymorphic instance. + // Need a special case here. + // See comments on MethodHandleNatives.linkMethod. + MethodType type = MethodType.methodType(m.getReturnType(), m.getParameterTypes()); + int flags = flagsMods(IS_METHOD, m.getModifiers(), REF_invokeVirtual); + init(VarHandle.class, m.getName(), type, flags); + if (isVarHandleMethodInvoke()) + return; + } throw new LinkageError(m.toString()); } assert(isResolved() && this.clazz != null); @@ -666,6 +694,16 @@ import java.util.Objects; return mem; } + static MemberName makeVarHandleMethodInvoke(String name, MethodType type) { + return makeVarHandleMethodInvoke(name, type, MH_INVOKE_MODS | SYNTHETIC); + } + static MemberName makeVarHandleMethodInvoke(String name, MethodType type, int mods) { + MemberName mem = new MemberName(VarHandle.class, name, type, REF_invokeVirtual); + mem.flags |= mods; // it's not resolved, but add these modifiers anyway + assert(mem.isVarHandleMethodInvoke()) : mem; + return mem; + } + // bare-bones constructor; the JVM will fill it in MemberName() { } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java index 235ffe60f57..98b43b6213d 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java @@ -26,9 +26,11 @@ package java.lang.invoke; -import java.util.*; import jdk.internal.HotSpotIntrinsicCandidate; +import java.util.Arrays; +import java.util.Objects; + import static java.lang.invoke.MethodHandleStatics.*; /** @@ -92,14 +94,16 @@ import static java.lang.invoke.MethodHandleStatics.*; * and {@code invoke} compile to an {@code invokevirtual} instruction. * More unusually, the compiler must record the actual argument types, * and may not perform method invocation conversions on the arguments. - * Instead, it must push them on the stack according to their own unconverted types. - * The method handle object itself is pushed on the stack before the arguments. - * The compiler then calls the method handle with a symbolic type descriptor which - * describes the argument and return types. + * Instead, it must generate instructions that push them on the stack according + * to their own unconverted types. The method handle object itself is pushed on + * the stack before the arguments. + * The compiler then generates an {@code invokevirtual} instruction that invokes + * the method handle with a symbolic type descriptor which describes the argument + * and return types. *

* To issue a complete symbolic type descriptor, the compiler must also determine * the return type. This is based on a cast on the method invocation expression, - * if there is one, or else {@code Object} if the invocation is an expression + * if there is one, or else {@code Object} if the invocation is an expression, * or else {@code void} if the invocation is a statement. * The cast may be to a primitive type (but not {@code void}). *

@@ -109,12 +113,12 @@ import static java.lang.invoke.MethodHandleStatics.*; * {@code Void} except the null reference. * *

Method handle invocation

- * The first time a {@code invokevirtual} instruction is executed - * it is linked, by symbolically resolving the names in the instruction + * The first time an {@code invokevirtual} instruction is executed + * it is linked by symbolically resolving the names in the instruction * and verifying that the method call is statically legal. - * This is true of calls to {@code invokeExact} and {@code invoke}. + * This also holds for calls to {@code invokeExact} and {@code invoke}. * In this case, the symbolic type descriptor emitted by the compiler is checked for - * correct syntax and names it contains are resolved. + * correct syntax, and names it contains are resolved. * Thus, an {@code invokevirtual} instruction which invokes * a method handle will always link, as long * as the symbolic type descriptor is syntactically well-formed @@ -163,7 +167,7 @@ import static java.lang.invoke.MethodHandleStatics.*; * in a program which uses method handles. *

* Because method types contain "live" {@code Class} objects, - * method type matching takes into account both types names and class loaders. + * method type matching takes into account both type names and class loaders. * Thus, even if a method handle {@code M} is created in one * class loader {@code L1} and used in another {@code L2}, * method handle calls are type-safe, because the caller's symbolic type @@ -174,7 +178,7 @@ import static java.lang.invoke.MethodHandleStatics.*; * and its type is assigned, while the resolution in {@code L2} happens * when the {@code invokevirtual} instruction is linked. *

- * Apart from the checking of type descriptors, + * Apart from type descriptor checks, * a method handle's capability to call its underlying method is unrestricted. * If a method handle is formed on a non-public method by a class * that has access to that method, the resulting handle can be used @@ -196,7 +200,7 @@ import static java.lang.invoke.MethodHandleStatics.*; * Java code can create a method handle that directly accesses * any method, constructor, or field that is accessible to that code. * This is done via a reflective, capability-based API called - * {@link java.lang.invoke.MethodHandles.Lookup MethodHandles.Lookup} + * {@link java.lang.invoke.MethodHandles.Lookup MethodHandles.Lookup}. * For example, a static method handle can be obtained * from {@link java.lang.invoke.MethodHandles.Lookup#findStatic Lookup.findStatic}. * There are also conversion methods from Core Reflection API objects, diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java index ed1dccc8041..026e3062ae8 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -1060,6 +1060,19 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; FAKE_METHOD_HANDLE_INVOKE[idx] = mh; return mh; } + static MethodHandle fakeVarHandleInvoke(MemberName method) { + // TODO caching, is it necessary? + MethodType type = MethodType.methodType(method.getReturnType(), UnsupportedOperationException.class, + VarHandle.class, Object[].class); + MethodHandle mh = throwException(type); + mh = mh.bindTo(new UnsupportedOperationException("cannot reflectively invoke VarHandle")); + if (!method.getInvocationType().equals(mh.type())) + throw new InternalError(method.toString()); + mh = mh.withInternalMemberName(method, false); + mh = mh.asVarargsCollector(Object[].class); + assert(method.isVarargs()); + return mh; + } /** * Create an alias for the method handle which, when called, diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java index 57ad668b903..16d28faea0b 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java @@ -25,12 +25,15 @@ package java.lang.invoke; +import jdk.internal.ref.CleanerFactory; +import sun.invoke.util.Wrapper; + import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Field; + import static java.lang.invoke.MethodHandleNatives.Constants.*; -import static java.lang.invoke.MethodHandleStatics.*; +import static java.lang.invoke.MethodHandleStatics.TRACE_METHOD_LINKAGE; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; -import jdk.internal.ref.CleanerFactory; /** * The JVM interface for the method handles package is all here. @@ -367,8 +370,14 @@ class MethodHandleNatives { Class defc, String name, Object type, Object[] appendixResult) { try { - if (defc == MethodHandle.class && refKind == REF_invokeVirtual) { - return Invokers.methodHandleInvokeLinkerMethod(name, fixMethodType(callerClass, type), appendixResult); + if (refKind == REF_invokeVirtual) { + if (defc == MethodHandle.class) { + return Invokers.methodHandleInvokeLinkerMethod( + name, fixMethodType(callerClass, type), appendixResult); + } else if (defc == VarHandle.class) { + return varHandleOperationLinkerMethod( + name, fixMethodType(callerClass, type), appendixResult); + } } } catch (Throwable ex) { if (ex instanceof LinkageError) @@ -400,6 +409,80 @@ class MethodHandleNatives { } } + /** + * Obtain the method to link to the VarHandle operation. + * This method is located here and not in Invokers to avoid + * intializing that and other classes early on in VM bootup. + */ + private static MemberName varHandleOperationLinkerMethod(String name, + MethodType mtype, + Object[] appendixResult) { + // Get the signature method type + MethodType sigType = mtype.basicType(); + + // Get the access kind from the method name + VarHandle.AccessMode ak; + try { + ak = VarHandle.AccessMode.valueOf(name); + } catch (IllegalArgumentException e) { + throw MethodHandleStatics.newInternalError(e); + } + + // If not polymorphic in the return type, such as the compareAndSet + // methods that return boolean + if (ak.isPolyMorphicInReturnType) { + if (ak.returnType != mtype.returnType()) { + // The caller contains a different return type than that + // defined by the method + throw newNoSuchMethodErrorOnVarHandle(name, mtype); + } + // Adjust the return type of the signature method type + sigType = sigType.changeReturnType(ak.returnType); + } + + // Get the guard method type for linking + MethodType guardType = sigType + // VarHandle at start + .insertParameterTypes(0, VarHandle.class) + // Access descriptor at end + .appendParameterTypes(VarHandle.AccessDescriptor.class); + + // Create the appendix descriptor constant + VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal()); + appendixResult[0] = ad; + + if (MethodHandleStatics.VAR_HANDLE_GUARDS) { + MemberName linker = new MemberName( + VarHandleGuards.class, "guard_" + getVarHandleMethodSignature(sigType), + guardType, REF_invokeStatic); + try { + return MemberName.getFactory().resolveOrFail( + REF_invokeStatic, linker, VarHandleGuards.class, ReflectiveOperationException.class); + } catch (ReflectiveOperationException ex) { + // Fall back to lambda form linkage if guard method is not available + // TODO Optionally log fallback ? + } + } + return Invokers.varHandleInvokeLinkerMethod(name, mtype); + } + static String getVarHandleMethodSignature(MethodType mt) { + StringBuilder sb = new StringBuilder(mt.parameterCount() + 1); + + for (int i = 0; i < mt.parameterCount(); i++) { + Class pt = mt.parameterType(i); + sb.append(getCharType(pt)); + } + + sb.append('_').append(getCharType(mt.returnType())); + + return sb.toString(); + } + static char getCharType(Class pt) { + return Wrapper.forBasicType(pt).basicTypeChar(); + } + static NoSuchMethodError newNoSuchMethodErrorOnVarHandle(String name, MethodType mtype) { + return new NoSuchMethodError("VarHandle." + name + mtype); + } /** * The JVM is resolving a CONSTANT_MethodHandle CP entry. And it wants our help. diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java index 9db2ad68f53..df1cba46fa8 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java @@ -50,9 +50,10 @@ import jdk.internal.misc.Unsafe; static final int PROFILE_LEVEL; static final boolean PROFILE_GWT; static final int CUSTOMIZE_THRESHOLD; + static final boolean VAR_HANDLE_GUARDS; static { - final Object[] values = new Object[9]; + final Object[] values = new Object[10]; AccessController.doPrivileged(new PrivilegedAction<>() { public Void run() { values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES"); @@ -64,6 +65,7 @@ import jdk.internal.misc.Unsafe; values[6] = Integer.getInteger("java.lang.invoke.MethodHandle.PROFILE_LEVEL", 0); values[7] = Boolean.parseBoolean(System.getProperty("java.lang.invoke.MethodHandle.PROFILE_GWT", "true")); values[8] = Integer.getInteger("java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD", 127); + values[9] = Boolean.parseBoolean(System.getProperty("java.lang.invoke.VarHandle.VAR_HANDLE_GUARDS", "true")); return null; } }); @@ -76,6 +78,7 @@ import jdk.internal.misc.Unsafe; PROFILE_LEVEL = (Integer) values[6]; PROFILE_GWT = (Boolean) values[7]; CUSTOMIZE_THRESHOLD = (Integer) values[8]; + VAR_HANDLE_GUARDS = (Boolean) values[9]; if (CUSTOMIZE_THRESHOLD < -1 || CUSTOMIZE_THRESHOLD > 127) { throw newInternalError("CUSTOMIZE_THRESHOLD should be in [-1...127] range"); diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index 0766cfc2047..76e29209fed 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -53,6 +53,10 @@ import java.util.stream.Stream; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Opcodes; +import static java.lang.invoke.MethodHandleImpl.Intrinsic; +import static java.lang.invoke.MethodHandleNatives.Constants.*; +import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException; + /** * This class consists exclusively of static methods that operate on or return * method handles. They fall into several categories: @@ -873,7 +877,14 @@ assertEquals("[x, y]", MH_asList.invoke("x", "y").toString()); * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker} * with the same {@code type} argument. - * + *

+ * If the class is {@code VarHandle} and the name string corresponds to + * the name of a signature-polymorphic access mode method, the resulting + * method handle is equivalent to one produced by + * {@link java.lang.invoke.MethodHandles#varHandleInvoker} with + * the access mode corresponding to the name string and with the same + * {@code type} arguments. + *

* Example: *

{@code
 import static java.lang.invoke.MethodHandles.*;
@@ -920,6 +931,9 @@ assertEquals("", (String) MH_newString.invokeExact());
             if (refc == MethodHandle.class) {
                 MethodHandle mh = findVirtualForMH(name, type);
                 if (mh != null)  return mh;
+            } else if (refc == VarHandle.class) {
+                MethodHandle mh = findVirtualForVH(name, type);
+                if (mh != null)  return mh;
             }
             byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
             MemberName method = resolveOrFail(refKind, refc, name, type);
@@ -936,6 +950,13 @@ assertEquals("", (String) MH_newString.invokeExact());
             assert(!MemberName.isMethodHandleInvokeName(name));
             return null;
         }
+        private MethodHandle findVirtualForVH(String name, MethodType type) {
+            try {
+                return varHandleInvoker(VarHandle.AccessMode.valueOf(name), type);
+            } catch (IllegalArgumentException e) {
+                return null;
+            }
+        }
 
         /**
          * Produces a method handle which creates an object and initializes it, using
@@ -1135,6 +1156,7 @@ assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
          * @exception SecurityException if a security manager is present and it
          *                              refuses access
          * @throws NullPointerException if any argument is null
+         * @see #findVarHandle(Class, String, Class)
          */
         public MethodHandle findGetter(Class refc, String name, Class type) throws NoSuchFieldException, IllegalAccessException {
             MemberName field = resolveOrFail(REF_getField, refc, name, type);
@@ -1157,12 +1179,60 @@ assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
          * @exception SecurityException if a security manager is present and it
          *                              refuses access
          * @throws NullPointerException if any argument is null
+         * @see #findVarHandle(Class, String, Class)
          */
         public MethodHandle findSetter(Class refc, String name, Class type) throws NoSuchFieldException, IllegalAccessException {
             MemberName field = resolveOrFail(REF_putField, refc, name, type);
             return getDirectField(REF_putField, refc, field);
         }
 
+        /**
+         * Produces a VarHandle giving access to non-static fields of type
+         * {@code T} declared by a receiver class of type {@code R}, supporting
+         * shape {@code (R : T)}.
+         * 

+ * Access checking is performed immediately on behalf of the lookup + * class. + *

+ * Certain access modes of the returned VarHandle are unsupported under + * the following conditions: + *

    + *
  • if the field is declared {@code final}, then the write, atomic + * update, and numeric atomic update access modes are unsupported. + *
  • if the field type is anything other than {@code int}, + * {@code long} or a reference type, then atomic update access modes + * are unsupported. (Future major platform releases of the JDK may + * support additional types for certain currently unsupported access + * modes.) + *
  • if the field type is anything other than {@code int} or + * {@code long}, then numeric atomic update access modes are + * unsupported. (Future major platform releases of the JDK may + * support additional numeric types for certain currently + * unsupported access modes.) + *
+ *

+ * If the field is declared {@code volatile} then the returned VarHandle + * will override access to the field (effectively ignore the + * {@code volatile} declaration) in accordance to it's specified + * access modes. + * @param recv the receiver class, of type {@code R}, that declares the + * non-static field + * @param name the field's name + * @param type the field's type, of type {@code T} + * @return a VarHandle giving access to non-static fields. + * @throws NoSuchFieldException if the field does not exist + * @throws IllegalAccessException if access checking fails, or if the field is {@code static} + * @exception SecurityException if a security manager is present and it + * refuses access + * @throws NullPointerException if any argument is null + * @since 9 + */ + public VarHandle findVarHandle(Class recv, String name, Class type) throws NoSuchFieldException, IllegalAccessException { + MemberName getField = resolveOrFail(REF_getField, recv, name, type); + MemberName putField = resolveOrFail(REF_putField, recv, name, type); + return getFieldVarHandle(REF_getField, REF_putField, recv, getField, putField); + } + /** * Produces a method handle giving read access to a static field. * The type of the method handle will have a return type of the field's @@ -1211,6 +1281,55 @@ assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method return getDirectField(REF_putStatic, refc, field); } + /** + * Produces a VarHandle giving access to a static field of type + * {@code T} declared by a given declaring class, supporting shape + * {@code ((empty) : T)}. + *

+ * Access checking is performed immediately on behalf of the lookup + * class. + *

+ * If the returned VarHandle is operated on, the declaring class will be + * initialized, if it has not already been initialized. + *

+ * Certain access modes of the returned VarHandle are unsupported under + * the following conditions: + *

    + *
  • if the field is declared {@code final}, then the write, atomic + * update, and numeric atomic update access modes are unsupported. + *
  • if the field type is anything other than {@code int}, + * {@code long} or a reference type, then atomic update access modes + * are unsupported. (Future major platform releases of the JDK may + * support additional types for certain currently unsupported access + * modes.) + *
  • if the field type is anything other than {@code int} or + * {@code long}, then numeric atomic update access modes are + * unsupported. (Future major platform releases of the JDK may + * support additional numeric types for certain currently + * unsupported access modes.) + *
+ *

+ * If the field is declared {@code volatile} then the returned VarHandle + * will override access to the field (effectively ignore the + * {@code volatile} declaration) in accordance to it's specified + * access modes. + * @param decl the class that declares the static field + * @param name the field's name + * @param type the field's type, of type {@code T} + * @return a VarHandle giving access to a static field + * @throws NoSuchFieldException if the field does not exist + * @throws IllegalAccessException if access checking fails, or if the field is not {@code static} + * @exception SecurityException if a security manager is present and it + * refuses access + * @throws NullPointerException if any argument is null + * @since 9 + */ + public VarHandle findStaticVarHandle(Class decl, String name, Class type) throws NoSuchFieldException, IllegalAccessException { + MemberName getField = resolveOrFail(REF_getStatic, decl, name, type); + MemberName putField = resolveOrFail(REF_putStatic, decl, name, type); + return getFieldVarHandle(REF_getStatic, REF_putStatic, decl, getField, putField); + } + /** * Produces an early-bound method handle for a non-static method. * The receiver must have a supertype {@code defc} in which a method @@ -1297,6 +1416,10 @@ return mh1; MethodHandle mh = unreflectForMH(m); if (mh != null) return mh; } + if (m.getDeclaringClass() == VarHandle.class) { + MethodHandle mh = unreflectForVH(m); + if (mh != null) return mh; + } MemberName method = new MemberName(m); byte refKind = method.getReferenceKind(); if (refKind == REF_invokeSpecial) @@ -1311,6 +1434,12 @@ return mh1; return MethodHandleImpl.fakeMethodHandleInvoke(new MemberName(m)); return null; } + private MethodHandle unreflectForVH(Method m) { + // these names require special lookups because they throw UnsupportedOperationException + if (MemberName.isVarHandleMethodInvokeName(m.getName())) + return MethodHandleImpl.fakeVarHandleInvoke(new MemberName(m)); + return null; + } /** * Produces a method handle for a reflected method. @@ -1434,6 +1563,57 @@ return mh1; return unreflectField(f, true); } + /** + * Produces a VarHandle that accesses fields of type {@code T} declared + * by a class of type {@code R}, as described by the given reflected + * field. + * If the field is non-static the VarHandle supports a shape of + * {@code (R : T)}, otherwise supports a shape of {@code ((empty) : T)}. + *

+ * Access checking is performed immediately on behalf of the lookup + * class, regardless of the value of the field's {@code accessible} + * flag. + *

+ * If the field is static, and if the returned VarHandle is operated + * on, the field's declaring class will be initialized, if it has not + * already been initialized. + *

+ * Certain access modes of the returned VarHandle are unsupported under + * the following conditions: + *

    + *
  • if the field is declared {@code final}, then the write, atomic + * update, and numeric atomic update access modes are unsupported. + *
  • if the field type is anything other than {@code int}, + * {@code long} or a reference type, then atomic update access modes + * are unsupported. (Future major platform releases of the JDK may + * support additional types for certain currently unsupported access + * modes.) + *
  • if the field type is anything other than {@code int} or + * {@code long}, then numeric atomic update access modes are + * unsupported. (Future major platform releases of the JDK may + * support additional numeric types for certain currently + * unsupported access modes.) + *
+ *

+ * If the field is declared {@code volatile} then the returned VarHandle + * will override access to the field (effectively ignore the + * {@code volatile} declaration) in accordance to it's specified + * access modes. + * @param f the reflected field, with a field of type {@code T}, and + * a declaring class of type {@code R} + * @return a VarHandle giving access to non-static fields or a static + * field + * @throws IllegalAccessException if access checking fails + * @throws NullPointerException if the argument is null + * @since 9 + */ + public VarHandle unreflectVarHandle(Field f) throws IllegalAccessException { + MemberName getField = new MemberName(f, false); + MemberName putField = new MemberName(f, true); + return getFieldVarHandleNoSecurityManager(getField.getReferenceKind(), putField.getReferenceKind(), + f.getDeclaringClass(), getField, putField); + } + /** * Cracks a direct method handle * created by this lookup object or a similar one. @@ -1454,7 +1634,9 @@ return mh1; */ public MethodHandleInfo revealDirect(MethodHandle target) { MemberName member = target.internalMemberName(); - if (member == null || (!member.isResolved() && !member.isMethodHandleInvoke())) + if (member == null || (!member.isResolved() && + !member.isMethodHandleInvoke() && + !member.isVarHandleMethodInvoke())) throw newIllegalArgumentException("not a direct method handle"); Class defc = member.getDeclaringClass(); byte refKind = member.getReferenceKind(); @@ -1829,6 +2011,52 @@ return mh1; return restrictReceiver(field, dmh, lookupClass()); return dmh; } + private VarHandle getFieldVarHandle(byte getRefKind, byte putRefKind, + Class refc, MemberName getField, MemberName putField) + throws IllegalAccessException { + final boolean checkSecurity = true; + return getFieldVarHandleCommon(getRefKind, putRefKind, refc, getField, putField, checkSecurity); + } + private VarHandle getFieldVarHandleNoSecurityManager(byte getRefKind, byte putRefKind, + Class refc, MemberName getField, MemberName putField) + throws IllegalAccessException { + final boolean checkSecurity = false; + return getFieldVarHandleCommon(getRefKind, putRefKind, refc, getField, putField, checkSecurity); + } + private VarHandle getFieldVarHandleCommon(byte getRefKind, byte putRefKind, + Class refc, MemberName getField, MemberName putField, + boolean checkSecurity) throws IllegalAccessException { + assert getField.isStatic() == putField.isStatic(); + assert getField.isGetter() && putField.isSetter(); + assert MethodHandleNatives.refKindIsStatic(getRefKind) == MethodHandleNatives.refKindIsStatic(putRefKind); + assert MethodHandleNatives.refKindIsGetter(getRefKind) && MethodHandleNatives.refKindIsSetter(putRefKind); + + checkField(getRefKind, refc, getField); + if (checkSecurity) + checkSecurityManager(refc, getField); + + if (!putField.isFinal()) { + // A VarHandle does not support updates to final fields, any + // such VarHandle to a final field will be read-only and + // therefore the following write-based accessibility checks are + // only required for non-final fields + checkField(putRefKind, refc, putField); + if (checkSecurity) + checkSecurityManager(refc, putField); + } + + boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(getRefKind) && + restrictProtectedReceiver(getField)); + if (doRestrict) { + assert !getField.isStatic(); + // receiver type of VarHandle is too wide; narrow to caller + if (!getField.getDeclaringClass().isAssignableFrom(lookupClass())) { + throw getField.makeAccessException("caller class must be a subclass below the method", lookupClass()); + } + refc = lookupClass(); + } + return VarHandles.makeFieldHandle(getField, refc, getField.getFieldType(), this.allowedModes == TRUSTED); + } /** Check access and get the requested constructor. */ private MethodHandle getDirectConstructor(Class refc, MemberName ctor) throws IllegalAccessException { final boolean checkSecurity = true; @@ -2018,6 +2246,205 @@ return mh1; return MethodHandleImpl.makeArrayElementAccessor(arrayClass, true); } + /** + * + * Produces a VarHandle giving access to elements of an array type + * {@code T[]}, supporting shape {@code (T[], int : T)}. + *

+ * Certain access modes of the returned VarHandle are unsupported under + * the following conditions: + *

    + *
  • if the component type is anything other than {@code int}, + * {@code long} or a reference type, then atomic update access modes + * are unsupported. (Future major platform releases of the JDK may + * support additional types for certain currently unsupported access + * modes.) + *
  • if the component type is anything other than {@code int} or + * {@code long}, then numeric atomic update access modes are + * unsupported. (Future major platform releases of the JDK may + * support additional numeric types for certain currently + * unsupported access modes.) + *
+ * @param arrayClass the class of an array, of type {@code T[]} + * @return a VarHandle giving access to elements of an array + * @throws NullPointerException if the arrayClass is null + * @throws IllegalArgumentException if arrayClass is not an array type + * @since 9 + */ + public static + VarHandle arrayElementVarHandle(Class arrayClass) throws IllegalArgumentException { + return VarHandles.makeArrayElementHandle(arrayClass); + } + + /** + * Produces a VarHandle giving access to elements of a {@code byte[]} array + * viewed as if it were a different primitive array type, such as + * {@code int[]} or {@code long[]}. The shape of the resulting VarHandle is + * {@code (byte[], int : T)}, where the {@code int} coordinate type + * corresponds to an argument that is an index in a {@code byte[]} array, + * and {@code T} is the component type of the given view array class. The + * returned VarHandle accesses bytes at an index in a {@code byte[]} array, + * composing bytes to or from a value of {@code T} according to the given + * endianness. + *

+ * The supported component types (variables types) are {@code short}, + * {@code char}, {@code int}, {@code long}, {@code float} and + * {@code double}. + *

+ * Access of bytes at a given index will result in an + * {@code IndexOutOfBoundsException} if the index is less than {@code 0} + * or greater than the {@code byte[]} array length minus the size (in bytes) + * of {@code T}. + *

+ * Access of bytes at an index may be aligned or misaligned for {@code T}, + * with respect to the underlying memory address, {@code A} say, associated + * with the array and index. + * If access is misaligned then access for anything other than the + * {@code get} and {@code set} access modes will result in an + * {@code IllegalStateException}. In such cases atomic access is only + * guaranteed with respect to the largest power of two that divides the GCD + * of {@code A} and the size (in bytes) of {@code T}. + * If access is aligned then following access modes are supported and are + * guaranteed to support atomic access: + *

    + *
  • read write access modes for all {@code T}; + *
  • atomic update access modes for {@code int}, {@code long}, + * {@code float} or {@code double}. + * (Future major platform releases of the JDK may support additional + * types for certain currently unsupported access modes.) + *
  • numeric atomic update access modes for {@code int} and {@code long}. + * (Future major platform releases of the JDK may support additional + * numeric types for certain currently unsupported access modes.) + *
+ *

+ * Misaligned access, and therefore atomicity guarantees, may be determined + * for {@code byte[]} arrays without operating on a specific array. Given + * an {@code index}, {@code T} and it's corresponding boxed type, + * {@code T_BOX}, misalignment may be determined as follows: + *

{@code
+     * int sizeOfT = T_BOX.BYTES;  // size in bytes of T
+     * int misalignedAtZeroIndex = ByteBuffer.wrap(new byte[0]).
+     *     alignmentOffset(0, sizeOfT);
+     * int misalignedAtIndex = (misalignedAtZeroIndex + index) % sizeOfT;
+     * boolean isMisaligned = misalignedAtIndex != 0;
+     * }
+ * + * @implNote + * The variable types {@code float} and {@code double} are supported as if + * by transformation to and access with the variable types {@code int} and + * {@code long} respectively. For example, the transformation of a + * {@code double} value to a long value is performed as if using + * {@link Double#doubleToRawLongBits(double)}, and the reverse + * transformation is performed as if using + * {@link Double#longBitsToDouble(long)}. + * + * @param viewArrayClass the view array class, with a component type of + * type {@code T} + * @param bigEndian true if the endianness of the view array elements, as + * stored in the underlying {@code byte} array, is big endian, otherwise + * little endian + * @return a VarHandle giving access to elements of a {@code byte[]} array + * viewed as if elements corresponding to the components type of the view + * array class + * @throws NullPointerException if viewArrayClass is null + * @throws IllegalArgumentException if viewArrayClass is not an array type + * @throws UnsupportedOperationException if the component type of + * viewArrayClass is not supported as a variable type + * @since 9 + */ + public static + VarHandle byteArrayViewVarHandle(Class viewArrayClass, + boolean bigEndian) throws IllegalArgumentException { + return VarHandles.byteArrayViewHandle(viewArrayClass, bigEndian); + } + + /** + * Produces a VarHandle giving access to elements of a {@code ByteBuffer} + * viewed as if it were an array of elements of a different primitive + * component type to that of {@code byte}, such as {@code int[]} or + * {@code long[]}. The shape of the resulting VarHandle is + * {@code (ByteBuffer, int : T)}, where the {@code int} coordinate type + * corresponds to an argument that is an index in a {@code ByteBuffer}, and + * {@code T} is the component type of the given view array class. The + * returned VarHandle accesses bytes at an index in a {@code ByteBuffer}, + * composing bytes to or from a value of {@code T} according to the given + * endianness. + *

+ * The supported component types (variables types) are {@code short}, + * {@code char}, {@code int}, {@code long}, {@code float} and + * {@code double}. + *

+ * Access will result in a {@code ReadOnlyBufferException} for anything + * other than the read access modes if the {@code ByteBuffer} is read-only. + *

+ * Access of bytes at a given index will result in an + * {@code IndexOutOfBoundsException} if the index is less than {@code 0} + * or greater than the {@code ByteBuffer} limit minus the size (in bytes) of + * {@code T}. + *

+ * Access of bytes at an index may be aligned or misaligned for {@code T}, + * with respect to the underlying memory address, {@code A} say, associated + * with the {@code ByteBuffer} and index. + * If access is misaligned then access for anything other than the + * {@code get} and {@code set} access modes will result in an + * {@code IllegalStateException}. In such cases atomic access is only + * guaranteed with respect to the largest power of two that divides the GCD + * of {@code A} and the size (in bytes) of {@code T}. + * If access is aligned then following access modes are supported and are + * guaranteed to support atomic access: + *

    + *
  • read write access modes for all {@code T}; + *
  • atomic update access modes for {@code int}, {@code long}, + * {@code float} or {@code double}. + * (Future major platform releases of the JDK may support additional + * types for certain currently unsupported access modes.) + *
  • numeric atomic update access modes for {@code int} and {@code long}. + * (Future major platform releases of the JDK may support additional + * numeric types for certain currently unsupported access modes.) + *
+ *

+ * Misaligned access, and therefore atomicity guarantees, may be determined + * for a {@code ByteBuffer}, {@code bb} (direct or otherwise), an + * {@code index}, {@code T} and it's corresponding boxed type, + * {@code T_BOX}, as follows: + *

{@code
+     * int sizeOfT = T_BOX.BYTES;  // size in bytes of T
+     * ByteBuffer bb = ...
+     * int misalignedAtIndex = bb.alignmentOffset(index, sizeOfT);
+     * boolean isMisaligned = misalignedAtIndex != 0;
+     * }
+ * + * @implNote + * The variable types {@code float} and {@code double} are supported as if + * by transformation to and access with the variable types {@code int} and + * {@code long} respectively. For example, the transformation of a + * {@code double} value to a long value is performed as if using + * {@link Double#doubleToRawLongBits(double)}, and the reverse + * transformation is performed as if using + * {@link Double#longBitsToDouble(long)}. + * + * @param viewArrayClass the view array class, with a component type of + * type {@code T} + * @param bigEndian true if the endianness of the view array elements, as + * stored in the underlying {@code ByteBuffer}, is big endian, otherwise + * little endian (Note this overrides the endianness of a + * {@code ByteBuffer}) + * @return a VarHandle giving access to elements of a {@code ByteBuffer} + * viewed as if elements corresponding to the components type of the view + * array class + * @throws NullPointerException if viewArrayClass is null + * @throws IllegalArgumentException if viewArrayClass is not an array type + * @throws UnsupportedOperationException if the component type of + * viewArrayClass is not supported as a variable type + * @since 9 + */ + public static + VarHandle byteBufferViewVarHandle(Class viewArrayClass, + boolean bigEndian) throws IllegalArgumentException { + return VarHandles.makeByteBufferViewHandle(viewArrayClass, bigEndian); + } + + /// method handle invocation (reflective style) /** @@ -2153,6 +2580,54 @@ return invoker; return type.invokers().genericInvoker(); } + /** + * Produces a special invoker method handle which can be used to + * invoke a signature-polymorphic access mode method on any VarHandle whose + * associated access mode type is compatible with the given type. + * The resulting invoker will have a type which is exactly equal to the + * desired given type, except that it will accept an additional leading + * argument of type {@code VarHandle}. + * + * @param accessMode the VarHandle access mode + * @param type the desired target type + * @return a method handle suitable for invoking an access mode method of + * any VarHandle whose access mode type is of the given type. + * @since 9 + */ + static public + MethodHandle varHandleExactInvoker(VarHandle.AccessMode accessMode, MethodType type) { + return type.invokers().varHandleMethodExactInvoker(accessMode); + } + + /** + * Produces a special invoker method handle which can be used to + * invoke a signature-polymorphic access mode method on any VarHandle whose + * associated access mode type is compatible with the given type. + * The resulting invoker will have a type which is exactly equal to the + * desired given type, except that it will accept an additional leading + * argument of type {@code VarHandle}. + *

+ * Before invoking its target, if the access mode type differs from the + * desired given type, the invoker will apply reference casts as necessary + * and box, unbox, or widen primitive values, as if by + * {@link MethodHandle#asType asType}. Similarly, the return value will be + * converted as necessary. + *

+ * This method is equivalent to the following code (though it may be more + * efficient): {@code publicLookup().findVirtual(VarHandle.class, accessMode.name(), type)} + * + * @param accessMode the VarHandle access mode + * @param type the desired target type + * @return a method handle suitable for invoking an access mode method of + * any VarHandle whose access mode type is convertible to the given + * type. + * @since 9 + */ + static public + MethodHandle varHandleInvoker(VarHandle.AccessMode accessMode, MethodType type) { + return type.invokers().varHandleMethodInvoker(accessMode); + } + static /*non-public*/ MethodHandle basicInvoker(MethodType type) { return type.invokers().basicInvoker(); diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java index 71690e5c439..815da30e131 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java @@ -95,7 +95,7 @@ class MethodType implements java.io.Serializable { // The rtype and ptypes fields define the structural identity of the method type: private final Class rtype; - private final Class[] ptypes; + private final @Stable Class[] ptypes; // The remaining fields are caches of various sorts: private @Stable MethodTypeForm form; // erased form, plus cached data about primitives diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java b/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java new file mode 100644 index 00000000000..7c8a049d68e --- /dev/null +++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.lang.invoke; + +import jdk.internal.vm.annotation.Stable; + +import java.lang.invoke.VarHandle.AccessMode; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +/** + * A var handle form containing a set of member name, one for each operation. + * Each member characterizes a static method. + */ +class VarForm { + + // Holds VarForm for VarHandle implementation classes + private static final ClassValue VFORMS + = new ClassValue<>() { + @Override + protected VarForm computeValue(Class impl) { + return new VarForm(linkFromStatic(impl)); + } + }; + + final @Stable MemberName[] table; + + VarForm(MemberName[] table) { + this.table = table; + } + + /** + * Creates a var form given an VarHandle implementation class. + * Each signature polymorphic method is linked to a static method of the + * same name on the implementation class or a super class. + */ + static VarForm createFromStatic(Class impl) { + return VFORMS.get(impl); + } + + /** + * Link all signature polymorphic methods. + */ + private static MemberName[] linkFromStatic(Class implClass) { + MemberName[] table = new MemberName[AccessMode.values().length]; + + for (Class c = implClass; c != VarHandle.class; c = c.getSuperclass()) { + for (Method m : c.getDeclaredMethods()) { + if (Modifier.isStatic(m.getModifiers())) { + try { + AccessMode am = AccessMode.valueOf(m.getName()); + assert table[am.ordinal()] == null; + table[am.ordinal()] = new MemberName(m); + } catch (IllegalArgumentException ex) { + // Ignore. Note the try/catch will be removed when + // AccessMode enum constant names are renamed + } + } + } + } + return table; + } +} \ No newline at end of file diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java new file mode 100644 index 00000000000..ed290ec7574 --- /dev/null +++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java @@ -0,0 +1,1360 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.invoke; + +import jdk.internal.HotSpotIntrinsicCandidate; +import jdk.internal.vm.annotation.ForceInline; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.BiFunction; + +import static java.lang.invoke.MethodHandleStatics.UNSAFE; +import static java.lang.invoke.MethodHandleStatics.newInternalError; + +/** + * A VarHandle is a dynamically typed reference to a variable, or to a + * parametrically-defined family of variables, including static fields, + * non-static fields, array elements, or components of an off-heap data + * structure. Access to such variables is supported under various + * access modes, including plain read/write access, volatile + * read/write access, and compare-and-swap. + * + *

VarHandles are immutable and have no visible state. VarHandles cannot be + * subclassed by the user. + * + *

A VarHandle has: + *

    + *
  • a {@link #varType variable type}, referred to as {@code T}, which is the + * type of variable(s) referenced by this VarHandle; + *
  • a list of {@link #coordinateTypes coordinate types}, referred to as + * {@code CT}, where the types (primitive and reference) are represented by + * {@link Class} objects). A list of arguments corresponding to instances of + * the coordinate types uniquely locates a variable referenced by this + * VarHandle; and + *
  • a shape, that combines the variable type and coordinate types, + * and is declared with the notation {@code (CT : T)}. An empty list of + * coordinate types is declared as {@code (empty)}. + *
+ * + *

Factory methods that produce or {@link java.lang.invoke.MethodHandles.Lookup + * lookup} VarHandle instances document the supported variable type, coordinate + * types, and shape. + * + * For example, a VarHandle referencing a non-static field will declare a shape + * of {@code (R : T)}, where {@code R} is the receiver type and + * {@code T} is the field type, and where the VarHandle and an instance of the + * receiver type can be utilized to access the field variable. + * A VarHandle referencing array elements will declare a shape of + * {@code (T[], int : T)}, where {@code T[]} is the array type and {@code T} + * its component type, and where the VarHandle, an instance of the array type, + * and an {@code int} index can be utilized to access an array element variable. + * + *

Each access mode is associated with a + * signature polymorphic method of the + * same name, where the VarHandle shape and access mode uniquely determine the + * canonical {@link #accessModeType(AccessMode) access mode type}, + * which in turn determines the matching constraints on a valid symbolic + * type descriptor at the call site of an access mode's method + * invocation. + * + * As such, VarHandles are dynamically and strongly typed. Their arity, + * argument types, and return type of an access mode method invocation are not + * statically checked. If they, and associated values, do not match the arity + * and types of the access mode's type, an exception will be thrown. + * + * The parameter types of an access mode method type will consist of those that + * are the VarHandles's coordinate types (in order), followed by access mode + * parameter types specific to the access mode. + * + *

An access mode's method documents the form of its method signature, which + * is derived from the access mode parameter types. The form is declared with + * the notation {@code (CT, P1 p1, P2 p2, ..., PN pn)R}, where {@code CT} is the + * coordinate types (as documented by a VarHandle factory method), {@code P1}, + * {@code P2} and {@code PN} are the first, second and the n'th access mode + * parameters named {@code p1}, {@code p2} and {@code pn} respectively, and + * {@code R} is the return type. + * + * For example, for the generic shape of {@code (CT : T)} the + * {@link #compareAndSet} access mode method documents that its method + * signature is of the form {@code (CT, T expectedValue, T newValue)boolean}, + * where the parameter types named {@code extendedValue} and {@code newValue} + * are the access mode parameter types. If the VarHandle accesses array + * elements with a shape of say {@code (T[], int : T)} then the access mode + * method type is {@code (T[], int, T, T)boolean}. + * + *

Access modes are grouped into the following categories: + *

    + *
  • read access modes that get the value of a variable under specified + * memory ordering effects. + * The set of corresponding access mode methods belonging to this group + * consists of the methods + * {@link #get get}, + * {@link #getVolatile getVolatile}, + * {@link #getAcquire getAcquire}, + * {@link #getOpaque getOpaque}. + *
  • write access modes that set the value of a variable under specified + * memory ordering effects. + * The set of corresponding access mode methods belonging to this group + * consists of the methods + * {@link #set set}, + * {@link #setVolatile setVolatile}, + * {@link #setRelease setRelease}, + * {@link #setOpaque setOpaque}. + *
  • atomic update access modes that, for example, atomically compare and set + * the value of a variable under specified memory ordering effects. + * The set of corresponding access mode methods belonging to this group + * consists of the methods + * {@link #compareAndSet compareAndSet}, + * {@link #weakCompareAndSet weakCompareAndSet}, + * {@link #weakCompareAndSetAcquire weakCompareAndSetAcquire}, + * {@link #weakCompareAndSetRelease weakCompareAndSetRelease}, + * {@link #compareAndExchangeAcquire compareAndExchangeAcquire}, + * {@link #compareAndExchangeVolatile compareAndExchangeVolatile}, + * {@link #compareAndExchangeRelease compareAndExchangeRelease}, + * {@link #getAndSet getAndSet}. + *
  • numeric atomic update access modes that, for example, atomically get and + * set with addition the value of a variable under specified memory ordering + * effects. + * The set of corresponding access mode methods belonging to this group + * consists of the methods + * {@link #getAndAdd getAndAdd}, + * {@link #addAndGet addAndGet}. + *
+ * + *

Factory methods that produce or {@link java.lang.invoke.MethodHandles.Lookup + * lookup} VarHandle instances document the set of access modes that are + * supported, which may also include documenting restrictions based on the + * variable type and whether a variable is read-only. If an access mode is not + * supported then the corresponding signature-polymorphic method will on + * invocation throw an {@code UnsupportedOperationException}. + * The {@link #get get} access mode is supported for all + * VarHandle instances and the corresponding method never throws + * {@code UnsupportedOperationException}. + * If a VarHandle references a read-only variable (for example a {@code final} + * field) then write, atomic update and numeric atomic update access modes are + * not supported and corresponding methods throw + * {@code UnsupportedOperationException}. + * Read/write access modes (if supported), with the exception of + * {@code get} and {@code set}, provide atomic access for + * reference types and all primitive types. + * Unless stated otherwise in the documentation of a factory method, the access + * modes {@code get} and {@code set} (if supported) provide atomic access for + * reference types and all primitives types, with the exception of {@code long} + * and {@code double} on 32-bit platforms + * + *

Access modes will override any memory ordering effects specified at + * the declaration site of a variable. For example, a VarHandle accessing a + * a field using the {@code get} access mode will access the field as + * specified by its access mode even if that field is declared + * {@code volatile}. When mixed access is performed extreme care should be + * taken since the Java Memory Model may permit surprising results. + * + *

In addition to supporting access to variables under various access modes, + * a set of static methods, referred to as memory fence methods, is also + * provided for fine-grained control of memory ordering. + * + * The Java Language Specification permits other threads to observe operations + * as if they were executed in orders different than are apparent in program + * source code, subject to constraints arising, for example, from the use of + * locks, {@code volatile} fields or VarHandles. The static methods, + * {@link #fullFence fullFence}, {@link #acquireFence acquireFence}, + * {@link #releaseFence releaseFence}, {@link #loadLoadFence loadLoadFence} and + * {@link #storeStoreFence storeStoreFence}, can also be used to impose + * constraints. Their specifications, as is the case for certain access modes, + * are phrased in terms of the lack of "reorderings" -- observable ordering + * effects that might otherwise occur if the fence was not present. More + * precise phrasing of the specification of access mode methods and memory fence + * methods may accompany future updates of the Java Language Specification. + * + *

Compilation of an access mode's method

+ * A Java method call expression naming an access mode method can invoke a + * VarHandle from Java source code. From the viewpoint of source code, these + * methods can take any arguments and their polymorphic result (if expressed) + * can be cast to any return type. Formally this is accomplished by giving the + * access mode methods variable arity {@code Object} arguments and + * {@code Object} return types (if the return type is polymorphic), but they + * have an additional quality called signature polymorphism which + * connects this freedom of invocation directly to the JVM execution stack. + *

+ * As is usual with virtual methods, source-level calls to access mode methods + * compile to an {@code invokevirtual} instruction. More unusually, the + * compiler must record the actual argument types, and may not perform method + * invocation conversions on the arguments. Instead, it must generate + * instructions to push them on the stack according to their own unconverted + * types. The VarHandle object itself will be pushed on the stack before the + * arguments. The compiler then generates an {@code invokevirtual} instruction + * that invokes the access mode method with a symbolic type descriptor which + * describes the argument and return types. + *

+ * To issue a complete symbolic type descriptor, the compiler must also + * determine the return type (if polymorphic). This is based on a cast on the + * method invocation expression, if there is one, or else {@code Object} if the + * invocation is an expression, or else {@code void} if the invocation is a + * statement. The cast may be to a primitive type (but not {@code void}). + *

+ * As a corner case, an uncasted {@code null} argument is given a symbolic type + * descriptor of {@code java.lang.Void}. The ambiguity with the type + * {@code Void} is harmless, since there are no references of type {@code Void} + * except the null reference. + * + * + *

Invocation of an access mode's method

+ * The first time an {@code invokevirtual} instruction is executed it is linked + * by symbolically resolving the names in the instruction and verifying that + * the method call is statically legal. This also holds for calls to access mode + * methods. In this case, the symbolic type descriptor emitted by the compiler + * is checked for correct syntax, and names it contains are resolved. Thus, an + * {@code invokevirtual} instruction which invokes an access mode method will + * always link, as long as the symbolic type descriptor is syntactically + * well-formed and the types exist. + *

+ * When the {@code invokevirtual} is executed after linking, the receiving + * VarHandle's access mode type is first checked by the JVM to ensure that it + * matches the symbolic type descriptor. If the type + * match fails, it means that the access mode method which the caller is + * invoking is not present on the individual VarHandle being invoked. + * + *

+ * Invocation of an access mode's signature-polymorphic method behaves as if an + * invocation of {@link MethodHandle#invoke}, where the receiving method handle + * is bound to a VarHandle instance and the access mode. More specifically, the + * following: + *

 {@code
+ * VarHandle vh = ..
+ * R r = (R) vh.{access-mode}(p1, p2, ..., pN);
+ * }
+ * behaves as if (modulo the access mode methods do not declare throwing of + * {@code Throwable}): + *
 {@code
+ * VarHandle vh = ..
+ * MethodHandle mh = MethodHandles.varHandleExactInvoker(
+ *                       VarHandle.AccessMode.{access-mode},
+ *                       vh.accessModeType(VarHandle.AccessMode.{access-mode}));
+ *
+ * mh = mh.bindTo(vh);
+ * R r = (R) mh.invoke(p1, p2, ..., pN)
+ * }
+ * or, more concisely, behaves as if: + *
 {@code
+ * VarHandle vh = ..
+ * MethodHandle mh = vh.toMethodHandle(VarHandle.AccessMode.{access-mode});
+ *
+ * R r = (R) mh.invoke(p1, p2, ..., pN)
+ * }
+ * In terms of equivalent {@code invokevirtual} bytecode behaviour an access + * mode method invocation is equivalent to: + *
 {@code
+ * MethodHandle mh = MethodHandles.lookup().findVirtual(
+ *                       VarHandle.class,
+ *                       VarHandle.AccessMode.{access-mode}.name(),
+ *                       MethodType.methodType(R, p1, p2, ..., pN));
+ *
+ * R r = (R) mh.invokeExact(vh, p1, p2, ..., pN)
+ * }
+ * where the desired method type is the symbolic type descriptor and a + * {@link MethodHandle#invokeExact} is performed, since before invocation of the + * target, the handle will apply reference casts as necessary and box, unbox, or + * widen primitive values, as if by {@link MethodHandle#asType asType} (see also + * {@link MethodHandles#varHandleInvoker}). + * + *

Invocation checking

+ * In typical programs, VarHandle access mode type matching will usually + * succeed. But if a match fails, the JVM will throw a + * {@link WrongMethodTypeException}. + *

+ * Thus, an access mode type mismatch which might show up as a linkage error + * in a statically typed program can show up as a dynamic + * {@code WrongMethodTypeException} in a program which uses VarHandles. + *

+ * Because access mode types contain "live" {@code Class} objects, method type + * matching takes into account both type names and class loaders. + * Thus, even if a VarHandle {@code VH} is created in one class loader + * {@code L1} and used in another {@code L2}, VarHandle access mode method + * calls are type-safe, because the caller's symbolic type descriptor, as + * resolved in {@code L2}, is matched against the original callee method's + * symbolic type descriptor, as resolved in {@code L1}. The resolution in + * {@code L1} happens when {@code VH} is created and its access mode types are + * assigned, while the resolution in {@code L2} happens when the + * {@code invokevirtual} instruction is linked. + *

+ * Apart from type descriptor checks, a VarHandles's capability to + * access it's variables is unrestricted. + * If a VarHandle is formed on a non-public variable by a class that has access + * to that variable, the resulting VarHandle can be used in any place by any + * caller who receives a reference to it. + *

+ * Unlike with the Core Reflection API, where access is checked every time a + * reflective method is invoked, VarHandle access checking is performed + * when the VarHandle is + * created. + * Thus, VarHandles to non-public variables, or to variables in non-public + * classes, should generally be kept secret. They should not be passed to + * untrusted code unless their use from the untrusted code would be harmless. + * + * + *

VarHandle creation

+ * Java code can create a VarHandle that directly accesses any field that is + * accessible to that code. This is done via a reflective, capability-based + * API called {@link java.lang.invoke.MethodHandles.Lookup + * MethodHandles.Lookup}. + * For example, a VarHandle for a non-static field can be obtained + * from {@link java.lang.invoke.MethodHandles.Lookup#findVarHandle + * Lookup.findVarHandle}. + * There is also a conversion method from Core Reflection API objects, + * {@link java.lang.invoke.MethodHandles.Lookup#unreflectVarHandle + * Lookup.unreflectVarHandle}. + *

+ * Access to protected field members is restricted to receivers only of the + * accessing class, or one of its subclasses, and the accessing class must in + * turn be a subclass (or package sibling) of the protected member's defining + * class. If a VarHandle refers to a protected non-static field of a declaring + * class outside the current package, the receiver argument will be narrowed to + * the type of the accessing class. + * + *

Interoperation between VarHandles and the Core Reflection API

+ * Using factory methods in the {@link java.lang.invoke.MethodHandles.Lookup + * Lookup} API, any field represented by a Core Reflection API object + * can be converted to a behaviorally equivalent VarHandle. + * For example, a reflective {@link java.lang.reflect.Field Field} can + * be converted to a VarHandle using + * {@link java.lang.invoke.MethodHandles.Lookup#unreflectVarHandle + * Lookup.unreflectVarHandle}. + * The resulting VarHandles generally provide more direct and efficient + * access to the underlying fields. + *

+ * As a special case, when the Core Reflection API is used to view the + * signature polymorphic access mode methods in this class, they appear as + * ordinary non-polymorphic methods. Their reflective appearance, as viewed by + * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod}, + * is unaffected by their special status in this API. + * For example, {@link java.lang.reflect.Method#getModifiers + * Method.getModifiers} + * will report exactly those modifier bits required for any similarly + * declared method, including in this case {@code native} and {@code varargs} + * bits. + *

+ * As with any reflected method, these methods (when reflected) may be invoked + * directly via {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}, + * via JNI, or indirectly via + * {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}. + * However, such reflective calls do not result in access mode method + * invocations. Such a call, if passed the required argument (a single one, of + * type {@code Object[]}), will ignore the argument and will throw an + * {@code UnsupportedOperationException}. + *

+ * Since {@code invokevirtual} instructions can natively invoke VarHandle + * access mode methods under any symbolic type descriptor, this reflective view + * conflicts with the normal presentation of these methods via bytecodes. + * Thus, these native methods, when reflectively viewed by + * {@code Class.getDeclaredMethod}, may be regarded as placeholders only. + *

+ * In order to obtain an invoker method for a particular access mode type, + * use {@link java.lang.invoke.MethodHandles#varHandleExactInvoker} or + * {@link java.lang.invoke.MethodHandles#varHandleInvoker}. The + * {@link java.lang.invoke.MethodHandles.Lookup#findVirtual Lookup.findVirtual} + * API is also able to return a method handle to call an access mode method for + * any specified access mode type and is equivalent in behaviour to + * {@link java.lang.invoke.MethodHandles#varHandleInvoker}. + * + *

Interoperation between VarHandles and Java generics

+ * A VarHandle can be obtained for a variable, such as a a field, which is + * declared with Java generic types. As with the Core Reflection API, the + * VarHandle's variable type will be constructed from the erasure of the + * source-level type. When a VarHandle access mode method is invoked, the + * types + * of its arguments or the return value cast type may be generic types or type + * instances. If this occurs, the compiler will replace those types by their + * erasures when it constructs the symbolic type descriptor for the + * {@code invokevirtual} instruction. + * + * @see MethodHandle + * @see MethodHandles + * @see MethodType + * @since 9 + */ +public abstract class VarHandle { + // Use explicit final fields rather than an @Stable array as + // this can reduce the memory per handle + // e.g. by 24 bytes on 64 bit architectures + final MethodType typeGet; + final MethodType typeSet; + final MethodType typeCompareSwap; + final MethodType typeCompareExchange; + final MethodType typeGetAndUpdate; + + final VarForm vform; + + VarHandle(VarForm vform, Class receiver, Class value, Class... intermediate) { + this.vform = vform; + + // (Receiver, ) + List> l = new ArrayList<>(); + if (receiver != null) + l.add(receiver); + l.addAll(Arrays.asList(intermediate)); + + // (Receiver, )Value + this.typeGet = MethodType.methodType(value, l); + + // (Receiver, , Value)void + l.add(value); + this.typeSet = MethodType.methodType(void.class, l); + + // (Receiver, , Value)Value + this.typeGetAndUpdate = MethodType.methodType(value, l); + + // (Receiver, , Value, Value)boolean + l.add(value); + this.typeCompareSwap = MethodType.methodType(boolean.class, l); + + // (Receiver, , Value, Value)Value + this.typeCompareExchange = MethodType.methodType(value, l); + } + + RuntimeException unsupported() { + return new UnsupportedOperationException(); + } + + // Plain accessors + + /** + * Returns the value of a variable, with memory semantics of reading as + * if the variable was declared non-{@code volatile}. Commonly referred to + * as plain read access. + * + *

The method signature is of the form {@code (CT)T}. + * + *

The symbolic type descriptor at the call site of {@code get} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.get)} on this VarHandle. + * + *

This access mode is supported by all VarHandle instances and never + * throws {@code UnsupportedOperationException}. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT)} + * , statically represented using varargs. + * @return the signature-polymorphic result that is the value of the + * variable + * , statically represented using {@code Object}. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + Object get(Object... args); + + /** + * Sets the value of a variable to the {@code newValue}, with memory + * semantics of setting as if the variable was declared non-{@code volatile} + * and non-{@code final}. Commonly referred to as plain write access. + * + *

The method signature is of the form {@code (CT, T newValue)void} + * + *

The symbolic type descriptor at the call site of {@code set} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.set)} on this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT, T newValue)} + * , statically represented using varargs. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + void set(Object... args); + + + // Volatile accessors + + /** + * Returns the value of a variable, with memory semantics of reading as if + * the variable was declared {@code volatile}. + * + *

The method signature is of the form {@code (CT)T}. + * + *

The symbolic type descriptor at the call site of {@code getVolatile} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.getVolatile)} on this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT)} + * , statically represented using varargs. + * @return the signature-polymorphic result that is the value of the + * variable + * , statically represented using {@code Object}. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + Object getVolatile(Object... args); + + /** + * Sets the value of a variable to the {@code newValue}, with memory + * semantics of setting as if the variable was declared {@code volatile}. + * + *

The method signature is of the form {@code (CT, T newValue)void}. + * + *

The symbolic type descriptor at the call site of {@code setVolatile} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.setVolatile)} on this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT, T newValue)} + * , statically represented using varargs. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + * @apiNote Ignoring the many semantic differences from C and C++, this + * method has memory ordering effects compatible with + * {@code memory_order_seq_cst}. + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + void setVolatile(Object... args); + + + /** + * Returns the value of a variable, accessed in program order, but with no + * assurance of memory ordering effects with respect to other threads. + * + *

The method signature is of the form {@code (CT)T}. + * + *

The symbolic type descriptor at the call site of {@code getOpaque} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.getOpaque)} on this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT)} + * , statically represented using varargs. + * @return the signature-polymorphic result that is the value of the + * variable + * , statically represented using {@code Object}. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + Object getOpaque(Object... args); + + /** + * Sets the value of a variable to the {@code newValue}, in program order, + * but with no assurance of memory ordering effects with respect to other + * threads. + * + *

The method signature is of the form {@code (CT, T newValue)void}. + * + *

The symbolic type descriptor at the call site of {@code setOpaque} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.setOpaque)} on this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT, T newValue)} + * , statically represented using varargs. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + void setOpaque(Object... args); + + + // Lazy accessors + + /** + * Returns the value of a variable, and ensures that subsequent loads and + * stores are not reordered before this access. + * + *

The method signature is of the form {@code (CT)T}. + * + *

The symbolic type descriptor at the call site of {@code getAcquire} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.getAcquire)} on this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT)} + * , statically represented using varargs. + * @return the signature-polymorphic result that is the value of the + * variable + * , statically represented using {@code Object}. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + * @apiNote Ignoring the many semantic differences from C and C++, this + * method has memory ordering effects compatible with + * {@code memory_order_acquire} ordering. + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + Object getAcquire(Object... args); + + /** + * Sets the value of a variable to the {@code newValue}, and ensures that + * prior loads and stores are not reordered after this access. + * + *

The method signature is of the form {@code (CT, T newValue)void}. + * + *

The symbolic type descriptor at the call site of {@code setRelease} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.setRelease)} on this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT, T newValue)} + * , statically represented using varargs. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + * @apiNote Ignoring the many semantic differences from C and C++, this + * method has memory ordering effects compatible with + * {@code memory_order_release} ordering. + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + void setRelease(Object... args); + + + // Compare and set accessors + + /** + * Atomically sets the value of a variable to the {@code newValue} with the + * memory semantics of {@link #setVolatile} if the variable's current value, + * referred to as the witness value, {@code ==} the + * {@code expectedValue}, as accessed with the memory semantics of + * {@link #getVolatile}. + * + *

The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}. + * + *

The symbolic type descriptor at the call site of {@code + * compareAndSet} must match the access mode type that is the result of + * calling {@code accessModeType(VarHandle.AccessMode.compareAndSet)} on + * this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT, T expectedValue, T newValue)} + * , statically represented using varargs. + * @return {@code true} if successful, otherwise {@code false} if the + * witness value was not the same as the {@code expectedValue}. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + * @see #setVolatile(Object...) + * @see #getVolatile(Object...) + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + boolean compareAndSet(Object... args); + + /** + * Atomically sets the value of a variable to the {@code newValue} with the + * memory semantics of {@link #setVolatile} if the variable's current value, + * referred to as the witness value, {@code ==} the + * {@code expectedValue}, as accessed with the memory semantics of + * {@link #getVolatile}. + * + *

The method signature is of the form {@code (CT, T expectedValue, T newValue)T}. + * + *

The symbolic type descriptor at the call site of {@code + * compareAndExchangeVolatile} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeVolatile)} + * on this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT, T expectedValue, T newValue)} + * , statically represented using varargs. + * @return the signature-polymorphic result that is the witness value, which + * will be the same as the {@code expectedValue} if successful + * , statically represented using {@code Object}. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + * @see #setVolatile(Object...) + * @see #getVolatile(Object...) + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + Object compareAndExchangeVolatile(Object... args); + + /** + * Atomically sets the value of a variable to the {@code newValue} with the + * memory semantics of {@link #set} if the variable's current value, + * referred to as the witness value, {@code ==} the + * {@code expectedValue}, as accessed with the memory semantics of + * {@link #getAcquire}. + * + *

The method signature is of the form {@code (CT, T expectedValue, T newValue)T}. + * + *

The symbolic type descriptor at the call site of {@code + * compareAndExchangeAcquire} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeAcquire)} on + * this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT, T expectedValue, T newValue)} + * , statically represented using varargs. + * @return the signature-polymorphic result that is the witness value, which + * will be the same as the {@code expectedValue} if successful + * , statically represented using {@code Object}. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + * @see #set(Object...) + * @see #getAcquire(Object...) + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + Object compareAndExchangeAcquire(Object... args); + + /** + * Atomically sets the value of a variable to the {@code newValue} with the + * memory semantics of {@link #setRelease} if the variable's current value, + * referred to as the witness value, {@code ==} the + * {@code expectedValue}, as accessed with the memory semantics of + * {@link #get}. + * + *

The method signature is of the form {@code (CT, T expectedValue, T newValue)T}. + * + *

The symbolic type descriptor at the call site of {@code + * compareAndExchangeRelease} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeRelease)} on this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT, T expectedValue, T newValue)} + * , statically represented using varargs. + * @return the signature-polymorphic result that is the witness value, which + * will be the same as the {@code expectedValue} if successful + * , statically represented using {@code Object}. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + * @see #setRelease(Object...) + * @see #get(Object...) + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + Object compareAndExchangeRelease(Object... args); + + // Weak (spurious failures allowed) + + /** + * Possibly atomically sets the value of a variable to the {@code newValue} + * with the semantics of {@link #set} if the variable's current value, + * referred to as the witness value, {@code ==} the + * {@code expectedValue}, as accessed with the memory semantics of + * {@link #get}. + * + *

This operation may fail spuriously (typically, due to memory + * contention) even if the current value does match the expected value. + * + *

The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}. + * + *

The symbolic type descriptor at the call site of {@code + * weakCompareAndSet} must match the access mode type that is the result of + * calling {@code accessModeType(VarHandle.AccessMode.weakCompareAndSet)} on + * this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT, T expectedValue, T newValue)} + * , statically represented using varargs. + * @return {@code true} if successful, otherwise {@code false} if the + * witness value was not the same as the {@code expectedValue} or if this + * operation spuriously failed. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + * @see #set(Object...) + * @see #get(Object...) + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + boolean weakCompareAndSet(Object... args); + + /** + * Possibly atomically sets the value of a variable to the {@code newValue} + * with the semantics of {@link #set} if the variable's current value, + * referred to as the witness value, {@code ==} the + * {@code expectedValue}, as accessed with the memory semantics of + * {@link #getAcquire}. + * + *

This operation may fail spuriously (typically, due to memory + * contention) even if the current value does match the expected value. + * + *

The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}. + * + *

The symbolic type descriptor at the call site of {@code + * weakCompareAndSetAcquire} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.weakCompareAndSetAcquire)} on this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT, T expectedValue, T newValue)} + * , statically represented using varargs. + * @return {@code true} if successful, otherwise {@code false} if the + * witness value was not the same as the {@code expectedValue} or if this + * operation spuriously failed. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + * @see #set(Object...) + * @see #getAcquire(Object...) + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + boolean weakCompareAndSetAcquire(Object... args); + + /** + * Possibly atomically sets the value of a variable to the {@code newValue} + * with the semantics of {@link #setRelease} if the variable's current + * value, referred to as the witness value, {@code ==} the + * {@code expectedValue}, as accessed with the memory semantics of + * {@link #get}. + * + *

This operation may fail spuriously (typically, due to memory + * contention) even if the current value does match the expected value. + * + *

The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}. + * + *

The symbolic type descriptor at the call site of {@code + * weakCompareAndSetRelease} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.weakCompareAndSetRelease)} on this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT, T expectedValue, T newValue)} + * , statically represented using varargs. + * @return {@code true} if successful, otherwise {@code false} if the + * witness value was not the same as the {@code expectedValue} or if this + * operation spuriously failed. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + * @see #setRelease(Object...) + * @see #get(Object...) + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + boolean weakCompareAndSetRelease(Object... args); + + /** + * Atomically sets the value of a variable to the {@code newValue} with the + * memory semantics of {@link #setVolatile} and returns the variable's + * previous value, as accessed with the memory semantics of + * {@link #getVolatile}. + * + *

The method signature is of the form {@code (CT, T newValue)T}. + * + *

The symbolic type descriptor at the call site of {@code getAndSet} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.getAndSet)} on this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT, T newValue)} + * , statically represented using varargs. + * @return the signature-polymorphic result that is the previous value of + * the variable + * , statically represented using {@code Object}. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + * @see #setVolatile(Object...) + * @see #getVolatile(Object...) + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + Object getAndSet(Object... args); + + + // Primitive adders + // Throw UnsupportedOperationException for refs + + /** + * Atomically adds the {@code value} to the current value of a variable with + * the memory semantics of {@link #setVolatile}, and returns the variable's + * previous value, as accessed with the memory semantics of + * {@link #getVolatile}. + * + *

The method signature is of the form {@code (CT, T value)T}. + * + *

The symbolic type descriptor at the call site of {@code getAndAdd} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.getAndAdd)} on this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT, T value)} + * , statically represented using varargs. + * @return the signature-polymorphic result that is the previous value of + * the variable + * , statically represented using {@code Object}. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + * @see #setVolatile(Object...) + * @see #getVolatile(Object...) + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + Object getAndAdd(Object... args); + + /** + * Atomically adds the {@code value} to the current value of a variable with + * the memory semantics of {@link #setVolatile}, and returns the variable's + * current (updated) value, as accessed with the memory semantics of + * {@link #getVolatile}. + * + *

The method signature is of the form {@code (CT, T value)T}. + * + *

The symbolic type descriptor at the call site of {@code addAndGet} + * must match the access mode type that is the result of calling + * {@code accessModeType(VarHandle.AccessMode.addAndGet)} on this VarHandle. + * + * @param args the signature-polymorphic parameter list of the form + * {@code (CT, T value)} + * , statically represented using varargs. + * @return the signature-polymorphic result that is the current value of + * the variable + * , statically represented using {@code Object}. + * @throws UnsupportedOperationException if the access mode is unsupported + * for this VarHandle. + * @throws WrongMethodTypeException if the access mode type is not + * compatible with the caller's symbolic type descriptor. + * @see #setVolatile(Object...) + * @see #getVolatile(Object...) + */ + public final native + @MethodHandle.PolymorphicSignature + @HotSpotIntrinsicCandidate + Object addAndGet(Object... args); + + enum AccessType { + get, // 0 + set, // 1 + compareAndSwap, // 2 + compareAndExchange, // 3 + getAndUpdate; // 4 + + MethodType getMethodType(VarHandle vh) { + return getMethodType(this.ordinal(), vh); + } + + @ForceInline + static MethodType getMethodType(int ordinal, VarHandle vh) { + if (ordinal == 0) { + return vh.typeGet; + } + else if (ordinal == 1) { + return vh.typeSet; + } + else if (ordinal == 2) { + return vh.typeCompareSwap; + } + else if (ordinal == 3) { + return vh.typeCompareExchange; + } + else if (ordinal == 4) { + return vh.typeGetAndUpdate; + } + else { + throw new IllegalStateException("Illegal access type: " + ordinal); + } + } + } + + /** + * The set of access modes that specify how a variable, referenced by a + * VarHandle, is accessed. + */ + public enum AccessMode { + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#get VarHandle.get} + */ + get(AccessType.get, Object.class), // 0 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#set VarHandle.set} + */ + set(AccessType.set, void.class), // 1 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#getVolatile VarHandle.getVolatile} + */ + getVolatile(AccessType.get, Object.class), // 2 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#setVolatile VarHandle.setVolatile} + */ + setVolatile(AccessType.set, void.class), // 3 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#getAcquire VarHandle.getAcquire} + */ + getAcquire(AccessType.get, Object.class), // 4 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#setRelease VarHandle.setRelease} + */ + setRelease(AccessType.set, void.class), // 5 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#getOpaque VarHandle.getOpaque} + */ + getOpaque(AccessType.get, Object.class), // 6 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#setOpaque VarHandle.setOpaque} + */ + setOpaque(AccessType.set, void.class), // 7 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#compareAndSet VarHandle.compareAndSet} + */ + compareAndSet(AccessType.compareAndSwap, boolean.class), // 8 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile} + */ + compareAndExchangeVolatile(AccessType.compareAndExchange, Object.class), // 9 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire} + */ + compareAndExchangeAcquire(AccessType.compareAndExchange, Object.class), // 10 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease} + */ + compareAndExchangeRelease(AccessType.compareAndExchange, Object.class), // 11 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet} + */ + weakCompareAndSet(AccessType.compareAndSwap, boolean.class), // 12 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire} + */ + weakCompareAndSetAcquire(AccessType.compareAndSwap, boolean.class), // 13 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease} + */ + weakCompareAndSetRelease(AccessType.compareAndSwap, boolean.class), // 14 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#getAndSet VarHandle.getAndSet} + */ + getAndSet(AccessType.getAndUpdate, Object.class), // 15 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#getAndAdd VarHandle.getAndAdd} + */ + getAndAdd(AccessType.getAndUpdate, Object.class), // 16 + /** + * The access mode whose access is specified by the corresponding + * method + * {@link VarHandle#addAndGet VarHandle.addAndGet} + */ + addAndGet(AccessType.getAndUpdate, Object.class), // 17 + ; + + final AccessType at; + final boolean isPolyMorphicInReturnType; + final Class returnType; + + AccessMode(AccessType at, Class returnType) { + this.at = at; + + // Assert that return type is correct + // Otherwise, when disabled avoid using reflection + assert returnType == getReturnType(name()); + + this.returnType = returnType; + isPolyMorphicInReturnType = returnType != Object.class; + } + + private static Class getReturnType(String name) { + try { + Method m = VarHandle.class.getMethod(name, Object[].class); + return m.getReturnType(); + } + catch (Exception e) { + throw newInternalError(e); + } + } + + @ForceInline + static MemberName getMemberName(int ordinal, VarForm vform) { + return vform.table[ordinal]; + } + } + + static final class AccessDescriptor { + final MethodType symbolicMethodType; + final int type; + final int mode; + + public AccessDescriptor(MethodType symbolicMethodType, int type, int mode) { + this.symbolicMethodType = symbolicMethodType; + this.type = type; + this.mode = mode; + } + } + + /** + * Returns the variable type of variables referenced by this VarHandle. + * + * @return the variable type of variables referenced by this VarHandle + */ + public final Class varType() { + return typeSet.parameterType(typeSet.parameterCount() - 1); + } + + /** + * Returns the coordinate types for this VarHandle. + * + * @return the coordinate types for this VarHandle. The returned + * list is unmodifiable + */ + public final List> coordinateTypes() { + return typeGet.parameterList(); + } + + /** + * Obtains the canonical access mode type for this VarHandle and a given + * access mode. + * + *

The access mode type's parameter types will consist of a prefix that + * is the coordinate types of this VarHandle followed by further + * types as defined by the access mode's method. + * The access mode type's return type is defined by the return type of the + * access mode's method. + * + * @param accessMode the access mode, corresponding to the + * signature-polymorphic method of the same name + * @return the access mode type for the given access mode + */ + public final MethodType accessModeType(AccessMode accessMode) { + return accessMode.at.getMethodType(this); + } + + + /** + * Returns {@code true} if the given access mode is supported, otherwise + * {@code false}. + * + *

The return of a {@code false} value for a given access mode indicates + * that an {@code UnsupportedOperationException} is thrown on invocation + * of the corresponding access mode's signature-polymorphic method. + * + * @param accessMode the access mode, corresponding to the + * signature-polymorphic method of the same name + * @return {@code true} if the given access mode is supported, otherwise + * {@code false}. + */ + public final boolean isAccessModeSupported(AccessMode accessMode) { + return AccessMode.getMemberName(accessMode.ordinal(), vform) != null; + } + + /** + * Obtains a method handle bound to this VarHandle and the given access + * mode. + * + * @apiNote This method, for a VarHandle {@code vh} and access mode + * {@code {access-mode}}, returns a method handle that is equivalent to + * method handle {@code bhm} in the following code (though it may be more + * efficient): + *

{@code
+     * MethodHandle mh = MethodHandles.varHandleExactInvoker(
+     *                       vh.accessModeType(VarHandle.AccessMode.{access-mode}));
+     *
+     * MethodHandle bmh = mh.bindTo(vh);
+     * }
+ * + * @param accessMode the access mode, corresponding to the + * signature-polymorphic method of the same name + * @return a method handle bound to this VarHandle and the given access mode + */ + public final MethodHandle toMethodHandle(AccessMode accessMode) { + MemberName mn = AccessMode.getMemberName(accessMode.ordinal(), vform); + if (mn != null) { + return DirectMethodHandle.make(mn). + bindTo(this). + asType(accessMode.at.getMethodType(this)); + } + else { + // Ensure an UnsupportedOperationException is thrown + return MethodHandles.varHandleInvoker(accessMode, accessModeType(accessMode)). + bindTo(this); + } + } + + /*non-public*/ + final void updateVarForm(VarForm newVForm) { + if (vform == newVForm) return; + UNSAFE.putObject(this, VFORM_OFFSET, newVForm); + UNSAFE.fullFence(); + } + + static final BiFunction AIOOBE_SUPPLIER = new BiFunction<>() { + @Override + public ArrayIndexOutOfBoundsException apply(Integer a, Integer b) { + return new ArrayIndexOutOfBoundsException(a, b); + } + }; + + private static final long VFORM_OFFSET; + + static { + try { + VFORM_OFFSET = UNSAFE.objectFieldOffset(VarHandle.class.getDeclaredField("vform")); + } + catch (ReflectiveOperationException e) { + throw newInternalError(e); + } + } + + + // Fence methods + + /** + * Ensures that loads and stores before the fence will not be reordered + * with + * loads and stores after the fence. + * + * @apiNote Ignoring the many semantic differences from C and C++, this + * method has memory ordering effects compatible with + * {@code atomic_thread_fence(memory_order_seq_cst)} + */ + @ForceInline + public static void fullFence() { + UNSAFE.fullFence(); + } + + /** + * Ensures that loads before the fence will not be reordered with loads and + * stores after the fence. + * + * @apiNote Ignoring the many semantic differences from C and C++, this + * method has memory ordering effects compatible with + * {@code atomic_thread_fence(memory_order_acquire)} + */ + @ForceInline + public static void acquireFence() { + UNSAFE.loadFence(); + } + + /** + * Ensures that loads and stores before the fence will not be + * reordered with stores after the fence. + * + * @apiNote Ignoring the many semantic differences from C and C++, this + * method has memory ordering effects compatible with + * {@code atomic_thread_fence(memory_order_release)} + */ + @ForceInline + public static void releaseFence() { + UNSAFE.storeFence(); + } + + /** + * Ensures that loads before the fence will not be reordered with + * loads after the fence. + */ + @ForceInline + public static void loadLoadFence() { + UNSAFE.loadLoadFence(); + } + + /** + * Ensures that stores before the fence will not be reordered with + * stores after the fence. + */ + @ForceInline + public static void storeStoreFence() { + UNSAFE.storeStoreFence(); + } +} diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandleByteArrayBase.java b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandleByteArrayBase.java new file mode 100644 index 00000000000..3c1680eee02 --- /dev/null +++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandleByteArrayBase.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.lang.invoke; + +import java.nio.Buffer; +import java.nio.ByteBuffer; + +import static java.lang.invoke.MethodHandleStatics.UNSAFE; + +/** + * The base class for generated byte array and byte buffer view + * implementations + */ +abstract class VarHandleByteArrayBase { + // Buffer.address + static final long BUFFER_ADDRESS; + // Buffer.limit + static final long BUFFER_LIMIT; + // ByteBuffer.hb + static final long BYTE_BUFFER_HB; + // ByteBuffer.isReadOnly + static final long BYTE_BUFFER_IS_READ_ONLY; + + static { + try { + BUFFER_ADDRESS = UNSAFE.objectFieldOffset( + Buffer.class.getDeclaredField("address")); + + BUFFER_LIMIT = UNSAFE.objectFieldOffset( + Buffer.class.getDeclaredField("limit")); + + BYTE_BUFFER_HB = UNSAFE.objectFieldOffset( + ByteBuffer.class.getDeclaredField("hb")); + + BYTE_BUFFER_IS_READ_ONLY = UNSAFE.objectFieldOffset( + ByteBuffer.class.getDeclaredField("isReadOnly")); + } + catch (ReflectiveOperationException e) { + throw new Error(e); + } + } + + static final boolean BE = UNSAFE.isBigEndian(); + + static IllegalStateException newIllegalStateExceptionForMisalignedAccess(int index) { + return new IllegalStateException("Misaligned access at index: " + index); + } +} diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java new file mode 100644 index 00000000000..983ea2e2080 --- /dev/null +++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java @@ -0,0 +1,1391 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.lang.invoke; + +import jdk.internal.vm.annotation.ForceInline; + +// This class is auto-generated by java.lang.invoke.VarHandles$GuardMethodGenerator. Do not edit. +final class VarHandleGuards { + + @ForceInline + final static MemberName getMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) { + MemberName mn = VarHandle.AccessMode.getMemberName(ad.mode, handle.vform); + if (mn == null) { + throw handle.unsupported(); + } + return mn; + } + + @ForceInline + @LambdaForm.Compiled + final static Object guard_L_L(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + Object r = MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + return symbolic.returnType().cast(r); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return vh_invoker.invokeBasic(handle, arg0); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_LL_V(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static Object guard_LL_L(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + Object r = MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + return symbolic.returnType().cast(r); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_LLL_Z(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static Object guard_LLL_L(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + return symbolic.returnType().cast(r); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static int guard_L_I(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (int) vh_invoker.invokeBasic(handle, arg0); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_LI_V(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static int guard_LI_I(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (int) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_LII_Z(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static int guard_LII_I(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static long guard_L_J(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (long) vh_invoker.invokeBasic(handle, arg0); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_LJ_V(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static long guard_LJ_J(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (long) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_LJJ_Z(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static long guard_LJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static float guard_L_F(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (float) vh_invoker.invokeBasic(handle, arg0); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_LF_V(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static float guard_LF_F(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (float) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_LFF_Z(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static float guard_LFF_F(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static double guard_L_D(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (double) vh_invoker.invokeBasic(handle, arg0); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_LD_V(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static double guard_LD_D(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (double) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_LDD_Z(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static double guard_LDD_D(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static Object guard__L(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + Object r = MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); + return symbolic.returnType().cast(r); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return vh_invoker.invokeBasic(handle); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_L_V(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_LL_Z(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static int guard__I(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (int) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (int) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (int) vh_invoker.invokeBasic(handle); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_I_V(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0); + } + } + + @ForceInline + @LambdaForm.Compiled + final static int guard_I_I(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (int) vh_invoker.invokeBasic(handle, arg0); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_II_Z(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static int guard_II_I(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (int) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static long guard__J(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (long) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (long) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (long) vh_invoker.invokeBasic(handle); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_J_V(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0); + } + } + + @ForceInline + @LambdaForm.Compiled + final static long guard_J_J(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (long) vh_invoker.invokeBasic(handle, arg0); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_JJ_Z(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static long guard_JJ_J(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (long) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static float guard__F(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (float) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (float) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (float) vh_invoker.invokeBasic(handle); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_F_V(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0); + } + } + + @ForceInline + @LambdaForm.Compiled + final static float guard_F_F(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (float) vh_invoker.invokeBasic(handle, arg0); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_FF_Z(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static float guard_FF_F(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (float) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static double guard__D(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (double) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (double) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (double) vh_invoker.invokeBasic(handle); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_D_V(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0); + } + } + + @ForceInline + @LambdaForm.Compiled + final static double guard_D_D(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (double) vh_invoker.invokeBasic(handle, arg0); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_DD_Z(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static double guard_DD_D(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (double) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static Object guard_LI_L(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + Object r = MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + return symbolic.returnType().cast(r); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_LIL_V(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static Object guard_LIL_L(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + return symbolic.returnType().cast(r); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_LILL_Z(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + } + } + + @ForceInline + @LambdaForm.Compiled + final static Object guard_LILL_L(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + return symbolic.returnType().cast(r); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_LII_V(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_LIII_Z(VarHandle handle, Object arg0, int arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + } + } + + @ForceInline + @LambdaForm.Compiled + final static int guard_LIII_I(VarHandle handle, Object arg0, int arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + } + } + + @ForceInline + @LambdaForm.Compiled + final static long guard_LI_J(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (long) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_LIJ_V(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static long guard_LIJ_J(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_LIJJ_Z(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + } + } + + @ForceInline + @LambdaForm.Compiled + final static long guard_LIJJ_J(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + } + } + + @ForceInline + @LambdaForm.Compiled + final static float guard_LI_F(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (float) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_LIF_V(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static float guard_LIF_F(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_LIFF_Z(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + } + } + + @ForceInline + @LambdaForm.Compiled + final static float guard_LIFF_F(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + } + } + + @ForceInline + @LambdaForm.Compiled + final static double guard_LI_D(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (double) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_LID_V(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static double guard_LID_D(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_LIDD_Z(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + } + } + + @ForceInline + @LambdaForm.Compiled + final static double guard_LIDD_D(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + } + } + + @ForceInline + @LambdaForm.Compiled + final static int guard_LJ_I(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (int) vh_invoker.invokeBasic(handle, arg0, arg1); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_LJI_V(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static int guard_LJI_I(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_LJII_Z(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + } + } + + @ForceInline + @LambdaForm.Compiled + final static int guard_LJII_I(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + } + } + + @ForceInline + @LambdaForm.Compiled + final static void guard_LJJ_V(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + } + } + + @ForceInline + @LambdaForm.Compiled + final static boolean guard_LJJJ_Z(VarHandle handle, Object arg0, long arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + } + } + + @ForceInline + @LambdaForm.Compiled + final static long guard_LJJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable { + MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); + MethodType symbolic = ad.symbolicMethodType; + if (target == symbolic) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else if (target.erase() == symbolic.erase()) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + } + else { + MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); + return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + } + } + +} diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandles.java b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandles.java new file mode 100644 index 00000000000..443710af502 --- /dev/null +++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandles.java @@ -0,0 +1,533 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.invoke; + +import static java.lang.invoke.MethodHandleStatics.UNSAFE; + +final class VarHandles { + + static VarHandle makeFieldHandle(MemberName f, Class refc, Class type, boolean isWriteAllowedOnFinalFields) { + if (!f.isStatic()) { + long foffset = MethodHandleNatives.objectFieldOffset(f); + if (!type.isPrimitive()) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleObjects.FieldInstanceReadOnly(refc, foffset, type) + : new VarHandleObjects.FieldInstanceReadWrite(refc, foffset, type); + } + else if (type == boolean.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleBooleans.FieldInstanceReadOnly(refc, foffset) + : new VarHandleBooleans.FieldInstanceReadWrite(refc, foffset); + } + else if (type == byte.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleBytes.FieldInstanceReadOnly(refc, foffset) + : new VarHandleBytes.FieldInstanceReadWrite(refc, foffset); + } + else if (type == short.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleShorts.FieldInstanceReadOnly(refc, foffset) + : new VarHandleShorts.FieldInstanceReadWrite(refc, foffset); + } + else if (type == char.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleChars.FieldInstanceReadOnly(refc, foffset) + : new VarHandleChars.FieldInstanceReadWrite(refc, foffset); + } + else if (type == int.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleInts.FieldInstanceReadOnly(refc, foffset) + : new VarHandleInts.FieldInstanceReadWrite(refc, foffset); + } + else if (type == long.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleLongs.FieldInstanceReadOnly(refc, foffset) + : new VarHandleLongs.FieldInstanceReadWrite(refc, foffset); + } + else if (type == float.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleFloats.FieldInstanceReadOnly(refc, foffset) + : new VarHandleFloats.FieldInstanceReadWrite(refc, foffset); + } + else if (type == double.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleDoubles.FieldInstanceReadOnly(refc, foffset) + : new VarHandleDoubles.FieldInstanceReadWrite(refc, foffset); + } + else { + throw new UnsupportedOperationException(); + } + } + else { + // TODO This is not lazy on first invocation + // and might cause some circular initialization issues + + // Replace with something similar to direct method handles + // where a barrier is used then elided after use + + if (UNSAFE.shouldBeInitialized(refc)) + UNSAFE.ensureClassInitialized(refc); + + Object base = MethodHandleNatives.staticFieldBase(f); + long foffset = MethodHandleNatives.staticFieldOffset(f); + if (!type.isPrimitive()) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleObjects.FieldStaticReadOnly(base, foffset, type) + : new VarHandleObjects.FieldStaticReadWrite(base, foffset, type); + } + else if (type == boolean.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleBooleans.FieldStaticReadOnly(base, foffset) + : new VarHandleBooleans.FieldStaticReadWrite(base, foffset); + } + else if (type == byte.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleBytes.FieldStaticReadOnly(base, foffset) + : new VarHandleBytes.FieldStaticReadWrite(base, foffset); + } + else if (type == short.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleShorts.FieldStaticReadOnly(base, foffset) + : new VarHandleShorts.FieldStaticReadWrite(base, foffset); + } + else if (type == char.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleChars.FieldStaticReadOnly(base, foffset) + : new VarHandleChars.FieldStaticReadWrite(base, foffset); + } + else if (type == int.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleInts.FieldStaticReadOnly(base, foffset) + : new VarHandleInts.FieldStaticReadWrite(base, foffset); + } + else if (type == long.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleLongs.FieldStaticReadOnly(base, foffset) + : new VarHandleLongs.FieldStaticReadWrite(base, foffset); + } + else if (type == float.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleFloats.FieldStaticReadOnly(base, foffset) + : new VarHandleFloats.FieldStaticReadWrite(base, foffset); + } + else if (type == double.class) { + return f.isFinal() && !isWriteAllowedOnFinalFields + ? new VarHandleDoubles.FieldStaticReadOnly(base, foffset) + : new VarHandleDoubles.FieldStaticReadWrite(base, foffset); + } + else { + throw new UnsupportedOperationException(); + } + } + } + + static VarHandle makeArrayElementHandle(Class arrayClass) { + if (!arrayClass.isArray()) + throw new IllegalArgumentException("not an array: " + arrayClass); + + Class componentType = arrayClass.getComponentType(); + + int aoffset = UNSAFE.arrayBaseOffset(arrayClass); + int ascale = UNSAFE.arrayIndexScale(arrayClass); + int ashift = 31 - Integer.numberOfLeadingZeros(ascale); + + if (!componentType.isPrimitive()) { + return new VarHandleObjects.Array(aoffset, ashift, arrayClass); + } + else if (componentType == boolean.class) { + return new VarHandleBooleans.Array(aoffset, ashift); + } + else if (componentType == byte.class) { + return new VarHandleBytes.Array(aoffset, ashift); + } + else if (componentType == short.class) { + return new VarHandleShorts.Array(aoffset, ashift); + } + else if (componentType == char.class) { + return new VarHandleChars.Array(aoffset, ashift); + } + else if (componentType == int.class) { + return new VarHandleInts.Array(aoffset, ashift); + } + else if (componentType == long.class) { + return new VarHandleLongs.Array(aoffset, ashift); + } + else if (componentType == float.class) { + return new VarHandleFloats.Array(aoffset, ashift); + } + else if (componentType == double.class) { + return new VarHandleDoubles.Array(aoffset, ashift); + } + else { + throw new UnsupportedOperationException(); + } + } + + static VarHandle byteArrayViewHandle(Class viewArrayClass, + boolean be) { + if (!viewArrayClass.isArray()) + throw new IllegalArgumentException("not an array: " + viewArrayClass); + + Class viewComponentType = viewArrayClass.getComponentType(); + + if (viewComponentType == long.class) { + return new VarHandleByteArrayAsLongs.ArrayHandle(be); + } + else if (viewComponentType == int.class) { + return new VarHandleByteArrayAsInts.ArrayHandle(be); + } + else if (viewComponentType == short.class) { + return new VarHandleByteArrayAsShorts.ArrayHandle(be); + } + else if (viewComponentType == char.class) { + return new VarHandleByteArrayAsChars.ArrayHandle(be); + } + else if (viewComponentType == double.class) { + return new VarHandleByteArrayAsDoubles.ArrayHandle(be); + } + else if (viewComponentType == float.class) { + return new VarHandleByteArrayAsFloats.ArrayHandle(be); + } + + throw new UnsupportedOperationException(); + } + + static VarHandle makeByteBufferViewHandle(Class viewArrayClass, + boolean be) { + if (!viewArrayClass.isArray()) + throw new IllegalArgumentException("not an array: " + viewArrayClass); + + Class viewComponentType = viewArrayClass.getComponentType(); + + if (viewComponentType == long.class) { + return new VarHandleByteArrayAsLongs.ByteBufferHandle(be); + } + else if (viewComponentType == int.class) { + return new VarHandleByteArrayAsInts.ByteBufferHandle(be); + } + else if (viewComponentType == short.class) { + return new VarHandleByteArrayAsShorts.ByteBufferHandle(be); + } + else if (viewComponentType == char.class) { + return new VarHandleByteArrayAsChars.ByteBufferHandle(be); + } + else if (viewComponentType == double.class) { + return new VarHandleByteArrayAsDoubles.ByteBufferHandle(be); + } + else if (viewComponentType == float.class) { + return new VarHandleByteArrayAsFloats.ByteBufferHandle(be); + } + + throw new UnsupportedOperationException(); + } + +// /** +// * A helper program to generate the VarHandleGuards class with a set of +// * static guard methods each of which corresponds to a particular shape and +// * performs a type check of the symbolic type descriptor with the VarHandle +// * type descriptor before linking/invoking to the underlying operation as +// * characterized by the operation member name on the VarForm of the +// * VarHandle. +// *

+// * The generated class essentially encapsulates pre-compiled LambdaForms, +// * one for each method, for the most set of common method signatures. +// * This reduces static initialization costs, footprint costs, and circular +// * dependencies that may arise if a class is generated per LambdaForm. +// *

+// * A maximum of L*T*S methods will be generated where L is the number of +// * access modes kinds (or unique operation signatures) and T is the number +// * of variable types and S is the number of shapes (such as instance field, +// * static field, or array access). +// * If there are 4 unique operation signatures, 5 basic types (Object, int, +// * long, float, double), and 3 shapes then a maximum of 60 methods will be +// * generated. However, the number is likely to be less since there +// * be duplicate signatures. +// *

+// * Each method is annotated with @LambdaForm.Compiled to inform the runtime +// * that such methods should be treated as if a method of a class that is the +// * result of compiling a LambdaForm. Annotation of such methods is +// * important for correct evaluation of certain assertions and method return +// * type profiling in HotSpot. +// */ +// public static class GuardMethodGenerator { +// +// static final String GUARD_METHOD_SIG_TEMPLATE = " _()"; +// +// static final String GUARD_METHOD_TEMPLATE = +// "@ForceInline\n" + +// "@LambdaForm.Compiled\n" + +// "final static throws Throwable {\n" + +// " MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);\n" + +// " MethodType symbolic = ad.symbolicMethodType;\n" + +// " if (target == symbolic) {\n" + +// " MethodHandle.linkToStatic();\n" + +// " }\n" + +// " else if (target.erase() == symbolic.erase()) {\n" + +// " MethodHandle.linkToStatic();\n" + +// " }\n" + +// " else {\n" + +// " MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);\n" + +// " vh_invoker.invokeBasic();\n" + +// " }\n" + +// "}"; +// +// static final String GET_MEMBER_NAME_METHOD = +// "@ForceInline\n" + +// "final static MemberName getMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) {\n" + +// " MemberName mn = VarHandle.AccessMode.getMemberName(ad.mode, handle.vform);\n" + +// " if (mn == null) {\n" + +// " throw handle.unsupported();\n" + +// " }\n" + +// " return mn;\n" + +// "}"; +// +// // A template for deriving the operations +// // could be supported by annotating VarHandle directly with the +// // operation kind and shape +// interface VarHandleTemplate { +// Object get(); +// +// void set(Object value); +// +// boolean compareAndSwap(Object actualValue, Object expectedValue); +// +// Object compareAndExchange(Object actualValue, Object expectedValue); +// +// Object getAndUpdate(Object value); +// } +// +// static class HandleType { +// final Class receiver; +// final Class[] intermediates; +// final Class value; +// +// HandleType(Class receiver, Class value, Class... intermediates) { +// this.receiver = receiver; +// this.intermediates = intermediates; +// this.value = value; +// } +// } +// +// /** +// * @param args parameters +// */ +// public static void main(String[] args) { +// System.out.println("package java.lang.invoke;"); +// System.out.println(); +// System.out.println("import jdk.internal.vm.annotation.ForceInline;"); +// System.out.println(); +// System.out.println("// This class is auto-generated by " + +// GuardMethodGenerator.class.getName() + +// ". Do not edit."); +// System.out.println("final class VarHandleGuards {"); +// +// System.out.println(); +// System.out.println(GET_MEMBER_NAME_METHOD); +// System.out.println(); +// +// // Declare the stream of shapes +// Stream hts = Stream.of( +// // Object->Object +// new HandleType(Object.class, Object.class), +// // Object->int +// new HandleType(Object.class, int.class), +// // Object->long +// new HandleType(Object.class, long.class), +// // Object->float +// new HandleType(Object.class, float.class), +// // Object->double +// new HandleType(Object.class, double.class), +// +// // ->Object +// new HandleType(null, Object.class), +// // ->int +// new HandleType(null, int.class), +// // ->long +// new HandleType(null, long.class), +// // ->float +// new HandleType(null, float.class), +// // ->double +// new HandleType(null, double.class), +// +// // Array[int]->Object +// new HandleType(Object.class, Object.class, int.class), +// // Array[int]->int +// new HandleType(Object.class, int.class, int.class), +// // Array[int]->long +// new HandleType(Object.class, long.class, int.class), +// // Array[int]->float +// new HandleType(Object.class, float.class, int.class), +// // Array[int]->double +// new HandleType(Object.class, double.class, int.class), +// +// // Array[long]->int +// new HandleType(Object.class, int.class, long.class), +// // Array[long]->long +// new HandleType(Object.class, long.class, long.class) +// ); +// +// hts.flatMap(ht -> Stream.of(VarHandleTemplate.class.getMethods()). +// map(m -> generateMethodType(m, ht.receiver, ht.value, ht.intermediates))). +// distinct(). +// map(mt -> generateMethod(mt)). +// forEach(s -> { +// System.out.println(s); +// System.out.println(); +// }); +// +// System.out.println("}"); +// } +// +// static MethodType generateMethodType(Method m, Class receiver, Class value, Class... intermediates) { +// Class returnType = m.getReturnType() == Object.class +// ? value : m.getReturnType(); +// +// List> params = new ArrayList<>(); +// if (receiver != null) +// params.add(receiver); +// for (int i = 0; i < intermediates.length; i++) { +// params.add(intermediates[i]); +// } +// for (Parameter p : m.getParameters()) { +// params.add(value); +// } +// return MethodType.methodType(returnType, params); +// } +// +// static String generateMethod(MethodType mt) { +// Class returnType = mt.returnType(); +// +// LinkedHashMap> params = new LinkedHashMap<>(); +// params.put("handle", VarHandle.class); +// for (int i = 0; i < mt.parameterCount(); i++) { +// params.put("arg" + i, mt.parameterType(i)); +// } +// params.put("ad", VarHandle.AccessDescriptor.class); +// +// // Generate method signature line +// String RETURN = className(returnType); +// String NAME = "guard"; +// String SIGNATURE = getSignature(mt); +// String PARAMS = params.entrySet().stream(). +// map(e -> className(e.getValue()) + " " + e.getKey()). +// collect(joining(", ")); +// String METHOD = GUARD_METHOD_SIG_TEMPLATE. +// replace("", RETURN). +// replace("", NAME). +// replace("", SIGNATURE). +// replace("", PARAMS); +// +// // Generate method +// params.remove("ad"); +// +// List LINK_TO_STATIC_ARGS = params.keySet().stream(). +// collect(toList()); +// LINK_TO_STATIC_ARGS.add("getMemberName(handle, ad)"); +// +// List LINK_TO_INVOKER_ARGS = params.keySet().stream(). +// collect(toList()); +// +// RETURN = returnType == void.class +// ? "" +// : returnType == Object.class +// ? "return " +// : "return (" + returnType.getName() + ") "; +// +// String RESULT_ERASED = returnType == void.class +// ? "" +// : returnType != Object.class +// ? "return (" + returnType.getName() + ") " +// : "Object r = "; +// +// String RETURN_ERASED = returnType != Object.class +// ? "" +// : " return symbolic.returnType().cast(r);"; +// +// return GUARD_METHOD_TEMPLATE. +// replace("", METHOD). +// replace("", NAME). +// replaceAll("", RETURN). +// replace("", RESULT_ERASED). +// replace("", RETURN_ERASED). +// replaceAll("", LINK_TO_STATIC_ARGS.stream(). +// collect(joining(", "))). +// replace("", LINK_TO_INVOKER_ARGS.stream(). +// collect(joining(", "))) +// ; +// } +// +// static String className(Class c) { +// String n = c.getName(); +// if (n.startsWith("java.lang.")) { +// n = n.replace("java.lang.", ""); +// if (n.startsWith("invoke.")) { +// n = n.replace("invoke.", ""); +// } +// } +// return n.replace('$', '.'); +// } +// +// static String getSignature(MethodType m) { +// StringBuilder sb = new StringBuilder(m.parameterCount() + 1); +// +// for (int i = 0; i < m.parameterCount(); i++) { +// Class pt = m.parameterType(i); +// sb.append(getCharType(pt)); +// } +// +// sb.append('_').append(getCharType(m.returnType())); +// +// return sb.toString(); +// } +// +// static char getCharType(Class pt) { +// if (pt == void.class) { +// return 'V'; +// } +// else if (!pt.isPrimitive()) { +// return 'L'; +// } +// else if (pt == boolean.class) { +// return 'Z'; +// } +// else if (pt == int.class) { +// return 'I'; +// } +// else if (pt == long.class) { +// return 'J'; +// } +// else if (pt == float.class) { +// return 'F'; +// } +// else if (pt == double.class) { +// return 'D'; +// } +// else { +// throw new IllegalStateException(pt.getName()); +// } +// } +// } +} diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template new file mode 100644 index 00000000000..bcec64bd390 --- /dev/null +++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template @@ -0,0 +1,602 @@ +/* + * Copyright (c) 2015, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.lang.invoke; + +import java.util.Objects; +import jdk.internal.vm.annotation.ForceInline; + +import static java.lang.invoke.MethodHandleStatics.UNSAFE; + +#warn + +final class VarHandle$Type$s { + + static class FieldInstanceReadOnly extends VarHandle { + final long fieldOffset; + final Class receiverType; +#if[Object] + final Class fieldType; +#end[Object] + + FieldInstanceReadOnly(Class receiverType, long fieldOffset{#if[Object]?, Class fieldType}) { + this(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadOnly.class); + } + + protected FieldInstanceReadOnly(Class receiverType, long fieldOffset{#if[Object]?, Class fieldType}, + Class handle) { + super(VarForm.createFromStatic(handle), receiverType, {#if[Object]?fieldType:$type$.class}); + this.fieldOffset = fieldOffset; + this.receiverType = receiverType; +#if[Object] + this.fieldType = fieldType; +#end[Object] + } + + @ForceInline + static $type$ get(FieldInstanceReadOnly handle, Object holder) { + return UNSAFE.get$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset); + } + + @ForceInline + static $type$ getVolatile(FieldInstanceReadOnly handle, Object holder) { + return UNSAFE.get$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset); + } + + @ForceInline + static $type$ getOpaque(FieldInstanceReadOnly handle, Object holder) { + return UNSAFE.get$Type$Opaque(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset); + } + + @ForceInline + static $type$ getAcquire(FieldInstanceReadOnly handle, Object holder) { + return UNSAFE.get$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset); + } + } + + static class FieldInstanceReadWrite extends FieldInstanceReadOnly { + + FieldInstanceReadWrite(Class receiverType, long fieldOffset{#if[Object]?, Class fieldType}) { + super(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadWrite.class); + } + + @ForceInline + static void set(FieldInstanceReadWrite handle, Object holder, $type$ value) { + UNSAFE.put$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static void setVolatile(FieldInstanceReadWrite handle, Object holder, $type$ value) { + UNSAFE.put$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static void setOpaque(FieldInstanceReadWrite handle, Object holder, $type$ value) { + UNSAFE.put$Type$Opaque(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static void setRelease(FieldInstanceReadWrite handle, Object holder, $type$ value) { + UNSAFE.put$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(value):value}); + } +#if[CAS] + + @ForceInline + static boolean compareAndSet(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) { + return UNSAFE.compareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(expected):expected}, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static $type$ compareAndExchangeVolatile(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) { + return UNSAFE.compareAndExchange$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(expected):expected}, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static $type$ compareAndExchangeAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) { + return UNSAFE.compareAndExchange$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(expected):expected}, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static $type$ compareAndExchangeRelease(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) { + return UNSAFE.compareAndExchange$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(expected):expected}, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static boolean weakCompareAndSet(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) { + return UNSAFE.weakCompareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(expected):expected}, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static boolean weakCompareAndSetAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) { + return UNSAFE.weakCompareAndSwap$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(expected):expected}, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static boolean weakCompareAndSetRelease(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) { + return UNSAFE.weakCompareAndSwap$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(expected):expected}, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static $type$ getAndSet(FieldInstanceReadWrite handle, Object holder, $type$ value) { + return UNSAFE.getAndSet$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(value):value}); + } +#end[CAS] +#if[AtomicAdd] + + @ForceInline + static $type$ getAndAdd(FieldInstanceReadWrite handle, Object holder, $type$ value) { + return UNSAFE.getAndAdd$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset, + value); + } + + @ForceInline + static $type$ addAndGet(FieldInstanceReadWrite handle, Object holder, $type$ value) { + return UNSAFE.getAndAdd$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)), + handle.fieldOffset, + value) + value; + } +#end[AtomicAdd] + } + + + static class FieldStaticReadOnly extends VarHandle { + final Object base; + final long fieldOffset; +#if[Object] + final Class fieldType; +#end[Object] + + FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class fieldType}) { + this(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.class); + } + + protected FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class fieldType}, + Class handle) { + super(VarForm.createFromStatic(handle), null, {#if[Object]?fieldType:$type$.class}); + this.base = base; + this.fieldOffset = fieldOffset; +#if[Object] + this.fieldType = fieldType; +#end[Object] + } + + @ForceInline + static $type$ get(FieldStaticReadOnly handle) { + return UNSAFE.get$Type$(handle.base, + handle.fieldOffset); + } + + @ForceInline + static $type$ getVolatile(FieldStaticReadOnly handle) { + return UNSAFE.get$Type$Volatile(handle.base, + handle.fieldOffset); + } + + @ForceInline + static $type$ getOpaque(FieldStaticReadOnly handle) { + return UNSAFE.get$Type$Opaque(handle.base, + handle.fieldOffset); + } + + @ForceInline + static $type$ getAcquire(FieldStaticReadOnly handle) { + return UNSAFE.get$Type$Acquire(handle.base, + handle.fieldOffset); + } + } + + static class FieldStaticReadWrite extends FieldStaticReadOnly { + + FieldStaticReadWrite(Object base, long fieldOffset{#if[Object]?, Class fieldType}) { + super(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.class); + } + + @ForceInline + static void set(FieldStaticReadWrite handle, $type$ value) { + UNSAFE.put$Type$(handle.base, + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static void setVolatile(FieldStaticReadWrite handle, $type$ value) { + UNSAFE.put$Type$Volatile(handle.base, + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static void setOpaque(FieldStaticReadWrite handle, $type$ value) { + UNSAFE.put$Type$Opaque(handle.base, + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static void setRelease(FieldStaticReadWrite handle, $type$ value) { + UNSAFE.put$Type$Release(handle.base, + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(value):value}); + } +#if[CAS] + + @ForceInline + static boolean compareAndSet(FieldStaticReadWrite handle, $type$ expected, $type$ value) { + return UNSAFE.compareAndSwap$Type$(handle.base, + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(expected):expected}, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + + @ForceInline + static $type$ compareAndExchangeVolatile(FieldStaticReadWrite handle, $type$ expected, $type$ value) { + return UNSAFE.compareAndExchange$Type$Volatile(handle.base, + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(expected):expected}, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static $type$ compareAndExchangeAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) { + return UNSAFE.compareAndExchange$Type$Acquire(handle.base, + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(expected):expected}, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static $type$ compareAndExchangeRelease(FieldStaticReadWrite handle, $type$ expected, $type$ value) { + return UNSAFE.compareAndExchange$Type$Release(handle.base, + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(expected):expected}, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static boolean weakCompareAndSet(FieldStaticReadWrite handle, $type$ expected, $type$ value) { + return UNSAFE.weakCompareAndSwap$Type$(handle.base, + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(expected):expected}, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static boolean weakCompareAndSetAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) { + return UNSAFE.weakCompareAndSwap$Type$Acquire(handle.base, + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(expected):expected}, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static boolean weakCompareAndSetRelease(FieldStaticReadWrite handle, $type$ expected, $type$ value) { + return UNSAFE.weakCompareAndSwap$Type$Release(handle.base, + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(expected):expected}, + {#if[Object]?handle.fieldType.cast(value):value}); + } + + @ForceInline + static $type$ getAndSet(FieldStaticReadWrite handle, $type$ value) { + return UNSAFE.getAndSet$Type$(handle.base, + handle.fieldOffset, + {#if[Object]?handle.fieldType.cast(value):value}); + } +#end[CAS] +#if[AtomicAdd] + + @ForceInline + static $type$ getAndAdd(FieldStaticReadWrite handle, $type$ value) { + return UNSAFE.getAndAdd$Type$(handle.base, + handle.fieldOffset, + value); + } + + @ForceInline + static $type$ addAndGet(FieldStaticReadWrite handle, $type$ value) { + return UNSAFE.getAndAdd$Type$(handle.base, + handle.fieldOffset, + value) + value; + } +#end[AtomicAdd] + } + + + static final class Array extends VarHandle { + final int abase; + final int ashift; +#if[Object] + final Class<{#if[Object]??:$type$[]}> arrayType; + final Class componentType; +#end[Object] + + Array(int abase, int ashift{#if[Object]?, Class arrayType}) { + super(VarForm.createFromStatic(Array.class), + {#if[Object]?arrayType:$type$[].class}, {#if[Object]?arrayType.getComponentType():$type$.class}, int.class); + this.abase = abase; + this.ashift = ashift; +#if[Object] + this.arrayType = {#if[Object]?arrayType:$type$[].class}; + this.componentType = arrayType.getComponentType(); +#end[Object] + } + + @ForceInline + static $type$ get(Array handle, Object oarray, int index) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + return array[index]; + } + + @ForceInline + static void set(Array handle, Object oarray, int index, $type$ value) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + array[index] = {#if[Object]?handle.componentType.cast(value):value}; + } + + @ForceInline + static $type$ getVolatile(Array handle, Object oarray, int index) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + return UNSAFE.get$Type$Volatile(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase); + } + + @ForceInline + static void setVolatile(Array handle, Object oarray, int index, $type$ value) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + UNSAFE.put$Type$Volatile(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + {#if[Object]?handle.componentType.cast(value):value}); + } + + @ForceInline + static $type$ getOpaque(Array handle, Object oarray, int index) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + return UNSAFE.get$Type$Opaque(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase); + } + + @ForceInline + static void setOpaque(Array handle, Object oarray, int index, $type$ value) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + UNSAFE.put$Type$Opaque(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + {#if[Object]?handle.componentType.cast(value):value}); + } + + @ForceInline + static $type$ getAcquire(Array handle, Object oarray, int index) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + return UNSAFE.get$Type$Acquire(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase); + } + + @ForceInline + static void setRelease(Array handle, Object oarray, int index, $type$ value) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + UNSAFE.put$Type$Release(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + {#if[Object]?handle.componentType.cast(value):value}); + } +#if[CAS] + + @ForceInline + static boolean compareAndSet(Array handle, Object oarray, int index, $type$ expected, $type$ value) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + return UNSAFE.compareAndSwap$Type$(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + {#if[Object]?handle.componentType.cast(expected):expected}, + {#if[Object]?handle.componentType.cast(value):value}); + } + + @ForceInline + static $type$ compareAndExchangeVolatile(Array handle, Object oarray, int index, $type$ expected, $type$ value) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + return UNSAFE.compareAndExchange$Type$Volatile(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + {#if[Object]?handle.componentType.cast(expected):expected}, + {#if[Object]?handle.componentType.cast(value):value}); + } + + @ForceInline + static $type$ compareAndExchangeAcquire(Array handle, Object oarray, int index, $type$ expected, $type$ value) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + return UNSAFE.compareAndExchange$Type$Acquire(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + {#if[Object]?handle.componentType.cast(expected):expected}, + {#if[Object]?handle.componentType.cast(value):value}); + } + + @ForceInline + static $type$ compareAndExchangeRelease(Array handle, Object oarray, int index, $type$ expected, $type$ value) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + return UNSAFE.compareAndExchange$Type$Release(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + {#if[Object]?handle.componentType.cast(expected):expected}, + {#if[Object]?handle.componentType.cast(value):value}); + } + + @ForceInline + static boolean weakCompareAndSet(Array handle, Object oarray, int index, $type$ expected, $type$ value) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + return UNSAFE.weakCompareAndSwap$Type$(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + {#if[Object]?handle.componentType.cast(expected):expected}, + {#if[Object]?handle.componentType.cast(value):value}); + } + + @ForceInline + static boolean weakCompareAndSetAcquire(Array handle, Object oarray, int index, $type$ expected, $type$ value) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + return UNSAFE.weakCompareAndSwap$Type$Acquire(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + {#if[Object]?handle.componentType.cast(expected):expected}, + {#if[Object]?handle.componentType.cast(value):value}); + } + + @ForceInline + static boolean weakCompareAndSetRelease(Array handle, Object oarray, int index, $type$ expected, $type$ value) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + return UNSAFE.weakCompareAndSwap$Type$Release(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + {#if[Object]?handle.componentType.cast(expected):expected}, + {#if[Object]?handle.componentType.cast(value):value}); + } + + @ForceInline + static $type$ getAndSet(Array handle, Object oarray, int index, $type$ value) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + return UNSAFE.getAndSet$Type$(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + {#if[Object]?handle.componentType.cast(value):value}); + } +#end[CAS] +#if[AtomicAdd] + + @ForceInline + static $type$ getAndAdd(Array handle, Object oarray, int index, $type$ value) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + return UNSAFE.getAndAdd$Type$(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + value); + } + + @ForceInline + static $type$ addAndGet(Array handle, Object oarray, int index, $type$ value) { +#if[Object] + Object[] array = (Object[]) handle.arrayType.cast(oarray); +#else[Object] + $type$[] array = ($type$[]) oarray; +#end[Object] + return UNSAFE.getAndAdd$Type$(array, + (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + value) + value; + } +#end[AtomicAdd] + } +} diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template new file mode 100644 index 00000000000..bdc77a820d2 --- /dev/null +++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template @@ -0,0 +1,497 @@ +/* + * Copyright (c) 2015, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.lang.invoke; + +import jdk.internal.misc.Unsafe; +import jdk.internal.vm.annotation.ForceInline; + +import java.nio.ByteBuffer; +import java.nio.ReadOnlyBufferException; +import java.util.Objects; + +import static java.lang.invoke.MethodHandleStatics.UNSAFE; + +#warn + +final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase { + + static final int ALIGN = $BoxType$.BYTES - 1; + +#if[floatingPoint] + @ForceInline + static $rawType$ convEndian(boolean big, $type$ v) { + $rawType$ rv = $Type$.$type$ToRaw$RawType$Bits(v); + return big == BE ? rv : $RawBoxType$.reverseBytes(rv); + } + + @ForceInline + static $type$ convEndian(boolean big, $rawType$ rv) { + rv = big == BE ? rv : $RawBoxType$.reverseBytes(rv); + return $Type$.$rawType$BitsTo$Type$(rv); + } +#else[floatingPoint] + @ForceInline + static $type$ convEndian(boolean big, $type$ n) { + return big == BE ? n : $BoxType$.reverseBytes(n); + } +#end[floatingPoint] + + + private static class ByteArrayViewVarHandle extends VarHandle { + final boolean be; + + ByteArrayViewVarHandle(Class implSubType, + Class arrayType, Class component, boolean be) { + super(VarForm.createFromStatic(implSubType), + arrayType, component, int.class); + this.be = be; + } + } + + static final class ArrayHandle extends ByteArrayViewVarHandle { + + ArrayHandle(boolean be) { + super(ArrayHandle.class, byte[].class, $type$.class, be); + } + + @ForceInline + static int index(byte[] ba, int index) { + return Objects.checkIndex(index, ba.length - ALIGN, null); + } + + @ForceInline + static long address(byte[] ba, int index) { + long address = ((long) index) + Unsafe.ARRAY_BYTE_BASE_OFFSET; + if ((address & ALIGN) != 0) + throw newIllegalStateExceptionForMisalignedAccess(index); + return address; + } + + @ForceInline + static $type$ get(ArrayHandle handle, Object oba, int index) { + byte[] ba = (byte[]) oba; +#if[floatingPoint] + $rawType$ rawValue = UNSAFE.get$RawType$Unaligned( + ba, + ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET, + handle.be); + return $Type$.$rawType$BitsTo$Type$(rawValue); +#else[floatingPoint] + return UNSAFE.get$Type$Unaligned( + ba, + ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET, + handle.be); +#end[floatingPoint] + } + + @ForceInline + static void set(ArrayHandle handle, Object oba, int index, $type$ value) { + byte[] ba = (byte[]) oba; +#if[floatingPoint] + UNSAFE.put$RawType$Unaligned( + ba, + ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET, + $Type$.$type$ToRaw$RawType$Bits(value), + handle.be); +#else[floatingPoint] + UNSAFE.put$RawType$Unaligned( + ba, + ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET, + value, + handle.be); +#end[floatingPoint] + } + + @ForceInline + static $type$ getVolatile(ArrayHandle handle, Object oba, int index) { + byte[] ba = (byte[]) oba; + return convEndian(handle.be, + UNSAFE.get$RawType$Volatile( + ba, + address(ba, index(ba, index)))); + } + + @ForceInline + static void setVolatile(ArrayHandle handle, Object oba, int index, $type$ value) { + byte[] ba = (byte[]) oba; + UNSAFE.put$RawType$Volatile( + ba, + address(ba, index(ba, index)), + convEndian(handle.be, value)); + } + + @ForceInline + static $type$ getAcquire(ArrayHandle handle, Object oba, int index) { + byte[] ba = (byte[]) oba; + return convEndian(handle.be, + UNSAFE.get$RawType$Acquire( + ba, + address(ba, index(ba, index)))); + } + + @ForceInline + static void setRelease(ArrayHandle handle, Object oba, int index, $type$ value) { + byte[] ba = (byte[]) oba; + UNSAFE.put$RawType$Release( + ba, + address(ba, index(ba, index)), + convEndian(handle.be, value)); + } + + @ForceInline + static $type$ getOpaque(ArrayHandle handle, Object oba, int index) { + byte[] ba = (byte[]) oba; + return convEndian(handle.be, + UNSAFE.get$RawType$Opaque( + ba, + address(ba, index(ba, index)))); + } + + @ForceInline + static void setOpaque(ArrayHandle handle, Object oba, int index, $type$ value) { + byte[] ba = (byte[]) oba; + UNSAFE.put$RawType$Opaque( + ba, + address(ba, index(ba, index)), + convEndian(handle.be, value)); + } +#if[CAS] + + @ForceInline + static boolean compareAndSet(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) { + byte[] ba = (byte[]) oba; + return UNSAFE.compareAndSwap$RawType$( + ba, + address(ba, index(ba, index)), + convEndian(handle.be, expected), convEndian(handle.be, value)); + } + + @ForceInline + static $type$ compareAndExchangeVolatile(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) { + byte[] ba = (byte[]) oba; + return convEndian(handle.be, + UNSAFE.compareAndExchange$RawType$Volatile( + ba, + address(ba, index(ba, index)), + convEndian(handle.be, expected), convEndian(handle.be, value))); + } + + @ForceInline + static $type$ compareAndExchangeAcquire(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) { + byte[] ba = (byte[]) oba; + return convEndian(handle.be, + UNSAFE.compareAndExchange$RawType$Acquire( + ba, + address(ba, index(ba, index)), + convEndian(handle.be, expected), convEndian(handle.be, value))); + } + + @ForceInline + static $type$ compareAndExchangeRelease(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) { + byte[] ba = (byte[]) oba; + return convEndian(handle.be, + UNSAFE.compareAndExchange$RawType$Release( + ba, + address(ba, index(ba, index)), + convEndian(handle.be, expected), convEndian(handle.be, value))); + } + + @ForceInline + static boolean weakCompareAndSet(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) { + byte[] ba = (byte[]) oba; + return UNSAFE.weakCompareAndSwap$RawType$( + ba, + address(ba, index(ba, index)), + convEndian(handle.be, expected), convEndian(handle.be, value)); + } + + @ForceInline + static boolean weakCompareAndSetAcquire(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) { + byte[] ba = (byte[]) oba; + return UNSAFE.weakCompareAndSwap$RawType$Acquire( + ba, + address(ba, index(ba, index)), + convEndian(handle.be, expected), convEndian(handle.be, value)); + } + + @ForceInline + static boolean weakCompareAndSetRelease(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) { + byte[] ba = (byte[]) oba; + return UNSAFE.weakCompareAndSwap$RawType$Release( + ba, + address(ba, index(ba, index)), + convEndian(handle.be, expected), convEndian(handle.be, value)); + } + + @ForceInline + static $type$ getAndSet(ArrayHandle handle, Object oba, int index, $type$ value) { + byte[] ba = (byte[]) oba; + return convEndian(handle.be, + UNSAFE.getAndSet$RawType$( + ba, + address(ba, index(ba, index)), + convEndian(handle.be, value))); + } +#end[CAS] +#if[AtomicAdd] + + @ForceInline + static $type$ getAndAdd(ArrayHandle handle, Object oba, int index, $type$ value) { + byte[] ba = (byte[]) oba; + return convEndian(handle.be, + UNSAFE.getAndAdd$RawType$( + ba, + address(ba, index(ba, index)), + convEndian(handle.be, value))); + } + + @ForceInline + static $type$ addAndGet(ArrayHandle handle, Object oba, int index, $type$ value) { + byte[] ba = (byte[]) oba; + return convEndian(handle.be, UNSAFE.getAndAdd$RawType$( + ba, + address(ba, index(ba, index)), + convEndian(handle.be, value))) + value; + } +#end[AtomicAdd] + } + + + static final class ByteBufferHandle extends ByteArrayViewVarHandle { + + ByteBufferHandle(boolean be) { + super(ByteBufferHandle.class, ByteBuffer.class, $type$.class, be); + } + + @ForceInline + static int index(ByteBuffer bb, int index) { + return Objects.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null); + } + + @ForceInline + static int indexRO(ByteBuffer bb, int index) { + if (UNSAFE.getBoolean(bb, BYTE_BUFFER_IS_READ_ONLY)) + throw new ReadOnlyBufferException(); + return Objects.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null); + } + + @ForceInline + static long address(ByteBuffer bb, int index) { + long address = ((long) index) + UNSAFE.getLong(bb, BUFFER_ADDRESS); + if ((address & ALIGN) != 0) + throw newIllegalStateExceptionForMisalignedAccess(index); + return address; + } + + @ForceInline + static $type$ get(ByteBufferHandle handle, Object obb, int index) { + ByteBuffer bb = (ByteBuffer) obb; +#if[floatingPoint] + $rawType$ rawValue = UNSAFE.get$RawType$Unaligned( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + ((long) index(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS), + handle.be); + return $Type$.$rawType$BitsTo$Type$(rawValue); +#else[floatingPoint] + return UNSAFE.get$Type$Unaligned( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + ((long) index(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS), + handle.be); +#end[floatingPoint] + } + + @ForceInline + static void set(ByteBufferHandle handle, Object obb, int index, $type$ value) { + ByteBuffer bb = (ByteBuffer) obb; +#if[floatingPoint] + UNSAFE.put$RawType$Unaligned( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + ((long) indexRO(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS), + $Type$.$type$ToRaw$RawType$Bits(value), + handle.be); +#else[floatingPoint] + UNSAFE.put$Type$Unaligned( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + ((long) indexRO(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS), + value, + handle.be); +#end[floatingPoint] + } + + @ForceInline + static $type$ getVolatile(ByteBufferHandle handle, Object obb, int index) { + ByteBuffer bb = (ByteBuffer) obb; + return convEndian(handle.be, + UNSAFE.get$RawType$Volatile( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, index(bb, index)))); + } + + @ForceInline + static void setVolatile(ByteBufferHandle handle, Object obb, int index, $type$ value) { + ByteBuffer bb = (ByteBuffer) obb; + UNSAFE.put$RawType$Volatile( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, indexRO(bb, index)), + convEndian(handle.be, value)); + } + + @ForceInline + static $type$ getAcquire(ByteBufferHandle handle, Object obb, int index) { + ByteBuffer bb = (ByteBuffer) obb; + return convEndian(handle.be, + UNSAFE.get$RawType$Acquire( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, index(bb, index)))); + } + + @ForceInline + static void setRelease(ByteBufferHandle handle, Object obb, int index, $type$ value) { + ByteBuffer bb = (ByteBuffer) obb; + UNSAFE.put$RawType$Release( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, indexRO(bb, index)), + convEndian(handle.be, value)); + } + + @ForceInline + static $type$ getOpaque(ByteBufferHandle handle, Object obb, int index) { + ByteBuffer bb = (ByteBuffer) obb; + return convEndian(handle.be, + UNSAFE.get$RawType$Opaque( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, index(bb, index)))); + } + + @ForceInline + static void setOpaque(ByteBufferHandle handle, Object obb, int index, $type$ value) { + ByteBuffer bb = (ByteBuffer) obb; + UNSAFE.put$RawType$Opaque( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, indexRO(bb, index)), + convEndian(handle.be, value)); + } +#if[CAS] + + @ForceInline + static boolean compareAndSet(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) { + ByteBuffer bb = (ByteBuffer) obb; + return UNSAFE.compareAndSwap$RawType$( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, indexRO(bb, index)), + convEndian(handle.be, expected), convEndian(handle.be, value)); + } + + @ForceInline + static $type$ compareAndExchangeVolatile(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) { + ByteBuffer bb = (ByteBuffer) obb; + return convEndian(handle.be, + UNSAFE.compareAndExchange$RawType$Volatile( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, indexRO(bb, index)), + convEndian(handle.be, expected), convEndian(handle.be, value))); + } + + @ForceInline + static $type$ compareAndExchangeAcquire(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) { + ByteBuffer bb = (ByteBuffer) obb; + return convEndian(handle.be, + UNSAFE.compareAndExchange$RawType$Acquire( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, indexRO(bb, index)), + convEndian(handle.be, expected), convEndian(handle.be, value))); + } + + @ForceInline + static $type$ compareAndExchangeRelease(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) { + ByteBuffer bb = (ByteBuffer) obb; + return convEndian(handle.be, + UNSAFE.compareAndExchange$RawType$Release( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, indexRO(bb, index)), + convEndian(handle.be, expected), convEndian(handle.be, value))); + } + + @ForceInline + static boolean weakCompareAndSet(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) { + ByteBuffer bb = (ByteBuffer) obb; + return UNSAFE.weakCompareAndSwap$RawType$( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, indexRO(bb, index)), + convEndian(handle.be, expected), convEndian(handle.be, value)); + } + + @ForceInline + static boolean weakCompareAndSetAcquire(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) { + ByteBuffer bb = (ByteBuffer) obb; + return UNSAFE.weakCompareAndSwap$RawType$Acquire( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, indexRO(bb, index)), + convEndian(handle.be, expected), convEndian(handle.be, value)); + } + + @ForceInline + static boolean weakCompareAndSetRelease(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) { + ByteBuffer bb = (ByteBuffer) obb; + return UNSAFE.weakCompareAndSwap$RawType$Release( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, indexRO(bb, index)), + convEndian(handle.be, expected), convEndian(handle.be, value)); + } + + @ForceInline + static $type$ getAndSet(ByteBufferHandle handle, Object obb, int index, $type$ value) { + ByteBuffer bb = (ByteBuffer) obb; + return convEndian(handle.be, + UNSAFE.getAndSet$RawType$( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, indexRO(bb, index)), + convEndian(handle.be, value))); + } +#end[CAS] +#if[AtomicAdd] + + @ForceInline + static $type$ getAndAdd(ByteBufferHandle handle, Object obb, int index, $type$ value) { + ByteBuffer bb = (ByteBuffer) obb; + return convEndian(handle.be, + UNSAFE.getAndAdd$RawType$( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, indexRO(bb, index)), + convEndian(handle.be, value))); + } + + @ForceInline + static $type$ addAndGet(ByteBufferHandle handle, Object obb, int index, $type$ value) { + ByteBuffer bb = (ByteBuffer) obb; + return convEndian(handle.be, + UNSAFE.getAndAdd$RawType$( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, indexRO(bb, index)), + convEndian(handle.be, value))) + value; + } +#end[AtomicAdd] + } +} diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java b/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java index ec2539f50b5..a6d8e41c48c 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -32,7 +32,8 @@ * certain types in this package have special relations to dynamic * language support in the virtual machine: *

    - *
  • The class {@link java.lang.invoke.MethodHandle MethodHandle} contains + *
  • The classes {@link java.lang.invoke.MethodHandle MethodHandle} + * {@link java.lang.invoke.VarHandle VarHandle} contain * signature polymorphic methods * which can be linked regardless of their type descriptor. * Normally, method linkage requires exact matching of type descriptors. diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/AbstractClassLoaderValue.java b/jdk/src/java.base/share/classes/java/lang/reflect/AbstractClassLoaderValue.java new file mode 100644 index 00000000000..1689f5d74e3 --- /dev/null +++ b/jdk/src/java.base/share/classes/java/lang/reflect/AbstractClassLoaderValue.java @@ -0,0 +1,431 @@ +/* + * Copyright (c) 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. + */ + +package java.lang.reflect; + +import jdk.internal.loader.BootLoader; +import jdk.internal.misc.JavaLangAccess; +import jdk.internal.misc.SharedSecrets; + +import java.util.Iterator; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiFunction; +import java.util.function.Supplier; + +/** + * AbstractClassLoaderValue is a superclass of root-{@link ClassLoaderValue} + * and {@link Sub sub}-ClassLoaderValue. + * + * @param the type of concrete ClassLoaderValue (this type) + * @param the type of values associated with ClassLoaderValue + */ +abstract class AbstractClassLoaderValue, V> { + + /** + * Sole constructor. + */ + AbstractClassLoaderValue() {} + + /** + * Returns the key component of this ClassLoaderValue. The key component of + * the root-{@link ClassLoaderValue} is the ClassLoaderValue itself, + * while the key component of a {@link #sub(Object) sub}-ClassLoaderValue + * is what was given to construct it. + * + * @return the key component of this ClassLoaderValue. + */ + public abstract Object key(); + + /** + * Constructs new sub-ClassLoaderValue of this ClassLoaderValue with given + * key component. + * + * @param key the key component of the sub-ClassLoaderValue. + * @param the type of the key component. + * @return a sub-ClassLoaderValue of this ClassLoaderValue for given key + */ + public Sub sub(K key) { + return new Sub<>(key); + } + + /** + * Returns {@code true} if this ClassLoaderValue is equal to given {@code clv} + * or if this ClassLoaderValue was derived from given {@code clv} by a chain + * of {@link #sub(Object)} invocations. + * + * @param clv the ClassLoaderValue to test this against + * @return if this ClassLoaderValue is equal to given {@code clv} or + * its descendant + */ + public abstract boolean isEqualOrDescendantOf(AbstractClassLoaderValue clv); + + /** + * Returns the value associated with this ClassLoaderValue and given ClassLoader + * or {@code null} if there is none. + * + * @param cl the ClassLoader for the associated value + * @return the value associated with this ClassLoaderValue and given ClassLoader + * or {@code null} if there is none. + */ + public V get(ClassLoader cl) { + Object val = AbstractClassLoaderValue.map(cl).get(this); + try { + return extractValue(val); + } catch (Memoizer.RecursiveInvocationException e) { + // propagate recursive get() for the same key that is just + // being calculated in computeIfAbsent() + throw e; + } catch (Throwable t) { + // don't propagate exceptions thrown from Memoizer - pretend + // that there was no entry + // (computeIfAbsent invocation will try to remove it anyway) + return null; + } + } + + /** + * Associates given value {@code v} with this ClassLoaderValue and given + * ClassLoader and returns {@code null} if there was no previously associated + * value or does nothing and returns previously associated value if there + * was one. + * + * @param cl the ClassLoader for the associated value + * @param v the value to associate + * @return previously associated value or null if there was none + */ + public V putIfAbsent(ClassLoader cl, V v) { + ConcurrentHashMap map = map(cl); + @SuppressWarnings("unchecked") + CLV clv = (CLV) this; + while (true) { + try { + Object val = map.putIfAbsent(clv, v); + return extractValue(val); + } catch (Memoizer.RecursiveInvocationException e) { + // propagate RecursiveInvocationException for the same key that + // is just being calculated in computeIfAbsent + throw e; + } catch (Throwable t) { + // don't propagate exceptions thrown from foreign Memoizer - + // pretend that there was no entry and retry + // (foreign computeIfAbsent invocation will try to remove it anyway) + } + // TODO: + // Thread.onSpinLoop(); // when available + } + } + + /** + * Removes the value associated with this ClassLoaderValue and given + * ClassLoader if the associated value is equal to given value {@code v} and + * returns {@code true} or does nothing and returns {@code false} if there is + * no currently associated value or it is not equal to given value {@code v}. + * + * @param cl the ClassLoader for the associated value + * @param v the value to compare with currently associated value + * @return {@code true} if the association was removed or {@code false} if not + */ + public boolean remove(ClassLoader cl, Object v) { + return AbstractClassLoaderValue.map(cl).remove(this, v); + } + + /** + * Returns the value associated with this ClassLoaderValue and given + * ClassLoader if there is one or computes the value by invoking given + * {@code mappingFunction}, associates it and returns it. + *

    + * Computation and association of the computed value is performed atomically + * by the 1st thread that requests a particular association while holding a + * lock associated with this ClassLoaderValue and given ClassLoader. + * Nested calls from the {@code mappingFunction} to {@link #get}, + * {@link #putIfAbsent} or {@link #computeIfAbsent} for the same association + * are not allowed and throw {@link IllegalStateException}. Nested call to + * {@link #remove} for the same association is allowed but will always return + * {@code false} regardless of passed-in comparison value. Nested calls for + * other association(s) are allowed, but care should be taken to avoid + * deadlocks. When two threads perform nested computations of the overlapping + * set of associations they should always request them in the same order. + * + * @param cl the ClassLoader for the associated value + * @param mappingFunction the function to compute the value + * @return the value associated with this ClassLoaderValue and given + * ClassLoader. + * @throws IllegalStateException if a direct or indirect invocation from + * within given {@code mappingFunction} that + * computes the value of a particular association + * to {@link #get}, {@link #putIfAbsent} or + * {@link #computeIfAbsent} + * for the same association is attempted. + */ + public V computeIfAbsent(ClassLoader cl, + BiFunction< + ? super ClassLoader, + ? super CLV, + ? extends V + > mappingFunction) throws IllegalStateException { + ConcurrentHashMap map = map(cl); + @SuppressWarnings("unchecked") + CLV clv = (CLV) this; + Memoizer mv = null; + while (true) { + Object val = (mv == null) ? map.get(clv) : map.putIfAbsent(clv, mv); + if (val == null) { + if (mv == null) { + // create Memoizer lazily when 1st needed and restart loop + mv = new Memoizer<>(cl, clv, mappingFunction); + continue; + } + // mv != null, therefore sv == null was a result of successful + // putIfAbsent + try { + // trigger Memoizer to compute the value + V v = mv.get(); + // attempt to replace our Memoizer with the value + map.replace(clv, mv, v); + // return computed value + return v; + } catch (Throwable t) { + // our Memoizer has thrown, attempt to remove it + map.remove(clv, mv); + // propagate exception because it's from our Memoizer + throw t; + } + } else { + try { + return extractValue(val); + } catch (Memoizer.RecursiveInvocationException e) { + // propagate recursive attempts to calculate the same + // value as being calculated at the moment + throw e; + } catch (Throwable t) { + // don't propagate exceptions thrown from foreign Memoizer - + // pretend that there was no entry and retry + // (foreign computeIfAbsent invocation will try to remove it anyway) + } + } + // TODO: + // Thread.onSpinLoop(); // when available + } + } + + /** + * Removes all values associated with given ClassLoader {@code cl} and + * {@link #isEqualOrDescendantOf(AbstractClassLoaderValue) this or descendants} + * of this ClassLoaderValue. + * This is not an atomic operation. Other threads may see some associations + * be already removed and others still present while this method is executing. + *

    + * The sole intention of this method is to cleanup after a unit test that + * tests ClassLoaderValue directly. It is not intended for use in + * actual algorithms. + * + * @param cl the associated ClassLoader of the values to be removed + */ + public void removeAll(ClassLoader cl) { + ConcurrentHashMap map = map(cl); + for (Iterator i = map.keySet().iterator(); i.hasNext(); ) { + if (i.next().isEqualOrDescendantOf(this)) { + i.remove(); + } + } + } + + private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); + + /** + * @return a ConcurrentHashMap for given ClassLoader + */ + @SuppressWarnings("unchecked") + private static > + ConcurrentHashMap map(ClassLoader cl) { + return (ConcurrentHashMap) + (cl == null ? BootLoader.getClassLoaderValueMap() + : JLA.createOrGetClassLoaderValueMap(cl)); + } + + /** + * @return value extracted from the {@link Memoizer} if given + * {@code memoizerOrValue} parameter is a {@code Memoizer} or + * just return given parameter. + */ + @SuppressWarnings("unchecked") + private V extractValue(Object memoizerOrValue) { + if (memoizerOrValue instanceof Memoizer) { + return ((Memoizer) memoizerOrValue).get(); + } else { + return (V) memoizerOrValue; + } + } + + /** + * A memoized supplier that invokes given {@code mappingFunction} just once + * and remembers the result or thrown exception for subsequent calls. + * If given mappingFunction returns null, it is converted to NullPointerException, + * thrown from the Memoizer's {@link #get()} method and remembered. + * If the Memoizer is invoked recursively from the given {@code mappingFunction}, + * {@link RecursiveInvocationException} is thrown, but it is not remembered. + * The in-flight call to the {@link #get()} can still complete successfully if + * such exception is handled by the mappingFunction. + */ + private static final class Memoizer, V> + implements Supplier { + + private final ClassLoader cl; + private final CLV clv; + private final BiFunction + mappingFunction; + + private volatile V v; + private volatile Throwable t; + private boolean inCall; + + Memoizer(ClassLoader cl, + CLV clv, + BiFunction + mappingFunction + ) { + this.cl = cl; + this.clv = clv; + this.mappingFunction = mappingFunction; + } + + @Override + public V get() throws RecursiveInvocationException { + V v = this.v; + if (v != null) return v; + Throwable t = this.t; + if (t == null) { + synchronized (this) { + if ((v = this.v) == null && (t = this.t) == null) { + if (inCall) { + throw new RecursiveInvocationException(); + } + inCall = true; + try { + this.v = v = Objects.requireNonNull( + mappingFunction.apply(cl, clv)); + } catch (Throwable x) { + this.t = t = x; + } finally { + inCall = false; + } + } + } + } + if (v != null) return v; + if (t instanceof Error) { + throw (Error) t; + } else if (t instanceof RuntimeException) { + throw (RuntimeException) t; + } else { + throw new UndeclaredThrowableException(t); + } + } + + static class RecursiveInvocationException extends IllegalStateException { + private static final long serialVersionUID = 1L; + + RecursiveInvocationException() { + super("Recursive call"); + } + } + } + + /** + * sub-ClassLoaderValue is an inner class of {@link AbstractClassLoaderValue} + * and also a subclass of it. It can therefore be instantiated as an inner + * class of either an instance of root-{@link ClassLoaderValue} or another + * instance of itself. This enables composing type-safe compound keys of + * arbitrary length: + *

    {@code
    +     * ClassLoaderValue clv = new ClassLoaderValue<>();
    +     * ClassLoaderValue.Sub.Sub.Sub clv_k123 =
    +     *     clv.sub(k1).sub(k2).sub(k3);
    +     * }
    + * From which individual components are accessible in a type-safe way: + *
    {@code
    +     * K1 k1 = clv_k123.parent().parent().key();
    +     * K2 k2 = clv_k123.parent().key();
    +     * K3 k3 = clv_k123.key();
    +     * }
    + * This allows specifying non-capturing lambdas for the mapping function of + * {@link #computeIfAbsent(ClassLoader, BiFunction)} operation that can + * access individual key components from passed-in + * sub-[sub-...]ClassLoaderValue instance in a type-safe way. + * + * @param the type of {@link #key()} component contained in the + * sub-ClassLoaderValue. + */ + final class Sub extends AbstractClassLoaderValue, V> { + + private final K key; + + Sub(K key) { + this.key = key; + } + + /** + * @return the parent ClassLoaderValue this sub-ClassLoaderValue + * has been {@link #sub(Object) derived} from. + */ + public AbstractClassLoaderValue parent() { + return AbstractClassLoaderValue.this; + } + + /** + * @return the key component of this sub-ClassLoaderValue. + */ + @Override + public K key() { + return key; + } + + /** + * sub-ClassLoaderValue is a descendant of given {@code clv} if it is + * either equal to it or if its {@link #parent() parent} is a + * descendant of given {@code clv}. + */ + @Override + public boolean isEqualOrDescendantOf(AbstractClassLoaderValue clv) { + return equals(Objects.requireNonNull(clv)) || + parent().isEqualOrDescendantOf(clv); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Sub)) return false; + @SuppressWarnings("unchecked") + Sub that = (Sub) o; + return this.parent().equals(that.parent()) && + Objects.equals(this.key, that.key); + } + + @Override + public int hashCode() { + return 31 * parent().hashCode() + + Objects.hashCode(key); + } + } +} diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/ClassLoaderValue.java b/jdk/src/java.base/share/classes/java/lang/reflect/ClassLoaderValue.java new file mode 100644 index 00000000000..4b550871676 --- /dev/null +++ b/jdk/src/java.base/share/classes/java/lang/reflect/ClassLoaderValue.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 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. + */ + +package java.lang.reflect; + +import java.util.Objects; +import java.util.function.BiFunction; + +/** + * root-ClassLoaderValue. Each instance defines a separate namespace for + * associated values. + *

    + * ClassLoaderValue allows associating a + * {@link #computeIfAbsent(ClassLoader, BiFunction) computed} non-null value with + * a {@code (ClassLoader, keys...)} tuple. The associated value, as well as the + * keys are strongly reachable from the associated ClassLoader so care should be + * taken to use such keys and values that only reference types resolvable from + * the associated ClassLoader. Failing that, ClassLoader leaks are inevitable. + *

    + * Example usage: + *

    {@code
    + * // create a root instance which represents a namespace and declares the type of
    + * // associated values (Class instances in this example)
    + * static final ClassLoaderValue> proxyClasses = new ClassLoaderValue<>();
    + *
    + * // create a compound key composed of a Module and a list of interfaces
    + * Module module = ...;
    + * List> interfaces = ...;
    + * ClassLoaderValue>.Sub.Sub>> key =
    + *     proxyClasses.sub(module).sub(interfaces);
    + *
    + * // use the compound key together with ClassLoader to lazily associate
    + * // the value with tuple (loader, module, interfaces) and return it
    + * ClassLoader loader = ...;
    + * Class proxyClass = key.computeIfAbsent(loader, (ld, ky) -> {
    + *     List> intfcs = ky.key();
    + *     Module m = ky.parent().key();
    + *     Class clazz = defineProxyClass(ld, m, intfcs);
    + *     return clazz;
    + * });
    + * }
    + *

    + * {@code classLoaderValue.(classLoader, ...)} represents an operation + * to {@link #get}, {@link #putIfAbsent}, {@link #computeIfAbsent} or {@link #remove} + * a value associated with a (classLoader, classLoaderValue) tuple. ClassLoader + * instances and root-{@link ClassLoaderValue} instances are compared using + * identity equality while {@link Sub sub}-ClassLoaderValue instances define + * {@link #equals(Object) equality} in terms of equality of its + * {@link Sub#parent() parent} ClassLoaderValue and its + * {@link #key() key} component. + * + * @param the type of value(s) associated with the root-ClassLoaderValue and + * all its {@link #sub(Object) descendants}. + * @author Peter Levart + * @since 9 + */ +final class ClassLoaderValue + extends AbstractClassLoaderValue, V> { + + /** + * Constructs new root-ClassLoaderValue representing its own namespace. + */ + public ClassLoaderValue() {} + + /** + * @return the key component of this root-ClassLoaderValue (itself). + */ + @Override + public ClassLoaderValue key() { + return this; + } + + /** + * root-ClassLoaderValue can only be equal to itself and has no predecessors. + */ + @Override + public boolean isEqualOrDescendantOf(AbstractClassLoaderValue clv) { + return equals(Objects.requireNonNull(clv)); + } +} diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java index 4f3bf3baa84..f1827ddbd0b 100644 --- a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java @@ -25,7 +25,6 @@ package java.lang.reflect; -import java.lang.ref.WeakReference; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Arrays; @@ -39,10 +38,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; -import java.util.WeakHashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; -import java.util.function.BiFunction; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -283,6 +280,13 @@ public class Proxy implements java.io.Serializable { private static final Class[] constructorParams = { InvocationHandler.class }; + /** + * a cache of proxy constructors with + * {@link Constructor#setAccessible(boolean) accessible} flag already set + */ + private static final ClassLoaderValue> proxyCache = + new ClassLoaderValue<>(); + /** * the invocation handler for this proxy instance. * @serial @@ -361,14 +365,55 @@ public class Proxy implements java.io.Serializable { Class... interfaces) throws IllegalArgumentException { - final List> intfs = List.of(interfaces); // interfaces cloned - final SecurityManager sm = System.getSecurityManager(); - final Class caller = Reflection.getCallerClass(); - if (sm != null) { - checkProxyAccess(caller, loader, intfs); - } + Class caller = System.getSecurityManager() == null + ? null + : Reflection.getCallerClass(); - return new ProxyBuilder(loader, intfs).build(); + return getProxyConstructor(caller, loader, interfaces) + .getDeclaringClass(); + } + + /** + * Returns the {@code Constructor} object of a proxy class that takes a + * single argument of type {@link InvocationHandler}, given a class loader + * and an array of interfaces. The returned constructor will have the + * {@link Constructor#setAccessible(boolean) accessible} flag already set. + * + * @param caller passed from a public-facing @CallerSensitive method if + * SecurityManager is set or {@code null} if there's no + * SecurityManager + * @param loader the class loader to define the proxy class + * @param interfaces the list of interfaces for the proxy class + * to implement + * @return a Constructor of the proxy class taking single + * {@code InvocationHandler} parameter + */ + private static Constructor getProxyConstructor(Class caller, + ClassLoader loader, + Class... interfaces) + { + // optimization for single interface + if (interfaces.length == 1) { + Class intf = interfaces[0]; + if (caller != null) { + checkProxyAccess(caller, loader, intf); + } + return proxyCache.sub(intf).computeIfAbsent( + loader, + (ld, clv) -> new ProxyBuilder(ld, clv.key()).build() + ); + } else { + // interfaces cloned + final Class[] intfsArray = interfaces.clone(); + if (caller != null) { + checkProxyAccess(caller, loader, intfsArray); + } + final List> intfs = Arrays.asList(intfsArray); + return proxyCache.sub(intfs).computeIfAbsent( + loader, + (ld, clv) -> new ProxyBuilder(ld, clv.key()).build() + ); + } } /* @@ -391,7 +436,7 @@ public class Proxy implements java.io.Serializable { */ private static void checkProxyAccess(Class caller, ClassLoader loader, - List> interfaces) + Class ... interfaces) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { @@ -399,147 +444,18 @@ public class Proxy implements java.io.Serializable { if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) { sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); } - ReflectUtil.checkProxyPackageAccess(ccl, interfaces.toArray(EMPTY_CLASS_ARRAY)); - } - } - - /* - * a key used for proxy class with 0 implemented interfaces - */ - private static final Object key0 = new Object(); - - /* - * Key1 and Key2 are optimized for the common use of dynamic proxies - * that implement 1 or 2 interfaces. - */ - - /* - * a key used for proxy class with 1 implemented interface - */ - private static final class Key1 extends WeakReference> { - private final int hash; - - Key1(Class intf) { - super(intf); - this.hash = intf.hashCode(); - } - - @Override - public int hashCode() { - return hash; - } - - @Override - public boolean equals(Object obj) { - Class intf; - return this == obj || - obj != null && - obj.getClass() == Key1.class && - (intf = get()) != null && - intf == ((Key1) obj).get(); - } - } - - /* - * a key used for proxy class with 2 implemented interfaces - */ - private static final class Key2 extends WeakReference> { - private final int hash; - private final WeakReference> ref2; - - Key2(Class intf1, Class intf2) { - super(intf1); - hash = 31 * intf1.hashCode() + intf2.hashCode(); - ref2 = new WeakReference<>(intf2); - } - - @Override - public int hashCode() { - return hash; - } - - @Override - public boolean equals(Object obj) { - Class intf1, intf2; - return this == obj || - obj != null && - obj.getClass() == Key2.class && - (intf1 = get()) != null && - intf1 == ((Key2) obj).get() && - (intf2 = ref2.get()) != null && - intf2 == ((Key2) obj).ref2.get(); - } - } - - /* - * a key used for proxy class with any number of implemented interfaces - * (used here for 3 or more only) - */ - private static final class KeyX { - private final int hash; - private final WeakReference>[] refs; - - @SuppressWarnings("unchecked") - KeyX(List> interfaces) { - hash = Arrays.hashCode(interfaces.toArray()); - refs = (WeakReference>[])new WeakReference[interfaces.size()]; - int i = 0; - for (Class intf : interfaces) { - refs[i++] = new WeakReference<>(intf); - } - } - - @Override - public int hashCode() { - return hash; - } - - @Override - public boolean equals(Object obj) { - return this == obj || - obj != null && - obj.getClass() == KeyX.class && - equals(refs, ((KeyX) obj).refs); - } - - private static boolean equals(WeakReference>[] refs1, - WeakReference>[] refs2) { - if (refs1.length != refs2.length) { - return false; - } - for (int i = 0; i < refs1.length; i++) { - Class intf = refs1[i].get(); - if (intf == null || intf != refs2[i].get()) { - return false; - } - } - return true; + ReflectUtil.checkProxyPackageAccess(ccl, interfaces); } } /** - * A function that maps an array of interfaces to an optimal key where - * Class objects representing interfaces are weakly referenced. + * Builder for a proxy class. + * + * If the module is not specified in this ProxyBuilder constructor, + * it will map from the given loader and interfaces to the module + * in which the proxy class will be defined. */ - private static final class KeyFactory - implements BiFunction>, Object> - { - @Override - public Object apply(T t, List> interfaces) { - switch (interfaces.size()) { - case 1: return new Key1(interfaces.get(0)); // the most frequent - case 2: return new Key2(interfaces.get(0), interfaces.get(1)); - case 0: return key0; - default: return new KeyX(interfaces); - } - } - } - - /** - * A factory function that generates, defines and returns the proxy class - * given the ClassLoader and array of interfaces. - */ - private static final class ProxyClassFactory { + private static final class ProxyBuilder { private static final Unsafe UNSAFE = Unsafe.getUnsafe(); // prefix for all proxy class names @@ -548,6 +464,10 @@ public class Proxy implements java.io.Serializable { // next number to use for generation of unique proxy class names private static final AtomicLong nextUniqueNumber = new AtomicLong(); + // a reverse cache of defined proxy classes + private static final ClassLoaderValue reverseProxyCache = + new ClassLoaderValue<>(); + private static Class defineProxyClass(Module m, List> interfaces) { String proxyPkg = null; // package to define proxy class in int accessFlags = Modifier.PUBLIC | Modifier.FINAL; @@ -601,8 +521,11 @@ public class Proxy implements java.io.Serializable { byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces.toArray(EMPTY_CLASS_ARRAY), accessFlags); try { - return UNSAFE.defineClass(proxyName, proxyClassFile, 0, proxyClassFile.length, - loader, null); + Class pc = UNSAFE.defineClass(proxyName, proxyClassFile, + 0, proxyClassFile.length, + loader, null); + reverseProxyCache.sub(pc).putIfAbsent(loader, Boolean.TRUE); + return pc; } catch (ClassFormatError e) { /* * A ClassFormatError here means that (barring bugs in the @@ -616,35 +539,14 @@ public class Proxy implements java.io.Serializable { } /** - * Test if the given class is a proxy class + * Test if given class is a class defined by + * {@link #defineProxyClass(Module, List)} */ static boolean isProxyClass(Class c) { - return proxyCache.containsValue(c); + return Objects.equals(reverseProxyCache.sub(c).get(c.getClassLoader()), + Boolean.TRUE); } - /** - * Returns the proxy class. It will return the cached proxy class - * if exists; otherwise, it will create the proxy class and store in - * the cache. - */ - static Class get(Module module, List> interfaces) { - return proxyCache.get(module, interfaces); - } - - /** - * a cache of proxy classes in the named and unnamed module - */ - private static final WeakCache>, Class> proxyCache = - new WeakCache<>(new KeyFactory(), - new BiFunction>, Class>() { - @Override - public Class apply(Module m, List> interfaces) { - Objects.requireNonNull(m); - return defineProxyClass(m, interfaces); - } - }); - - private static boolean isExportedType(Class c) { String pn = c.getPackageName(); return Modifier.isPublic(c.getModifiers()) && c.getModule().isExported(pn); @@ -685,25 +587,18 @@ public class Proxy implements java.io.Serializable { } }); - private static final boolean isDebug() { + private static boolean isDebug() { return !DEBUG.isEmpty(); } - private static final boolean isDebug(String flag) { + private static boolean isDebug(String flag) { return DEBUG.equals(flag); } - } - /** - * Builder for a proxy class. - * - * If the module is not specified in this ProxyBuilder constructor, - * it will map from the given loader and interfaces to the module - * in which the proxy class will be defined. - */ - private static final class ProxyBuilder { - final ClassLoader loader; - final List> interfaces; - final Module module; + // ProxyBuilder instance members start here.... + + private final ClassLoader loader; + private final List> interfaces; + private final Module module; ProxyBuilder(ClassLoader loader, List> interfaces) { if (!VM.isModuleSystemInited()) { throw new InternalError("Proxy is not supported until module system is fully initialzed"); @@ -723,16 +618,34 @@ public class Proxy implements java.io.Serializable { assert getLoader(module) == loader; } + ProxyBuilder(ClassLoader loader, Class intf) { + this(loader, Collections.singletonList(intf)); + } + /** - * Generate a proxy class. If the target module does not have any + * Generate a proxy class and return its proxy Constructor with + * accessible flag already set. If the target module does not have access * to any interface types, IllegalAccessError will be thrown by the VM * at defineClass time. * * Must call the checkProxyAccess method to perform permission checks * before calling this. */ - Class build() { - return ProxyClassFactory.get(module, interfaces); + Constructor build() { + Class proxyClass = defineProxyClass(module, interfaces); + final Constructor cons; + try { + cons = proxyClass.getConstructor(constructorParams); + } catch (NoSuchMethodException e) { + throw new InternalError(e.toString(), e); + } + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + cons.setAccessible(true); + return null; + } + }); + return cons; } /** @@ -742,9 +655,9 @@ public class Proxy implements java.io.Serializable { * @throws IllegalArgumentException if it violates the restrictions specified * in {@link Proxy#newProxyInstance} */ - static void validateProxyInterfaces(ClassLoader loader, - List> interfaces, - Set> refTypes) + private static void validateProxyInterfaces(ClassLoader loader, + List> interfaces, + Set> refTypes) { Map, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.size()); for (Class intf : interfaces) { @@ -779,10 +692,11 @@ public class Proxy implements java.io.Serializable { * Returns all types referenced by all public method signatures of * the proxy interfaces */ - static Set> referencedTypes(ClassLoader loader, List> interfaces) { + private static Set> referencedTypes(ClassLoader loader, + List> interfaces) { return interfaces.stream() .flatMap(intf -> Stream.of(intf.getMethods()) - .flatMap(m -> methodRefTypes(m)) + .flatMap(ProxyBuilder::methodRefTypes) .map(ProxyBuilder::getElementType) .filter(t -> !t.isPrimitive())) .collect(Collectors.toSet()); @@ -792,11 +706,11 @@ public class Proxy implements java.io.Serializable { * Extracts all types referenced on a method signature including * its return type, parameter types, and exception types. */ - static Stream> methodRefTypes(Method m) { + private static Stream> methodRefTypes(Method m) { return Stream.of(new Class[] { m.getReturnType() }, m.getParameterTypes(), m.getExceptionTypes()) - .flatMap(a -> Stream.of(a)); + .flatMap(Stream::of); } /** @@ -813,7 +727,9 @@ public class Proxy implements java.io.Serializable { * package. Reads edge and qualified exports are added for * dynamic module to access. */ - static Module mapToModule(ClassLoader loader, List> interfaces, Set> refTypes) { + private static Module mapToModule(ClassLoader loader, + List> interfaces, + Set> refTypes) { Map, Module> modulePrivateTypes = new HashMap<>(); Map, Module> packagePrivateTypes = new HashMap<>(); for (Class intf : interfaces) { @@ -884,10 +800,9 @@ public class Proxy implements java.io.Serializable { Set> visited = new HashSet<>(); while (!deque.isEmpty()) { Class c = deque.poll(); - if (visited.contains(c)) { + if (!visited.add(c)) { continue; } - visited.add(c); ensureAccess(target, c); // add all superinterfaces @@ -906,7 +821,7 @@ public class Proxy implements java.io.Serializable { /* * Ensure the given module can access the given class. */ - static void ensureAccess(Module target, Class c) { + private static void ensureAccess(Module target, Class c) { Module m = c.getModule(); // add read edge and qualified export for the target module to access if (!target.canRead(m)) { @@ -921,7 +836,7 @@ public class Proxy implements java.io.Serializable { /* * Ensure the given class is visible to the class loader. */ - static void ensureVisible(ClassLoader ld, Class c) { + private static void ensureVisible(ClassLoader ld, Class c) { Class type = null; try { type = Class.forName(c.getName(), false, ld); @@ -933,7 +848,7 @@ public class Proxy implements java.io.Serializable { } } - static Class getElementType(Class type) { + private static Class getElementType(Class type) { Class e = type; while (e.isArray()) { e = e.getComponentType(); @@ -941,7 +856,8 @@ public class Proxy implements java.io.Serializable { return e; } - private static final WeakHashMap dynProxyModules = new WeakHashMap<>(); + private static final ClassLoaderValue dynProxyModules = + new ClassLoaderValue<>(); private static final AtomicInteger counter = new AtomicInteger(); /* @@ -950,12 +866,12 @@ public class Proxy implements java.io.Serializable { * * Each class loader will have one dynamic module. */ - static Module getDynamicModule(ClassLoader loader) { - return dynProxyModules.computeIfAbsent(loader, ld -> { + private static Module getDynamicModule(ClassLoader loader) { + return dynProxyModules.computeIfAbsent(loader, (ld, clv) -> { // create a dynamic module and setup module access String mn = "jdk.proxy" + counter.incrementAndGet(); String pn = PROXY_PACKAGE_PREFIX + "." + mn; - Module m = Modules.defineModule(loader, mn, Collections.singleton(pn)); + Module m = Modules.defineModule(ld, mn, Collections.singleton(pn)); Modules.addReads(m, Proxy.class.getModule()); // java.base to create proxy instance Modules.addExports(m, pn, Object.class.getModule()); @@ -1062,40 +978,31 @@ public class Proxy implements java.io.Serializable { InvocationHandler h) { Objects.requireNonNull(h); - final List> intfs = List.of(interfaces); // interfaces cloned - final SecurityManager sm = System.getSecurityManager(); - final Class caller = Reflection.getCallerClass(); - if (sm != null) { - checkProxyAccess(caller, loader, intfs); - } + final Class caller = System.getSecurityManager() == null + ? null + : Reflection.getCallerClass(); /* - * Look up or generate the designated proxy class. + * Look up or generate the designated proxy class and its constructor. */ - Class cl = new ProxyBuilder(loader, intfs).build(); + Constructor cons = getProxyConstructor(caller, loader, interfaces); - return newProxyInstance(cl, caller, h); + return newProxyInstance(caller, cons, h); } - private static Object newProxyInstance(Class proxyClass, Class caller, InvocationHandler h) { + private static Object newProxyInstance(Class caller, // null if no SecurityManager + Constructor cons, + InvocationHandler h) { /* * Invoke its constructor with the designated invocation handler. */ try { - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - checkNewProxyPermission(caller, proxyClass); + if (caller != null) { + checkNewProxyPermission(caller, cons.getDeclaringClass()); } - final Constructor cons = proxyClass.getConstructor(constructorParams); - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - cons.setAccessible(true); - return null; - } - }); return cons.newInstance(new Object[]{h}); - } catch (IllegalAccessException | InstantiationException | NoSuchMethodException e) { + } catch (IllegalAccessException | InstantiationException e) { throw new InternalError(e.toString(), e); } catch (InvocationTargetException e) { Throwable t = e.getCause(); @@ -1150,7 +1057,7 @@ public class Proxy implements java.io.Serializable { * @throws NullPointerException if {@code cl} is {@code null} */ public static boolean isProxyClass(Class cl) { - return Proxy.class.isAssignableFrom(cl) && ProxyClassFactory.isProxyClass(cl); + return Proxy.class.isAssignableFrom(cl) && ProxyBuilder.isProxyClass(cl); } /** diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/WeakCache.java b/jdk/src/java.base/share/classes/java/lang/reflect/WeakCache.java deleted file mode 100644 index e9103b60208..00000000000 --- a/jdk/src/java.base/share/classes/java/lang/reflect/WeakCache.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.lang.reflect; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.function.BiFunction; -import java.util.function.Supplier; - -/** - * Cache mapping pairs of {@code (key, sub-key) -> value}. Keys and values are - * weakly but sub-keys are strongly referenced. Keys are passed directly to - * {@link #get} method which also takes a {@code parameter}. Sub-keys are - * calculated from keys and parameters using the {@code subKeyFactory} function - * passed to the constructor. Values are calculated from keys and parameters - * using the {@code valueFactory} function passed to the constructor. - * Keys can be {@code null} and are compared by identity while sub-keys returned by - * {@code subKeyFactory} or values returned by {@code valueFactory} - * can not be null. Sub-keys are compared using their {@link #equals} method. - * Entries are expunged from cache lazily on each invocation to {@link #get}, - * {@link #containsValue} or {@link #size} methods when the WeakReferences to - * keys are cleared. Cleared WeakReferences to individual values don't cause - * expunging, but such entries are logically treated as non-existent and - * trigger re-evaluation of {@code valueFactory} on request for their - * key/subKey. - * - * @author Peter Levart - * @param type of keys - * @param

    type of parameters - * @param type of values - */ -final class WeakCache { - - private final ReferenceQueue refQueue - = new ReferenceQueue<>(); - // the key type is Object for supporting null key - private final ConcurrentMap>> map - = new ConcurrentHashMap<>(); - private final ConcurrentMap, Boolean> reverseMap - = new ConcurrentHashMap<>(); - private final BiFunction subKeyFactory; - private final BiFunction valueFactory; - - /** - * Construct an instance of {@code WeakCache} - * - * @param subKeyFactory a function mapping a pair of - * {@code (key, parameter) -> sub-key} - * @param valueFactory a function mapping a pair of - * {@code (key, parameter) -> value} - * @throws NullPointerException if {@code subKeyFactory} or - * {@code valueFactory} is null. - */ - public WeakCache(BiFunction subKeyFactory, - BiFunction valueFactory) { - this.subKeyFactory = Objects.requireNonNull(subKeyFactory); - this.valueFactory = Objects.requireNonNull(valueFactory); - } - - /** - * Look-up the value through the cache. This always evaluates the - * {@code subKeyFactory} function and optionally evaluates - * {@code valueFactory} function if there is no entry in the cache for given - * pair of (key, subKey) or the entry has already been cleared. - * - * @param key possibly null key - * @param parameter parameter used together with key to create sub-key and - * value (should not be null) - * @return the cached value (never null) - * @throws NullPointerException if {@code parameter} passed in or - * {@code sub-key} calculated by - * {@code subKeyFactory} or {@code value} - * calculated by {@code valueFactory} is null. - */ - public V get(K key, P parameter) { - Objects.requireNonNull(parameter); - - expungeStaleEntries(); - - Object cacheKey = CacheKey.valueOf(key, refQueue); - - // lazily install the 2nd level valuesMap for the particular cacheKey - ConcurrentMap> valuesMap = map.get(cacheKey); - if (valuesMap == null) { - ConcurrentMap> oldValuesMap - = map.putIfAbsent(cacheKey, - valuesMap = new ConcurrentHashMap<>()); - if (oldValuesMap != null) { - valuesMap = oldValuesMap; - } - } - - // create subKey and retrieve the possible Supplier stored by that - // subKey from valuesMap - Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter)); - Supplier supplier = valuesMap.get(subKey); - Factory factory = null; - - while (true) { - if (supplier != null) { - // supplier might be a Factory or a CacheValue instance - V value = supplier.get(); - if (value != null) { - return value; - } - } - // else no supplier in cache - // or a supplier that returned null (could be a cleared CacheValue - // or a Factory that wasn't successful in installing the CacheValue) - - // lazily construct a Factory - if (factory == null) { - factory = new Factory(key, parameter, subKey, valuesMap); - } - - if (supplier == null) { - supplier = valuesMap.putIfAbsent(subKey, factory); - if (supplier == null) { - // successfully installed Factory - supplier = factory; - } - // else retry with winning supplier - } else { - if (valuesMap.replace(subKey, supplier, factory)) { - // successfully replaced - // cleared CacheEntry / unsuccessful Factory - // with our Factory - supplier = factory; - } else { - // retry with current supplier - supplier = valuesMap.get(subKey); - } - } - } - } - - /** - * Checks whether the specified non-null value is already present in this - * {@code WeakCache}. The check is made using identity comparison regardless - * of whether value's class overrides {@link Object#equals} or not. - * - * @param value the non-null value to check - * @return true if given {@code value} is already cached - * @throws NullPointerException if value is null - */ - public boolean containsValue(V value) { - Objects.requireNonNull(value); - - expungeStaleEntries(); - return reverseMap.containsKey(new LookupValue<>(value)); - } - - /** - * Returns the current number of cached entries that - * can decrease over time when keys/values are GC-ed. - */ - public int size() { - expungeStaleEntries(); - return reverseMap.size(); - } - - @SuppressWarnings("unchecked") // refQueue.poll actually returns CacheKey - private void expungeStaleEntries() { - CacheKey cacheKey; - while ((cacheKey = (CacheKey)refQueue.poll()) != null) { - cacheKey.expungeFrom(map, reverseMap); - } - } - - /** - * A factory {@link Supplier} that implements the lazy synchronized - * construction of the value and installment of it into the cache. - */ - private final class Factory implements Supplier { - - private final K key; - private final P parameter; - private final Object subKey; - private final ConcurrentMap> valuesMap; - - Factory(K key, P parameter, Object subKey, - ConcurrentMap> valuesMap) { - this.key = key; - this.parameter = parameter; - this.subKey = subKey; - this.valuesMap = valuesMap; - } - - @Override - public synchronized V get() { // serialize access - // re-check - Supplier supplier = valuesMap.get(subKey); - if (supplier != this) { - // something changed while we were waiting: - // might be that we were replaced by a CacheValue - // or were removed because of failure -> - // return null to signal WeakCache.get() to retry - // the loop - return null; - } - // else still us (supplier == this) - - // create new value - V value = null; - try { - value = Objects.requireNonNull(valueFactory.apply(key, parameter)); - } finally { - if (value == null) { // remove us on failure - valuesMap.remove(subKey, this); - } - } - // the only path to reach here is with non-null value - assert value != null; - - // wrap value with CacheValue (WeakReference) - CacheValue cacheValue = new CacheValue<>(value); - - // try replacing us with CacheValue (this should always succeed) - if (valuesMap.replace(subKey, this, cacheValue)) { - // put also in reverseMap - reverseMap.put(cacheValue, Boolean.TRUE); - } else { - throw new AssertionError("Should not reach here"); - } - - // successfully replaced us with new CacheValue -> return the value - // wrapped by it - return value; - } - } - - /** - * Common type of value suppliers that are holding a referent. - * The {@link #equals} and {@link #hashCode} of implementations is defined - * to compare the referent by identity. - */ - private interface Value extends Supplier {} - - /** - * An optimized {@link Value} used to look-up the value in - * {@link WeakCache#containsValue} method so that we are not - * constructing the whole {@link CacheValue} just to look-up the referent. - */ - private static final class LookupValue implements Value { - private final V value; - - LookupValue(V value) { - this.value = value; - } - - @Override - public V get() { - return value; - } - - @Override - public int hashCode() { - return System.identityHashCode(value); // compare by identity - } - - @Override - public boolean equals(Object obj) { - return obj == this || - obj instanceof Value && - this.value == ((Value) obj).get(); // compare by identity - } - } - - /** - * A {@link Value} that weakly references the referent. - */ - private static final class CacheValue - extends WeakReference implements Value - { - private final int hash; - - CacheValue(V value) { - super(value); - this.hash = System.identityHashCode(value); // compare by identity - } - - @Override - public int hashCode() { - return hash; - } - - @Override - public boolean equals(Object obj) { - V value; - return obj == this || - obj instanceof Value && - // cleared CacheValue is only equal to itself - (value = get()) != null && - value == ((Value) obj).get(); // compare by identity - } - } - - /** - * CacheKey containing a weakly referenced {@code key}. It registers - * itself with the {@code refQueue} so that it can be used to expunge - * the entry when the {@link WeakReference} is cleared. - */ - private static final class CacheKey extends WeakReference { - - // a replacement for null keys - private static final Object NULL_KEY = new Object(); - - static Object valueOf(K key, ReferenceQueue refQueue) { - return key == null - // null key means we can't weakly reference it, - // so we use a NULL_KEY singleton as cache key - ? NULL_KEY - // non-null key requires wrapping with a WeakReference - : new CacheKey<>(key, refQueue); - } - - private final int hash; - - private CacheKey(K key, ReferenceQueue refQueue) { - super(key, refQueue); - this.hash = System.identityHashCode(key); // compare by identity - } - - @Override - public int hashCode() { - return hash; - } - - @Override - @SuppressWarnings("unchecked") - public boolean equals(Object obj) { - K key; - return obj == this || - obj != null && - obj.getClass() == this.getClass() && - // cleared CacheKey is only equal to itself - (key = this.get()) != null && - // compare key by identity - key == ((CacheKey) obj).get(); // Cast is safe from getClass check - } - - void expungeFrom(ConcurrentMap> map, - ConcurrentMap reverseMap) { - // removing just by key is always safe here because after a CacheKey - // is cleared and enqueue-ed it is only equal to itself - // (see equals method)... - ConcurrentMap valuesMap = map.remove(this); - // remove also from reverseMap if needed - if (valuesMap != null) { - for (Object cacheValue : valuesMap.values()) { - reverseMap.remove(cacheValue); - } - } - } - } -} diff --git a/jdk/src/java.base/share/classes/java/net/InetAddress.java b/jdk/src/java.base/share/classes/java/net/InetAddress.java index 0878c57848b..d385aac06e5 100644 --- a/jdk/src/java.base/share/classes/java/net/InetAddress.java +++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -30,8 +30,10 @@ import java.util.Iterator; import java.util.List; import java.util.ArrayList; import java.util.Objects; -import java.util.ServiceLoader; +import java.util.Scanner; import java.security.AccessController; +import java.io.File; +import java.io.FileNotFoundException; import java.io.ObjectStreamException; import java.io.ObjectStreamField; import java.io.IOException; @@ -49,7 +51,6 @@ import jdk.internal.misc.SharedSecrets; import sun.security.action.*; import sun.net.InetAddressCachePolicy; import sun.net.util.IPAddressUtil; -import sun.net.spi.nameservice.*; /** * This class represents an Internet Protocol (IP) address. @@ -207,6 +208,7 @@ class InetAddress implements java.io.Serializable { /* Specify address family preference */ static transient boolean preferIPv6Address = false; + static class InetAddressHolder { /** * Reserve the original application specified hostname. @@ -279,7 +281,7 @@ class InetAddress implements java.io.Serializable { } /* Used to store the name service provider */ - private static List nameServices = null; + private static transient NameService nameService = null; /* Used to store the best available hostname */ private transient String canonicalHostName = null; @@ -623,7 +625,6 @@ class InetAddress implements java.io.Serializable { */ private static String getHostFromNameService(InetAddress addr, boolean check) { String host = null; - for (NameService nameService : nameServices) { try { // first lookup the hostname host = nameService.getHostByAddr(addr.getAddress()); @@ -657,18 +658,12 @@ class InetAddress implements java.io.Serializable { host = addr.getHostAddress(); return host; } - - break; - } catch (SecurityException e) { host = addr.getHostAddress(); - break; } catch (UnknownHostException e) { host = addr.getHostAddress(); // let next provider resolve the hostname } - } - return host; } @@ -860,88 +855,287 @@ class InetAddress implements java.io.Serializable { } } - static InetAddressImpl impl; + /** + * NameService provides host and address lookup service + * + * @since 9 + */ + private interface NameService { - private static NameService createNSProvider(String provider) { - if (provider == null) - return null; + /** + * Lookup a host mapping by name. Retrieve the IP addresses + * associated with a host + * + * @param host the specified hostname + * @return array of IP addresses for the requested host + * @throws UnknownHostException + * if no IP address for the {@code host} could be found + */ + InetAddress[] lookupAllHostAddr(String host) + throws UnknownHostException; + + /** + * Lookup the host corresponding to the IP address provided + * + * @param addr byte array representing an IP address + * @return {@code String} representing the host name mapping + * @throws UnknownHostException + * if no host found for the specified IP address + */ + String getHostByAddr(byte[] addr) throws UnknownHostException; + + } + + /** + * The default NameService implementation, which delegates to the underlying + * OS network libraries to resolve host address mappings. + * + * @since 9 + */ + private static final class PlatformNameService implements NameService { - NameService nameService = null; - if (provider.equals("default")) { - // initialize the default name service - nameService = new NameService() { public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException { + return impl.lookupAllHostAddr(host); - } - public String getHostByAddr(byte[] addr) - throws UnknownHostException { - return impl.getHostByAddr(addr); - } - }; - } else { - final String providerName = provider; - try { - nameService = java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction<>() { - public NameService run() { - Iterator itr = - ServiceLoader.load(NameServiceDescriptor.class) - .iterator(); - while (itr.hasNext()) { - NameServiceDescriptor nsd = itr.next(); - if (providerName. - equalsIgnoreCase(nsd.getType()+"," - +nsd.getProviderName())) { - try { - return nsd.createNameService(); - } catch (Exception e) { - e.printStackTrace(); - System.err.println( - "Cannot create name service:" - +providerName+": " + e); - } - } + } - return null; - } - } - ); - } catch (java.security.PrivilegedActionException e) { - } + public String getHostByAddr(byte[] addr) throws UnknownHostException { + + return impl.getHostByAddr(addr); + } - return nameService; } + /** + * The HostsFileNameService provides host address mapping + * by reading the entries in a hosts file, which is specified by + * {@code jdk.net.hosts.file} system property + * + *

    The file format is that which corresponds with the /etc/hosts file + * IP Address host alias list. + * + *

    When the file lookup is enabled it replaces the default NameService + * implementation + * + * @since 9 + */ + private static final class HostsFileNameService implements NameService { + + private final String hostsFile; + + public HostsFileNameService (String hostsFileName) { + this.hostsFile = hostsFileName; + } + + private String addrToString(byte addr[]) { + String stringifiedAddress = null; + + if (addr.length == Inet4Address.INADDRSZ) { + stringifiedAddress = Inet4Address.numericToTextFormat(addr); + } else { // treat as an IPV6 jobby + byte[] newAddr + = IPAddressUtil.convertFromIPv4MappedAddress(addr); + if (newAddr != null) { + stringifiedAddress = Inet4Address.numericToTextFormat(addr); + } else { + stringifiedAddress = Inet6Address.numericToTextFormat(addr); + } + } + return stringifiedAddress; + } + + /** + * Lookup the host name corresponding to the IP address provided. + * Search the configured host file a host name corresponding to + * the specified IP address. + * + * @param addr byte array representing an IP address + * @return {@code String} representing the host name mapping + * @throws UnknownHostException + * if no host found for the specified IP address + */ + @Override + public String getHostByAddr(byte[] addr) throws UnknownHostException { + String hostEntry; + String host = null; + + String addrString = addrToString(addr); + try (Scanner hostsFileScanner = new Scanner(new File(hostsFile), "UTF-8")) { + while (hostsFileScanner.hasNextLine()) { + hostEntry = hostsFileScanner.nextLine(); + if (!hostEntry.startsWith("#")) { + hostEntry = removeComments(hostEntry); + if (hostEntry.contains(addrString)) { + host = extractHost(hostEntry, addrString); + if (host != null) { + break; + } + } + } + } + } catch (FileNotFoundException e) { + throw new UnknownHostException("Unable to resolve address " + + addrString + " as hosts file " + hostsFile + + " not found "); + } + + if ((host == null) || (host.equals("")) || (host.equals(" "))) { + throw new UnknownHostException("Requested address " + + addrString + + " resolves to an invalid entry in hosts file " + + hostsFile); + } + return host; + } + + + /** + *

    Lookup a host mapping by name. Retrieve the IP addresses + * associated with a host. + * + *

    Search the configured hosts file for the addresses assocaited with + * with the specified host name. + * + * @param host the specified hostname + * @return array of IP addresses for the requested host + * @throws UnknownHostException + * if no IP address for the {@code host} could be found + */ + + public InetAddress[] lookupAllHostAddr(String host) + throws UnknownHostException { + String hostEntry; + String addrStr = null; + InetAddress[] res = null; + byte addr[] = new byte[4]; + ArrayList inetAddresses = null; + + // lookup the file and create a list InetAddress for the specfied host + try (Scanner hostsFileScanner = new Scanner(new File(hostsFile), "UTF-8")) { + while (hostsFileScanner.hasNextLine()) { + hostEntry = hostsFileScanner.nextLine(); + if (!hostEntry.startsWith("#")) { + hostEntry = removeComments(hostEntry); + if (hostEntry.contains(host)) { + addrStr = extractHostAddr(hostEntry, host); + if ((addrStr != null) && (!addrStr.equals(""))) { + addr = createAddressByteArray(addrStr); + if (inetAddresses == null) { + inetAddresses = new ArrayList<>(1); + } + if (addr != null) { + inetAddresses.add(InetAddress.getByAddress(host, addr)); + } + } + } + } + } + } catch (FileNotFoundException e) { + throw new UnknownHostException("Unable to resolve host " + host + + " as hosts file " + hostsFile + " not found "); + } + + if (inetAddresses != null) { + res = inetAddresses.toArray(new InetAddress[inetAddresses.size()]); + } else { + throw new UnknownHostException("Unable to resolve host " + host + + " in hosts file " + hostsFile); + } + return res; + } + + private String removeComments(String hostsEntry) { + String filteredEntry = hostsEntry; + int hashIndex; + + if ((hashIndex = hostsEntry.indexOf("#")) != -1) { + filteredEntry = hostsEntry.substring(0, hashIndex); + } + return filteredEntry; + } + + private byte [] createAddressByteArray(String addrStr) { + byte[] addrArray; + // check if IPV4 address - most likely + addrArray = IPAddressUtil.textToNumericFormatV4(addrStr); + if (addrArray == null) { + addrArray = IPAddressUtil.textToNumericFormatV6(addrStr); + } + return addrArray; + } + + /** host to ip address mapping */ + private String extractHostAddr(String hostEntry, String host) { + String[] mapping = hostEntry.split("\\s+"); + String hostAddr = null; + + if (mapping.length >= 2) { + // look at the host aliases + for (int i = 1; i < mapping.length; i++) { + if (mapping[i].equalsIgnoreCase(host)) { + hostAddr = mapping[0]; + } + } + } + return hostAddr; + } + + /** + * IP Address to host mapping + * use first host alias in list + */ + private String extractHost(String hostEntry, String addrString) { + String[] mapping = hostEntry.split("\\s+"); + String host = null; + + if (mapping.length >= 2) { + if (mapping[0].equalsIgnoreCase(addrString)) { + host = mapping[1]; + } + } + return host; + } + } + + static final InetAddressImpl impl; + static { // create the impl impl = InetAddressImplFactory.create(); - // get name service if provided and requested - String provider = null;; - String propPrefix = "sun.net.spi.nameservice.provider."; - int n = 1; - nameServices = new ArrayList<>(); - provider = AccessController.doPrivileged( - new GetPropertyAction(propPrefix + n)); - while (provider != null) { - NameService ns = createNSProvider(provider); - if (ns != null) - nameServices.add(ns); - - n++; - provider = AccessController.doPrivileged( - new GetPropertyAction(propPrefix + n)); + // create name service + nameService = createNameService(); } - // if not designate any name services provider, - // create a default one - if (nameServices.size() == 0) { - NameService ns = createNSProvider("default"); - nameServices.add(ns); + /** + * Create an instance of the NameService interface based on + * the setting of the {@codejdk.net.hosts.file} system property. + * + *

    The default NameService is the PlatformNameService, which typically + * delegates name and address resolution calls to the underlying + * OS network libraries. + * + *

    A HostsFileNameService is created if the {@code jdk.net.hosts.file} + * system property is set. If the specified file doesn't exist, the name or + * address lookup will result in an UnknownHostException. Thus, non existent + * hosts file is handled as if the file is empty. + * + * @return a NameService + */ + private static NameService createNameService() { + + String hostsFileName = AccessController + .doPrivileged(new GetPropertyAction("jdk.net.hosts.file")); + NameService theNameService; + if (hostsFileName != null) { + theNameService = new HostsFileNameService(hostsFileName); + } else { + theNameService = new PlatformNameService(); } + return theNameService; } /** @@ -1286,20 +1480,16 @@ class InetAddress implements java.io.Serializable { InetAddress[] addresses = null; UnknownHostException ex = null; - for (NameService nameService : nameServices) { try { addresses = nameService.lookupAllHostAddr(host); - break; } catch (UnknownHostException uhe) { if (host.equalsIgnoreCase("localhost")) { addresses = new InetAddress[] { impl.loopbackAddress() }; - break; } else { ex = uhe; } } - } if (addresses == null) { throw ex == null ? new UnknownHostException(host) : ex; diff --git a/jdk/src/java.base/share/classes/java/nio/Buffer.java b/jdk/src/java.base/share/classes/java/nio/Buffer.java index 51436dc2f1b..d534fb3ae73 100644 --- a/jdk/src/java.base/share/classes/java/nio/Buffer.java +++ b/jdk/src/java.base/share/classes/java/nio/Buffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -25,9 +25,10 @@ package java.nio; -import java.util.Spliterator; import jdk.internal.HotSpotIntrinsicCandidate; +import java.util.Spliterator; + /** * A container for data of a specific primitive type. * @@ -188,7 +189,15 @@ public abstract class Buffer { private int limit; private int capacity; - // Used only by direct buffers + // Used by heap byte buffers or direct buffers with Unsafe access + // For heap byte buffers this field will be the address relative to the + // array base address and offset into that array. The address might + // not align on a word boundary for slices, nor align at a long word + // (8 byte) boundary for byte[] allocations on 32-bit systems. + // For direct buffers it is the start address of the memory region. The + // address might not align on a word boundary for slices, nor when created + // using JNI, see NewDirectByteBuffer(void*, long). + // Should ideally be declared final // NOTE: hoisted here for speed in JNI GetDirectBufferAddress long address; diff --git a/jdk/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template b/jdk/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template index 40a39eb0ed9..68ec8340e0d 100644 --- a/jdk/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template +++ b/jdk/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template @@ -140,6 +140,7 @@ class Direct$Type$Buffer$RW$$BO$ att = null; #else[rw] super(cap); + this.isReadOnly = true; #end[rw] } @@ -180,6 +181,7 @@ class Direct$Type$Buffer$RW$$BO$ att = null; #else[rw] super(cap, addr, fd, unmapper); + this.isReadOnly = true; #end[rw] } @@ -200,6 +202,7 @@ class Direct$Type$Buffer$RW$$BO$ att = db; #else[rw] super(db, mark, pos, lim, cap, off); + this.isReadOnly = true; #end[rw] } @@ -213,6 +216,15 @@ class Direct$Type$Buffer$RW$$BO$ return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, off); } +#if[byte] + public $Type$Buffer slice(int pos, int lim) { + assert (pos >= 0); + assert (pos <= lim); + int rem = lim - pos; + return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, pos); + } +#end[byte] + public $Type$Buffer duplicate() { return new Direct$Type$Buffer$RW$$BO$(this, this.markValue(), diff --git a/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template b/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template index 9ca784b8a77..65f6cb31b27 100644 --- a/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template +++ b/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -74,6 +74,9 @@ class Heap$Type$Buffer$RW$ super(cap, lim); this.isReadOnly = true; #end[rw] +#if[byte] + this.address = arrayBaseOffset; +#end[byte] } Heap$Type$Buffer$RW$($type$[] buf, int off, int len) { // package-private @@ -87,6 +90,9 @@ class Heap$Type$Buffer$RW$ super(buf, off, len); this.isReadOnly = true; #end[rw] +#if[byte] + this.address = arrayBaseOffset; +#end[byte] } protected Heap$Type$Buffer$RW$($type$[] buf, @@ -103,6 +109,9 @@ class Heap$Type$Buffer$RW$ super(buf, mark, pos, lim, cap, off); this.isReadOnly = true; #end[rw] +#if[byte] + this.address = arrayBaseOffset + off; +#end[byte] } public $Type$Buffer slice() { @@ -114,6 +123,20 @@ class Heap$Type$Buffer$RW$ this.position() + offset); } +#if[byte] + $Type$Buffer slice(int pos, int lim) { + assert (pos >= 0); + assert (pos <= lim); + int rem = lim - pos; + return new Heap$Type$Buffer$RW$(hb, + -1, + 0, + rem, + rem, + pos + offset); + } +#end[byte] + public $Type$Buffer duplicate() { return new Heap$Type$Buffer$RW$(hb, this.markValue(), @@ -144,7 +167,7 @@ class Heap$Type$Buffer$RW$ #if[byte] private long byteOffset(long i) { - return arrayBaseOffset + i + offset; + return address + i; } #end[byte] diff --git a/jdk/src/java.base/share/classes/java/nio/StringCharBuffer.java b/jdk/src/java.base/share/classes/java/nio/StringCharBuffer.java index 4a5f0517691..71f4b368d29 100644 --- a/jdk/src/java.base/share/classes/java/nio/StringCharBuffer.java +++ b/jdk/src/java.base/share/classes/java/nio/StringCharBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -39,6 +39,7 @@ class StringCharBuffer // package-private if ((start < 0) || (start > n) || (end < start) || (end > n)) throw new IndexOutOfBoundsException(); str = s; + this.isReadOnly = true; } public CharBuffer slice() { @@ -58,6 +59,7 @@ class StringCharBuffer // package-private int offset) { super(mark, pos, limit, cap, null, offset); str = s; + this.isReadOnly = true; } public CharBuffer duplicate() { diff --git a/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template b/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template index 72efc279778..104f504b551 100644 --- a/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template +++ b/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -269,7 +269,7 @@ public abstract class $Type$Buffer // final $type$[] hb; // Non-null only for heap buffers final int offset; - boolean isReadOnly; // Valid only for heap buffers + boolean isReadOnly; // Creates a new buffer with the given mark, position, limit, capacity, // backing array, and array offset @@ -530,6 +530,10 @@ public abstract class $Type$Buffer * it will be read-only if, and only if, this buffer is read-only.

    * * @return The new $type$ buffer +#if[byte] + * + * @see #alignedSlice(int) +#end[byte] */ public abstract $Type$Buffer slice(); @@ -1611,6 +1615,143 @@ public abstract class $Type$Buffer return this; } + /** + * Returns the memory address, pointing to the byte at the given index, + * modulus the given unit size. + * + *

    A return value greater than zero indicates the address of the byte at + * the index is misaligned for the unit size, and the value's quantity + * indicates how much the index should be rounded up or down to locate a + * byte at an aligned address. Otherwise, a value of {@code 0} indicates + * that the address of the byte at the index is aligned for the unit size. + * + * @apiNote + * This method may be utilized to determine if unit size bytes from an + * index can be accessed atomically, if supported by the native platform. + * + * @implNote + * This implementation throws {@code UnsupportedOperationException} for + * non-direct buffers when the given unit size is greater then {@code 8}. + * + * @param index + * The index to query for alignment offset, must be non-negative, no + * upper bounds check is performed + * + * @param unitSize + * The unit size in bytes, must be a power of {@code 2} + * + * @return The indexed byte's memory address modulus the unit size + * + * @throws IllegalArgumentException + * If the index is negative or the unit size is not a power of + * {@code 2} + * + * @throws UnsupportedOperationException + * If the native platform does not guarantee stable alignment offset + * values for the given unit size when managing the memory regions + * of buffers of the same kind as this buffer (direct or + * non-direct). For example, if garbage collection would result + * in the moving of a memory region covered by a non-direct buffer + * from one location to another and both locations have different + * alignment characteristics. + * + * @see #alignedSlice(int) + * @since 9 + */ + public final int alignmentOffset(int index, int unitSize) { + if (index < 0) + throw new IllegalArgumentException("Index less than zero: " + index); + if (unitSize < 1 || (unitSize & (unitSize - 1)) != 0) + throw new IllegalArgumentException("Unit size not a power of two: " + unitSize); + if (unitSize > 8 && !isDirect()) + throw new UnsupportedOperationException("Unit size unsupported for non-direct buffers: " + unitSize); + + return (int) ((address + index) % unitSize); + } + + /** + * Creates a new byte buffer whose content is a shared and aligned + * subsequence of this buffer's content. + * + *

    The content of the new buffer will start at this buffer's current + * position rounded up to the index of the nearest aligned byte for the + * given unit size, and end at this buffer's limit rounded down to the index + * of the nearest aligned byte for the given unit size. + * If rounding results in out-of-bound values then the new buffer's capacity + * and limit will be zero. If rounding is within bounds the following + * expressions will be true for a new buffer {@code nb} and unit size + * {@code unitSize}: + *

    {@code
    +     * nb.alignmentOffset(0, unitSize) == 0
    +     * nb.alignmentOffset(nb.limit(), unitSize) == 0
    +     * }
    + * + *

    Changes to this buffer's content will be visible in the new + * buffer, and vice versa; the two buffers' position, limit, and mark + * values will be independent. + * + *

    The new buffer's position will be zero, its capacity and its limit + * will be the number of bytes remaining in this buffer or fewer subject to + * alignment, its mark will be undefined, and its byte order will be + * {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}. + * + * The new buffer will be direct if, and only if, this buffer is direct, and + * it will be read-only if, and only if, this buffer is read-only.

    + * + * @apiNote + * This method may be utilized to create a new buffer where unit size bytes + * from index, that is a multiple of the unit size, may be accessed + * atomically, if supported by the native platform. + * + * @implNote + * This implementation throws {@code UnsupportedOperationException} for + * non-direct buffers when the given unit size is greater then {@code 8}. + * + * @param unitSize + * The unit size in bytes, must be a power of {@code 2} + * + * @return The new byte buffer + * + * @throws IllegalArgumentException + * If the unit size not a power of {@code 2} + * + * @throws UnsupportedOperationException + * If the native platform does not guarantee stable aligned slices + * for the given unit size when managing the memory regions + * of buffers of the same kind as this buffer (direct or + * non-direct). For example, if garbage collection would result + * in the moving of a memory region covered by a non-direct buffer + * from one location to another and both locations have different + * alignment characteristics. + * + * @see #alignmentOffset(int, int) + * @see #slice() + * @since 9 + */ + public final ByteBuffer alignedSlice(int unitSize) { + int pos = position(); + int lim = limit(); + + int pos_mod = alignmentOffset(pos, unitSize); + int lim_mod = alignmentOffset(lim, unitSize); + + // Round up the position to align with unit size + int aligned_pos = (pos_mod > 0) + ? pos + (unitSize - pos_mod) + : pos; + + // Round down the limit to align with unit size + int aligned_lim = lim - lim_mod; + + if (aligned_pos > lim || aligned_lim < pos) { + aligned_pos = aligned_lim = pos; + } + + return slice(aligned_pos, aligned_lim); + } + + abstract ByteBuffer slice(int pos, int lim); + // Unchecked accessors, for use by ByteBufferAs-X-Buffer classes // abstract byte _get(int i); // package-private diff --git a/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java b/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java index 955415af8b6..74eba85bd16 100644 --- a/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java +++ b/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -47,7 +47,6 @@ import java.util.Arrays; import java.util.Locale; import java.util.Objects; import java.util.ResourceBundle; -import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import sun.util.locale.provider.LocaleProviderAdapter; @@ -146,6 +145,12 @@ public class DateFormatSymbols implements Serializable, Cloneable { initializeData(locale); } + /** + * Constructs an uninitialized DateFormatSymbols. + */ + private DateFormatSymbols(boolean flag) { + } + /** * Era strings. For example: "AD" and "BC". An array of 2 strings, * indexed by Calendar.BC and Calendar.AD. @@ -679,54 +684,80 @@ public class DateFormatSymbols implements Serializable, Cloneable { */ transient volatile int cachedHashCode; - private void initializeData(Locale desiredLocale) { - locale = desiredLocale; - - // Copy values of a cached instance if any. + /** + * Initializes this DateFormatSymbols with the locale data. This method uses + * a cached DateFormatSymbols instance for the given locale if available. If + * there's no cached one, this method creates an uninitialized instance and + * populates its fields from the resource bundle for the locale, and caches + * the instance. Note: zoneStrings isn't initialized in this method. + */ + private void initializeData(Locale locale) { SoftReference ref = cachedInstances.get(locale); DateFormatSymbols dfs; - if (ref != null && (dfs = ref.get()) != null) { - copyMembers(dfs, this); - return; - } + if (ref == null || (dfs = ref.get()) == null) { + if (ref != null) { + // Remove the empty SoftReference + cachedInstances.remove(locale, ref); + } + dfs = new DateFormatSymbols(false); - // Initialize the fields from the ResourceBundle for locale. - LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(DateFormatSymbolsProvider.class, locale); - // Avoid any potential recursions - if (!(adapter instanceof ResourceBundleBasedAdapter)) { - adapter = LocaleProviderAdapter.getResourceBundleBased(); - } - ResourceBundle resource = ((ResourceBundleBasedAdapter)adapter).getLocaleData().getDateFormatData(locale); + // Initialize the fields from the ResourceBundle for locale. + LocaleProviderAdapter adapter + = LocaleProviderAdapter.getAdapter(DateFormatSymbolsProvider.class, locale); + // Avoid any potential recursions + if (!(adapter instanceof ResourceBundleBasedAdapter)) { + adapter = LocaleProviderAdapter.getResourceBundleBased(); + } + ResourceBundle resource + = ((ResourceBundleBasedAdapter)adapter).getLocaleData().getDateFormatData(locale); - // JRE and CLDR use different keys - // JRE: Eras, short.Eras and narrow.Eras - // CLDR: long.Eras, Eras and narrow.Eras - if (resource.containsKey("Eras")) { - eras = resource.getStringArray("Eras"); - } else if (resource.containsKey("long.Eras")) { - eras = resource.getStringArray("long.Eras"); - } else if (resource.containsKey("short.Eras")) { - eras = resource.getStringArray("short.Eras"); - } - months = resource.getStringArray("MonthNames"); - shortMonths = resource.getStringArray("MonthAbbreviations"); - ampms = resource.getStringArray("AmPmMarkers"); - localPatternChars = resource.getString("DateTimePatternChars"); + dfs.locale = locale; + // JRE and CLDR use different keys + // JRE: Eras, short.Eras and narrow.Eras + // CLDR: long.Eras, Eras and narrow.Eras + if (resource.containsKey("Eras")) { + dfs.eras = resource.getStringArray("Eras"); + } else if (resource.containsKey("long.Eras")) { + dfs.eras = resource.getStringArray("long.Eras"); + } else if (resource.containsKey("short.Eras")) { + dfs.eras = resource.getStringArray("short.Eras"); + } + dfs.months = resource.getStringArray("MonthNames"); + dfs.shortMonths = resource.getStringArray("MonthAbbreviations"); + dfs.ampms = resource.getStringArray("AmPmMarkers"); + dfs.localPatternChars = resource.getString("DateTimePatternChars"); - // Day of week names are stored in a 1-based array. - weekdays = toOneBasedArray(resource.getStringArray("DayNames")); - shortWeekdays = toOneBasedArray(resource.getStringArray("DayAbbreviations")); + // Day of week names are stored in a 1-based array. + dfs.weekdays = toOneBasedArray(resource.getStringArray("DayNames")); + dfs.shortWeekdays = toOneBasedArray(resource.getStringArray("DayAbbreviations")); - // Put a clone in the cache - ref = new SoftReference<>((DateFormatSymbols)this.clone()); - SoftReference x = cachedInstances.putIfAbsent(locale, ref); - if (x != null) { - DateFormatSymbols y = x.get(); - if (y == null) { - // Replace the empty SoftReference with ref. - cachedInstances.put(locale, ref); + // Put dfs in the cache + ref = new SoftReference<>(dfs); + SoftReference x = cachedInstances.putIfAbsent(locale, ref); + if (x != null) { + DateFormatSymbols y = x.get(); + if (y == null) { + // Replace the empty SoftReference with ref. + cachedInstances.replace(locale, x, ref); + } else { + ref = x; + dfs = y; + } + } + // If the bundle's locale isn't the target locale, put another cache + // entry for the bundle's locale. + Locale bundleLocale = resource.getLocale(); + if (!bundleLocale.equals(locale)) { + SoftReference z + = cachedInstances.putIfAbsent(bundleLocale, ref); + if (z != null && z.get() == null) { + cachedInstances.replace(bundleLocale, z, ref); + } } } + + // Copy the field values from dfs to this instance. + copyMembers(dfs, this); } private static String[] toOneBasedArray(String[] src) { @@ -808,12 +839,14 @@ public class DateFormatSymbols implements Serializable, Cloneable { /** * Clones all the data members from the source DateFormatSymbols to - * the target DateFormatSymbols. This is only for subclasses. + * the target DateFormatSymbols. + * * @param src the source DateFormatSymbols. * @param dst the target DateFormatSymbols. */ private void copyMembers(DateFormatSymbols src, DateFormatSymbols dst) { + dst.locale = src.locale; dst.eras = Arrays.copyOf(src.eras, src.eras.length); dst.months = Arrays.copyOf(src.months, src.months.length); dst.shortMonths = Arrays.copyOf(src.shortMonths, src.shortMonths.length); diff --git a/jdk/src/java.base/share/classes/java/time/chrono/Chronology.java b/jdk/src/java.base/share/classes/java/time/chrono/Chronology.java index 5783f93ddf1..c9d6baa3ac8 100644 --- a/jdk/src/java.base/share/classes/java/time/chrono/Chronology.java +++ b/jdk/src/java.base/share/classes/java/time/chrono/Chronology.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -61,12 +61,17 @@ */ package java.time.chrono; +import static java.time.temporal.ChronoField.HOUR_OF_DAY; +import static java.time.temporal.ChronoField.MINUTE_OF_HOUR; +import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; + import java.time.Clock; import java.time.DateTimeException; import java.time.Instant; import java.time.LocalDate; import java.time.LocalTime; import java.time.ZoneId; +import java.time.ZoneOffset; import java.time.format.DateTimeFormatterBuilder; import java.time.format.ResolverStyle; import java.time.format.TextStyle; @@ -712,6 +717,59 @@ public interface Chronology extends Comparable { return new ChronoPeriodImpl(this, years, months, days); } + //--------------------------------------------------------------------- + + /** + * Gets the number of seconds from the epoch of 1970-01-01T00:00:00Z. + *

    + * The number of seconds is calculated using the proleptic-year, + * month, day-of-month, hour, minute, second, and zoneOffset. + * + * @param prolepticYear the chronology proleptic-year + * @param month the chronology month-of-year + * @param dayOfMonth the chronology day-of-month + * @param hour the hour-of-day, from 0 to 23 + * @param minute the minute-of-hour, from 0 to 59 + * @param second the second-of-minute, from 0 to 59 + * @param zoneOffset the zone offset, not null + * @return the number of seconds relative to 1970-01-01T00:00:00Z, may be negative + * @throws DateTimeException if any of the values are out of range + * @since 9 + */ + public default long epochSecond(int prolepticYear, int month, int dayOfMonth, + int hour, int minute, int second, ZoneOffset zoneOffset) { + Objects.requireNonNull(zoneOffset, "zoneOffset"); + HOUR_OF_DAY.checkValidValue(hour); + MINUTE_OF_HOUR.checkValidValue(minute); + SECOND_OF_MINUTE.checkValidValue(second); + long daysInSec = Math.multiplyExact(date(prolepticYear, month, dayOfMonth).toEpochDay(), 86400); + long timeinSec = (hour * 60 + minute) * 60 + second; + return Math.addExact(daysInSec, timeinSec - zoneOffset.getTotalSeconds()); + } + + /** + * Gets the number of seconds from the epoch of 1970-01-01T00:00:00Z. + *

    + * The number of seconds is calculated using the era, year-of-era, + * month, day-of-month, hour, minute, second, and zoneOffset. + * + * @param era the era of the correct type for the chronology, not null + * @param yearOfEra the chronology year-of-era + * @param month the chronology month-of-year + * @param dayOfMonth the chronology day-of-month + * @param hour the hour-of-day, from 0 to 23 + * @param minute the minute-of-hour, from 0 to 59 + * @param second the second-of-minute, from 0 to 59 + * @param zoneOffset the zone offset, not null + * @return the number of seconds relative to 1970-01-01T00:00:00Z, may be negative + * @throws DateTimeException if any of the values are out of range + * @since 9 + */ + public default long epochSecond(Era era, int yearOfEra, int month, int dayOfMonth, + int hour, int minute, int second, ZoneOffset zoneOffset) { + Objects.requireNonNull(era, "era"); + return epochSecond(prolepticYear(era, yearOfEra), month, dayOfMonth, hour, minute, second, zoneOffset); + } //----------------------------------------------------------------------- /** * Compares this chronology to another chronology. diff --git a/jdk/src/java.base/share/classes/java/time/chrono/IsoChronology.java b/jdk/src/java.base/share/classes/java/time/chrono/IsoChronology.java index 65ba755360c..7ce8e4ba21a 100644 --- a/jdk/src/java.base/share/classes/java/time/chrono/IsoChronology.java +++ b/jdk/src/java.base/share/classes/java/time/chrono/IsoChronology.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -61,14 +61,17 @@ */ package java.time.chrono; -import java.io.InvalidObjectException; import static java.time.temporal.ChronoField.DAY_OF_MONTH; import static java.time.temporal.ChronoField.ERA; +import static java.time.temporal.ChronoField.HOUR_OF_DAY; +import static java.time.temporal.ChronoField.MINUTE_OF_HOUR; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; +import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.Serializable; import java.time.Clock; @@ -79,8 +82,9 @@ import java.time.LocalDateTime; import java.time.Month; import java.time.Period; import java.time.Year; -import java.time.ZoneId; import java.time.ZonedDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; import java.time.format.ResolverStyle; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; @@ -132,6 +136,8 @@ public final class IsoChronology extends AbstractChronology implements Serializa */ private static final long serialVersionUID = -1440403870442975015L; + private static final long DAYS_0000_TO_1970 = (146097 * 5L) - (30L * 365L + 7L); // taken from LocalDate + /** * Restricted constructor. */ @@ -263,6 +269,94 @@ public final class IsoChronology extends AbstractChronology implements Serializa return LocalDate.from(temporal); } + //----------------------------------------------------------------------- + /** + * Gets the number of seconds from the epoch of 1970-01-01T00:00:00Z. + *

    + * The number of seconds is calculated using the year, + * month, day-of-month, hour, minute, second, and zoneOffset. + * + * @param prolepticYear the year, from MIN_YEAR to MAX_YEAR + * @param month the month-of-year, from 1 to 12 + * @param dayOfMonth the day-of-month, from 1 to 31 + * @param hour the hour-of-day, from 0 to 23 + * @param minute the minute-of-hour, from 0 to 59 + * @param second the second-of-minute, from 0 to 59 + * @param zoneOffset the zone offset, not null + * @return the number of seconds relative to 1970-01-01T00:00:00Z, may be negative + * @throws DateTimeException if the value of any argument is out of range, + * or if the day-of-month is invalid for the month-of-year + * @since 9 + */ + @Override + public long epochSecond(int prolepticYear, int month, int dayOfMonth, + int hour, int minute, int second, ZoneOffset zoneOffset) { + YEAR.checkValidValue(prolepticYear); + MONTH_OF_YEAR.checkValidValue(month); + DAY_OF_MONTH.checkValidValue(dayOfMonth); + HOUR_OF_DAY.checkValidValue(hour); + MINUTE_OF_HOUR.checkValidValue(minute); + SECOND_OF_MINUTE.checkValidValue(second); + Objects.requireNonNull(zoneOffset, "zoneOffset"); + if (dayOfMonth > 28) { + int dom = numberOfDaysOfMonth(prolepticYear, month); + if (dayOfMonth > dom) { + if (dayOfMonth == 29) { + throw new DateTimeException("Invalid date 'February 29' as '" + prolepticYear + "' is not a leap year"); + } else { + throw new DateTimeException("Invalid date '" + Month.of(month).name() + " " + dayOfMonth + "'"); + } + } + } + + long totalDays = 0; + int timeinSec = 0; + totalDays += 365L * prolepticYear; + if (prolepticYear >= 0) { + totalDays += (prolepticYear + 3L) / 4 - (prolepticYear + 99L) / 100 + (prolepticYear + 399L) / 400; + } else { + totalDays -= prolepticYear / -4 - prolepticYear / -100 + prolepticYear / -400; + } + totalDays += (367 * month - 362) / 12; + totalDays += dayOfMonth - 1; + if (month > 2) { + totalDays--; + if (IsoChronology.INSTANCE.isLeapYear(prolepticYear) == false) { + totalDays--; + } + } + totalDays -= DAYS_0000_TO_1970; + timeinSec = (hour * 60 + minute ) * 60 + second; + return Math.addExact(Math.multiplyExact(totalDays, 86400L), timeinSec - zoneOffset.getTotalSeconds()); + } + + /** + * Gets the number of days for the given month in the given year. + * + * @param year the year to represent, from MIN_YEAR to MAX_YEAR + * @param month the month-of-year to represent, from 1 to 12 + * @return the number of days for the given month in the given year + */ + private int numberOfDaysOfMonth(int year, int month) { + int dom; + switch (month) { + case 2: + dom = (IsoChronology.INSTANCE.isLeapYear(year) ? 29 : 28); + break; + case 4: + case 6: + case 9: + case 11: + dom = 30; + break; + default: + dom = 31; + break; + } + return dom; + } + + /** * Obtains an ISO local date-time from another date-time object. *

    diff --git a/jdk/src/java.base/share/classes/java/time/temporal/ChronoField.java b/jdk/src/java.base/share/classes/java/time/temporal/ChronoField.java index fe3254e60ab..d3c6a056fd1 100644 --- a/jdk/src/java.base/share/classes/java/time/temporal/ChronoField.java +++ b/jdk/src/java.base/share/classes/java/time/temporal/ChronoField.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -270,6 +270,8 @@ public enum ChronoField implements TemporalField { * In lenient mode the value is not validated. It is combined with * {@code AMPM_OF_DAY} to form {@code HOUR_OF_DAY} by multiplying * the {AMPM_OF_DAY} value by 12. + *

    + * See {@link #CLOCK_HOUR_OF_AMPM} for the related field that counts hours from 1 to 12. */ HOUR_OF_AMPM("HourOfAmPm", HOURS, HALF_DAYS, ValueRange.of(0, 11)), /** @@ -284,6 +286,8 @@ public enum ChronoField implements TemporalField { * 0 to 12 in smart mode. In lenient mode the value is not validated. * The field is converted to an {@code HOUR_OF_AMPM} with the same value, * unless the value is 12, in which case it is converted to 0. + *

    + * See {@link #HOUR_OF_AMPM} for the related field that counts hours from 0 to 11. */ CLOCK_HOUR_OF_AMPM("ClockHourOfAmPm", HOURS, HALF_DAYS, ValueRange.of(1, 12)), /** @@ -299,12 +303,14 @@ public enum ChronoField implements TemporalField { * {@code NANO_OF_SECOND} to produce a {@code LocalTime}. * In lenient mode, any excess days are added to the parsed date, or * made available via {@link java.time.format.DateTimeFormatter#parsedExcessDays()}. + *

    + * See {@link #CLOCK_HOUR_OF_DAY} for the related field that counts hours from 1 to 24. */ HOUR_OF_DAY("HourOfDay", HOURS, DAYS, ValueRange.of(0, 23), "hour"), /** * The clock-hour-of-day. *

    - * This counts the hour within the AM/PM, from 1 to 24. + * This counts the hour within the day, from 1 to 24. * This is the hour that would be observed on a 24-hour analog wall clock. * This field has the same meaning for all calendar systems. *

    @@ -313,6 +319,8 @@ public enum ChronoField implements TemporalField { * 0 to 24 in smart mode. In lenient mode the value is not validated. * The field is converted to an {@code HOUR_OF_DAY} with the same value, * unless the value is 24, in which case it is converted to 0. + *

    + * See {@link #HOUR_OF_DAY} for the related field that counts hours from 0 to 23. */ CLOCK_HOUR_OF_DAY("ClockHourOfDay", HOURS, DAYS, ValueRange.of(1, 24)), /** diff --git a/jdk/src/java.base/share/classes/java/util/Deque.java b/jdk/src/java.base/share/classes/java/util/Deque.java index 098be9b4bf9..2714373fe63 100644 --- a/jdk/src/java.base/share/classes/java/util/Deque.java +++ b/jdk/src/java.base/share/classes/java/util/Deque.java @@ -174,7 +174,7 @@ package java.util; * that do allow null elements are strongly encouraged not to * take advantage of the ability to insert nulls. This is so because * {@code null} is used as a special return value by various methods - * to indicated that the deque is empty. + * to indicate that the deque is empty. * *

    {@code Deque} implementations generally do not define * element-based versions of the {@code equals} and {@code hashCode} diff --git a/jdk/src/java.base/share/classes/java/util/GregorianCalendar.java b/jdk/src/java.base/share/classes/java/util/GregorianCalendar.java index d244e7d37b2..6ce8e8e9b7a 100644 --- a/jdk/src/java.base/share/classes/java/util/GregorianCalendar.java +++ b/jdk/src/java.base/share/classes/java/util/GregorianCalendar.java @@ -424,7 +424,7 @@ public class GregorianCalendar extends Calendar { * DAY_OF_MONTH 1 1 28* 31 * DAY_OF_YEAR 1 1 365* 366 * DAY_OF_WEEK 1 1 7 7 - * DAY_OF_WEEK_IN_MONTH -1 -1 4* 6 + * DAY_OF_WEEK_IN_MONTH 1 1 4* 6 * AM_PM 0 0 1 1 * HOUR 0 0 11 11 * HOUR_OF_DAY 0 0 23 23 diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java b/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java index b3fb80dcd37..a558cdad2f3 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java @@ -480,7 +480,7 @@ public class CompletableFuture implements Future, CompletionStage { } static void lazySetNext(Completion c, Completion next) { - U.putOrderedObject(c, NEXT, next); + U.putObjectRelease(c, NEXT, next); } /** @@ -583,9 +583,9 @@ public class CompletableFuture implements Future, CompletionStage { */ final CompletableFuture postFire(CompletableFuture a, int mode) { if (a != null && a.stack != null) { - if (mode < 0 || a.result == null) + if (a.result == null) a.cleanStack(); - else + else if (mode >= 0) a.postComplete(); } if (result != null && stack != null) { @@ -1107,9 +1107,9 @@ public class CompletableFuture implements Future, CompletionStage { final CompletableFuture postFire(CompletableFuture a, CompletableFuture b, int mode) { if (b != null && b.stack != null) { // clean second source - if (mode < 0 || b.result == null) + if (b.result == null) b.cleanStack(); - else + else if (mode >= 0) b.postComplete(); } return postFire(a, mode); diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index d7cfc66f7a0..d6ae6557978 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -628,10 +628,14 @@ public class ConcurrentHashMap extends AbstractMap volatile V val; volatile Node next; - Node(int hash, K key, V val, Node next) { + Node(int hash, K key, V val) { this.hash = hash; this.key = key; this.val = val; + } + + Node(int hash, K key, V val, Node next) { + this(hash, key, val); this.next = next; } @@ -1024,8 +1028,7 @@ public class ConcurrentHashMap extends AbstractMap if (tab == null || (n = tab.length) == 0) tab = initTable(); else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) { - if (casTabAt(tab, i, null, - new Node(hash, key, value, null))) + if (casTabAt(tab, i, null, new Node(hash, key, value))) break; // no lock when adding to empty bin } else if ((fh = f.hash) == MOVED) @@ -1048,8 +1051,7 @@ public class ConcurrentHashMap extends AbstractMap } Node pred = e; if ((e = e.next) == null) { - pred.next = new Node(hash, key, - value, null); + pred.next = new Node(hash, key, value); break; } } @@ -1709,7 +1711,7 @@ public class ConcurrentHashMap extends AbstractMap Node node = null; try { if ((val = mappingFunction.apply(key)) != null) - node = new Node(h, key, val, null); + node = new Node(h, key, val); } finally { setTabAt(tab, i, node); } @@ -1740,7 +1742,7 @@ public class ConcurrentHashMap extends AbstractMap if (pred.next != null) throw new IllegalStateException("Recursive update"); added = true; - pred.next = new Node(h, key, val, null); + pred.next = new Node(h, key, val); } break; } @@ -1909,7 +1911,7 @@ public class ConcurrentHashMap extends AbstractMap try { if ((val = remappingFunction.apply(key, null)) != null) { delta = 1; - node = new Node(h, key, val, null); + node = new Node(h, key, val); } } finally { setTabAt(tab, i, node); @@ -1951,8 +1953,7 @@ public class ConcurrentHashMap extends AbstractMap if (pred.next != null) throw new IllegalStateException("Recursive update"); delta = 1; - pred.next = - new Node(h, key, val, null); + pred.next = new Node(h, key, val); } break; } @@ -2030,7 +2031,7 @@ public class ConcurrentHashMap extends AbstractMap if (tab == null || (n = tab.length) == 0) tab = initTable(); else if ((f = tabAt(tab, i = (n - 1) & h)) == null) { - if (casTabAt(tab, i, null, new Node(h, key, value, null))) { + if (casTabAt(tab, i, null, new Node(h, key, value))) { delta = 1; val = value; break; @@ -2065,8 +2066,7 @@ public class ConcurrentHashMap extends AbstractMap if ((e = e.next) == null) { delta = 1; val = value; - pred.next = - new Node(h, key, val, null); + pred.next = new Node(h, key, val); break; } } @@ -2227,7 +2227,7 @@ public class ConcurrentHashMap extends AbstractMap static final class ForwardingNode extends Node { final Node[] nextTable; ForwardingNode(Node[] tab) { - super(MOVED, null, null, null); + super(MOVED, null, null); this.nextTable = tab; } @@ -2263,7 +2263,7 @@ public class ConcurrentHashMap extends AbstractMap */ static final class ReservationNode extends Node { ReservationNode() { - super(RESERVED, null, null, null); + super(RESERVED, null, null); } Node find(int h, Object k) { @@ -2690,12 +2690,12 @@ public class ConcurrentHashMap extends AbstractMap } /** - * Returns a list on non-TreeNodes replacing those in given list. + * Returns a list of non-TreeNodes replacing those in given list. */ static Node untreeify(Node b) { Node hd = null, tl = null; for (Node q = b; q != null; q = q.next) { - Node p = new Node(q.hash, q.key, q.val, null); + Node p = new Node(q.hash, q.key, q.val); if (tl == null) hd = p; else @@ -2801,7 +2801,7 @@ public class ConcurrentHashMap extends AbstractMap * Creates bin with initial set of nodes headed by b. */ TreeBin(TreeNode b) { - super(TREEBIN, null, null, null); + super(TREEBIN, null, null); this.first = b; TreeNode r = null; for (TreeNode x = b, next; x != null; x = next) { diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index 4f8fdd92c49..9b23efa6157 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -309,7 +309,7 @@ public class ConcurrentLinkedDeque } void lazySetNext(Node val) { - U.putOrderedObject(this, NEXT, val); + U.putObjectRelease(this, NEXT, val); } boolean casNext(Node cmp, Node val) { @@ -317,7 +317,7 @@ public class ConcurrentLinkedDeque } void lazySetPrev(Node val) { - U.putOrderedObject(this, PREV, val); + U.putObjectRelease(this, PREV, val); } boolean casPrev(Node cmp, Node val) { diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index d302b6f55b8..ba4ee87f335 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -198,7 +198,7 @@ public class ConcurrentLinkedQueue extends AbstractQueue } static void lazySetNext(Node node, Node val) { - U.putOrderedObject(node, NEXT, val); + U.putObjectRelease(node, NEXT, val); } static boolean casNext(Node node, Node cmp, Node val) { diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java b/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java index 3f5ce5e371d..069d6e0f871 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java @@ -239,7 +239,7 @@ public class Exchanger { * not to be as readily inlined by dynamic compilers when they are * hidden behind other methods that would more nicely name and * encapsulate the intended effects). This includes the use of - * putOrderedX to clear fields of the per-thread Nodes between + * putXRelease to clear fields of the per-thread Nodes between * uses. Note that field Node.item is not declared as volatile * even though it is read by releasing threads, because they only * do so after CAS operations that must precede access, and all @@ -376,7 +376,7 @@ public class Exchanger { for (int h = p.hash, spins = SPINS;;) { Object v = p.match; if (v != null) { - U.putOrderedObject(p, MATCH, null); + U.putObjectRelease(p, MATCH, null); p.item = null; // clear for next use p.hash = h; return v; @@ -507,7 +507,7 @@ public class Exchanger { break; } } - U.putOrderedObject(p, MATCH, null); + U.putObjectRelease(p, MATCH, null); p.item = null; p.hash = h; return v; diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java index 3a7c0ab4eb8..bcb6d59fcad 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java @@ -289,7 +289,7 @@ public class ForkJoinPool extends AbstractExecutorService { * on to try or create other queues -- they block only when * creating and registering new queues. Because it is used only as * a spinlock, unlocking requires only a "releasing" store (using - * putOrderedInt). The qlock is also used during termination + * putIntRelease). The qlock is also used during termination * detection, in which case it is forced to a negative * non-lockable value. * @@ -1071,7 +1071,7 @@ public class ForkJoinPool extends AbstractExecutorService { popped = true; top = s; } - U.putOrderedInt(this, QLOCK, 0); + U.putIntRelease(this, QLOCK, 0); } } return popped; @@ -1261,7 +1261,7 @@ public class ForkJoinPool extends AbstractExecutorService { popped = true; top = s - 1; } - U.putOrderedInt(this, QLOCK, 0); + U.putIntRelease(this, QLOCK, 0); if (popped) return t; } diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java index 54d8931de4f..9629e83bd3b 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java @@ -92,7 +92,7 @@ public class ForkJoinWorkerThread extends Thread { ForkJoinWorkerThread(ForkJoinPool pool, ThreadGroup threadGroup, AccessControlContext acc) { super(threadGroup, null, "aForkJoinWorkerThread"); - U.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, acc); + U.putObjectRelease(this, INHERITEDACCESSCONTROLCONTEXT, acc); eraseThreadLocals(); // clear before registering this.pool = pool; this.workQueue = pool.registerWorker(this); diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/FutureTask.java b/jdk/src/java.base/share/classes/java/util/concurrent/FutureTask.java index 27943fd7cb6..aade083ffe3 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/FutureTask.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/FutureTask.java @@ -174,7 +174,7 @@ public class FutureTask implements RunnableFuture { if (t != null) t.interrupt(); } finally { // final state - U.putOrderedInt(this, STATE, INTERRUPTED); + U.putIntRelease(this, STATE, INTERRUPTED); } } } finally { @@ -230,7 +230,7 @@ public class FutureTask implements RunnableFuture { protected void set(V v) { if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) { outcome = v; - U.putOrderedInt(this, STATE, NORMAL); // final state + U.putIntRelease(this, STATE, NORMAL); // final state finishCompletion(); } } @@ -248,7 +248,7 @@ public class FutureTask implements RunnableFuture { protected void setException(Throwable t) { if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) { outcome = t; - U.putOrderedInt(this, STATE, EXCEPTIONAL); // final state + U.putIntRelease(this, STATE, EXCEPTIONAL); // final state finishCompletion(); } } diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java b/jdk/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java index d3c4518a3b6..0e84bf4e050 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java @@ -1496,7 +1496,7 @@ public class SubmissionPublisher implements Flow.Publisher, else if (((c & CONSUME) != 0 || U.compareAndSwapInt(this, CTL, c, c | CONSUME)) && U.compareAndSwapObject(a, i, x, null)) { - U.putOrderedInt(this, HEAD, ++h); + U.putIntRelease(this, HEAD, ++h); U.getAndAddLong(this, DEMAND, -1L); if ((w = waiter) != null) signalWaiter(w); diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java index 01fc1c2c0d7..5241392ed92 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java @@ -136,7 +136,7 @@ public class AtomicBoolean implements java.io.Serializable { * @since 1.6 */ public final void lazySet(boolean newValue) { - U.putOrderedInt(this, VALUE, (newValue ? 1 : 0)); + U.putIntRelease(this, VALUE, (newValue ? 1 : 0)); } /** diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java index 96e13f60ed8..920b45bd5ab 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java @@ -108,7 +108,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { * @since 1.6 */ public final void lazySet(int newValue) { - U.putOrderedInt(this, VALUE, newValue); + U.putIntRelease(this, VALUE, newValue); } /** diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java index f3a262b65b4..001a35008d9 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java @@ -136,7 +136,7 @@ public class AtomicIntegerArray implements java.io.Serializable { * @since 1.6 */ public final void lazySet(int i, int newValue) { - U.putOrderedInt(array, checkedByteOffset(i), newValue); + U.putIntRelease(array, checkedByteOffset(i), newValue); } /** diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java index d14454228f8..09b372dc822 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java @@ -475,7 +475,7 @@ public abstract class AtomicIntegerFieldUpdater { public final void lazySet(T obj, int newValue) { accessCheck(obj); - U.putOrderedInt(obj, offset, newValue); + U.putIntRelease(obj, offset, newValue); } public final int get(T obj) { diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java index 2af5d1dd07f..85ff9030da3 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java @@ -124,7 +124,7 @@ public class AtomicLong extends Number implements java.io.Serializable { * @since 1.6 */ public final void lazySet(long newValue) { - U.putOrderedLong(this, VALUE, newValue); + U.putLongRelease(this, VALUE, newValue); } /** diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java index 58aa1875b19..041e561b2a7 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java @@ -135,7 +135,7 @@ public class AtomicLongArray implements java.io.Serializable { * @since 1.6 */ public final void lazySet(int i, long newValue) { - U.putOrderedLong(array, checkedByteOffset(i), newValue); + U.putLongRelease(array, checkedByteOffset(i), newValue); } /** diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java index dccca9e15b2..8770b2d962a 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java @@ -457,7 +457,7 @@ public abstract class AtomicLongFieldUpdater { public final void lazySet(T obj, long newValue) { accessCheck(obj); - U.putOrderedLong(obj, offset, newValue); + U.putLongRelease(obj, offset, newValue); } public final long get(T obj) { diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java index 9d4d2a385c7..d0a0b0a90cf 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java @@ -103,7 +103,7 @@ public class AtomicReference implements java.io.Serializable { * @since 1.6 */ public final void lazySet(V newValue) { - U.putOrderedObject(this, VALUE, newValue); + U.putObjectRelease(this, VALUE, newValue); } /** diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java index 03f950d43e0..a2e8b2b7805 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java @@ -147,7 +147,7 @@ public class AtomicReferenceArray implements java.io.Serializable { * @since 1.6 */ public final void lazySet(int i, E newValue) { - U.putOrderedObject(array, checkedByteOffset(i), newValue); + U.putObjectRelease(array, checkedByteOffset(i), newValue); } /** diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java index f9e4989cbbe..b30341f73f9 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java @@ -426,7 +426,7 @@ public abstract class AtomicReferenceFieldUpdater { public final void lazySet(T obj, V newValue) { accessCheck(obj); valueCheck(newValue); - U.putOrderedObject(obj, offset, newValue); + U.putObjectRelease(obj, offset, newValue); } @SuppressWarnings("unchecked") diff --git a/jdk/src/java.base/share/classes/jdk/internal/jimage/decompressor/CompressIndexes.java b/jdk/src/java.base/share/classes/jdk/internal/jimage/decompressor/CompressIndexes.java index bcc9513bd6f..709b82a808c 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/jimage/decompressor/CompressIndexes.java +++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/decompressor/CompressIndexes.java @@ -42,107 +42,95 @@ import java.util.List; * to the jimage file provided by the shipped JDK by tools running on JDK 8. */ public class CompressIndexes { - private static final int INTEGER_SIZE = 4; + private static final int COMPRESSED_FLAG = 1 << (Byte.SIZE - 1); + private static final int HEADER_WIDTH = 3; + private static final int HEADER_SHIFT = Byte.SIZE - HEADER_WIDTH; public static List decompressFlow(byte[] values) { List lst = new ArrayList<>(); - for (int i = 0; i < values.length;) { - byte b = values[i]; - int length = isCompressed(b) ? getLength(b) : INTEGER_SIZE; + + for (int i = 0; i < values.length; i += getHeaderLength(values[i])) { int decompressed = decompress(values, i); lst.add(decompressed); - i += length; } + return lst; } public static int readInt(DataInputStream cr) throws IOException { - byte[] b = new byte[1]; - cr.readFully(b); - byte firstByte = b[0]; - boolean compressed = CompressIndexes.isCompressed(firstByte); - int toRead = 4; - if(compressed) { - toRead = CompressIndexes.getLength(firstByte); + // Get header byte. + byte header = cr.readByte(); + // Determine size. + int size = getHeaderLength(header); + // Prepare result. + int result = getHeaderValue(header); + + // For each value byte + for (int i = 1; i < size; i++) { + // Merge byte value. + result <<= Byte.SIZE; + result |= cr.readByte() & 0xFF; } - byte[] content = new byte[toRead-1]; - cr.readFully(content); - ByteBuffer bb = ByteBuffer.allocate(content.length+1); - bb.put(firstByte); - bb.put(content); - int index = CompressIndexes.decompress(bb.array(), 0); - return index; + + return result; } - public static int getLength(byte b) { - return ((byte) (b & 0x60) >> 5); + private static boolean isCompressed(byte b) { + return (b & COMPRESSED_FLAG) != 0; } - public static boolean isCompressed(byte b) { - return b < 0; + private static int getHeaderLength(byte b) { + return isCompressed(b) ? (b >> HEADER_SHIFT) & 3 : Integer.BYTES; + } + + private static int getHeaderValue(byte b) { + return isCompressed(b) ? b & (1 << HEADER_SHIFT) - 1 : b; } public static int decompress(byte[] value, int offset) { - byte b1 = value[offset]; - ByteBuffer buffer = ByteBuffer.allocate(INTEGER_SIZE); - if (isCompressed(b1)) { // compressed - int length = getLength(b1); - byte clearedValue = (byte) (b1 & 0x1F); + // Get header byte. + byte header = value[offset]; + // Determine size. + int size = getHeaderLength(header); + // Prepare result. + int result = getHeaderValue(header); - int start = INTEGER_SIZE - length; - buffer.put(start, clearedValue); - for (int i = offset + 1; i < offset + length; i++) { - buffer.put(++start, value[i]); - } - } else { - buffer.put(value, offset, INTEGER_SIZE); + // For each value byte + for (int i = 1; i < size; i++) { + // Merge byte value. + result <<= Byte.SIZE; + result |= value[offset + i] & 0xFF; } - return buffer.getInt(0); + + return result; } - public static byte[] compress(int val) { - ByteBuffer result = ByteBuffer.allocate(4).putInt(val); - byte[] array = result.array(); - - if ((val & 0xFF000000) == 0) { // nothing on 4th - if ((val & 0x00FF0000) == 0) { // nothing on 3rd - if ((val & 0x0000FF00) == 0) { // nothing on 2nd - if ((val & 0x000000E0) == 0) { // only in 1st, encode length in the byte. - //sign bit and size 1 ==> 101X - result = ByteBuffer.allocate(1); - result.put((byte) (0xA0 | array[3])); - } else { // add a byte for size - //sign bit and size 2 ==> 110X - result = ByteBuffer.allocate(2); - result.put((byte) 0xC0); - result.put(array[3]); - } - } else { // content in 2nd - if ((val & 0x0000E000) == 0) {// encode length in the byte. - //sign bit and size 2 ==> 110X - result = ByteBuffer.allocate(2); - result.put((byte) (0xC0 | array[2])); - result.put(array[3]); - } else { // add a byte for size - //sign bit and size 3 ==> 111X - result = ByteBuffer.allocate(3); - result.put((byte) 0xE0); - result.put(array[2]); - result.put(array[3]); - } - } - } else {// content in 3rd - if ((val & 0x00E00000) == 0) {// encode length in the byte. - //sign bit and size 3 ==> 111X - result = ByteBuffer.allocate(3); - result.put((byte) (0xE0 | array[1])); - result.put(array[2]); - result.put(array[3]); - } else { // add a byte, useless - // - } - } + public static byte[] compress(int value) { + // Only positive values are supported. + if (value < 0) { + throw new IllegalArgumentException("value < 0"); } - return result.array(); + + // Determine number of significant digits. + int width = 32 - Integer.numberOfLeadingZeros(value); + // Determine number of byte to represent. Allow for header if + // compressed. + int size = Math.min(((width + HEADER_WIDTH - 1) >> 3) + 1, Integer.BYTES); + + // Allocate result buffer. + byte[] result = new byte[size]; + + // Insert significant bytes in result. + for (int i = 0; i < size; i++) { + result[i] = (byte)(value >> ((size - i - 1) * Byte.SIZE)); + } + + // If compressed, mark and insert size. + if (size < Integer.BYTES) { + result[0] |= (byte)(COMPRESSED_FLAG | (size << HEADER_SHIFT)); + } + + return result; } + } diff --git a/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java b/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java index 13c3eeda5d6..6fc5e7d4ec8 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java +++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java @@ -39,6 +39,7 @@ import java.security.PrivilegedAction; import java.util.Arrays; import java.util.Enumeration; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import java.util.jar.JarInputStream; import java.util.jar.Manifest; import java.util.stream.Stream; @@ -68,6 +69,10 @@ public class BootLoader { // ServiceCatalog for the boot class loader private static final ServicesCatalog SERVICES_CATALOG = new ServicesCatalog(); + // ClassLoaderValue map for boot class loader + private static final ConcurrentHashMap CLASS_LOADER_VALUE_MAP = + new ConcurrentHashMap<>(); + /** * Returns the unnamed module for the boot loader. */ @@ -82,6 +87,13 @@ public class BootLoader { return SERVICES_CATALOG; } + /** + * Returns the ClassLoaderValue map for the boot class loader. + */ + public static ConcurrentHashMap getClassLoaderValueMap() { + return CLASS_LOADER_VALUE_MAP; + } + /** * Register a module with this class loader so that its classes (and * resources) become visible via this class loader. diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java b/jdk/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java index ce340a1327c..b7c68dad251 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java @@ -86,8 +86,8 @@ public final class InnocuousThread extends Thread { private InnocuousThread(ThreadGroup group, Runnable target, String name, ClassLoader tccl) { super(group, target, name, 0L, false); - UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC); - UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, tccl); + UNSAFE.putObjectRelease(this, INHERITEDACCESSCONTROLCONTEXT, ACC); + UNSAFE.putObjectRelease(this, CONTEXTCLASSLOADER, tccl); } @Override diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java index 158d3c49abc..7ca99963791 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java @@ -33,6 +33,7 @@ import java.lang.reflect.Module; import java.net.URL; import java.security.AccessControlContext; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Stream; import jdk.internal.module.ServicesCatalog; @@ -145,6 +146,12 @@ public interface JavaLangAccess { */ ServicesCatalog createOrGetServicesCatalog(ClassLoader cl); + /** + * Returns the ConcurrentHashMap used as a storage for ClassLoaderValue(s) + * associated with the given class loader, creating it if it doesn't already exist. + */ + ConcurrentHashMap createOrGetClassLoaderValueMap(ClassLoader cl); + /** * Returns a class loaded by the bootstrap class loader. */ diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java b/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java index 8b8a0ff9531..beb64fd5155 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java @@ -1457,25 +1457,7 @@ public final class Unsafe { @HotSpotIntrinsicCandidate public native void putDoubleVolatile(Object o, long offset, double x); - /** - * Version of {@link #putObjectVolatile(Object, long, Object)} - * that does not guarantee immediate visibility of the store to - * other threads. This method is generally only useful if the - * underlying field is a Java volatile (or if an array cell, one - * that is otherwise only accessed using volatile accesses). - * - * Corresponds to C11 atomic_store_explicit(..., memory_order_release). - */ - @HotSpotIntrinsicCandidate - public native void putOrderedObject(Object o, long offset, Object x); - /** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)} */ - @HotSpotIntrinsicCandidate - public native void putOrderedInt(Object o, long offset, int x); - - /** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)} */ - @HotSpotIntrinsicCandidate - public native void putOrderedLong(Object o, long offset, long x); /** Acquire version of {@link #getObjectVolatile(Object, long)} */ @HotSpotIntrinsicCandidate @@ -1531,6 +1513,16 @@ public final class Unsafe { return getDoubleVolatile(o, offset); } + /* + * Versions of {@link #putObjectVolatile(Object, long, Object)} + * that do not guarantee immediate visibility of the store to + * other threads. This method is generally only useful if the + * underlying field is a Java volatile (or if an array cell, one + * that is otherwise only accessed using volatile accesses). + * + * Corresponds to C11 atomic_store_explicit(..., memory_order_release). + */ + /** Release version of {@link #putObjectVolatile(Object, long, Object)} */ @HotSpotIntrinsicCandidate public final void putObjectRelease(Object o, long offset, Object x) { diff --git a/jdk/src/java.base/share/classes/sun/misc/VMSupport.java b/jdk/src/java.base/share/classes/jdk/internal/vm/VMSupport.java similarity index 99% rename from jdk/src/java.base/share/classes/sun/misc/VMSupport.java rename to jdk/src/java.base/share/classes/jdk/internal/vm/VMSupport.java index 68faba7bfe1..d6e4519f013 100644 --- a/jdk/src/java.base/share/classes/sun/misc/VMSupport.java +++ b/jdk/src/java.base/share/classes/jdk/internal/vm/VMSupport.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package sun.misc; +package jdk.internal.vm; import java.io.ByteArrayOutputStream; import java.io.IOException; diff --git a/jdk/src/java.base/share/classes/module-info.java b/jdk/src/java.base/share/classes/module-info.java index e13a95739f3..2d1aae28616 100644 --- a/jdk/src/java.base/share/classes/module-info.java +++ b/jdk/src/java.base/share/classes/module-info.java @@ -86,8 +86,7 @@ module java.base { // see JDK-8044773 exports jdk.net; - // These will move to a jdk.internal module via JEP-260 - exports sun.misc; + // This will move to a jdk.internal module via JEP-260 exports sun.reflect; @@ -173,6 +172,7 @@ module java.base { java.xml, jdk.charsets, jdk.scripting.nashorn, + jdk.unsupported, jdk.vm.ci; exports jdk.internal.perf to java.desktop, @@ -180,15 +180,18 @@ module java.base { jdk.jvmstat; exports jdk.internal.ref to java.desktop; + exports jdk.internal.vm.annotation to + jdk.unsupported; exports jdk.internal.util.jar to jdk.jartool; + exports jdk.internal.vm to + java.management, + jdk.jvmstat; exports sun.net to java.httpclient; exports sun.net.dns to java.security.jgss, jdk.naming.dns; - exports sun.net.spi.nameservice to - jdk.naming.dns; exports sun.net.util to java.desktop, jdk.jconsole, @@ -281,7 +284,6 @@ module java.base { // JDK-internal service types uses jdk.internal.logger.DefaultLoggerFinder; - uses sun.net.spi.nameservice.NameServiceDescriptor; uses sun.security.ssl.ClientKeyExchangeService; uses sun.util.spi.CalendarProvider; uses sun.util.locale.provider.LocaleDataMetaInfo; diff --git a/jdk/src/java.base/share/classes/sun/misc/CRC16.java b/jdk/src/java.base/share/classes/sun/misc/CRC16.java deleted file mode 100644 index 3ec66a0fb24..00000000000 --- a/jdk/src/java.base/share/classes/sun/misc/CRC16.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 1994, 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. 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.misc; - -/** - * The CRC-16 class calculates a 16 bit cyclic redundancy check of a set - * of bytes. This error detecting code is used to determine if bit rot - * has occurred in a byte stream. - */ - -public class CRC16 { - - /** value contains the currently computed CRC, set it to 0 initally */ - public int value; - - public CRC16() { - value = 0; - } - - /** update CRC with byte b */ - public void update(byte aByte) { - int a, b; - - a = (int) aByte; - for (int count = 7; count >=0; count--) { - a = a << 1; - b = (a >>> 8) & 1; - if ((value & 0x8000) != 0) { - value = ((value << 1) + b) ^ 0x1021; - } else { - value = (value << 1) + b; - } - } - value = value & 0xffff; - return; - } - - /** reset CRC value to 0 */ - public void reset() { - value = 0; - } -} diff --git a/jdk/src/java.base/share/classes/sun/misc/Cache.java b/jdk/src/java.base/share/classes/sun/misc/Cache.java deleted file mode 100644 index fb0a9ea8724..00000000000 --- a/jdk/src/java.base/share/classes/sun/misc/Cache.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * 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.misc; - -import java.lang.ref.SoftReference; -import java.util.Dictionary; -import java.util.Enumeration; -import java.util.NoSuchElementException; - -/** - * Caches the collision list. - */ -class CacheEntry { - int hash; - Object key; - CacheEntry next; - SoftReference value; - - public CacheEntry() { - value = null; - } - - public CacheEntry(Object o) { - value = new SoftReference<>(o); - } - - public Object get() { - return value.get(); - } - - public void setThing(Object thing) { - value = new SoftReference<>(thing); - } -} - -/** - * The Cache class. Maps keys to values. Any object can be used as - * a key and/or value. This is very similar to the Hashtable - * class, except that after putting an object into the Cache, - * it is not guaranteed that a subsequent get will return it. - * The Cache will automatically remove entries if memory is - * getting tight and if the entry is not referenced from outside - * the Cache.

    - * - * To sucessfully store and retrieve objects from a hash table the - * object used as the key must implement the hashCode() and equals() - * methods.

    - * - * This example creates a Cache of numbers. It uses the names of - * the numbers as keys: - *

    - *      Cache numbers = new Cache();
    - *      numbers.put("one", new Integer(1));
    - *      numbers.put("two", new Integer(1));
    - *      numbers.put("three", new Integer(1));
    - * 
    - * To retrieve a number use: - *
    - *      Integer n = (Integer)numbers.get("two");
    - *      if (n != null) {
    - *          System.out.println("two = " + n);
    - *      }
    - * 
    - * - * @see java.lang.Object#hashCode - * @see java.lang.Object#equals - * @deprecated Consider {@link java.util.LinkedHashMap} for LRU caches. - */ -@Deprecated -public - class Cache extends Dictionary { - /** - * The hash table data. - */ - private CacheEntry table[]; - - /** - * The total number of entries in the hash table. - */ - private int count; - - /** - * Rehashes the table when count exceeds this threshold. - */ - private int threshold; - - /** - * The load factor for the hashtable. - */ - private float loadFactor; - - private void init(int initialCapacity, float loadFactor) { - if ((initialCapacity <= 0) || (loadFactor <= 0.0)) { - throw new IllegalArgumentException(); - } - this.loadFactor = loadFactor; - table = new CacheEntry[initialCapacity]; - threshold = (int) (initialCapacity * loadFactor); - } - - /** - * Constructs a new, empty Cache with the specified initial - * capacity and the specified load factor. - * @param initialCapacity the initial number of buckets - * @param loadFactor a number between 0.0 and 1.0, it defines - * the threshold for rehashing the Cache into - * a bigger one. - * @exception IllegalArgumentException If the initial capacity - * is less than or equal to zero. - * @exception IllegalArgumentException If the load factor is - * less than or equal to zero. - */ - public Cache (int initialCapacity, float loadFactor) { - init(initialCapacity, loadFactor); - } - - /** - * Constructs a new, empty Cache with the specified initial - * capacity. - * @param initialCapacity the initial number of buckets - */ - public Cache (int initialCapacity) { - init(initialCapacity, 0.75f); - } - - /** - * Constructs a new, empty Cache. A default capacity and load factor - * is used. Note that the Cache will automatically grow when it gets - * full. - */ - public Cache () { - try { - init(101, 0.75f); - } catch (IllegalArgumentException ex) { - // This should never happen - throw new Error("panic"); - } - } - - /** - * Returns the number of elements contained within the Cache. - */ - public int size() { - return count; - } - - /** - * Returns true if the Cache contains no elements. - */ - public boolean isEmpty() { - return count == 0; - } - - /** - * Returns an enumeration of the Cache's keys. - * @see Cache#elements - * @see Enumeration - */ - public synchronized Enumeration keys() { - return new CacheEnumerator(table, true); - } - - /** - * Returns an enumeration of the elements. Use the Enumeration methods - * on the returned object to fetch the elements sequentially. - * @see Cache#keys - * @see Enumeration - */ - public synchronized Enumeration elements() { - return new CacheEnumerator(table, false); - } - - /** - * Gets the object associated with the specified key in the Cache. - * @param key the key in the hash table - * @return the element for the key or null if the key - * is not defined in the hash table. - * @see Cache#put - */ - public synchronized Object get(Object key) { - CacheEntry tab[] = table; - int hash = key.hashCode(); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (CacheEntry e = tab[index]; e != null; e = e.next) { - if ((e.hash == hash) && e.key.equals(key)) { - return e.get(); - } - } - return null; - } - - /** - * Rehashes the contents of the table into a bigger table. - * This is method is called automatically when the Cache's - * size exceeds the threshold. - */ - protected void rehash() { - int oldCapacity = table.length; - CacheEntry oldTable[] = table; - - int newCapacity = oldCapacity * 2 + 1; - CacheEntry newTable[] = new CacheEntry[newCapacity]; - - threshold = (int) (newCapacity * loadFactor); - table = newTable; - - // System.out.println("rehash old=" + oldCapacity + ", new=" + - // newCapacity + ", thresh=" + threshold + ", count=" + count); - - for (int i = oldCapacity; i-- > 0;) { - for (CacheEntry old = oldTable[i]; old != null;) { - CacheEntry e = old; - old = old.next; - if (e.get() != null) { - int index = (e.hash & 0x7FFFFFFF) % newCapacity; - e.next = newTable[index]; - newTable[index] = e; - } else - count--; /* remove entries that have disappeared */ - } - } - } - - /** - * Puts the specified element into the Cache, using the specified - * key. The element may be retrieved by doing a get() with the same - * key. The key and the element cannot be null. - * @param key the specified hashtable key - * @param value the specified element - * @return the old value of the key, or null if it did not have one. - * @exception NullPointerException If the value of the specified - * element is null. - * @see Cache#get - */ - public synchronized Object put(Object key, Object value) { - // Make sure the value is not null - if (value == null) { - throw new NullPointerException(); - } - // Makes sure the key is not already in the cache. - CacheEntry tab[] = table; - int hash = key.hashCode(); - int index = (hash & 0x7FFFFFFF) % tab.length; - CacheEntry ne = null; - for (CacheEntry e = tab[index]; e != null; e = e.next) { - if ((e.hash == hash) && e.key.equals(key)) { - Object old = e.get(); - e.setThing(value); - return old; - } else if (e.get() == null) - ne = e; /* reuse old flushed value */ - } - - if (count >= threshold) { - // Rehash the table if the threshold is exceeded - rehash(); - return put(key, value); - } - // Creates the new entry. - if (ne == null) { - ne = new CacheEntry (); - ne.next = tab[index]; - tab[index] = ne; - count++; - } - ne.hash = hash; - ne.key = key; - ne.setThing(value); - return null; - } - - /** - * Removes the element corresponding to the key. Does nothing if the - * key is not present. - * @param key the key that needs to be removed - * @return the value of key, or null if the key was not found. - */ - public synchronized Object remove(Object key) { - CacheEntry tab[] = table; - int hash = key.hashCode(); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (CacheEntry e = tab[index], prev = null; e != null; prev = e, e = e.next) { - if ((e.hash == hash) && e.key.equals(key)) { - if (prev != null) { - prev.next = e.next; - } else { - tab[index] = e.next; - } - count--; - return e.get(); - } - } - return null; - } -} - -/** - * A Cache enumerator class. This class should remain opaque - * to the client. It will use the Enumeration interface. - */ -class CacheEnumerator implements Enumeration { - boolean keys; - int index; - CacheEntry table[]; - CacheEntry entry; - - CacheEnumerator (CacheEntry table[], boolean keys) { - this.table = table; - this.keys = keys; - this.index = table.length; - } - - public boolean hasMoreElements() { - while (index >= 0) { - while (entry != null) - if (entry.get() != null) - return true; - else - entry = entry.next; - while (--index >= 0 && (entry = table[index]) == null) ; - } - return false; - } - - public Object nextElement() { - while (index >= 0) { - if (entry == null) - while (--index >= 0 && (entry = table[index]) == null) ; - if (entry != null) { - CacheEntry e = entry; - entry = e.next; - if (e.get() != null) - return keys ? e.key : e.get(); - } - } - throw new NoSuchElementException("CacheEnumerator"); - } - -} diff --git a/jdk/src/java.base/share/classes/sun/net/TransferProtocolClient.java b/jdk/src/java.base/share/classes/sun/net/TransferProtocolClient.java index b3a9fd556e6..daa929ad3ef 100644 --- a/jdk/src/java.base/share/classes/sun/net/TransferProtocolClient.java +++ b/jdk/src/java.base/share/classes/sun/net/TransferProtocolClient.java @@ -83,7 +83,7 @@ public class TransferProtocolClient extends NetworkClient { code = Integer.parseInt(response, 0, 3, 10); } catch (NumberFormatException e) { code = -1; - } catch (StringIndexOutOfBoundsException e) { + } catch (IndexOutOfBoundsException e) { /* this line doesn't contain a response code, so we just completely ignore it */ continue; diff --git a/jdk/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java b/jdk/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java index f21217c58c5..7791f679ec3 100644 --- a/jdk/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java +++ b/jdk/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java @@ -440,7 +440,7 @@ public class FtpClient extends sun.net.ftp.FtpClient { code = Integer.parseInt(response, 0, 3, 10); } catch (NumberFormatException e) { code = -1; - } catch (StringIndexOutOfBoundsException e) { + } catch (IndexOutOfBoundsException e) { /* this line doesn't contain a response code, so we just completely ignore it */ continue; diff --git a/jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java b/jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java index 4f8fde23876..38d64d23009 100644 --- a/jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java +++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -299,6 +299,13 @@ public class FtpURLConnection extends URLConnection { // Just keep throwing for now. throw e; } catch (FtpProtocolException fe) { + if (ftp != null) { + try { + ftp.close(); + } catch (IOException ioe) { + fe.addSuppressed(ioe); + } + } throw new IOException(fe); } try { @@ -481,11 +488,34 @@ public class FtpURLConnection extends URLConnection { msgh.add("content-type", "text/plain"); msgh.add("access-type", "directory"); } catch (IOException ex) { - throw new FileNotFoundException(fullpath); + FileNotFoundException fnfe = new FileNotFoundException(fullpath); + if (ftp != null) { + try { + ftp.close(); + } catch (IOException ioe) { + fnfe.addSuppressed(ioe); + } + } + throw fnfe; } catch (FtpProtocolException ex2) { - throw new FileNotFoundException(fullpath); + FileNotFoundException fnfe = new FileNotFoundException(fullpath); + if (ftp != null) { + try { + ftp.close(); + } catch (IOException ioe) { + fnfe.addSuppressed(ioe); + } + } + throw fnfe; } } catch (FtpProtocolException ftpe) { + if (ftp != null) { + try { + ftp.close(); + } catch (IOException ioe) { + ftpe.addSuppressed(ioe); + } + } throw new IOException(ftpe); } setProperties(msgh); diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/AbstractPollArrayWrapper.java b/jdk/src/java.base/share/classes/sun/nio/ch/AbstractPollArrayWrapper.java index 0f1c594fd7f..c25ec92b88e 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/AbstractPollArrayWrapper.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/AbstractPollArrayWrapper.java @@ -25,8 +25,6 @@ package sun.nio.ch; -import sun.misc.*; - /** * Manipulates a native array of pollfd structs. diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java b/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java index b49723aa462..99eaf14dec3 100644 --- a/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java +++ b/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java @@ -1198,8 +1198,9 @@ class DH_ServerKeyExchange extends ServerKeyExchange if (!localSupportedSignAlgs.contains( preferableSignatureAlgorithm)) { throw new SSLHandshakeException( - "Unsupported SignatureAndHashAlgorithm in " + - "ServerKeyExchange message"); + "Unsupported SignatureAndHashAlgorithm in " + + "ServerKeyExchange message: " + + preferableSignatureAlgorithm); } } else { this.preferableSignatureAlgorithm = null; @@ -1232,7 +1233,8 @@ class DH_ServerKeyExchange extends ServerKeyExchange sig = RSASignature.getInstance(); break; default: - throw new SSLKeyException("neither an RSA or a DSA key"); + throw new SSLKeyException( + "neither an RSA or a DSA key: " + algorithm); } } @@ -1482,7 +1484,8 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange { preferableSignatureAlgorithm)) { throw new SSLHandshakeException( "Unsupported SignatureAndHashAlgorithm in " + - "ServerKeyExchange message"); + "ServerKeyExchange message: " + + preferableSignatureAlgorithm); } } @@ -1522,7 +1525,8 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange { case "RSA": return RSASignature.getInstance(); default: - throw new NoSuchAlgorithmException("neither an RSA or a EC key"); + throw new NoSuchAlgorithmException( + "neither an RSA or a EC key : " + keyAlgorithm); } } @@ -1729,7 +1733,8 @@ class CertificateRequest extends HandshakeMessage algorithmsLen = input.getInt16(); if (algorithmsLen < 2) { throw new SSLProtocolException( - "Invalid supported_signature_algorithms field"); + "Invalid supported_signature_algorithms field: " + + algorithmsLen); } algorithms = new ArrayList(); @@ -1748,7 +1753,8 @@ class CertificateRequest extends HandshakeMessage if (remains != 0) { throw new SSLProtocolException( - "Invalid supported_signature_algorithms field"); + "Invalid supported_signature_algorithms field. remains: " + + remains); } } else { algorithms = new ArrayList(); @@ -1765,7 +1771,8 @@ class CertificateRequest extends HandshakeMessage } if (len != 0) { - throw new SSLProtocolException("Bad CertificateRequest DN length"); + throw new SSLProtocolException( + "Bad CertificateRequest DN length: " + len); } authorities = v.toArray(new DistinguishedName[v.size()]); @@ -1995,8 +2002,8 @@ static final class CertificateVerify extends HandshakeMessage { if (!localSupportedSignAlgs.contains( preferableSignatureAlgorithm)) { throw new SSLHandshakeException( - "Unsupported SignatureAndHashAlgorithm in " + - "CertificateVerify message"); + "Unsupported SignatureAndHashAlgorithm in " + + "CertificateVerify message: " + preferableSignatureAlgorithm); } } @@ -2364,7 +2371,8 @@ static final class Finished extends HandshakeMessage { SecretKey prfKey = kg.generateKey(); if ("RAW".equals(prfKey.getFormat()) == false) { throw new ProviderException( - "Invalid PRF output, format must be RAW"); + "Invalid PRF output, format must be RAW. " + + "Format received: " + prfKey.getFormat()); } byte[] finished = prfKey.getEncoded(); return finished; diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/RSAClientKeyExchange.java b/jdk/src/java.base/share/classes/sun/security/ssl/RSAClientKeyExchange.java index 7b8387fb684..38a942d03b7 100644 --- a/jdk/src/java.base/share/classes/sun/security/ssl/RSAClientKeyExchange.java +++ b/jdk/src/java.base/share/classes/sun/security/ssl/RSAClientKeyExchange.java @@ -68,7 +68,8 @@ final class RSAClientKeyExchange extends HandshakeMessage { ProtocolVersion maxVersion, SecureRandom generator, PublicKey publicKey) throws IOException { if (publicKey.getAlgorithm().equals("RSA") == false) { - throw new SSLKeyException("Public key not of type RSA"); + throw new SSLKeyException("Public key not of type RSA: " + + publicKey.getAlgorithm()); } this.protocolVersion = protocolVersion; @@ -100,7 +101,8 @@ final class RSAClientKeyExchange extends HandshakeMessage { int messageSize, PrivateKey privateKey) throws IOException { if (privateKey.getAlgorithm().equals("RSA") == false) { - throw new SSLKeyException("Private key not of type RSA"); + throw new SSLKeyException("Private key not of type RSA: " + + privateKey.getAlgorithm()); } if (currentVersion.useTLS10PlusSpec()) { @@ -161,8 +163,8 @@ final class RSAClientKeyExchange extends HandshakeMessage { } } catch (InvalidKeyException ibk) { // the message is too big to process with RSA - throw new SSLProtocolException( - "Unable to process PreMasterSecret, may be too big"); + throw new SSLException( + "Unable to process PreMasterSecret", ibk); } catch (Exception e) { // unlikely to happen, otherwise, must be a provider exception if (debug != null && Debug.isOn("handshake")) { diff --git a/jdk/src/java.base/share/native/libjava/VMSupport.c b/jdk/src/java.base/share/native/libjava/VMSupport.c index eb4ab4b2240..560a0053f10 100644 --- a/jdk/src/java.base/share/native/libjava/VMSupport.c +++ b/jdk/src/java.base/share/native/libjava/VMSupport.c @@ -27,36 +27,17 @@ #include "jni_util.h" #include "jlong.h" #include "jvm.h" -#include "jdk_util.h" -#include "sun_misc_VMSupport.h" - -typedef jobject (JNICALL *INIT_AGENT_PROPERTIES_FN)(JNIEnv *, jobject); - -static INIT_AGENT_PROPERTIES_FN InitAgentProperties_fp = NULL; +#include "jdk_internal_vm_VMSupport.h" JNIEXPORT jobject JNICALL -Java_sun_misc_VMSupport_initAgentProperties(JNIEnv *env, jclass cls, jobject props) +Java_jdk_internal_vm_VMSupport_initAgentProperties(JNIEnv *env, jclass cls, jobject props) { - if (InitAgentProperties_fp == NULL) { - if (!JDK_InitJvmHandle()) { - JNU_ThrowInternalError(env, - "Handle for JVM not found for symbol lookup"); - return NULL; - } - InitAgentProperties_fp = (INIT_AGENT_PROPERTIES_FN) - JDK_FindJvmEntry("JVM_InitAgentProperties"); - if (InitAgentProperties_fp == NULL) { - JNU_ThrowInternalError(env, - "Mismatched VM version: JVM_InitAgentProperties not found"); - return NULL; - } - } - return (*InitAgentProperties_fp)(env, props); + return JVM_InitAgentProperties(env, props); } JNIEXPORT jstring JNICALL -Java_sun_misc_VMSupport_getVMTemporaryDirectory(JNIEnv *env, jclass cls) +Java_jdk_internal_vm_VMSupport_getVMTemporaryDirectory(JNIEnv *env, jclass cls) { return JVM_GetTemporaryDirectory(env); } diff --git a/jdk/src/java.base/share/native/libjava/jdk_util.c b/jdk/src/java.base/share/native/libjava/jdk_util.c index 7d13403d326..f7f55ad37e0 100644 --- a/jdk/src/java.base/share/native/libjava/jdk_util.c +++ b/jdk/src/java.base/share/native/libjava/jdk_util.c @@ -47,7 +47,7 @@ JDK_GetVersionInfo0(jdk_version_info* info, size_t info_size) { (version_build & 0xFF); info->patch_version = version_patch; info->thread_park_blocker = 1; - // Advertise presence of sun.misc.PostVMInitHook: + // Advertise presence of PostVMInitHook: // future optimization: detect if this is enabled. info->post_vm_init_hook_enabled = 1; info->pending_list_uses_discovered_field = 1; diff --git a/jdk/src/java.base/share/native/libjli/java.c b/jdk/src/java.base/share/native/libjli/java.c index 9fd3ffd5c1c..66ac6ce907f 100644 --- a/jdk/src/java.base/share/native/libjli/java.c +++ b/jdk/src/java.base/share/native/libjli/java.c @@ -2003,16 +2003,21 @@ ShowSplashScreen() void *image_data = NULL; float scale_factor = 1; char *scaled_splash_name = NULL; - + jboolean isImageScaled = JNI_FALSE; + size_t maxScaledImgNameLength = 0; if (file_name == NULL){ return; } + maxScaledImgNameLength = DoSplashGetScaledImgNameMaxPstfixLen(file_name); - scaled_splash_name = DoSplashGetScaledImageName( - jar_name, file_name, &scale_factor); + scaled_splash_name = JLI_MemAlloc( + maxScaledImgNameLength * sizeof(char)); + isImageScaled = DoSplashGetScaledImageName(jar_name, file_name, + &scale_factor, + scaled_splash_name, maxScaledImgNameLength); if (jar_name) { - if (scaled_splash_name) { + if (isImageScaled) { image_data = JLI_JarUnpackFile( jar_name, scaled_splash_name, &data_size); } @@ -2030,17 +2035,14 @@ ShowSplashScreen() } } else { DoSplashInit(); - if (scaled_splash_name) { + if (isImageScaled) { DoSplashSetScaleFactor(scale_factor); DoSplashLoadFile(scaled_splash_name); } else { DoSplashLoadFile(file_name); } } - - if (scaled_splash_name) { - JLI_MemFree(scaled_splash_name); - } + JLI_MemFree(scaled_splash_name); DoSplashSetFileJarName(file_name, jar_name); diff --git a/jdk/src/java.base/share/native/libjli/splashscreen.h b/jdk/src/java.base/share/native/libjli/splashscreen.h index 3afd68c71e2..5fc296acfb3 100644 --- a/jdk/src/java.base/share/native/libjli/splashscreen.h +++ b/jdk/src/java.base/share/native/libjli/splashscreen.h @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ - +#include "jni.h" int DoSplashLoadMemory(void* pdata, int size); /* requires preloading the file */ int DoSplashLoadFile(const char* filename); @@ -30,5 +30,6 @@ void DoSplashInit(void); void DoSplashClose(void); void DoSplashSetFileJarName(const char* fileName, const char* jarName); void DoSplashSetScaleFactor(float scaleFactor); -char* DoSplashGetScaledImageName(const char* jarName, const char* fileName, - float* scaleFactor); +jboolean DoSplashGetScaledImageName(const char* jarName, const char* fileName, + float* scaleFactor, char *scaleImageName, const size_t scaleImageNameLength); +int DoSplashGetScaledImgNameMaxPstfixLen(const char *fileName); diff --git a/jdk/src/java.base/share/native/libjli/splashscreen_stubs.c b/jdk/src/java.base/share/native/libjli/splashscreen_stubs.c index f741ccf807a..9ae76c95e58 100644 --- a/jdk/src/java.base/share/native/libjli/splashscreen_stubs.c +++ b/jdk/src/java.base/share/native/libjli/splashscreen_stubs.c @@ -25,7 +25,7 @@ #include #include "splashscreen.h" - +#include "jni.h" extern void* SplashProcAddress(const char* name); /* in java_md.c */ /* @@ -38,8 +38,10 @@ typedef void (*SplashClose_t)(void); typedef void (*SplashSetFileJarName_t)(const char* fileName, const char* jarName); typedef void (*SplashSetScaleFactor_t)(float scaleFactor); -typedef char* (*SplashGetScaledImageName_t)(const char* fileName, - const char* jarName, float* scaleFactor); +typedef jboolean (*SplashGetScaledImageName_t)(const char* fileName, + const char* jarName, float* scaleFactor, + char *scaleImageName, const size_t scaleImageNameLength); +typedef int (*SplashGetScaledImgNameMaxPstfixLen_t)(const char* filename); /* * This macro invokes a function from the shared lib. @@ -60,6 +62,7 @@ typedef char* (*SplashGetScaledImageName_t)(const char* fileName, #define INVOKE(name,def) _INVOKE(name,def,return) #define INVOKEV(name) _INVOKE(name, ,;) + int DoSplashLoadMemory(void* pdata, int size) { INVOKE(SplashLoadMemory, 0)(pdata, size); } @@ -84,7 +87,13 @@ void DoSplashSetScaleFactor(float scaleFactor) { INVOKEV(SplashSetScaleFactor)(scaleFactor); } -char* DoSplashGetScaledImageName(const char* fileName, const char* jarName, - float* scaleFactor) { - INVOKE(SplashGetScaledImageName, NULL)(fileName, jarName, scaleFactor); +jboolean DoSplashGetScaledImageName(const char* fileName, const char* jarName, + float* scaleFactor, char *scaledImageName, const size_t scaledImageNameLength) { + INVOKE(SplashGetScaledImageName, 0)(fileName, jarName, scaleFactor, + scaledImageName, scaledImageNameLength); } + +int DoSplashGetScaledImgNameMaxPstfixLen(const char *fileName) { + INVOKE(SplashGetScaledImgNameMaxPstfixLen, 0)(fileName); +} + diff --git a/jdk/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java b/jdk/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java index 81db74f09e3..06c5e656512 100644 --- a/jdk/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java +++ b/jdk/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java @@ -29,7 +29,6 @@ import java.io.IOException; import java.nio.channels.*; import java.nio.channels.spi.*; import java.util.*; -import sun.misc.*; /** diff --git a/jdk/src/java.base/unix/classes/sun/nio/ch/PollArrayWrapper.java b/jdk/src/java.base/unix/classes/sun/nio/ch/PollArrayWrapper.java index 80eb14dc4f5..620455df8ad 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/ch/PollArrayWrapper.java +++ b/jdk/src/java.base/unix/classes/sun/nio/ch/PollArrayWrapper.java @@ -25,8 +25,6 @@ package sun.nio.ch; -import sun.misc.*; - /** * Manipulates a native array of pollfd structs on Solaris: diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixException.java b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixException.java index 22a41ebccc4..540578d8251 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixException.java +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -70,6 +70,12 @@ class UnixException extends Exception { return errorString(); } + @Override + public Throwable fillInStackTrace() { + // This is an internal exception; the stack trace is irrelevant. + return this; + } + /** * Map well known errors to specific exceptions where possible; otherwise * return more general FileSystemException. diff --git a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsException.java b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsException.java index 17e0fd258d7..1312d5a0938 100644 --- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsException.java +++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -69,6 +69,12 @@ class WindowsException extends Exception { return errorString(); } + @Override + public Throwable fillInStackTrace() { + // This is an internal exception; the stack trace is irrelevant. + return this; + } + private IOException translateToIOException(String file, String other) { // not created with last error if (lastError() == 0) diff --git a/jdk/src/java.compact3/share/classes/module-info.java b/jdk/src/java.compact3/share/classes/module-info.java index aff5c522263..cbc67be6319 100644 --- a/jdk/src/java.compact3/share/classes/module-info.java +++ b/jdk/src/java.compact3/share/classes/module-info.java @@ -26,7 +26,6 @@ module java.compact3 { requires public java.compact2; requires public java.compiler; - requires public java.httpclient; requires public java.instrument; requires public java.management; requires public java.naming; diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppEvent.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppEvent.java deleted file mode 100644 index 643351748cd..00000000000 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppEvent.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * 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.apple.eawt; - -import java.io.File; -import java.net.URI; -import java.util.*; -import java.awt.Window; - -/** - * AppEvents are sent to listeners and handlers installed on the {@link Application}. - * - * @since Java for Mac OS X 10.6 Update 3 - * @since Java for Mac OS X 10.5 Update 8 - */ -@SuppressWarnings("serial") // JDK implementation class -public abstract class AppEvent extends EventObject { - AppEvent() { - super(Application.getApplication()); - } - - /** - * Contains a list of files. - */ - @SuppressWarnings("serial") // JDK implementation class - public abstract static class FilesEvent extends AppEvent { - final List files; - - FilesEvent(final List files) { - this.files = files; - } - - /** - * @return the list of files - */ - public List getFiles() { - return files; - } - } - - /** - * Event sent when the app is asked to open a list of files. - * - * @see OpenFilesHandler#openFiles(OpenFilesEvent) - */ - @SuppressWarnings("serial") // JDK implementation class - public static class OpenFilesEvent extends FilesEvent { - final String searchTerm; - - OpenFilesEvent(final List files, final String searchTerm) { - super(files); - this.searchTerm = searchTerm; - } - - /** - * If the files were opened using the Spotlight search menu or a Finder search window, this method obtains the search term used to find the files. - * This is useful for highlighting the search term in the documents when they are opened. - * @return the search term used to find the files - */ - public String getSearchTerm() { - return searchTerm; - } - } - - /** - * Event sent when the app is asked to print a list of files. - * - * @see PrintFilesHandler#printFiles(PrintFilesEvent) - */ - @SuppressWarnings("serial") // JDK implementation class - public static class PrintFilesEvent extends FilesEvent { - PrintFilesEvent(final List files) { - super(files); - } - } - - /** - * Event sent when the app is asked to open a URI. - * - * @see OpenURIHandler#openURI(OpenURIEvent) - */ - @SuppressWarnings("serial") // JDK implementation class - public static class OpenURIEvent extends AppEvent { - final URI uri; - - OpenURIEvent(final URI uri) { - this.uri = uri; - } - - /** - * @return the URI the app was asked to open - */ - public URI getURI() { - return uri; - } - } - - /** - * Event sent when the application is asked to open it's about window. - * - * @see AboutHandler#handleAbout() - */ - @SuppressWarnings("serial") // JDK implementation class - public static class AboutEvent extends AppEvent { AboutEvent() { } } - - /** - * Event sent when the application is asked to open it's preferences window. - * - * @see PreferencesHandler#handlePreferences() - */ - @SuppressWarnings("serial") // JDK implementation class - public static class PreferencesEvent extends AppEvent { PreferencesEvent() { } } - - /** - * Event sent when the application is asked to quit. - * - * @see QuitHandler#handleQuitRequestWith(QuitEvent, QuitResponse) - */ - @SuppressWarnings("serial") // JDK implementation class - public static class QuitEvent extends AppEvent { QuitEvent() { } } - - /** - * Event sent when the application is asked to re-open itself. - * - * @see AppReOpenedListener#appReOpened(AppReOpenedEvent) - */ - @SuppressWarnings("serial") // JDK implementation class - public static class AppReOpenedEvent extends AppEvent { AppReOpenedEvent() { } } - - /** - * Event sent when the application has become the foreground app, and when it has resigned being the foreground app. - * - * @see AppForegroundListener#appRaisedToForeground(AppForegroundEvent) - * @see AppForegroundListener#appMovedToBackground(AppForegroundEvent) - */ - @SuppressWarnings("serial") // JDK implementation class - public static class AppForegroundEvent extends AppEvent { AppForegroundEvent() { } } - - /** - * Event sent when the application has been hidden or shown. - * - * @see AppHiddenListener#appHidden(AppHiddenEvent) - * @see AppHiddenListener#appUnhidden(AppHiddenEvent) - */ - @SuppressWarnings("serial") // JDK implementation class - public static class AppHiddenEvent extends AppEvent { AppHiddenEvent() { } } - - /** - * Event sent when the user session has been changed via Fast User Switching. - * - * @see UserSessionListener#userSessionActivated(UserSessionEvent) - * @see UserSessionListener#userSessionDeactivated(UserSessionEvent) - */ - @SuppressWarnings("serial") // JDK implementation class - public static class UserSessionEvent extends AppEvent { UserSessionEvent() { } } - - /** - * Event sent when the displays attached to the system enter and exit power save sleep. - * - * @see ScreenSleepListener#screenAboutToSleep(ScreenSleepEvent) - * @see ScreenSleepListener#screenAwoke(ScreenSleepEvent) - */ - @SuppressWarnings("serial") // JDK implementation class - public static class ScreenSleepEvent extends AppEvent { ScreenSleepEvent() { } } - - /** - * Event sent when the system enters and exits power save sleep. - * - * @see SystemSleepListener#systemAboutToSleep(SystemSleepEvent) - * @see SystemSleepListener#systemAwoke(SystemSleepEvent) - */ - @SuppressWarnings("serial") // JDK implementation class - public static class SystemSleepEvent extends AppEvent { SystemSleepEvent() { } } - - /** - * Event sent when a window is entering/exiting or has entered/exited full screen state. - * - * @see FullScreenUtilities - * - * @since Java for Mac OS X 10.7 Update 1 - */ - @SuppressWarnings("serial") // JDK implementation class - public static class FullScreenEvent extends AppEvent { - final Window window; - - FullScreenEvent(final Window window) { - this.window = window; - } - - /** - * @return window transitioning between full screen states - */ - public Window getWindow() { - return window; - } - } -} diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppReOpenedListener.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppReOpenedListener.java deleted file mode 100644 index dd5ac146514..00000000000 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppReOpenedListener.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. 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.apple.eawt; - -import com.apple.eawt.AppEvent.AppReOpenedEvent; - -/** - * Implementors receive notification when the app has been asked to open again. - * Re-open events occur when the user clicks on the running app's Dock icon. - * Re-open events also occur when the app is double-clicked in the Finder and the app is already running. - * - * This notification is useful for showing a new document when your app has no open windows. - * - * @see Application#addAppEventListener(AppEventListener) - * - * @since Java for Mac OS X 10.6 Update 3 - * @since Java for Mac OS X 10.5 Update 8 - */ -public interface AppReOpenedListener extends AppEventListener { - /** - * Called when the app has been re-opened (it's Dock icon was clicked on, or was double-clicked in the Finder) - * @param e the request to re-open the app - */ - public void appReOpened(final AppReOpenedEvent e); -} diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/Application.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/Application.java index 3535b4ae3d6..8ad28ebb9b7 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/Application.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/Application.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -26,10 +26,10 @@ package com.apple.eawt; import java.awt.Image; -import java.awt.Point; import java.awt.PopupMenu; import java.awt.Toolkit; import java.awt.Window; +import java.awt.desktop.*; import java.beans.Beans; import javax.swing.JMenuBar; @@ -104,38 +104,38 @@ public class Application { } /** - * Adds sub-types of {@link AppEventListener} to listen for notifications from the native Mac OS X system. + * Adds sub-types of {@link SystemEventListener} to listen for notifications from the native Mac OS X system. * * @see AppForegroundListener * @see AppHiddenListener * @see AppReOpenedListener - * @see ScreenSleepListener - * @see SystemSleepListener - * @see UserSessionListener + * @see AppScreenSleepListener + * @see AppSystemSleepListener + * @see AppUserSessionListener * * @param listener * @since Java for Mac OS X 10.6 Update 3 * @since Java for Mac OS X 10.5 Update 8 */ - public void addAppEventListener(final AppEventListener listener) { + public void addAppEventListener(final SystemEventListener listener) { eventHandler.addListener(listener); } /** - * Removes sub-types of {@link AppEventListener} from listening for notifications from the native Mac OS X system. + * Removes sub-types of {@link SystemEventListener} from listening for notifications from the native Mac OS X system. * * @see AppForegroundListener * @see AppHiddenListener * @see AppReOpenedListener - * @see ScreenSleepListener - * @see SystemSleepListener - * @see UserSessionListener + * @see AppScreenSleepListener + * @see AppSystemSleepListener + * @see AppUserSessionListener * * @param listener * @since Java for Mac OS X 10.6 Update 3 * @since Java for Mac OS X 10.5 Update 8 */ - public void removeAppEventListener(final AppEventListener listener) { + public void removeAppEventListener(final SystemEventListener listener) { eventHandler.removeListener(listener); } @@ -367,6 +367,17 @@ public class Application { iconHandler.setDockIconBadge(badge); } + /** + * Displays a progress bar to this application's Dock icon. + * Acceptable values are from 0 to 100, any other disables progress indication. + * + * @param value progress value + * @since 1.9 + */ + public void setDockIconProgress(final int value) { + iconHandler.setDockIconProgress(value); + } + /** * Sets the default menu bar to use when there are no active frames. * Only used when the system property "apple.laf.useScreenMenuBar" is "true", and @@ -397,168 +408,4 @@ public class Application { ((CPlatformWindow)platformWindow).toggleFullScreen(); } - - // -- DEPRECATED API -- - - /** - * Adds the specified ApplicationListener as a receiver of callbacks from this class. - * This method throws a RuntimeException if the newer About, Preferences, Quit, etc handlers are installed. - * - * @param listener an implementation of ApplicationListener that handles ApplicationEvents - * - * @deprecated register individual handlers for each task (About, Preferences, Open, Print, Quit, etc) - * @since 1.4 - */ - @SuppressWarnings("deprecation") - @Deprecated - public void addApplicationListener(final ApplicationListener listener) { - eventHandler.legacyHandler.addLegacyAppListener(listener); - } - - /** - * Removes the specified ApplicationListener from being a receiver of callbacks from this class. - * This method throws a RuntimeException if the newer About, Preferences, Quit, etc handlers are installed. - * - * @param listener an implementation of ApplicationListener that had previously been registered to handle ApplicationEvents - * - * @deprecated unregister individual handlers for each task (About, Preferences, Open, Print, Quit, etc) - * @since 1.4 - */ - @SuppressWarnings("deprecation") - @Deprecated - public void removeApplicationListener(final ApplicationListener listener) { - eventHandler.legacyHandler.removeLegacyAppListener(listener); - } - - /** - * Enables the Preferences item in the application menu. The ApplicationListener receives a callback for - * selection of the Preferences item in the application menu only if this is set to {@code true}. - * - * If a Preferences item isn't present, this method adds and enables it. - * - * @param enable specifies whether the Preferences item in the application menu should be enabled ({@code true}) or not ({@code false}) - * - * @deprecated no replacement - * @since 1.4 - */ - @Deprecated - public void setEnabledPreferencesMenu(final boolean enable) { - menuBarHandler.setPreferencesMenuItemVisible(true); - menuBarHandler.setPreferencesMenuItemEnabled(enable); - } - - /** - * Enables the About item in the application menu. The ApplicationListener receives a callback for - * selection of the About item in the application menu only if this is set to {@code true}. Because AWT supplies - * a standard About window when an application may not, by default this is set to {@code true}. - * - * If the About item isn't present, this method adds and enables it. - * - * @param enable specifies whether the About item in the application menu should be enabled ({@code true}) or not ({@code false}) - * - * @deprecated no replacement - * @since 1.4 - */ - @Deprecated - public void setEnabledAboutMenu(final boolean enable) { - menuBarHandler.setAboutMenuItemEnabled(enable); - } - - /** - * Determines if the Preferences item of the application menu is enabled. - * - * @deprecated no replacement - * @since 1.4 - */ - @Deprecated - public boolean getEnabledPreferencesMenu() { - return menuBarHandler.isPreferencesMenuItemEnabled(); - } - - /** - * Determines if the About item of the application menu is enabled. - * - * @deprecated no replacement - * @since 1.4 - */ - @Deprecated - public boolean getEnabledAboutMenu() { - return menuBarHandler.isAboutMenuItemEnabled(); - } - - /** - * Determines if the About item of the application menu is present. - * - * @deprecated no replacement - * @since 1.4 - */ - @Deprecated - public boolean isAboutMenuItemPresent() { - return menuBarHandler.isAboutMenuItemVisible(); - } - - /** - * Adds the About item to the application menu if the item is not already present. - * - * @deprecated use {@link #setAboutHandler(AboutHandler)} with a non-null {@link AboutHandler} parameter - * @since 1.4 - */ - @Deprecated - public void addAboutMenuItem() { - menuBarHandler.setAboutMenuItemVisible(true); - } - - /** - * Removes the About item from the application menu if the item is present. - * - * @deprecated use {@link #setAboutHandler(AboutHandler)} with a null parameter - * @since 1.4 - */ - @Deprecated - public void removeAboutMenuItem() { - menuBarHandler.setAboutMenuItemVisible(false); - } - - /** - * Determines if the About Preferences of the application menu is present. By default there is no Preferences menu item. - * - * @deprecated no replacement - * @since 1.4 - */ - @Deprecated - public boolean isPreferencesMenuItemPresent() { - return menuBarHandler.isPreferencesMenuItemVisible(); - } - - /** - * Adds the Preferences item to the application menu if the item is not already present. - * - * @deprecated use {@link #setPreferencesHandler(PreferencesHandler)} with a non-null {@link PreferencesHandler} parameter - * @since 1.4 - */ - @Deprecated - public void addPreferencesMenuItem() { - menuBarHandler.setPreferencesMenuItemVisible(true); - } - - /** - * Removes the Preferences item from the application menu if that item is present. - * - * @deprecated use {@link #setPreferencesHandler(PreferencesHandler)} with a null parameter - * @since 1.4 - */ - @Deprecated - public void removePreferencesMenuItem() { - menuBarHandler.setPreferencesMenuItemVisible(false); - } - - /** - * @deprecated Use {@code java.awt.MouseInfo.getPointerInfo().getLocation()}. - * - * @since 1.4 - */ - @Deprecated - public static Point getMouseLocationOnScreen() { - return java.awt.MouseInfo.getPointerInfo().getLocation(); - } } diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationAdapter.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationAdapter.java index 17339373153..aba03e9f744 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationAdapter.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -46,7 +46,7 @@ package com.apple.eawt; * @see ScreenSleepListener * @see SystemSleepListener * - * @deprecated replaced by {@link AboutHandler}, {@link PreferencesHandler}, {@link AppReOpenedListener}, {@link OpenFilesHandler}, {@link PrintFilesHandler}, {@link QuitHandler}, {@link QuitResponse}. + * @deprecated replaced by {@link AboutHandler}, {@link PreferencesHandler}, {@link AppReOpenedListener}, {@link OpenFilesHandler}, {@link PrintFilesHandler}, {@link QuitHandler}, {@link MacQuitResponse}. * @since 1.4 */ @SuppressWarnings("deprecation") diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationEvent.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationEvent.java index 0cfe0741682..49617f6c852 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationEvent.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -30,7 +30,7 @@ import java.util.EventObject; /** * The class of events sent to the deprecated ApplicationListener callbacks. * - * @deprecated replaced by {@link AboutHandler}, {@link PreferencesHandler}, {@link AppReOpenedListener}, {@link OpenFilesHandler}, {@link PrintFilesHandler}, {@link QuitHandler}, {@link QuitResponse} + * @deprecated replaced by {@link AboutHandler}, {@link PreferencesHandler}, {@link AppReOpenedListener}, {@link OpenFilesHandler}, {@link PrintFilesHandler}, {@link QuitHandler}, {@link MacQuitResponse} * @since 1.4 */ @Deprecated diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationListener.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationListener.java index ea2efcf0ede..eabcb92aafe 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationListener.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -47,7 +47,7 @@ import java.util.EventListener; * @see SystemSleepListener * * @since 1.4 - * @deprecated replaced by {@link AboutHandler}, {@link PreferencesHandler}, {@link AppReOpenedListener}, {@link OpenFilesHandler}, {@link PrintFilesHandler}, {@link QuitHandler}, {@link QuitResponse} + * @deprecated replaced by {@link AboutHandler}, {@link PreferencesHandler}, {@link AppReOpenedListener}, {@link OpenFilesHandler}, {@link PrintFilesHandler}, {@link QuitHandler}, {@link MacQuitResponse} */ @SuppressWarnings("deprecation") @Deprecated @@ -134,7 +134,7 @@ public interface ApplicationListener extends EventListener { * {@code event}. To reject the quit, set {@code isHandled(false)}. * * @param event a Quit Application event - * @deprecated use {@link QuitHandler} and {@link QuitResponse} + * @deprecated use {@link QuitHandler} and {@link MacQuitResponse} */ @Deprecated public void handleQuit(ApplicationEvent event); diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenAdapter.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenAdapter.java index 8e60b7b0e2b..4a124da6e38 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenAdapter.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -25,7 +25,7 @@ package com.apple.eawt; -import com.apple.eawt.AppEvent.FullScreenEvent; +import com.apple.eawt.event.FullScreenEvent; /** * Abstract adapter class for receiving fullscreen events. This class is provided diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenHandler.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenHandler.java index 64e81b08a00..c1d36d8add2 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenHandler.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -25,13 +25,13 @@ package com.apple.eawt; +import com.apple.eawt.event.FullScreenEvent; import java.awt.*; import java.util.*; import java.util.List; import javax.swing.RootPaneContainer; -import com.apple.eawt.AppEvent.FullScreenEvent; import sun.awt.SunToolkit; import java.lang.annotation.Native; diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenListener.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenListener.java index 4872ad7646a..737a67f6f83 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenListener.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -25,9 +25,9 @@ package com.apple.eawt; +import com.apple.eawt.event.FullScreenEvent; import java.util.EventListener; -import com.apple.eawt.AppEvent.FullScreenEvent; /** * diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/QuitResponse.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/MacQuitResponse.java similarity index 86% rename from jdk/src/java.desktop/macosx/classes/com/apple/eawt/QuitResponse.java rename to jdk/src/java.desktop/macosx/classes/com/apple/eawt/MacQuitResponse.java index 18b4db5140f..ab37dfc93d9 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/QuitResponse.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/MacQuitResponse.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -25,9 +25,11 @@ package com.apple.eawt; +import java.awt.desktop.QuitResponse; + /** * Used to respond to a request to quit the application. - * The QuitResponse may be used after the {@link QuitHandler#handleQuitRequestWith(AppEvent.QuitEvent, QuitResponse)} method has returned, and may be used from any thread. + * The QuitResponse may be used after the {@link QuitHandler#handleQuitRequestWith(AppEvent.QuitEvent, MacQuitResponse)} method has returned, and may be used from any thread. * * @see Application#setQuitHandler(QuitHandler) * @see QuitHandler @@ -36,16 +38,17 @@ package com.apple.eawt; * @since Java for Mac OS X 10.6 Update 3 * @since Java for Mac OS X 10.5 Update 8 */ -public class QuitResponse { +public class MacQuitResponse implements QuitResponse { final _AppEventHandler appEventHandler; - QuitResponse(final _AppEventHandler appEventHandler) { + MacQuitResponse(final _AppEventHandler appEventHandler) { this.appEventHandler = appEventHandler; } /** * Notifies the external quit requester that the quit will proceed, and performs the default {@link QuitStrategy}. */ + @Override public void performQuit() { if (appEventHandler.currentQuitResponse != this) return; appEventHandler.performQuit(); @@ -55,6 +58,7 @@ public class QuitResponse { * Notifies the external quit requester that the user has explicitly canceled the pending quit, and leaves the application running. * Note: this will cancel a pending log-out, restart, or shutdown. */ + @Override public void cancelQuit() { if (appEventHandler.currentQuitResponse != this) return; appEventHandler.cancelQuit(); diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/OpenURIHandler.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/OpenURIHandler.java deleted file mode 100644 index 1964344f94a..00000000000 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/OpenURIHandler.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. 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.apple.eawt; - -import com.apple.eawt.AppEvent.OpenURIEvent; - -/** - * An implementor is notified when the application is asked to open a URI. - * The application only sends {@link com.apple.eawt.EAWTEvent.OpenURIEvent}s when it has been launched as a bundled Mac application, and it's Info.plist claims URL schemes in it's {@code CFBundleURLTypes} entry. - * See the Info.plist Key Reference for more information about adding a {@code CFBundleURLTypes} key to your app's Info.plist. - * - * @see Application#setOpenURIHandler(OpenURIHandler) - * - * @since Java for Mac OS X 10.6 Update 3 - * @since Java for Mac OS X 10.5 Update 8 - */ -public interface OpenURIHandler { - /** - * Called when the application is asked to open a URI - * @param e the request to open a URI - */ - public void openURI(final OpenURIEvent e); -} diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppDockIconHandler.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppDockIconHandler.java index 4f09f53e930..eab1efb3447 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppDockIconHandler.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppDockIconHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -35,6 +35,7 @@ import sun.lwawt.macosx.CImage.Creator; class _AppDockIconHandler { private static native void nativeSetDockMenu(final long cmenu); private static native void nativeSetDockIconImage(final long image); + private static native void nativeSetDockIconProgress(final int value); private static native long nativeGetDockIconImage(); private static native void nativeSetDockIconBadge(final String badge); @@ -93,6 +94,10 @@ class _AppDockIconHandler { nativeSetDockIconBadge(badge); } + void setDockIconProgress(int value) { + nativeSetDockIconProgress(value); + } + static Creator getCImageCreator() { try { final Method getCreatorMethod = CImage.class.getDeclaredMethod("getCreator", new Class[] {}); diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppEventHandler.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppEventHandler.java index d40b57a31f6..a417f692ab8 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppEventHandler.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -25,17 +25,47 @@ package com.apple.eawt; -import java.awt.*; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.desktop.AboutEvent; +import java.awt.desktop.AboutHandler; +import java.awt.desktop.AppForegroundEvent; +import java.awt.desktop.AppForegroundListener; +import java.awt.desktop.AppHiddenEvent; +import java.awt.desktop.AppHiddenListener; +import java.awt.desktop.AppReopenedEvent; +import java.awt.desktop.AppReopenedListener; +import java.awt.desktop.OpenFilesEvent; +import java.awt.desktop.OpenFilesHandler; +import java.awt.desktop.OpenURIEvent; +import java.awt.desktop.OpenURIHandler; +import java.awt.desktop.PreferencesEvent; +import java.awt.desktop.PreferencesHandler; +import java.awt.desktop.PrintFilesEvent; +import java.awt.desktop.PrintFilesHandler; +import java.awt.desktop.QuitEvent; +import java.awt.desktop.QuitHandler; +import java.awt.desktop.QuitStrategy; +import java.awt.desktop.ScreenSleepEvent; +import java.awt.desktop.ScreenSleepListener; +import java.awt.desktop.SystemEventListener; +import java.awt.desktop.SystemSleepEvent; +import java.awt.desktop.SystemSleepListener; +import java.awt.desktop.UserSessionEvent; +import java.awt.desktop.UserSessionEvent.Reason; +import java.awt.desktop.UserSessionListener; import java.awt.event.WindowEvent; import java.io.File; -import java.net.*; -import java.util.*; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.IdentityHashMap; +import java.util.LinkedList; import java.util.List; +import java.util.Map; import sun.awt.AppContext; import sun.awt.SunToolkit; -import com.apple.eawt.AppEvent.*; - class _AppEventHandler { private static final int NOTIFY_ABOUT = 1; private static final int NOTIFY_PREFS = 2; @@ -84,9 +114,7 @@ class _AppEventHandler { final _ScreenSleepDispatcher screenSleepDispatcher = new _ScreenSleepDispatcher(); final _SystemSleepDispatcher systemSleepDispatcher = new _SystemSleepDispatcher(); - final _AppEventLegacyHandler legacyHandler = new _AppEventLegacyHandler(this); - - QuitStrategy defaultQuitAction = QuitStrategy.SYSTEM_EXIT_0; + QuitStrategy defaultQuitAction = QuitStrategy.NORMAL_EXIT; _AppEventHandler() { final String strategyProp = System.getProperty("apple.eawt.quitStrategy"); @@ -94,15 +122,16 @@ class _AppEventHandler { if ("CLOSE_ALL_WINDOWS".equals(strategyProp)) { setDefaultQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS); - } else if ("SYSTEM_EXIT_O".equals(strategyProp)) { - setDefaultQuitStrategy(QuitStrategy.SYSTEM_EXIT_0); + } else if ("SYSTEM_EXIT_O".equals(strategyProp) + || "NORMAL_EXIT".equals(strategyProp)) { + setDefaultQuitStrategy(QuitStrategy.NORMAL_EXIT); } else { System.err.println("unrecognized apple.eawt.quitStrategy: " + strategyProp); } } - void addListener(final AppEventListener listener) { - if (listener instanceof AppReOpenedListener) reOpenAppDispatcher.addListener((AppReOpenedListener)listener); + void addListener(final SystemEventListener listener) { + if (listener instanceof AppReopenedListener) reOpenAppDispatcher.addListener((AppReopenedListener)listener); if (listener instanceof AppForegroundListener) foregroundAppDispatcher.addListener((AppForegroundListener)listener); if (listener instanceof AppHiddenListener) hiddenAppDispatcher.addListener((AppHiddenListener)listener); if (listener instanceof UserSessionListener) userSessionDispatcher.addListener((UserSessionListener)listener); @@ -110,8 +139,8 @@ class _AppEventHandler { if (listener instanceof SystemSleepListener) systemSleepDispatcher.addListener((SystemSleepListener)listener); } - void removeListener(final AppEventListener listener) { - if (listener instanceof AppReOpenedListener) reOpenAppDispatcher.removeListener((AppReOpenedListener)listener); + void removeListener(final SystemEventListener listener) { + if (listener instanceof AppReopenedListener) reOpenAppDispatcher.removeListener((AppReopenedListener)listener); if (listener instanceof AppForegroundListener) foregroundAppDispatcher.removeListener((AppForegroundListener)listener); if (listener instanceof AppHiddenListener) hiddenAppDispatcher.removeListener((AppHiddenListener)listener); if (listener instanceof UserSessionListener) userSessionDispatcher.removeListener((UserSessionListener)listener); @@ -127,10 +156,10 @@ class _AppEventHandler { this.defaultQuitAction = defaultQuitAction; } - QuitResponse currentQuitResponse; - synchronized QuitResponse obtainQuitResponse() { + MacQuitResponse currentQuitResponse; + synchronized MacQuitResponse obtainQuitResponse() { if (currentQuitResponse != null) return currentQuitResponse; - return currentQuitResponse = new QuitResponse(this); + return currentQuitResponse = new MacQuitResponse(this); } synchronized void cancelQuit() { @@ -142,7 +171,7 @@ class _AppEventHandler { currentQuitResponse = null; try { - if (defaultQuitAction == QuitStrategy.SYSTEM_EXIT_0) System.exit(0); + if (defaultQuitAction == QuitStrategy.NORMAL_EXIT) System.exit(0); if (defaultQuitAction != QuitStrategy.CLOSE_ALL_WINDOWS) { throw new RuntimeException("Unknown quit action"); @@ -270,10 +299,10 @@ class _AppEventHandler { } } - class _AppReOpenedDispatcher extends _AppEventMultiplexor { - void performOnListener(AppReOpenedListener listener, final _NativeEvent event) { - final AppReOpenedEvent e = new AppReOpenedEvent(); - listener.appReOpened(e); + class _AppReOpenedDispatcher extends _AppEventMultiplexor { + void performOnListener(AppReopenedListener listener, final _NativeEvent event) { + final AppReopenedEvent e = new AppReopenedEvent(); + listener.appReopened(e); } } @@ -302,7 +331,9 @@ class _AppEventHandler { } class _UserSessionDispatcher extends _BooleanAppEventMultiplexor { - UserSessionEvent createEvent(final boolean isTrue) { return new UserSessionEvent(); } + UserSessionEvent createEvent(final boolean isTrue) { + return new UserSessionEvent(Reason.UNSPECIFIED); + } void performFalseEventOn(final UserSessionListener listener, final UserSessionEvent e) { listener.userSessionDeactivated(e); @@ -391,7 +422,7 @@ class _AppEventHandler { } void performUsing(final QuitHandler handler, final _NativeEvent event) { - final QuitResponse response = obtainQuitResponse(); // obtains the "current" quit response + final MacQuitResponse response = obtainQuitResponse(); // obtains the "current" quit response handler.handleQuitRequestWith(new QuitEvent(), response); } } @@ -524,9 +555,6 @@ class _AppEventHandler { setHandlerContext(AppContext.getAppContext()); - // if a new handler is installed, block addition of legacy ApplicationListeners - if (handler == legacyHandler) return; - legacyHandler.blockLegacyAPI(); } void performDefaultAction(final _NativeEvent event) { } // by default, do nothing @@ -574,10 +602,6 @@ class _AppEventHandler { } } } - - // if a new handler is installed, block addition of legacy ApplicationListeners - if (handler == legacyHandler) return; - legacyHandler.blockLegacyAPI(); } } } diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppEventLegacyHandler.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppEventLegacyHandler.java deleted file mode 100644 index b0556e3440d..00000000000 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppEventLegacyHandler.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2011, 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. 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.apple.eawt; - -import java.awt.Toolkit; -import java.io.File; -import java.util.*; - -import com.apple.eawt.AppEvent.*; - -@SuppressWarnings("deprecation") -class _AppEventLegacyHandler implements AboutHandler, PreferencesHandler, _OpenAppHandler, AppReOpenedListener, OpenFilesHandler, PrintFilesHandler, QuitHandler { - final _AppEventHandler parent; - final Vector legacyAppListeners = new Vector(); - boolean blockLegacyAPI; - boolean initializedParentDispatchers; - - _AppEventLegacyHandler(final _AppEventHandler parent) { - this.parent = parent; - } - - void blockLegacyAPI() { - blockLegacyAPI = true; - } - - void checkIfLegacyAPIBlocked() { - if (!blockLegacyAPI) return; - throw new IllegalStateException("Cannot add com.apple.eawt.ApplicationListener after installing an app event handler"); - } - - void addLegacyAppListener(final ApplicationListener listener) { - checkIfLegacyAPIBlocked(); - - if (!initializedParentDispatchers) { - final _AppMenuBarHandler menuBarHandler = Application.getApplication().menuBarHandler; - final boolean prefsMenuAlreadyExplicitlySet = menuBarHandler.prefsMenuItemExplicitlySet; - - parent.aboutDispatcher.setHandler(this); - parent.preferencesDispatcher.setHandler(this); - if (!prefsMenuAlreadyExplicitlySet) { - menuBarHandler.setPreferencesMenuItemVisible(false); // default behavior is not to have a preferences item - } - parent.openAppDispatcher.setHandler(this); - parent.reOpenAppDispatcher.addListener(this); - parent.openFilesDispatcher.setHandler(this); - parent.printFilesDispatcher.setHandler(this); - parent.quitDispatcher.setHandler(this); - - initializedParentDispatchers = true; - } - - synchronized (legacyAppListeners) { - legacyAppListeners.addElement(listener); - } - } - - public void removeLegacyAppListener(final ApplicationListener listener) { - checkIfLegacyAPIBlocked(); - - synchronized (legacyAppListeners) { - legacyAppListeners.removeElement(listener); - } - } - - @Override - public void handleAbout(final AboutEvent e) { - final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit()); - sendEventToEachListenerUntilHandled(ae, new EventDispatcher() { - public void dispatchEvent(final ApplicationListener listener) { - listener.handleAbout(ae); - } - }); - - if (ae.isHandled()) return; - parent.openCocoaAboutWindow(); - } - - @Override - public void handlePreferences(final PreferencesEvent e) { - final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit()); - sendEventToEachListenerUntilHandled(ae, new EventDispatcher() { - public void dispatchEvent(final ApplicationListener listener) { - listener.handlePreferences(ae); - } - }); - } - - @Override - public void handleOpenApp() { - final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit()); - sendEventToEachListenerUntilHandled(ae, new EventDispatcher() { - public void dispatchEvent(final ApplicationListener listener) { - listener.handleOpenApplication(ae); - } - }); - } - - @Override - public void appReOpened(final AppReOpenedEvent e) { - final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit()); - sendEventToEachListenerUntilHandled(ae, new EventDispatcher() { - public void dispatchEvent(final ApplicationListener listener) { - listener.handleReOpenApplication(ae); - } - }); - } - - @Override - public void openFiles(final OpenFilesEvent e) { - final List files = e.getFiles(); - for (final File file : files) { // legacy ApplicationListeners only understood one file at a time - final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit(), file.getAbsolutePath()); - sendEventToEachListenerUntilHandled(ae, new EventDispatcher() { - public void dispatchEvent(final ApplicationListener listener) { - listener.handleOpenFile(ae); - } - }); - } - } - - @Override - public void printFiles(PrintFilesEvent e) { - final List files = e.getFiles(); - for (final File file : files) { // legacy ApplicationListeners only understood one file at a time - final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit(), file.getAbsolutePath()); - sendEventToEachListenerUntilHandled(ae, new EventDispatcher() { - public void dispatchEvent(final ApplicationListener listener) { - listener.handlePrintFile(ae); - } - }); - } - } - - @Override - public void handleQuitRequestWith(final QuitEvent e, final QuitResponse response) { - final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit()); - sendEventToEachListenerUntilHandled(ae, new EventDispatcher() { - public void dispatchEvent(final ApplicationListener listener) { - listener.handleQuit(ae); - } - }); - - if (ae.isHandled()) { - parent.performQuit(); - } else { - parent.cancelQuit(); - } - } - - interface EventDispatcher { - void dispatchEvent(final ApplicationListener listener); - } - - // helper that cycles through the loop and aborts if the event is handled, or there are no listeners - void sendEventToEachListenerUntilHandled(final ApplicationEvent event, final EventDispatcher dispatcher) { - synchronized (legacyAppListeners) { - if (legacyAppListeners.size() == 0) return; - - final Enumeration e = legacyAppListeners.elements(); - while (e.hasMoreElements() && !event.isHandled()) { - dispatcher.dispatchEvent(e.nextElement()); - } - } - } -} diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java index 3ac88f81379..3a132f25595 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -26,7 +26,6 @@ package com.apple.eawt; import java.awt.Frame; -import java.awt.peer.MenuComponentPeer; import javax.swing.*; import javax.swing.plaf.MenuBarUI; diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/event/FullScreenEvent.java b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/event/FullScreenEvent.java new file mode 100644 index 00000000000..3ff90ac5e1d --- /dev/null +++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/event/FullScreenEvent.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 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. 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.apple.eawt.event; + +import com.apple.eawt.Application; +import java.awt.Window; +import java.util.EventObject; + +@SuppressWarnings("serial") // JDK implementation class +public class FullScreenEvent extends EventObject { + + final Window window; + + /** + * @param window window + */ + public FullScreenEvent(final Window window) { + super(Application.getApplication()); + this.window = window; + } + + /** + * @return window transitioning between full screen states + */ + public Window getWindow() { + return window; + } +} diff --git a/jdk/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java b/jdk/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java index 05fe2531c13..823ad8aef10 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java +++ b/jdk/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java @@ -32,7 +32,7 @@ import java.awt.GraphicsDevice; import java.awt.Insets; import java.awt.Window; import java.util.Objects; - +import sun.java2d.SunGraphicsEnvironment; import sun.java2d.opengl.CGLGraphicsConfig; public final class CGraphicsDevice extends GraphicsDevice @@ -140,7 +140,7 @@ public final class CGraphicsDevice extends GraphicsDevice public void displayChanged() { xResolution = nativeGetXResolution(displayID); yResolution = nativeGetYResolution(displayID); - scale = (int) nativeGetScaleFactor(displayID); + initScaleFactor(); //TODO configs/fullscreenWindow/modes? } @@ -249,6 +249,17 @@ public final class CGraphicsDevice extends GraphicsDevice return nativeGetDisplayModes(displayID); } + private void initScaleFactor() { + if (SunGraphicsEnvironment.isUIScaleEnabled()) { + double debugScale = SunGraphicsEnvironment.getDebugScale(); + scale = (int) (debugScale >= 1 + ? Math.round(debugScale) + : nativeGetScaleFactor(displayID)); + } else { + scale = 1; + } + } + private static native double nativeGetScaleFactor(int displayID); private static native void nativeSetDisplayMode(int displayID, int w, int h, int bpp, int refrate); diff --git a/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java b/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java index d152a5f01c0..9e883938e46 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java +++ b/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java @@ -142,94 +142,6 @@ public final class CFontManager extends SunFontManager { } } - @Override - public Font2D createFont2D(File fontFile, int fontFormat, boolean isCopy, CreatedFontTracker tracker) throws FontFormatException { - - String fontFilePath = fontFile.getPath(); - Font2D font2D = null; - final File fFile = fontFile; - final CreatedFontTracker _tracker = tracker; - try { - switch (fontFormat) { - case Font.TRUETYPE_FONT: - font2D = new TrueTypeFont(fontFilePath, null, 0, true); - break; - case Font.TYPE1_FONT: - font2D = new Type1Font(fontFilePath, null, isCopy); - break; - default: - throw new FontFormatException("Unrecognised Font Format"); - } - } catch (FontFormatException e) { - if (isCopy) { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - if (_tracker != null) { - _tracker.subBytes((int)fFile.length()); - } - fFile.delete(); - return null; - } - }); - } - throw(e); - } - if (isCopy) { - FileFont.setFileToRemove(font2D, fontFile, tracker); - synchronized (FontManager.class) { - - if (tmpFontFiles == null) { - tmpFontFiles = new Vector(); - } - tmpFontFiles.add(fontFile); - - if (fileCloser == null) { - final Runnable fileCloserRunnable = new Runnable() { - public void run() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - - for (int i=0;i) () -> { - /* The thread must be a member of a thread group - * which will not get GCed before VM exit. - * Make its parent the top-level thread group. - */ - ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); - fileCloser = new ManagedLocalsThread(rootTG, fileCloserRunnable); - fileCloser.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(fileCloser); - return null; - } - ); - } - } - } - return font2D; - } - protected void registerFontsInDir(String dirName, boolean useJavaRasterizer, int fontRank, boolean defer, boolean resolveSymLinks) { loadNativeDirFonts(dirName); super.registerFontsInDir(dirName, useJavaRasterizer, fontRank, defer, resolveSymLinks); diff --git a/jdk/src/java.desktop/macosx/classes/sun/java2d/OSXOffScreenSurfaceData.java b/jdk/src/java.desktop/macosx/classes/sun/java2d/OSXOffScreenSurfaceData.java index 9f4f5b2f219..c4a09d86cef 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/java2d/OSXOffScreenSurfaceData.java +++ b/jdk/src/java.desktop/macosx/classes/sun/java2d/OSXOffScreenSurfaceData.java @@ -478,13 +478,9 @@ public class OSXOffScreenSurfaceData extends OSXSurfaceData // implements Raster // For the Sun2D renderer we should rely on the implementation of the super class. // BufImageSurfaceData.java doesn't have an implementation of copyArea() and relies on the super class. - int offsetX = 0; - int offsetY = 0; - if (sg2d.transformState == SunGraphics2D.TRANSFORM_ANY_TRANSLATE || - sg2d.transformState == SunGraphics2D.TRANSFORM_INT_TRANSLATE) { - offsetX = (int) sg2d.transform.getTranslateX(); - offsetY = (int) sg2d.transform.getTranslateY(); - } else if (sg2d.transformState != SunGraphics2D.TRANSFORM_ISIDENT) { return false; } + if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) { + return false; + } // reset the clip (this is how it works on windows) // we actually can handle a case with any clips but windows ignores the light clip @@ -498,18 +494,23 @@ public class OSXOffScreenSurfaceData extends OSXSurfaceData // implements Raster return true; } - // the rectangle returned from clipCopyArea() is in the coordinate space of the surface (image) - // we need to substract the offsetX and offsetY to move it to the coordinate space of the graphics2d. - // sg2d.drawImage expects the destination rect to be in the coord space of the graphics2d. - // (vm) - x = clippedCopyAreaRect.x - offsetX; - y = clippedCopyAreaRect.y - offsetY; + // the rectangle returned from clipCopyArea() is in the coordinate space + // of the surface (image) + x = clippedCopyAreaRect.x; + y = clippedCopyAreaRect.y; w = clippedCopyAreaRect.width; h = clippedCopyAreaRect.height; - // copy (dst coordinates are in the coord space of the graphics2d, and src coordinates are - // in the coordinate space of the image) - sg2d.drawImage(this.bim, x + dx, y + dy, x + dx + w, y + dy + h, x + offsetX, y + offsetY, x + w + offsetX, y + h + offsetY, null); + // copy (dst coordinates are in the coord space of the graphics2d, and + // src coordinates are in the coordinate space of the image) + // sg2d.drawImage expects the destination rect to be in the coord space + // of the graphics2d. (vm) + // we need to substract the transX and transY to move it + // to the coordinate space of the graphics2d. + int dstX = x + dx - sg2d.transX; + int dstY = y + dy - sg2d.transY; + sg2d.drawImage(this.bim, dstX, dstY, dstX + w, dstY + h, + x, y, x + w, y + h, null); // restore the clip sg2d.setClip(clip); diff --git a/jdk/src/java.desktop/macosx/classes/sun/java2d/OSXSurfaceData.java b/jdk/src/java.desktop/macosx/classes/sun/java2d/OSXSurfaceData.java index d1444b81a90..a0fd6486cb5 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/java2d/OSXSurfaceData.java +++ b/jdk/src/java.desktop/macosx/classes/sun/java2d/OSXSurfaceData.java @@ -1094,19 +1094,13 @@ public abstract class OSXSurfaceData extends BufImgSurfaceData { } /** - * Clips the copy area to the heavywieght bounds and returns the cliped rectangle. The tricky part here is the - * passed arguments x, y are in the coordinate space of the sg2d/lightweight comp. In order to do the clipping we - * translate them to the coordinate space of the surface, and the returned clipped rectangle is in the coordinate - * space of the surface. + * Clips the copy area to the heavyweight bounds and returns the clipped rectangle. + * The returned clipped rectangle is in the coordinate space of the surface. */ protected Rectangle clipCopyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy) { // we need to clip against the heavyweight bounds copyAreaBounds.setBounds(sg2d.devClip.getLoX(), sg2d.devClip.getLoY(), sg2d.devClip.getWidth(), sg2d.devClip.getHeight()); - // put src rect into surface coordinate space - x += sg2d.transX; - y += sg2d.transY; - // clip src rect srcCopyAreaRect.setBounds(x, y, w, h); intersection(srcCopyAreaRect, copyAreaBounds, srcCopyAreaRect); diff --git a/jdk/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java b/jdk/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java index b59349f9cb8..2eb9048e71e 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java +++ b/jdk/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java @@ -175,31 +175,6 @@ public abstract class CGLSurfaceData extends OGLSurfaceData { return scale; } - @Override - public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, - int dx, int dy) { - final int state = sg2d.transformState; - if (state > SunGraphics2D.TRANSFORM_TRANSLATESCALE - || sg2d.compositeState >= SunGraphics2D.COMP_XOR) { - return false; - } - if (state <= SunGraphics2D.TRANSFORM_ANY_TRANSLATE) { - x += sg2d.transX; - y += sg2d.transY; - } else if (state == SunGraphics2D.TRANSFORM_TRANSLATESCALE) { - final double[] coords = {x, y, x + w, y + h, x + dx, y + dy}; - sg2d.transform.transform(coords, 0, coords, 0, 3); - x = (int) Math.ceil(coords[0] - 0.5); - y = (int) Math.ceil(coords[1] - 0.5); - w = ((int) Math.ceil(coords[2] - 0.5)) - x; - h = ((int) Math.ceil(coords[3] - 0.5)) - y; - dx = ((int) Math.ceil(coords[4] - 0.5)) - x; - dy = ((int) Math.ceil(coords[5] - 0.5)) - y; - } - oglRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy); - return true; - } - protected native void clearWindow(); public static class CGLWindowSurfaceData extends CGLSurfaceData { diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java index 2870e7ba22b..b74719f149b 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -370,6 +370,11 @@ public abstract class LWToolkit extends SunToolkit implements Runnable { return true; } + @Override + public final boolean isTaskbarSupported() { + return true; + } + @Override public final KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() { return LWKeyboardFocusManagerPeer.getInstance(); diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDesktopPeer.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDesktopPeer.java index 1bc37a7aa46..f06865ef9aa 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDesktopPeer.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDesktopPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -25,9 +25,14 @@ package sun.lwawt.macosx; +import com.apple.eawt.Application; + +import javax.swing.*; import java.awt.Desktop.Action; +import java.awt.desktop.*; import java.awt.peer.DesktopPeer; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.net.URI; @@ -37,34 +42,126 @@ import java.net.URI; * * @see DesktopPeer */ -public class CDesktopPeer implements DesktopPeer { +final public class CDesktopPeer implements DesktopPeer { + @Override public boolean isSupported(Action action) { - // OPEN, EDIT, PRINT, MAIL, BROWSE all supported. - // Though we don't really differentiate between OPEN / EDIT return true; } + @Override public void open(File file) throws IOException { this.lsOpenFile(file, false); } + @Override public void edit(File file) throws IOException { this.lsOpenFile(file, false); } + @Override public void print(File file) throws IOException { this.lsOpenFile(file, true); } + @Override public void mail(URI uri) throws IOException { this.lsOpen(uri); } + @Override public void browse(URI uri) throws IOException { this.lsOpen(uri); } + @Override + public void addAppEventListener(SystemEventListener listener) { + Application.getApplication().addAppEventListener(listener); + } + + @Override + public void removeAppEventListener(SystemEventListener listener) { + Application.getApplication().removeAppEventListener(listener); + } + + @Override + public void setAboutHandler(AboutHandler aboutHandler) { + Application.getApplication().setAboutHandler(aboutHandler); + } + + @Override + public void setPreferencesHandler(PreferencesHandler preferencesHandler) { + Application.getApplication().setPreferencesHandler(preferencesHandler); + } + + @Override + public void setOpenFileHandler(OpenFilesHandler openFileHandler) { + Application.getApplication().setOpenFileHandler(openFileHandler); + } + + @Override + public void setPrintFileHandler(PrintFilesHandler printFileHandler) { + Application.getApplication().setPrintFileHandler(printFileHandler); + } + + @Override + public void setOpenURIHandler(OpenURIHandler openURIHandler) { + Application.getApplication().setOpenURIHandler(openURIHandler); + } + + @Override + public void setQuitHandler(QuitHandler quitHandler) { + Application.getApplication().setQuitHandler(quitHandler); + } + + @Override + public void setQuitStrategy(QuitStrategy strategy) { + Application.getApplication().setQuitStrategy(strategy); + } + + @Override + public void enableSuddenTermination() { + Application.getApplication().enableSuddenTermination(); + } + + @Override + public void disableSuddenTermination() { + Application.getApplication().disableSuddenTermination(); + } + + @Override + public void requestForeground(boolean allWindows) { + Application.getApplication().requestForeground(allWindows); + } + + @Override + public void openHelpViewer() { + Application.getApplication().openHelpViewer(); + } + + @Override + public void setDefaultMenuBar(JMenuBar menuBar) { + Application.getApplication().setDefaultMenuBar(menuBar); + } + + @Override + public boolean browseFileDirectory(File file) { + try { + return com.apple.eio.FileManager.revealInFinder(file); + } catch (FileNotFoundException ex) { + return false; //handled in java.awt.Desktop + } + } + + @Override + public boolean moveToTrash(File file) { + try { + return com.apple.eio.FileManager.moveToTrash(file); + } catch (FileNotFoundException ex) { + return false; //handled in java.awt.Desktop + } + } + private void lsOpen(URI uri) throws IOException { int status = _lsOpenURI(uri.toString()); diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTaskbarPeer.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTaskbarPeer.java new file mode 100644 index 00000000000..df6073e841a --- /dev/null +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTaskbarPeer.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 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. 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.lwawt.macosx; + +import com.apple.eawt.Application; +import java.awt.Image; +import java.awt.PopupMenu; +import java.awt.Taskbar.Feature; +import java.awt.peer.TaskbarPeer; + +final public class CTaskbarPeer implements TaskbarPeer { + + CTaskbarPeer() {} + + @Override + public boolean isSupported(Feature feature) { + switch(feature) { + case ICON_BADGE_TEXT: + case ICON_BADGE_NUMBER: + case ICON_IMAGE: + case MENU: + case PROGRESS_VALUE: + case USER_ATTENTION: + return true; + default: + return false; + } + } + + @Override + public void setProgressValue(int value) { + Application.getApplication().setDockIconProgress(value); + } + + @Override + public void setIconBadge(String badge) { + Application.getApplication().setDockIconBadge(badge); + } + + @Override + public Image getIconImage() { + return Application.getApplication().getDockIconImage(); + } + + @Override + public void setIconImage(Image image) { + Application.getApplication().setDockIconImage(image); + } + + @Override + public PopupMenu getMenu() { + return Application.getApplication().getDockMenu(); + } + + @Override + public void setMenu(PopupMenu menu) { + Application.getApplication().setDockMenu(menu); + } + + @Override + public void requestUserAttention(boolean enabled, boolean critical) { + if (enabled) { + Application.getApplication().requestUserAttention(critical); + } + } +} diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java index b4116a17f3a..f0bf99c7321 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -25,6 +25,7 @@ package sun.lwawt.macosx; +import java.awt.peer.TaskbarPeer; import java.awt.*; import java.awt.datatransfer.Clipboard; import java.awt.dnd.*; @@ -293,6 +294,11 @@ public final class LWCToolkit extends LWToolkit { return new CDesktopPeer(); } + @Override + public TaskbarPeer createTaskbarPeer(Taskbar target) { + return new CTaskbarPeer(); + } + @Override public LWCursorManager getCursorManager() { return CCursorManager.getInstance(); diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m index 8070995baa6..67115418d38 100644 --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -43,6 +43,7 @@ -(void) resetTrackingArea; -(void) deliverJavaKeyEventHelper: (NSEvent*) event; -(BOOL) isCodePointInUnicodeBlockNeedingIMEvent: (unichar) codePoint; +-(NSMutableString *) parseString : (id) complexString; @end // Uncomment this line to see fprintfs of each InputMethod API being called on this View @@ -66,26 +67,26 @@ static BOOL shouldUsePressAndHold() { // Note: Must be called on main (AppKit) thread only - (id) initWithRect: (NSRect) rect platformView: (jobject) cPlatformView - windowLayer: (CALayer*) windowLayer + windowLayer: (CALayer*) windowLayer { -AWT_ASSERT_APPKIT_THREAD; + AWT_ASSERT_APPKIT_THREAD; // Initialize ourselves self = [super initWithFrame: rect]; if (self == nil) return self; - + m_cPlatformView = cPlatformView; fInputMethodLOCKABLE = NULL; fKeyEventsNeeded = NO; fProcessingKeystroke = NO; - + fEnablePressAndHold = shouldUsePressAndHold(); fInPressAndHold = NO; fPAHNeedsToSelect = NO; - + mouseIsOver = NO; [self resetTrackingArea]; [self setAutoresizesSubviews:NO]; - + if (windowLayer != nil) { self.cglLayer = windowLayer; //Layer hosting view @@ -96,7 +97,7 @@ AWT_ASSERT_APPKIT_THREAD; //[self setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawDuringViewResize]; //[self setLayerContentsPlacement: NSViewLayerContentsPlacementTopLeft]; //[self setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable]; - + #ifdef REMOTELAYER CGLLayer *parentLayer = (CGLLayer*)self.cglLayer; parentLayer.parentLayer = NULL; @@ -118,36 +119,36 @@ AWT_ASSERT_APPKIT_THREAD; } #endif /* REMOTELAYER */ } - + return self; } - (void) dealloc { -AWT_ASSERT_APPKIT_THREAD; - + AWT_ASSERT_APPKIT_THREAD; + self.cglLayer = nil; - + JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; (*env)->DeleteGlobalRef(env, m_cPlatformView); m_cPlatformView = NULL; - + if (fInputMethodLOCKABLE != NULL) { JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; - + JNFDeleteGlobalRef(env, fInputMethodLOCKABLE); fInputMethodLOCKABLE = NULL; } - - + + [super dealloc]; } - (void) viewDidMoveToWindow { -AWT_ASSERT_APPKIT_THREAD; - + AWT_ASSERT_APPKIT_THREAD; + [AWTToolkit eventCountPlusPlus]; - + [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^() { [[self window] makeFirstResponder: self]; }]; @@ -231,7 +232,7 @@ AWT_ASSERT_APPKIT_THREAD; NSPoint eventLocation = [event locationInWindow]; NSPoint localPoint = [self convertPoint: eventLocation fromView: nil]; - + if ([self mouse: localPoint inRect: [self bounds]]) { [self deliverJavaMouseEvent: event]; } else { @@ -275,10 +276,10 @@ AWT_ASSERT_APPKIT_THREAD; - (void) keyDown: (NSEvent *)event { fProcessingKeystroke = YES; fKeyEventsNeeded = YES; - + // Allow TSM to look at the event and potentially send back NSTextInputClient messages. [self interpretKeyEvents:[NSArray arrayWithObject:event]]; - + if (fEnablePressAndHold && [event willBeHandledByComplexInputMethod]) { fProcessingKeystroke = NO; if (!fInPressAndHold) { @@ -287,14 +288,14 @@ AWT_ASSERT_APPKIT_THREAD; } return; } - + NSString *eventCharacters = [event characters]; BOOL isDeadKey = (eventCharacters != nil && [eventCharacters length] == 0); - + if ((![self hasMarkedText] && fKeyEventsNeeded) || isDeadKey) { [self deliverJavaKeyEventHelper: event]; } - + fProcessingKeystroke = NO; } @@ -307,15 +308,15 @@ AWT_ASSERT_APPKIT_THREAD; } - (BOOL) performKeyEquivalent: (NSEvent *) event { - // if IM is active key events should be ignored + // if IM is active key events should be ignored if (![self hasMarkedText] && !fInPressAndHold) { [self deliverJavaKeyEventHelper: event]; } - - // Workaround for 8020209: special case for "Cmd =" and "Cmd ." - // because Cocoa calls performKeyEquivalent twice for these keystrokes - NSUInteger modFlags = [event modifierFlags] & - (NSCommandKeyMask | NSAlternateKeyMask | NSShiftKeyMask | NSControlKeyMask); + + // Workaround for 8020209: special case for "Cmd =" and "Cmd ." + // because Cocoa calls performKeyEquivalent twice for these keystrokes + NSUInteger modFlags = [event modifierFlags] & + (NSCommandKeyMask | NSAlternateKeyMask | NSShiftKeyMask | NSControlKeyMask); if (modFlags == NSCommandKeyMask) { NSString *eventChars = [event charactersIgnoringModifiers]; if ([eventChars length] == 1) { @@ -325,9 +326,9 @@ AWT_ASSERT_APPKIT_THREAD; return YES; } } - + } - + return NO; } @@ -341,36 +342,36 @@ AWT_ASSERT_APPKIT_THREAD; if ([window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]]) { isEnabled = [(AWTWindow*)[window delegate] isEnabled]; } - + if (!isEnabled) { return; } - + NSEventType type = [event type]; - + // check synthesized mouse entered/exited events if ((type == NSMouseEntered && mouseIsOver) || (type == NSMouseExited && !mouseIsOver)) { return; }else if ((type == NSMouseEntered && !mouseIsOver) || (type == NSMouseExited && mouseIsOver)) { mouseIsOver = !mouseIsOver; } - + [AWTToolkit eventCountPlusPlus]; - + JNIEnv *env = [ThreadUtilities getJNIEnv]; - + NSPoint eventLocation = [event locationInWindow]; NSPoint localPoint = [self convertPoint: eventLocation fromView: nil]; NSPoint absP = [NSEvent mouseLocation]; - + // Convert global numbers between Cocoa's coordinate system and Java. // TODO: need consitent way for doing that both with global as well as with local coordinates. // The reason to do it here is one more native method for getting screen dimension otherwise. - + NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame]; absP.y = screenRect.size.height - absP.y; jint clickCount; - + if (type == NSMouseEntered || type == NSMouseExited || type == NSScrollWheel || @@ -379,7 +380,7 @@ AWT_ASSERT_APPKIT_THREAD; } else { clickCount = [event clickCount]; } - + static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent"); static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDD)V"); jobject jEvent = JNFNewObject(env, jctor_NSEvent, @@ -392,7 +393,7 @@ AWT_ASSERT_APPKIT_THREAD; [event deltaY], [event deltaX]); CHECK_NULL(jEvent); - + static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_MEMBER_CACHE(jm_deliverMouseEvent, jc_PlatformView, "deliverMouseEvent", "(Lsun/lwawt/macosx/NSEvent;)V"); JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent); @@ -404,10 +405,10 @@ AWT_ASSERT_APPKIT_THREAD; [self removeTrackingArea:rolloverTrackingArea]; [rolloverTrackingArea release]; } - + int options = (NSTrackingActiveAlways | NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingEnabledDuringMouseDrag); - + rolloverTrackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] options: options owner:self @@ -434,17 +435,17 @@ AWT_ASSERT_APPKIT_THREAD; } [sLastKeyEvent release]; sLastKeyEvent = [event retain]; - + [AWTToolkit eventCountPlusPlus]; JNIEnv *env = [ThreadUtilities getJNIEnv]; - + jstring characters = NULL; jstring charactersIgnoringModifiers = NULL; if ([event type] != NSFlagsChanged) { characters = JNFNSToJavaString(env, [event characters]); charactersIgnoringModifiers = JNFNSToJavaString(env, [event charactersIgnoringModifiers]); } - + static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent"); static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IISLjava/lang/String;Ljava/lang/String;)V"); jobject jEvent = JNFNewObject(env, jctor_NSEvent, @@ -454,12 +455,12 @@ AWT_ASSERT_APPKIT_THREAD; characters, charactersIgnoringModifiers); CHECK_NULL(jEvent); - + static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_PlatformView, "deliverKeyEvent", "(Lsun/lwawt/macosx/NSEvent;)V"); JNFCallVoidMethod(env, m_cPlatformView, jm_deliverKeyEvent, jEvent); - + if (characters != NULL) { (*env)->DeleteLocalRef(env, characters); } @@ -479,34 +480,34 @@ AWT_ASSERT_APPKIT_THREAD; - (void) drawRect:(NSRect)dirtyRect { -AWT_ASSERT_APPKIT_THREAD; - + AWT_ASSERT_APPKIT_THREAD; + [super drawRect:dirtyRect]; JNIEnv *env = [ThreadUtilities getJNIEnv]; if (env != NULL) { -/* - if ([self inLiveResize]) { - NSRect rs[4]; - NSInteger count; - [self getRectsExposedDuringLiveResize:rs count:&count]; - for (int i = 0; i < count; i++) { - JNU_CallMethodByName(env, NULL, [m_awtWindow cPlatformView], - "deliverWindowDidExposeEvent", "(FFFF)V", - (jfloat)rs[i].origin.x, (jfloat)rs[i].origin.y, - (jfloat)rs[i].size.width, (jfloat)rs[i].size.height); - if ((*env)->ExceptionOccurred(env)) { - (*env)->ExceptionDescribe(env); - (*env)->ExceptionClear(env); - } - } - } else { -*/ + /* + if ([self inLiveResize]) { + NSRect rs[4]; + NSInteger count; + [self getRectsExposedDuringLiveResize:rs count:&count]; + for (int i = 0; i < count; i++) { + JNU_CallMethodByName(env, NULL, [m_awtWindow cPlatformView], + "deliverWindowDidExposeEvent", "(FFFF)V", + (jfloat)rs[i].origin.x, (jfloat)rs[i].origin.y, + (jfloat)rs[i].size.width, (jfloat)rs[i].size.height); + if ((*env)->ExceptionOccurred(env)) { + (*env)->ExceptionDescribe(env); + (*env)->ExceptionClear(env); + } + } + } else { + */ static JNF_CLASS_CACHE(jc_CPlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_MEMBER_CACHE(jm_deliverWindowDidExposeEvent, jc_CPlatformView, "deliverWindowDidExposeEvent", "()V"); JNFCallVoidMethod(env, m_cPlatformView, jm_deliverWindowDidExposeEvent); -/* - } -*/ + /* + } + */ } } @@ -518,6 +519,15 @@ AWT_ASSERT_APPKIT_THREAD; return NO; } +-(NSMutableString *) parseString : (id) complexString { + if ([complexString isKindOfClass:[NSString class]]) { + return [complexString mutableCopy]; + } + else { + return [complexString mutableString]; + } +} + // NSAccessibility support - (jobject)awtComponent:(JNIEnv*)env { @@ -557,17 +567,17 @@ AWT_ASSERT_APPKIT_THREAD; - (id)accessibilityAttributeValue:(NSString *)attribute { AWT_ASSERT_APPKIT_THREAD; - + if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { JNIEnv *env = [ThreadUtilities getJNIEnv]; - + (*env)->PushLocalFrame(env, 4); - + id result = NSAccessibilityUnignoredChildrenForOnlyChild([self getAxData:env]); - + (*env)->PopLocalFrame(env, NULL); - + return result; } else @@ -584,28 +594,28 @@ AWT_ASSERT_APPKIT_THREAD; { AWT_ASSERT_APPKIT_THREAD; JNIEnv *env = [ThreadUtilities getJNIEnv]; - + (*env)->PushLocalFrame(env, 4); - + id result = [[self getAxData:env] accessibilityHitTest:point withEnv:env]; - + (*env)->PopLocalFrame(env, NULL); - + return result; } - (id)accessibilityFocusedUIElement { AWT_ASSERT_APPKIT_THREAD; - + JNIEnv *env = [ThreadUtilities getJNIEnv]; - + (*env)->PushLocalFrame(env, 4); - + id result = [[self getAxData:env] accessibilityFocusedUIElement]; - + (*env)->PopLocalFrame(env, NULL); - + return result; } @@ -625,7 +635,8 @@ AWT_ASSERT_APPKIT_THREAD; NSString *selectedText = [self accessibleSelectedText]; NSAttributedString *styledText = [[NSAttributedString alloc] initWithString:selectedText]; NSData *rtfdData = [styledText RTFDFromRange:NSMakeRange(0, [styledText length]) - documentAttributes:@{NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType}]; + documentAttributes: + @{NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType}]; [styledText release]; return rtfdData; } @@ -643,12 +654,12 @@ AWT_ASSERT_APPKIT_THREAD; - (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType { if ([[self window] firstResponder] != self) return nil; // let AWT components handle themselves - + if ([sendType isEqual:NSStringPboardType] || [returnType isEqual:NSStringPboardType]) { NSString *selectedText = [self accessibleSelectedText]; if (selectedText) return self; } - + return nil; } @@ -660,13 +671,13 @@ AWT_ASSERT_APPKIT_THREAD; [pboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; return [pboard setString:[self accessibleSelectedText] forType:NSStringPboardType]; } - + if ([types containsObject:NSRTFDPboardType]) { [pboard declareTypes:[NSArray arrayWithObject:NSRTFDPboardType] owner:nil]; return [pboard setData:[self accessibleSelectedTextAsRTFD] forType:NSRTFDPboardType]; } - + return NO; } @@ -678,17 +689,17 @@ AWT_ASSERT_APPKIT_THREAD; NSString *text = [pboard stringForType:NSStringPboardType]; return [self replaceAccessibleTextSelection:text]; } - + if ([[pboard types] containsObject:NSRTFDPboardType]) { NSData *rtfdData = [pboard dataForType:NSRTFDPboardType]; NSAttributedString *styledText = [[NSAttributedString alloc] initWithRTFD:rtfdData documentAttributes:NULL]; NSString *text = [styledText string]; [styledText release]; - + return [self replaceAccessibleTextSelection:text]; } - + return NO; } @@ -710,12 +721,12 @@ AWT_ASSERT_APPKIT_THREAD; // If draggingSource is nil route the message to the superclass (if responding to the selector): CDragSource *dragSource = self._dragSource; NSDragOperation dragOp = NSDragOperationNone; - + if (dragSource != nil) dragOp = [dragSource draggingSourceOperationMaskForLocal:flag]; else if ([super respondsToSelector:@selector(draggingSourceOperationMaskForLocal:)]) dragOp = [super draggingSourceOperationMaskForLocal:flag]; - + return dragOp; } @@ -724,12 +735,12 @@ AWT_ASSERT_APPKIT_THREAD; // If draggingSource is nil route the message to the superclass (if responding to the selector): CDragSource *dragSource = self._dragSource; NSArray* array = nil; - + if (dragSource != nil) array = [dragSource namesOfPromisedFilesDroppedAtDestination:dropDestination]; else if ([super respondsToSelector:@selector(namesOfPromisedFilesDroppedAtDestination:)]) array = [super namesOfPromisedFilesDroppedAtDestination:dropDestination]; - + return array; } @@ -737,7 +748,7 @@ AWT_ASSERT_APPKIT_THREAD; { // If draggingSource is nil route the message to the superclass (if responding to the selector): CDragSource *dragSource = self._dragSource; - + if (dragSource != nil) [dragSource draggedImage:image beganAt:screenPoint]; else if ([super respondsToSelector:@selector(draggedImage::)]) @@ -748,7 +759,7 @@ AWT_ASSERT_APPKIT_THREAD; { // If draggingSource is nil route the message to the superclass (if responding to the selector): CDragSource *dragSource = self._dragSource; - + if (dragSource != nil) [dragSource draggedImage:image endedAt:screenPoint operation:operation]; else if ([super respondsToSelector:@selector(draggedImage:::)]) @@ -759,7 +770,7 @@ AWT_ASSERT_APPKIT_THREAD; { // If draggingSource is nil route the message to the superclass (if responding to the selector): CDragSource *dragSource = self._dragSource; - + if (dragSource != nil) [dragSource draggedImage:image movedTo:screenPoint]; else if ([super respondsToSelector:@selector(draggedImage::)]) @@ -771,12 +782,12 @@ AWT_ASSERT_APPKIT_THREAD; // If draggingSource is nil route the message to the superclass (if responding to the selector): CDragSource *dragSource = self._dragSource; BOOL result = FALSE; - + if (dragSource != nil) result = [dragSource ignoreModifierKeysWhileDragging]; else if ([super respondsToSelector:@selector(ignoreModifierKeysWhileDragging)]) result = [super ignoreModifierKeysWhileDragging]; - + return result; } @@ -789,12 +800,12 @@ AWT_ASSERT_APPKIT_THREAD; // If draggingDestination is nil route the message to the superclass: CDropTarget *dropTarget = self._dropTarget; NSDragOperation dragOp = NSDragOperationNone; - + if (dropTarget != nil) dragOp = [dropTarget draggingEntered:sender]; else if ([super respondsToSelector:@selector(draggingEntered:)]) dragOp = [super draggingEntered:sender]; - + return dragOp; } @@ -803,12 +814,12 @@ AWT_ASSERT_APPKIT_THREAD; // If draggingDestination is nil route the message to the superclass: CDropTarget *dropTarget = self._dropTarget; NSDragOperation dragOp = NSDragOperationNone; - + if (dropTarget != nil) dragOp = [dropTarget draggingUpdated:sender]; else if ([super respondsToSelector:@selector(draggingUpdated:)]) dragOp = [super draggingUpdated:sender]; - + return dragOp; } @@ -816,7 +827,7 @@ AWT_ASSERT_APPKIT_THREAD; { // If draggingDestination is nil route the message to the superclass: CDropTarget *dropTarget = self._dropTarget; - + if (dropTarget != nil) [dropTarget draggingExited:sender]; else if ([super respondsToSelector:@selector(draggingExited:)]) @@ -828,12 +839,12 @@ AWT_ASSERT_APPKIT_THREAD; // If draggingDestination is nil route the message to the superclass: CDropTarget *dropTarget = self._dropTarget; BOOL result = FALSE; - + if (dropTarget != nil) result = [dropTarget prepareForDragOperation:sender]; else if ([super respondsToSelector:@selector(prepareForDragOperation:)]) result = [super prepareForDragOperation:sender]; - + return result; } @@ -842,12 +853,12 @@ AWT_ASSERT_APPKIT_THREAD; // If draggingDestination is nil route the message to the superclass: CDropTarget *dropTarget = self._dropTarget; BOOL result = FALSE; - + if (dropTarget != nil) result = [dropTarget performDragOperation:sender]; else if ([super respondsToSelector:@selector(performDragOperation:)]) result = [super performDragOperation:sender]; - + return result; } @@ -855,7 +866,7 @@ AWT_ASSERT_APPKIT_THREAD; { // If draggingDestination is nil route the message to the superclass: CDropTarget *dropTarget = self._dropTarget; - + if (dropTarget != nil) [dropTarget concludeDragOperation:sender]; else if ([super respondsToSelector:@selector(concludeDragOperation:)]) @@ -866,7 +877,7 @@ AWT_ASSERT_APPKIT_THREAD; { // If draggingDestination is nil route the message to the superclass: CDropTarget *dropTarget = self._dropTarget; - + if (dropTarget != nil) [dropTarget draggingEnded:sender]; else if ([super respondsToSelector:@selector(draggingEnded:)]) @@ -885,49 +896,49 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); #ifdef IM_DEBUG fprintf(stderr, "AWTView InputMethod Selector Called : [insertText]: %s\n", [aString UTF8String]); #endif // IM_DEBUG - + if (fInputMethodLOCKABLE == NULL) { return; } - + // Insert happens at the end of PAH fInPressAndHold = NO; - + // insertText gets called when the user commits text generated from an input method. It also gets // called during ordinary input as well. We only need to send an input method event when we have marked // text, or 'text in progress'. We also need to send the event if we get an insert text out of the blue! // (i.e., when the user uses the Character palette or Inkwell), or when the string to insert is a complex // Unicode value. - NSUInteger utf16Length = [aString lengthOfBytesUsingEncoding:NSUTF16StringEncoding]; - NSUInteger utf8Length = [aString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + NSMutableString * useString = [self parseString:aString]; + NSUInteger utf16Length = [useString lengthOfBytesUsingEncoding:NSUTF16StringEncoding]; + NSUInteger utf8Length = [useString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; BOOL aStringIsComplex = NO; if ((utf16Length > 2) || - ((utf8Length > 1) && [self isCodePointInUnicodeBlockNeedingIMEvent:[aString characterAtIndex:0]])) { + ((utf8Length > 1) && [self isCodePointInUnicodeBlockNeedingIMEvent:[useString characterAtIndex:0]])) { aStringIsComplex = YES; } - + if ([self hasMarkedText] || !fProcessingKeystroke || aStringIsComplex) { JNIEnv *env = [ThreadUtilities getJNIEnv]; - + static JNF_MEMBER_CACHE(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V"); // We need to select the previous glyph so that it is overwritten. if (fPAHNeedsToSelect) { JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_selectPreviousGlyph); fPAHNeedsToSelect = NO; } - + static JNF_MEMBER_CACHE(jm_insertText, jc_CInputMethod, "insertText", "(Ljava/lang/String;)V"); - jstring insertedText = JNFNSToJavaString(env, aString); + jstring insertedText = JNFNSToJavaString(env, useString); JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_insertText, insertedText); // AWT_THREADING Safe (AWTRunLoopMode) (*env)->DeleteLocalRef(env, insertedText); - + // The input method event will create psuedo-key events for each character in the committed string. // We also don't want to send the character that triggered the insertText, usually a return. [3337563] fKeyEventsNeeded = NO; } - fPAHNeedsToSelect = NO; - } - (void) doCommandBySelector:(SEL)aSelector @@ -947,7 +958,7 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); { if (!fInputMethodLOCKABLE) return; - + BOOL isAttributedString = [aString isKindOfClass:[NSAttributedString class]]; NSAttributedString *attrString = (isAttributedString ? (NSAttributedString *)aString : nil); NSString *incomingString = (isAttributedString ? [aString string] : aString); @@ -958,14 +969,14 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); static JNF_MEMBER_CACHE(jm_addAttribute, jc_CInputMethod, "addAttribute", "(ZZII)V"); static JNF_MEMBER_CACHE(jm_dispatchText, jc_CInputMethod, "dispatchText", "(IIZ)V"); JNIEnv *env = [ThreadUtilities getJNIEnv]; - + // NSInputContext already did the analysis of the TSM event and created attributes indicating // the underlining and color that should be done to the string. We need to look at the underline // style and color to determine what kind of Java hilighting needs to be done. jstring inProcessText = JNFNSToJavaString(env, incomingString); JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_startIMUpdate, inProcessText); // AWT_THREADING Safe (AWTRunLoopMode) (*env)->DeleteLocalRef(env, inProcessText); - + if (isAttributedString) { NSUInteger length; NSRange effectiveRange; @@ -981,25 +992,25 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); (NSNumber *)[attributes objectForKey:NSUnderlineStyleAttributeName]; NSInteger underlineSize = [underlineSizeObj integerValue]; isThickUnderline = (underlineSize > 1); - + NSColor *underlineColorObj = (NSColor *)[attributes objectForKey:NSUnderlineColorAttributeName]; isGray = !([underlineColorObj isEqual:[NSColor blackColor]]); - + JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_addAttribute, isThickUnderline, isGray, effectiveRange.location, effectiveRange.length); // AWT_THREADING Safe (AWTRunLoopMode) } } } - + static JNF_MEMBER_CACHE(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V"); // We need to select the previous glyph so that it is overwritten. if (fPAHNeedsToSelect) { JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_selectPreviousGlyph); fPAHNeedsToSelect = NO; } - + JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_dispatchText, selectionRange.location, selectionRange.length, JNI_FALSE); // AWT_THREADING Safe (AWTRunLoopMode) - + // If the marked text is being cleared (zero-length string) don't handle the key event. if ([incomingString length] == 0) { fKeyEventsNeeded = NO; @@ -1011,16 +1022,16 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); #ifdef IM_DEBUG fprintf(stderr, "AWTView InputMethod Selector Called : [unmarkText]\n"); #endif // IM_DEBUG - + if (!fInputMethodLOCKABLE) { return; } - + // unmarkText cancels any input in progress and commits it to the text field. static JNF_MEMBER_CACHE(jm_unmarkText, jc_CInputMethod, "unmarkText", "()V"); JNIEnv *env = [ThreadUtilities getJNIEnv]; JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_unmarkText); // AWT_THREADING Safe (AWTRunLoopMode) - + } - (BOOL) hasMarkedText @@ -1028,24 +1039,24 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); #ifdef IM_DEBUG fprintf(stderr, "AWTView InputMethod Selector Called : [hasMarkedText]\n"); #endif // IM_DEBUG - + if (!fInputMethodLOCKABLE) { return NO; } - + static JNF_MEMBER_CACHE(jf_fCurrentText, jc_CInputMethod, "fCurrentText", "Ljava/text/AttributedString;"); static JNF_MEMBER_CACHE(jf_fCurrentTextLength, jc_CInputMethod, "fCurrentTextLength", "I"); JNIEnv *env = [ThreadUtilities getJNIEnv]; jobject currentText = JNFGetObjectField(env, fInputMethodLOCKABLE, jf_fCurrentText); - + jint currentTextLength = JNFGetIntField(env, fInputMethodLOCKABLE, jf_fCurrentTextLength); - + BOOL hasMarkedText = (currentText != NULL && currentTextLength > 0); - + if (currentText != NULL) { (*env)->DeleteLocalRef(env, currentText); } - + return hasMarkedText; } @@ -1054,7 +1065,7 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); #ifdef IM_DEBUG fprintf(stderr, "AWTView InputMethod Selector Called : [conversationIdentifier]\n"); #endif // IM_DEBUG - + return (NSInteger) self; } @@ -1066,16 +1077,16 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); #ifdef IM_DEBUG fprintf(stderr, "AWTView InputMethod Selector Called : [attributedSubstringFromRange] location=%lu, length=%lu\n", (unsigned long)theRange.location, (unsigned long)theRange.length); #endif // IM_DEBUG - + static JNF_MEMBER_CACHE(jm_substringFromRange, jc_CInputMethod, "attributedSubstringFromRange", "(II)Ljava/lang/String;"); JNIEnv *env = [ThreadUtilities getJNIEnv]; jobject theString = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_substringFromRange, theRange.location, theRange.length); // AWT_THREADING Safe (AWTRunLoopMode) - + id result = [[[NSAttributedString alloc] initWithString:JNFJavaToNSString(env, theString)] autorelease]; #ifdef IM_DEBUG NSLog(@"attributedSubstringFromRange returning \"%@\"", result); #endif // IM_DEBUG - + (*env)->DeleteLocalRef(env, theString); return result; } @@ -1085,24 +1096,24 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); */ - (NSRange) markedRange { - + #ifdef IM_DEBUG fprintf(stderr, "AWTView InputMethod Selector Called : [markedRange]\n"); #endif // IM_DEBUG - + if (!fInputMethodLOCKABLE) { return NSMakeRange(NSNotFound, 0); } - + static JNF_MEMBER_CACHE(jm_markedRange, jc_CInputMethod, "markedRange", "()[I"); JNIEnv *env = [ThreadUtilities getJNIEnv]; jarray array; jboolean isCopy; jint *_array; NSRange range = NSMakeRange(NSNotFound, 0); - + array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_markedRange); // AWT_THREADING Safe (AWTRunLoopMode) - + if (array) { _array = (*env)->GetIntArrayElements(env, array, &isCopy); if (_array != NULL) { @@ -1116,7 +1127,7 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); } (*env)->DeleteLocalRef(env, array); } - + return range; } @@ -1128,18 +1139,18 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); if (!fInputMethodLOCKABLE) { return NSMakeRange(NSNotFound, 0); } - + static JNF_MEMBER_CACHE(jm_selectedRange, jc_CInputMethod, "selectedRange", "()[I"); JNIEnv *env = [ThreadUtilities getJNIEnv]; jarray array; jboolean isCopy; jint *_array; NSRange range = NSMakeRange(NSNotFound, 0); - + #ifdef IM_DEBUG fprintf(stderr, "AWTView InputMethod Selector Called : [selectedRange]\n"); #endif // IM_DEBUG - + array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_selectedRange); // AWT_THREADING Safe (AWTRunLoopMode) if (array) { _array = (*env)->GetIntArrayElements(env, array, &isCopy); @@ -1150,7 +1161,7 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); } (*env)->DeleteLocalRef(env, array); } - + return range; } @@ -1161,7 +1172,7 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); if (!fInputMethodLOCKABLE) { return NSZeroRect; } - + static JNF_MEMBER_CACHE(jm_firstRectForCharacterRange, jc_CInputMethod, "firstRectForCharacterRange", "(I)[I"); JNIEnv *env = [ThreadUtilities getJNIEnv]; @@ -1169,16 +1180,16 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); jboolean isCopy; jint *_array; NSRect rect; - + #ifdef IM_DEBUG fprintf(stderr, "AWTView InputMethod Selector Called : [firstRectForCharacterRange:] location=%lu, length=%lu\n", (unsigned long)theRange.location, (unsigned long)theRange.length); #endif // IM_DEBUG - + array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_firstRectForCharacterRange, theRange.location); // AWT_THREADING Safe (AWTRunLoopMode) - + _array = (*env)->GetIntArrayElements(env, array, &isCopy); if (_array) { rect = ConvertNSScreenRect(env, NSMakeRect(_array[0], _array[1], _array[2], _array[3])); @@ -1187,7 +1198,7 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); rect = NSZeroRect; } (*env)->DeleteLocalRef(env, array); - + #ifdef IM_DEBUG fprintf(stderr, "firstRectForCharacterRange returning x=%f, y=%f, width=%f, height=%f\n", @@ -1204,23 +1215,23 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); if (!fInputMethodLOCKABLE) { return NSNotFound; } - + static JNF_MEMBER_CACHE(jm_characterIndexForPoint, jc_CInputMethod, "characterIndexForPoint", "(II)I"); JNIEnv *env = [ThreadUtilities getJNIEnv]; - + NSPoint flippedLocation = ConvertNSScreenPoint(env, thePoint); - + #ifdef IM_DEBUG fprintf(stderr, "AWTView InputMethod Selector Called : [characterIndexForPoint:(NSPoint)thePoint] x=%f, y=%f\n", flippedLocation.x, flippedLocation.y); #endif // IM_DEBUG - + jint index = JNFCallIntMethod(env, fInputMethodLOCKABLE, jm_characterIndexForPoint, (jint)flippedLocation.x, (jint)flippedLocation.y); // AWT_THREADING Safe (AWTRunLoopMode) - + #ifdef IM_DEBUG fprintf(stderr, "characterIndexForPoint returning %ld\n", index); #endif // IM_DEBUG - + if (index == -1) { return NSNotFound; } else { @@ -1233,7 +1244,7 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); #ifdef IM_DEBUG fprintf(stderr, "AWTView InputMethod Selector Called : [validAttributesForMarkedText]\n"); #endif // IM_DEBUG - + return [NSArray array]; } @@ -1242,14 +1253,14 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); #ifdef IM_DEBUG fprintf(stderr, "AWTView InputMethod Selector Called : [setInputMethod]\n"); #endif // IM_DEBUG - + JNIEnv *env = [ThreadUtilities getJNIEnv]; - + // Get rid of the old one if (fInputMethodLOCKABLE) { JNFDeleteGlobalRef(env, fInputMethodLOCKABLE); } - + // Save a global ref to the new input method. if (inputMethod != NULL) fInputMethodLOCKABLE = JNFNewGlobalRef(env, inputMethod); @@ -1262,7 +1273,7 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); #ifdef IM_DEBUG fprintf(stderr, "AWTView InputMethod Selector Called : [abandonInput]\n"); #endif // IM_DEBUG - + [ThreadUtilities performOnMainThread:@selector(markedTextAbandoned:) on:[NSInputManager currentInputManager] withObject:self waitUntilDone:YES]; [self unmarkText]; } @@ -1284,22 +1295,22 @@ Java_sun_lwawt_macosx_CPlatformView_nativeCreateView (JNIEnv *env, jobject obj, jint originX, jint originY, jint width, jint height, jlong windowLayerPtr) { __block AWTView *newView = nil; - -JNF_COCOA_ENTER(env); - + + JNF_COCOA_ENTER(env); + NSRect rect = NSMakeRect(originX, originY, width, height); jobject cPlatformView = (*env)->NewGlobalRef(env, obj); - + [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ - + CALayer *windowLayer = jlong_to_ptr(windowLayerPtr); newView = [[AWTView alloc] initWithRect:rect platformView:cPlatformView windowLayer:windowLayer]; }]; - -JNF_COCOA_EXIT(env); - + + JNF_COCOA_EXIT(env); + return ptr_to_jlong(newView); } @@ -1313,24 +1324,24 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformView_nativeSetAutoResizable (JNIEnv *env, jclass cls, jlong viewPtr, jboolean toResize) { -JNF_COCOA_ENTER(env); + JNF_COCOA_ENTER(env); - NSView *view = (NSView *)jlong_to_ptr(viewPtr); - - [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ - - if (toResize) { - [view setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable]; - } else { - [view setAutoresizingMask: NSViewMinYMargin | NSViewMaxXMargin]; - } - - if ([view superview] != nil) { - [[view superview] setAutoresizesSubviews:(BOOL)toResize]; - } - + NSView *view = (NSView *)jlong_to_ptr(viewPtr); + + [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ + + if (toResize) { + [view setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable]; + } else { + [view setAutoresizingMask: NSViewMinYMargin | NSViewMaxXMargin]; + } + + if ([view superview] != nil) { + [[view superview] setAutoresizesSubviews:(BOOL)toResize]; + } + }]; -JNF_COCOA_EXIT(env); + JNF_COCOA_EXIT(env); } /* @@ -1345,17 +1356,17 @@ Java_sun_lwawt_macosx_CPlatformView_nativeGetNSViewDisplayID { __block jint ret; //CGDirectDisplayID -JNF_COCOA_ENTER(env); + JNF_COCOA_ENTER(env); - NSView *view = (NSView *)jlong_to_ptr(viewPtr); + NSView *view = (NSView *)jlong_to_ptr(viewPtr); NSWindow *window = [view window]; [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ - - ret = (jint)[[AWTWindow getNSWindowDisplayID_AppKitThread: window] intValue]; + + ret = (jint)[[AWTWindow getNSWindowDisplayID_AppKitThread: window] intValue]; }]; -JNF_COCOA_EXIT(env); + JNF_COCOA_EXIT(env); return ret; } @@ -1372,13 +1383,13 @@ Java_sun_lwawt_macosx_CPlatformView_nativeGetLocationOnScreen { jobject jRect = NULL; -JNF_COCOA_ENTER(env); + JNF_COCOA_ENTER(env); __block NSRect rect = NSZeroRect; - NSView *view = (NSView *)jlong_to_ptr(viewPtr); + NSView *view = (NSView *)jlong_to_ptr(viewPtr); [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ - + NSRect viewBounds = [view bounds]; NSRect frameInWindow = [view convertRect:viewBounds toView:nil]; rect = [[view window] convertRectToScreen:frameInWindow]; @@ -1388,7 +1399,7 @@ JNF_COCOA_ENTER(env); }]; jRect = NSToJavaRect(env, rect); -JNF_COCOA_EXIT(env); + JNF_COCOA_EXIT(env); return jRect; } @@ -1404,16 +1415,16 @@ JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CPlatformView_nativeIsViewUnder { __block jboolean underMouse = JNI_FALSE; -JNF_COCOA_ENTER(env); + JNF_COCOA_ENTER(env); NSView *nsView = OBJC(viewPtr); - [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ - NSPoint ptWindowCoords = [[nsView window] mouseLocationOutsideOfEventStream]; - NSPoint ptViewCoords = [nsView convertPoint:ptWindowCoords fromView:nil]; - underMouse = [nsView hitTest:ptViewCoords] != nil; + [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ + NSPoint ptWindowCoords = [[nsView window] mouseLocationOutsideOfEventStream]; + NSPoint ptViewCoords = [nsView convertPoint:ptWindowCoords fromView:nil]; + underMouse = [nsView hitTest:ptViewCoords] != nil; }]; -JNF_COCOA_EXIT(env); + JNF_COCOA_EXIT(env); return underMouse; } diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.h b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.h index c0a8a7c3b7f..8d0723c555a 100644 --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.h +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -40,6 +40,8 @@ NSMenu *fDockMenu; CMenuBar *fDefaultMenuBar; + NSProgressIndicator *fProgressIndicator; + BOOL fHandlesDocumentTypes; BOOL fHandlesURLTypes; } @@ -47,6 +49,8 @@ @property (nonatomic, retain) NSMenuItem *fPreferencesMenu; @property (nonatomic, retain) NSMenuItem *fAboutMenu; +@property (nonatomic, retain) NSProgressIndicator *fProgressIndicator; + @property (nonatomic, retain) NSMenu *fDockMenu; @property (nonatomic, retain) CMenuBar *fDefaultMenuBar; diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.m index da48e7351dc..6e9d6a423f2 100644 --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.m +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -100,6 +100,7 @@ AWT_ASSERT_APPKIT_THREAD; @synthesize fPreferencesMenu; @synthesize fAboutMenu; +@synthesize fProgressIndicator; @synthesize fDockMenu; @synthesize fDefaultMenuBar; @@ -200,6 +201,18 @@ AWT_ASSERT_APPKIT_THREAD; self.fPreferencesMenu = (NSMenuItem*)[appMenu itemWithTag:PREFERENCES_TAG]; self.fAboutMenu = (NSMenuItem*)[appMenu itemAtIndex:0]; + + NSDockTile *dockTile = [NSApp dockTile]; + self.fProgressIndicator = [[NSProgressIndicator alloc] + initWithFrame:NSMakeRect(3.f, 0.f, dockTile.size.width - 6.f, 20.f)]; + + [fProgressIndicator setStyle:NSProgressIndicatorBarStyle]; + [fProgressIndicator setIndeterminate:NO]; + [[dockTile contentView] addSubview:fProgressIndicator]; + [fProgressIndicator setMinValue:0]; + [fProgressIndicator setMaxValue:100]; + [fProgressIndicator setHidden:YES]; + [fProgressIndicator release]; // If the java application has a bundle with an Info.plist file with // a CFBundleDocumentTypes entry, then it is set up to handle Open Doc @@ -252,6 +265,7 @@ AWT_ASSERT_APPKIT_THREAD; self.fAboutMenu = nil; self.fDockMenu = nil; self.fDefaultMenuBar = nil; + self.fProgressIndicator = nil; [super dealloc]; } @@ -468,6 +482,9 @@ AWT_ASSERT_APPKIT_THREAD; [dockImageView setImageScaling:NSImageScaleProportionallyUpOrDown]; [dockImageView setImage:image]; + [[ApplicationDelegate sharedDelegate].fProgressIndicator removeFromSuperview]; + [dockImageView addSubview:[ApplicationDelegate sharedDelegate].fProgressIndicator]; + // add it to the NSDockTile [dockTile setContentView: dockImageView]; [dockTile display]; @@ -475,6 +492,20 @@ AWT_ASSERT_APPKIT_THREAD; [dockImageView release]; } ++ (void)_setDockIconProgress:(NSNumber *)value { +AWT_ASSERT_APPKIT_THREAD; + + ApplicationDelegate *delegate = [ApplicationDelegate sharedDelegate]; + if ([value doubleValue] >= 0 && [value doubleValue] <=100) { + [delegate.fProgressIndicator setDoubleValue:[value doubleValue]]; + [delegate.fProgressIndicator setHidden:NO]; + } else { + [delegate.fProgressIndicator setHidden:YES]; + } + + [[NSApp dockTile] display]; +} + // Obtains the image of the Dock icon, either manually set, a drawn copy, or the default NSApplicationIcon + (NSImage *)_dockIconImage { AWT_ASSERT_APPKIT_THREAD; @@ -608,6 +639,24 @@ JNF_COCOA_ENTER(env); JNF_COCOA_EXIT(env); } +/* + * Class: com_apple_eawt__AppDockIconHandler + * Method: nativeSetDockIconProgress + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockIconProgress + (JNIEnv *env, jclass clz, jint value) +{ + JNF_COCOA_ENTER(env); + + [ThreadUtilities performOnMainThread:@selector(_setDockIconProgress:) + on:[ApplicationDelegate class] + withObject:[NSNumber numberWithInt:value] + waitUntilDone:NO]; + + JNF_COCOA_EXIT(env); +} + /* * Class: com_apple_eawt__AppDockIconHandler * Method: nativeGetDockIconImage diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m index 7fc6f62ec55..c8bcc573b03 100644 --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -29,12 +29,12 @@ #import #import +#import "CRobotKeyCode.h" #import "LWCToolkit.h" #import "sun_lwawt_macosx_CRobot.h" #import "java_awt_event_InputEvent.h" #import "sizecalc.h" - // Starting number for event numbers generated by Robot. // Apple docs don't mention at all what are the requirements // for these numbers. It seems that they must be higher @@ -354,241 +354,10 @@ static void PostMouseEvent(const CGPoint point, CGMouseButton button, } } -// NOTE: Don't modify this table directly. It is machine generated. See below. -static const unsigned char javaToMacKeyCode[] = { - 127, // 0 0 VK_UNDEFINED No_Equivalent - 127, // 1 0x1 Not_Used - 127, // 2 0x2 Not_Used - 127, // 3 0x3 VK_CANCEL No_Equivalent - 127, // 4 0x4 Not_Used - 127, // 5 0x5 Not_Used - 127, // 6 0x6 Not_Used - 127, // 7 0x7 Not_Used - 51, // 8 0x8 VK_BACK_SPACE - 48, // 9 0x9 VK_TAB - 36, // 10 0xa VK_ENTER - 127, // 11 0xb Not_Used - 71, // 12 0xc VK_CLEAR - 127, // 13 0xd Not_Used - 127, // 14 0xe Not_Used - 127, // 15 0xf Not_Used - 56, // 16 0x10 VK_SHIFT - 59, // 17 0x11 VK_CONTROL - 58, // 18 0x12 VK_ALT - 113, // 19 0x13 VK_PAUSE - 57, // 20 0x14 VK_CAPS_LOCK - 127, // 21 0x15 VK_KANA No_Equivalent - 127, // 22 0x16 Not_Used - 127, // 23 0x17 Not_Used - 127, // 24 0x18 VK_FINAL No_Equivalent - 127, // 25 0x19 VK_KANJI No_Equivalent - 127, // 26 0x1a Not_Used - 53, // 27 0x1b VK_ESCAPE - 127, // 28 0x1c VK_CONVERT No_Equivalent - 127, // 29 0x1d VK_NONCONVERT No_Equivalent - 127, // 30 0x1e VK_ACCEPT No_Equivalent - 127, // 31 0x1f VK_MODECHANGE No_Equivalent - 49, // 32 0x20 VK_SPACE - 116, // 33 0x21 VK_PAGE_UP - 121, // 34 0x22 VK_PAGE_DOWN - 119, // 35 0x23 VK_END - 115, // 36 0x24 VK_HOME - 123, // 37 0x25 VK_LEFT - 126, // 38 0x26 VK_UP - 124, // 39 0x27 VK_RIGHT - 125, // 40 0x28 VK_DOWN - 127, // 41 0x29 Not_Used - 127, // 42 0x2a Not_Used - 127, // 43 0x2b Not_Used - 43, // 44 0x2c VK_COMMA - 27, // 45 0x2d VK_MINUS - 47, // 46 0x2e VK_PERIOD - 44, // 47 0x2f VK_SLASH - 29, // 48 0x30 VK_0 - 18, // 49 0x31 VK_1 - 19, // 50 0x32 VK_2 - 20, // 51 0x33 VK_3 - 21, // 52 0x34 VK_4 - 23, // 53 0x35 VK_5 - 22, // 54 0x36 VK_6 - 26, // 55 0x37 VK_7 - 28, // 56 0x38 VK_8 - 25, // 57 0x39 VK_9 - 127, // 58 0x3a Not_Used - 41, // 59 0x3b VK_SEMICOLON - 127, // 60 0x3c Not_Used - 24, // 61 0x3d VK_EQUALS - 127, // 62 0x3e Not_Used - 127, // 63 0x3f Not_Used - 127, // 64 0x40 Not_Used - 0, // 65 0x41 VK_A - 11, // 66 0x42 VK_B - 8, // 67 0x43 VK_C - 2, // 68 0x44 VK_D - 14, // 69 0x45 VK_E - 3, // 70 0x46 VK_F - 5, // 71 0x47 VK_G - 4, // 72 0x48 VK_H - 34, // 73 0x49 VK_I - 38, // 74 0x4a VK_J - 40, // 75 0x4b VK_K - 37, // 76 0x4c VK_L - 46, // 77 0x4d VK_M - 45, // 78 0x4e VK_N - 31, // 79 0x4f VK_O - 35, // 80 0x50 VK_P - 12, // 81 0x51 VK_Q - 15, // 82 0x52 VK_R - 1, // 83 0x53 VK_S - 17, // 84 0x54 VK_T - 32, // 85 0x55 VK_U - 9, // 86 0x56 VK_V - 13, // 87 0x57 VK_W - 7, // 88 0x58 VK_X - 16, // 89 0x59 VK_Y - 6, // 90 0x5a VK_Z - 33, // 91 0x5b VK_OPEN_BRACKET - 42, // 92 0x5c VK_BACK_SLASH - 30, // 93 0x5d VK_CLOSE_BRACKET - 127, // 94 0x5e Not_Used - 127, // 95 0x5f Not_Used - 82, // 96 0x60 VK_NUMPAD0 - 83, // 97 0x61 VK_NUMPAD1 - 84, // 98 0x62 VK_NUMPAD2 - 85, // 99 0x63 VK_NUMPAD3 - 86, // 100 0x64 VK_NUMPAD4 - 87, // 101 0x65 VK_NUMPAD5 - 88, // 102 0x66 VK_NUMPAD6 - 89, // 103 0x67 VK_NUMPAD7 - 91, // 104 0x68 VK_NUMPAD8 - 92, // 105 0x69 VK_NUMPAD9 - 67, // 106 0x6a VK_MULTIPLY - 69, // 107 0x6b VK_ADD - 127, // 108 0x6c VK_SEPARATER No_Equivalent - 78, // 109 0x6d VK_SUBTRACT - 65, // 110 0x6e VK_DECIMAL - 75, // 111 0x6f VK_DIVIDE - 122, // 112 0x70 VK_F1 - 120, // 113 0x71 VK_F2 - 99, // 114 0x72 VK_F3 - 118, // 115 0x73 VK_F4 - 96, // 116 0x74 VK_F5 - 97, // 117 0x75 VK_F6 - 98, // 118 0x76 VK_F7 - 100, // 119 0x77 VK_F8 - 101, // 120 0x78 VK_F9 - 109, // 121 0x79 VK_F10 - 103, // 122 0x7a VK_F11 - 111, // 123 0x7b VK_F12 - 127, // 124 0x7c Not_Used - 127, // 125 0x7d Not_Used - 127, // 126 0x7e Not_Used - 117, // 127 0x7f VK_DELETE - 127, // 128 0x80 VK_DEAD_GRAVE No_Equivalent - 127, // 129 0x81 VK_DEAD_ACUTE No_Equivalent - 127, // 130 0x82 VK_DEAD_CIRCUMFLEX No_Equivalent - 127, // 131 0x83 VK_DEAD_TILDE No_Equivalent - 127, // 132 0x84 VK_DEAD_MACRON No_Equivalent - 127, // 133 0x85 VK_DEAD_BREVE No_Equivalent - 127, // 134 0x86 VK_DEAD_ABOVEDOT No_Equivalent - 127, // 135 0x87 VK_DEAD_DIAERESIS No_Equivalent - 127, // 136 0x88 VK_DEAD_ABOVERING No_Equivalent - 127, // 137 0x89 VK_DEAD_DOUBLEACUTE No_Equivalent - 127, // 138 0x8a VK_DEAD_CARON No_Equivalent - 127, // 139 0x8b VK_DEAD_CEDILLA No_Equivalent - 127, // 140 0x8c VK_DEAD_OGONEK No_Equivalent - 127, // 141 0x8d VK_DEAD_IOTA No_Equivalent - 127, // 142 0x8e VK_DEAD_VOICED_SOUND No_Equivalent - 127, // 143 0x8f VK_DEAD_SEMIVOICED_SOUND No_Equivalent - 127, // 144 0x90 VK_NUM_LOCK No_Equivalent - 107, // 145 0x91 VK_SCROLL_LOCK - 127, // 146 0x92 Not_Used - 127, // 147 0x93 Not_Used - 127, // 148 0x94 Not_Used - 127, // 149 0x95 Not_Used - 127, // 150 0x96 VK_AMPERSAND No_Equivalent - 127, // 151 0x97 VK_ASTERISK No_Equivalent - 127, // 152 0x98 VK_QUOTEDBL No_Equivalent - 127, // 153 0x99 VK_LESS No_Equivalent - 105, // 154 0x9a VK_PRINTSCREEN - 127, // 155 0x9b VK_INSERT No_Equivalent - 114, // 156 0x9c VK_HELP - 55, // 157 0x9d VK_META - 127, // 158 0x9e Not_Used - 127, // 159 0x9f Not_Used - 127, // 160 0xa0 VK_GREATER No_Equivalent - 127, // 161 0xa1 VK_BRACELEFT No_Equivalent - 127, // 162 0xa2 VK_BRACERIGHT No_Equivalent - 127, // 163 0xa3 Not_Used - 127, // 164 0xa4 Not_Used - 127, // 165 0xa5 Not_Used - 127, // 166 0xa6 Not_Used - 127, // 167 0xa7 Not_Used - 127, // 168 0xa8 Not_Used - 127, // 169 0xa9 Not_Used - 127, // 170 0xaa Not_Used - 127, // 171 0xab Not_Used - 127, // 172 0xac Not_Used - 127, // 173 0xad Not_Used - 127, // 174 0xae Not_Used - 127, // 175 0xaf Not_Used - 127, // 176 0xb0 Not_Used - 127, // 177 0xb1 Not_Used - 127, // 178 0xb2 Not_Used - 127, // 179 0xb3 Not_Used - 127, // 180 0xb4 Not_Used - 127, // 181 0xb5 Not_Used - 127, // 182 0xb6 Not_Used - 127, // 183 0xb7 Not_Used - 127, // 184 0xb8 Not_Used - 127, // 185 0xb9 Not_Used - 127, // 186 0xba Not_Used - 127, // 187 0xbb Not_Used - 127, // 188 0xbc Not_Used - 127, // 189 0xbd Not_Used - 127, // 190 0xbe Not_Used - 127, // 191 0xbf Not_Used - 50, // 192 0xc0 VK_BACK_QUOTE - 127, // 193 0xc1 Not_Used - 127, // 194 0xc2 Not_Used - 127, // 195 0xc3 Not_Used - 127, // 196 0xc4 Not_Used - 127, // 197 0xc5 Not_Used - 127, // 198 0xc6 Not_Used - 127, // 199 0xc7 Not_Used - 127, // 200 0xc8 Not_Used - 127, // 201 0xc9 Not_Used - 127, // 202 0xca Not_Used - 127, // 203 0xcb Not_Used - 127, // 204 0xcc Not_Used - 127, // 205 0xcd Not_Used - 127, // 206 0xce Not_Used - 127, // 207 0xcf Not_Used - 127, // 208 0xd0 Not_Used - 127, // 209 0xd1 Not_Used - 127, // 210 0xd2 Not_Used - 127, // 211 0xd3 Not_Used - 127, // 212 0xd4 Not_Used - 127, // 213 0xd5 Not_Used - 127, // 214 0xd6 Not_Used - 127, // 215 0xd7 Not_Used - 127, // 216 0xd8 Not_Used - 127, // 217 0xd9 Not_Used - 127, // 218 0xda Not_Used - 127, // 219 0xdb Not_Used - 127, // 220 0xdc Not_Used - 127, // 221 0xdd Not_Used - 39 // 222 0xde VK_QUOTE -}; - -// NOTE: All values above 222 don't have an equivalent on MacOSX. static inline CGKeyCode GetCGKeyCode(jint javaKeyCode) { - if (javaKeyCode > 222) { - return 127; - } else { - return javaToMacKeyCode[javaKeyCode]; - } + CRobotKeyCodeMapping *keyCodeMapping = [CRobotKeyCodeMapping sharedInstance]; + return [keyCodeMapping getOSXKeyCodeForJavaKey:javaKeyCode]; } static int GetClickCount(BOOL isDown) { diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobotKeyCode.h b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobotKeyCode.h new file mode 100644 index 00000000000..d06b9e8ee46 --- /dev/null +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobotKeyCode.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#import + +#ifndef KeyCodeConverter_CRobotKeyCode_h +#define KeyCodeConverter_CRobotKeyCode_h + +const static int OSX_kVK_ANSI_A = 0x00; +const static int OSX_kVK_ANSI_S = 0x01; +const static int OSX_kVK_ANSI_D = 0x02; +const static int OSX_kVK_ANSI_F = 0x03; +const static int OSX_kVK_ANSI_H = 0x04; +const static int OSX_kVK_ANSI_G = 0x05; +const static int OSX_kVK_ANSI_Z = 0x06; +const static int OSX_kVK_ANSI_X = 0x07; +const static int OSX_kVK_ANSI_C = 0x08; +const static int OSX_kVK_ANSI_V = 0x09; +const static int OSX_kVK_ISO_Section = 0x0A; +const static int OSX_kVK_ANSI_B = 0x0B; +const static int OSX_kVK_ANSI_Q = 0x0C; +const static int OSX_kVK_ANSI_W = 0x0D; +const static int OSX_kVK_ANSI_E = 0x0E; +const static int OSX_kVK_ANSI_R = 0x0F; +const static int OSX_kVK_ANSI_Y = 0x10; +const static int OSX_kVK_ANSI_T = 0x11; +const static int OSX_kVK_ANSI_1 = 0x12; +const static int OSX_kVK_ANSI_2 = 0x13; +const static int OSX_kVK_ANSI_3 = 0x14; +const static int OSX_kVK_ANSI_4 = 0x15; +const static int OSX_kVK_ANSI_6 = 0x16; +const static int OSX_kVK_ANSI_5 = 0x17; +const static int OSX_kVK_ANSI_Equal = 0x18; +const static int OSX_kVK_ANSI_9 = 0x19; +const static int OSX_kVK_ANSI_7 = 0x1A; +const static int OSX_kVK_ANSI_Minus = 0x1B; +const static int OSX_kVK_ANSI_8 = 0x1C; +const static int OSX_kVK_ANSI_0 = 0x1D; +const static int OSX_kVK_ANSI_RightBracket = 0x1E; +const static int OSX_kVK_ANSI_O = 0x1F; +const static int OSX_kVK_ANSI_U = 0x20; +const static int OSX_kVK_ANSI_LeftBracket = 0x21; +const static int OSX_kVK_ANSI_I = 0x22; +const static int OSX_kVK_ANSI_P = 0x23; +const static int OSX_kVK_ANSI_L = 0x25; +const static int OSX_kVK_ANSI_J = 0x26; +const static int OSX_kVK_ANSI_Quote = 0x27; +const static int OSX_kVK_ANSI_K = 0x28; +const static int OSX_kVK_ANSI_Semicolon = 0x29; +const static int OSX_kVK_ANSI_Backslash = 0x2A; +const static int OSX_kVK_ANSI_Comma = 0x2B; +const static int OSX_kVK_ANSI_Slash = 0x2C; +const static int OSX_kVK_ANSI_N = 0x2D; +const static int OSX_kVK_ANSI_M = 0x2E; +const static int OSX_kVK_ANSI_Period = 0x2F; +const static int OSX_kVK_ANSI_Grave = 0x32; +const static int OSX_kVK_ANSI_KeypadDecimal = 0x41; +const static int OSX_kVK_ANSI_KeypadMultiply = 0x43; +const static int OSX_kVK_ANSI_KeypadPlus = 0x45; +const static int OSX_kVK_ANSI_KeypadClear = 0x47; +const static int OSX_kVK_ANSI_KeypadDivide = 0x4B; +const static int OSX_kVK_ANSI_KeypadEnter = 0x4C; +const static int OSX_kVK_ANSI_KeypadMinus = 0x4E; +const static int OSX_kVK_ANSI_KeypadEquals = 0x51; +const static int OSX_kVK_ANSI_Keypad0 = 0x52; +const static int OSX_kVK_ANSI_Keypad1 = 0x53; +const static int OSX_kVK_ANSI_Keypad2 = 0x54; +const static int OSX_kVK_ANSI_Keypad3 = 0x55; +const static int OSX_kVK_ANSI_Keypad4 = 0x56; +const static int OSX_kVK_ANSI_Keypad5 = 0x57; +const static int OSX_kVK_ANSI_Keypad6 = 0x58; +const static int OSX_kVK_ANSI_Keypad7 = 0x59; +const static int OSX_kVK_ANSI_Keypad8 = 0x5B; +const static int OSX_kVK_ANSI_Keypad9 = 0x5C; +const static int OSX_kVK_Return = 0x24; +const static int OSX_kVK_Tab = 0x30; +const static int OSX_kVK_Space = 0x31; +const static int OSX_Delete = 0x33; +const static int OSX_Escape = 0x35; +const static int OSX_Command = 0x37; +const static int OSX_Shift = 0x38; +const static int OSX_CapsLock = 0x39; +const static int OSX_Option = 0x3A; +const static int OSX_Control = 0x3B; +const static int OSX_RightShift = 0x3C; +const static int OSX_RightOption = 0x3D; +const static int OSX_RightControl = 0x3E; +const static int OSX_Function = 0x3F; +const static int OSX_F17 = 0x40; +const static int OSX_VolumeUp = 0x48; +const static int OSX_VolumeDown = 0x49; +const static int OSX_Mute = 0x4A; +const static int OSX_F18 = 0x4F; +const static int OSX_F19 = 0x50; +const static int OSX_F20 = 0x5A; +const static int OSX_F5 = 0x60; +const static int OSX_F6 = 0x61; +const static int OSX_F7 = 0x62; +const static int OSX_F3 = 0x63; +const static int OSX_F8 = 0x64; +const static int OSX_F9 = 0x65; +const static int OSX_F11 = 0x67; +const static int OSX_F13 = 0x69; +const static int OSX_F16 = 0x6A; +const static int OSX_F14 = 0x6B; +const static int OSX_F10 = 0x6D; +const static int OSX_F12 = 0x6F; +const static int OSX_F15 = 0x71; +const static int OSX_Help = 0x72; +const static int OSX_Home = 0x73; +const static int OSX_PageUp = 0x74; +const static int OSX_ForwardDelete = 0x75; +const static int OSX_F4 = 0x76; +const static int OSX_End = 0x77; +const static int OSX_F2 = 0x78; +const static int OSX_PageDown = 0x79; +const static int OSX_F1 = 0x7A; +const static int OSX_LeftArrow = 0x7B; +const static int OSX_RightArrow = 0x7C; +const static int OSX_DownArrow = 0x7D; +const static int OSX_UpArrow = 0x7E; +const static int OSX_Undefined = 0x7F; + +@interface CRobotKeyCodeMapping : NSObject { + +} + +@property (readwrite, retain) NSDictionary *javaToMacKeyMap; + ++ (CRobotKeyCodeMapping *)sharedInstance ; +- (int)getOSXKeyCodeForJavaKey:(int) javaKey; + +@end + +#endif diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobotKeyCode.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobotKeyCode.m new file mode 100644 index 00000000000..eb19f00d922 --- /dev/null +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobotKeyCode.m @@ -0,0 +1,178 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#import "CRobotKeyCode.h" +#import "java_awt_event_KeyEvent.h" + +@implementation CRobotKeyCodeMapping + +@synthesize javaToMacKeyMap; + ++(CRobotKeyCodeMapping *) sharedInstance { + static CRobotKeyCodeMapping *instance = nil; + static dispatch_once_t executeOnce; + + dispatch_once(&executeOnce, ^{ + instance = [[CRobotKeyCodeMapping alloc] init]; + }); + + return instance; +} + +-(id) init { + self = [super init]; + + if (nil != self) { + javaToMacKeyMap = [NSDictionary dictionaryWithObjectsAndKeys : + [NSNumber numberWithInt : OSX_Delete], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_BACK_SPACE], + [NSNumber numberWithInt : OSX_kVK_Tab], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_TAB], + [NSNumber numberWithInt : OSX_kVK_Return], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_ENTER], + [NSNumber numberWithInt : OSX_kVK_ANSI_KeypadClear], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_CLEAR], + [NSNumber numberWithInt : OSX_Shift], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_SHIFT], + [NSNumber numberWithInt : OSX_Control], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_CONTROL], + [NSNumber numberWithInt : OSX_Option], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_ALT], + [NSNumber numberWithInt : OSX_CapsLock], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_CAPS_LOCK], + [NSNumber numberWithInt : OSX_Escape], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_ESCAPE], + [NSNumber numberWithInt : OSX_kVK_Space], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_SPACE], + [NSNumber numberWithInt : OSX_PageUp], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_PAGE_UP], + [NSNumber numberWithInt : OSX_PageDown], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_PAGE_DOWN], + [NSNumber numberWithInt : OSX_End], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_END], + [NSNumber numberWithInt : OSX_Home], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_HOME], + [NSNumber numberWithInt : OSX_LeftArrow], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_LEFT], + [NSNumber numberWithInt : OSX_UpArrow], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_UP], + [NSNumber numberWithInt : OSX_RightArrow], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_RIGHT], + [NSNumber numberWithInt : OSX_DownArrow], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_DOWN], + [NSNumber numberWithInt : OSX_kVK_ANSI_Comma], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_COMMA], + [NSNumber numberWithInt : OSX_kVK_ANSI_Minus], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_MINUS], + [NSNumber numberWithInt : OSX_kVK_ANSI_Period], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_PERIOD], + [NSNumber numberWithInt : OSX_kVK_ANSI_Slash], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_SLASH], + + [NSNumber numberWithInt : OSX_kVK_ANSI_0], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_0], + [NSNumber numberWithInt : OSX_kVK_ANSI_1], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_1], + [NSNumber numberWithInt : OSX_kVK_ANSI_2], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_2], + [NSNumber numberWithInt : OSX_kVK_ANSI_3], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_3], + [NSNumber numberWithInt : OSX_kVK_ANSI_4], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_4], + [NSNumber numberWithInt : OSX_kVK_ANSI_5], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_5], + [NSNumber numberWithInt : OSX_kVK_ANSI_6], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_6], + [NSNumber numberWithInt : OSX_kVK_ANSI_7], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_7], + [NSNumber numberWithInt : OSX_kVK_ANSI_8], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_8], + [NSNumber numberWithInt : OSX_kVK_ANSI_9], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_9], + + [NSNumber numberWithInt : OSX_kVK_ANSI_Semicolon], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_SEMICOLON], + [NSNumber numberWithInt : OSX_kVK_ANSI_Equal], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_EQUALS], + + [NSNumber numberWithInt : OSX_kVK_ANSI_A], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_A], + [NSNumber numberWithInt : OSX_kVK_ANSI_B], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_B], + [NSNumber numberWithInt : OSX_kVK_ANSI_C], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_C], + [NSNumber numberWithInt : OSX_kVK_ANSI_D], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_D], + [NSNumber numberWithInt : OSX_kVK_ANSI_E], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_E], + [NSNumber numberWithInt : OSX_kVK_ANSI_F], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F], + [NSNumber numberWithInt : OSX_kVK_ANSI_G], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_G], + [NSNumber numberWithInt : OSX_kVK_ANSI_H], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_H], + [NSNumber numberWithInt : OSX_kVK_ANSI_I], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_I], + [NSNumber numberWithInt : OSX_kVK_ANSI_J], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_J], + [NSNumber numberWithInt : OSX_kVK_ANSI_K], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_K], + [NSNumber numberWithInt : OSX_kVK_ANSI_L], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_L], + [NSNumber numberWithInt : OSX_kVK_ANSI_M], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_M], + [NSNumber numberWithInt : OSX_kVK_ANSI_N], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_N], + [NSNumber numberWithInt : OSX_kVK_ANSI_O], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_O], + [NSNumber numberWithInt : OSX_kVK_ANSI_P], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_P], + [NSNumber numberWithInt : OSX_kVK_ANSI_Q], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_Q], + [NSNumber numberWithInt : OSX_kVK_ANSI_R], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_R], + [NSNumber numberWithInt : OSX_kVK_ANSI_S], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_S], + [NSNumber numberWithInt : OSX_kVK_ANSI_T], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_T], + [NSNumber numberWithInt : OSX_kVK_ANSI_U], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_U], + [NSNumber numberWithInt : OSX_kVK_ANSI_V], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_V], + [NSNumber numberWithInt : OSX_kVK_ANSI_W], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_W], + [NSNumber numberWithInt : OSX_kVK_ANSI_X], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_X], + [NSNumber numberWithInt : OSX_kVK_ANSI_Y], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_Y], + [NSNumber numberWithInt : OSX_kVK_ANSI_Z], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_Z], + + [NSNumber numberWithInt : OSX_kVK_ANSI_LeftBracket], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_OPEN_BRACKET], + [NSNumber numberWithInt : OSX_kVK_ANSI_Backslash], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_BACK_SLASH], + [NSNumber numberWithInt : OSX_kVK_ANSI_RightBracket], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_CLOSE_BRACKET], + + [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad0], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD0], + [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad1], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD1], + [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad2], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD2], + [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad3], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD3], + [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad4], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD4], + [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad5], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD5], + [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad6], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD6], + [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad7], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD7], + [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad8], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD8], + [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad9], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD9], + + [NSNumber numberWithInt : OSX_kVK_ANSI_KeypadMultiply], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_MULTIPLY], + [NSNumber numberWithInt : OSX_kVK_ANSI_KeypadPlus], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_ADD], + [NSNumber numberWithInt : OSX_kVK_ANSI_KeypadMinus], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_SUBTRACT], + [NSNumber numberWithInt : OSX_kVK_ANSI_KeypadDecimal], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_DECIMAL], + [NSNumber numberWithInt : OSX_kVK_ANSI_KeypadDivide], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_DIVIDE], + + [NSNumber numberWithInt : OSX_F1], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F1], + [NSNumber numberWithInt : OSX_F2], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F2], + [NSNumber numberWithInt : OSX_F3], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F3], + [NSNumber numberWithInt : OSX_F4], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F4], + [NSNumber numberWithInt : OSX_F5], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F5], + [NSNumber numberWithInt : OSX_F6], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F6], + [NSNumber numberWithInt : OSX_F7], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F7], + [NSNumber numberWithInt : OSX_F8], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F8], + [NSNumber numberWithInt : OSX_F9], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F9], + [NSNumber numberWithInt : OSX_F10], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F10], + [NSNumber numberWithInt : OSX_F11], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F11], + [NSNumber numberWithInt : OSX_F12], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F12], + + [NSNumber numberWithInt : OSX_ForwardDelete], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_DELETE], + [NSNumber numberWithInt : OSX_Help], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_HELP], + [NSNumber numberWithInt : OSX_Command], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_META], + [NSNumber numberWithInt : OSX_kVK_ANSI_Grave], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_BACK_QUOTE], + [NSNumber numberWithInt : OSX_kVK_ANSI_Quote], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_QUOTE], + + [NSNumber numberWithInt : OSX_F13], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F13], + [NSNumber numberWithInt : OSX_F14], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F14], + [NSNumber numberWithInt : OSX_F15], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F15], + [NSNumber numberWithInt : OSX_F16], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F16], + [NSNumber numberWithInt : OSX_F17], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F17], + [NSNumber numberWithInt : OSX_F18], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F18], + [NSNumber numberWithInt : OSX_F19], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F19], + [NSNumber numberWithInt : OSX_F20], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F20], + + nil]; + } + + return self; +} + +-(int) getOSXKeyCodeForJavaKey : (int) javaKey { + id val = [javaToMacKeyMap objectForKey : [NSNumber numberWithInt : javaKey]]; + + if (nil != val) { + return [val intValue]; + } else { + return OSX_Undefined; + } +} + +@end diff --git a/jdk/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m b/jdk/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m index 7235367bf60..82619b70244 100644 --- a/jdk/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m +++ b/jdk/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m @@ -133,16 +133,16 @@ BOOL isSWTRunning() { return getenv(envVar) != NULL; } -char* SplashGetScaledImageName(const char* jar, const char* file, - float *scaleFactor) { +jboolean SplashGetScaledImageName(const char* jar, const char* file, + float *scaleFactor, char *scaledFile, + const size_t scaledImageLength) { *scaleFactor = 1; if(isSWTRunning()){ - return nil; + return JNI_FALSE; } NSAutoreleasePool *pool = [NSAutoreleasePool new]; - char* scaledFile = nil; __block float screenScaleFactor = 1; [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ @@ -170,12 +170,18 @@ char* SplashGetScaledImageName(const char* jar, const char* file, if ((fileName2x != nil) && (jar || [[NSFileManager defaultManager] fileExistsAtPath: fileName2x])){ + if (strlen([fileName2x UTF8String]) > scaledImageLength) { + [pool drain]; + return JNI_FALSE; + } *scaleFactor = 2; - scaledFile = strdup([fileName2x UTF8String]); + strcpy(scaledFile, [fileName2x UTF8String]); + [pool drain]; + return JNI_TRUE; } } [pool drain]; - return scaledFile; + return JNI_FALSE; } void diff --git a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java index 16bb987de3a..5b57582bee9 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java +++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java @@ -698,7 +698,7 @@ public class WindowsLookAndFeel extends BasicLookAndFeel // DeskTop. "Desktop.background", new DesktopProperty( - "win.desktop.backgroundColor", + "win.mdi.backgroundColor", table.get("desktop")), "Desktop.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] { @@ -1810,6 +1810,11 @@ public class WindowsLookAndFeel extends BasicLookAndFeel LazyValue menuArrowIcon = t -> WindowsIconFactory.getMenuArrowIcon(); + Color highlight = (Color) Toolkit.getDefaultToolkit(). + getDesktopProperty("win.3d.highlightColor"); + + Color shadow = (Color) Toolkit.getDefaultToolkit(). + getDesktopProperty("win.3d.shadowColor"); Object[] lazyDefaults = { "Button.border", buttonBorder, @@ -1838,8 +1843,12 @@ public class WindowsLookAndFeel extends BasicLookAndFeel "TextArea.margin", textFieldMargin, "TextField.border", textFieldBorder, "TextField.margin", textFieldMargin, - "TitledBorder.border", - new XPBorderValue(Part.BP_GROUPBOX, etchedBorder), + "TitledBorder.border", new UIDefaults.LazyValue() { + public Object createValue(UIDefaults table) { + return new BorderUIResource. + EtchedBorderUIResource(highlight, shadow); + } + }, "ToggleButton.border", radioButtonBorder, "ToolBar.border", toolBarBorder, "ToolTip.border", toolTipBorder, diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileFormat.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileFormat.java index 7a8c5bc6a68..7a91bfc0a75 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileFormat.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -45,11 +45,12 @@ final class AuFileFormat extends AudioFileFormat { static final int AU_LINEAR_24 = 4; /* 24-bit linear PCM */ static final int AU_LINEAR_32 = 5; /* 32-bit linear PCM */ static final int AU_FLOAT = 6; /* 32-bit IEEE floating point */ - static final int AU_DOUBLE = 7; /* 64-bit IEEE floating point */ - static final int AU_ADPCM_G721 = 23; /* 4-bit CCITT g.721 ADPCM */ - static final int AU_ADPCM_G722 = 24; /* CCITT g.722 ADPCM */ - static final int AU_ADPCM_G723_3 = 25; /* CCITT g.723 3-bit ADPCM */ - static final int AU_ADPCM_G723_5 = 26; /* CCITT g.723 5-bit ADPCM */ +// we don't support these ... +// static final int AU_DOUBLE = 7; /* 64-bit IEEE floating point */ +// static final int AU_ADPCM_G721 = 23; /* 4-bit CCITT g.721 ADPCM */ +// static final int AU_ADPCM_G722 = 24; /* CCITT g.722 ADPCM */ +// static final int AU_ADPCM_G723_3 = 25; /* CCITT g.723 3-bit ADPCM */ +// static final int AU_ADPCM_G723_5 = 26; /* CCITT g.723 5-bit ADPCM */ static final int AU_ALAW_8 = 27; /* 8-bit ISDN A-law */ static final int AU_HEADERSIZE = 24; @@ -64,24 +65,28 @@ final class AuFileFormat extends AudioFileFormat { auType = -1; - if( AudioFormat.Encoding.ALAW.equals(encoding) ) { - if( format.getSampleSizeInBits()==8 ) { + if (AudioFormat.Encoding.ALAW.equals(encoding)) { + if (format.getSampleSizeInBits() == 8) { auType = AU_ALAW_8; } - } else if( AudioFormat.Encoding.ULAW.equals(encoding) ) { - if( format.getSampleSizeInBits()==8 ) { + } else if (AudioFormat.Encoding.ULAW.equals(encoding)) { + if (format.getSampleSizeInBits() == 8) { auType = AU_ULAW_8; } - } else if( AudioFormat.Encoding.PCM_SIGNED.equals(encoding) ) { - if( format.getSampleSizeInBits()==8 ) { + } else if (AudioFormat.Encoding.PCM_SIGNED.equals(encoding)) { + if (format.getSampleSizeInBits() == 8) { auType = AU_LINEAR_8; - } else if( format.getSampleSizeInBits()==16 ) { + } else if (format.getSampleSizeInBits() == 16) { auType = AU_LINEAR_16; - } else if( format.getSampleSizeInBits()==24 ) { + } else if (format.getSampleSizeInBits() == 24) { auType = AU_LINEAR_24; - } else if( format.getSampleSizeInBits()==32 ) { + } else if (format.getSampleSizeInBits() == 32) { auType = AU_LINEAR_32; } + } else if (AudioFormat.Encoding.PCM_FLOAT.equals(encoding)) { + if (format.getSampleSizeInBits() == 32) { + auType = AU_FLOAT; + } } } diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileReader.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileReader.java index 180f45c9076..876c3b78e80 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileReader.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -30,6 +30,7 @@ import java.io.IOException; import java.io.InputStream; import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFileFormat.Type; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.UnsupportedAudioFileException; @@ -56,7 +57,7 @@ public final class AuFileReader extends SunFileReader { final int headerSize = dis.readInt(); final int dataSize = dis.readInt(); - final int encoding_local = dis.readInt(); + final int auType = dis.readInt(); final int sampleRate = dis.readInt(); final int channels = dis.readInt(); if (channels <= 0) { @@ -65,40 +66,38 @@ public final class AuFileReader extends SunFileReader { final int sampleSizeInBits; final AudioFormat.Encoding encoding; - switch (encoding_local) { - case AuFileFormat.AU_ULAW_8: - encoding = AudioFormat.Encoding.ULAW; - sampleSizeInBits = 8; - break; - case AuFileFormat.AU_ALAW_8: - encoding = AudioFormat.Encoding.ALAW; - sampleSizeInBits = 8; - break; - case AuFileFormat.AU_LINEAR_8: - // $$jb: 04.29.99: 8bit linear is *signed*, not *unsigned* - encoding = AudioFormat.Encoding.PCM_SIGNED; - sampleSizeInBits = 8; - break; - case AuFileFormat.AU_LINEAR_16: - encoding = AudioFormat.Encoding.PCM_SIGNED; - sampleSizeInBits = 16; - break; - case AuFileFormat.AU_LINEAR_24: - encoding = AudioFormat.Encoding.PCM_SIGNED; - - sampleSizeInBits = 24; - break; - case AuFileFormat.AU_LINEAR_32: - encoding = AudioFormat.Encoding.PCM_SIGNED; - - sampleSizeInBits = 32; - break; - // $jb: 03.19.99: we don't support these ... - /* case AuFileFormat.AU_FLOAT: - encoding = new AudioFormat.FLOAT; - sampleSizeInBits = 32; - break; - case AuFileFormat.AU_DOUBLE: + switch (auType) { + case AuFileFormat.AU_ULAW_8: + encoding = AudioFormat.Encoding.ULAW; + sampleSizeInBits = 8; + break; + case AuFileFormat.AU_ALAW_8: + encoding = AudioFormat.Encoding.ALAW; + sampleSizeInBits = 8; + break; + case AuFileFormat.AU_LINEAR_8: + // $$jb: 04.29.99: 8bit linear is *signed*, not *unsigned* + encoding = AudioFormat.Encoding.PCM_SIGNED; + sampleSizeInBits = 8; + break; + case AuFileFormat.AU_LINEAR_16: + encoding = AudioFormat.Encoding.PCM_SIGNED; + sampleSizeInBits = 16; + break; + case AuFileFormat.AU_LINEAR_24: + encoding = AudioFormat.Encoding.PCM_SIGNED; + sampleSizeInBits = 24; + break; + case AuFileFormat.AU_LINEAR_32: + encoding = AudioFormat.Encoding.PCM_SIGNED; + sampleSizeInBits = 32; + break; + case AuFileFormat.AU_FLOAT: + encoding = AudioFormat.Encoding.PCM_FLOAT; + sampleSizeInBits = 32; + break; + // we don't support these ... + /* case AuFileFormat.AU_DOUBLE: encoding = new AudioFormat.DOUBLE; sampleSizeInBits = 8; break; @@ -117,9 +116,9 @@ public final class AuFileReader extends SunFileReader { SamplePerUnit = 8; break; */ - default: - // unsupported filetype, throw exception - throw new UnsupportedAudioFileException("not a valid AU file"); + default: + // unsupported filetype, throw exception + throw new UnsupportedAudioFileException("not a valid AU file"); } final int frameSize = calculatePCMFrameSize(sampleSizeInBits, channels); @@ -136,7 +135,6 @@ public final class AuFileReader extends SunFileReader { final AudioFormat format = new AudioFormat(encoding, sampleRate, sampleSizeInBits, channels, frameSize, sampleRate, true); - return new AuFileFormat(AudioFileFormat.Type.AU, dataSize + headerSize, - format, length); + return new AuFileFormat(Type.AU, dataSize + headerSize, format, length); } } diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileWriter.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileWriter.java index b498c916435..723ffcd2c42 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileWriter.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileWriter.java @@ -39,6 +39,7 @@ import java.io.SequenceInputStream; import java.util.Objects; import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFileFormat.Type; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; @@ -59,32 +60,32 @@ public final class AuFileWriter extends SunFileWriter { * Constructs a new AuFileWriter object. */ public AuFileWriter() { - super(new AudioFileFormat.Type[]{AudioFileFormat.Type.AU}); + super(new Type[]{Type.AU}); } @Override - public AudioFileFormat.Type[] getAudioFileTypes(AudioInputStream stream) { + public Type[] getAudioFileTypes(AudioInputStream stream) { - AudioFileFormat.Type[] filetypes = new AudioFileFormat.Type[types.length]; + Type[] filetypes = new Type[types.length]; System.arraycopy(types, 0, filetypes, 0, types.length); // make sure we can write this stream AudioFormat format = stream.getFormat(); AudioFormat.Encoding encoding = format.getEncoding(); - if( (AudioFormat.Encoding.ALAW.equals(encoding)) || - (AudioFormat.Encoding.ULAW.equals(encoding)) || - (AudioFormat.Encoding.PCM_SIGNED.equals(encoding)) || - (AudioFormat.Encoding.PCM_UNSIGNED.equals(encoding)) ) { - + if (AudioFormat.Encoding.ALAW.equals(encoding) + || AudioFormat.Encoding.ULAW.equals(encoding) + || AudioFormat.Encoding.PCM_SIGNED.equals(encoding) + || AudioFormat.Encoding.PCM_UNSIGNED.equals(encoding) + || AudioFormat.Encoding.PCM_FLOAT.equals(encoding)) { return filetypes; } - return new AudioFileFormat.Type[0]; + return new Type[0]; } @Override - public int write(AudioInputStream stream, AudioFileFormat.Type fileType, OutputStream out) throws IOException { + public int write(AudioInputStream stream, Type fileType, OutputStream out) throws IOException { Objects.requireNonNull(stream); Objects.requireNonNull(fileType); Objects.requireNonNull(out); @@ -101,7 +102,7 @@ public final class AuFileWriter extends SunFileWriter { } @Override - public int write(AudioInputStream stream, AudioFileFormat.Type fileType, File out) throws IOException { + public int write(AudioInputStream stream, Type fileType, File out) throws IOException { Objects.requireNonNull(stream); Objects.requireNonNull(fileType); Objects.requireNonNull(out); @@ -141,61 +142,35 @@ public final class AuFileWriter extends SunFileWriter { * Returns the AudioFileFormat describing the file that will be written from this AudioInputStream. * Throws IllegalArgumentException if not supported. */ - private AudioFileFormat getAudioFileFormat(AudioFileFormat.Type type, AudioInputStream stream) { + private AudioFileFormat getAudioFileFormat(Type type, AudioInputStream stream) { if (!isFileTypeSupported(type, stream)) { throw new IllegalArgumentException("File type " + type + " not supported."); } - AudioFormat format = null; - AuFileFormat fileFormat = null; - AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED; - AudioFormat streamFormat = stream.getFormat(); - AudioFormat.Encoding streamEncoding = streamFormat.getEncoding(); - - - int sampleSizeInBits; - int fileSize; - - if( (AudioFormat.Encoding.ALAW.equals(streamEncoding)) || - (AudioFormat.Encoding.ULAW.equals(streamEncoding)) ) { - - encoding = streamEncoding; - sampleSizeInBits = streamFormat.getSampleSizeInBits(); - - } else if ( streamFormat.getSampleSizeInBits()==8 ) { + AudioFormat.Encoding encoding = streamFormat.getEncoding(); + if (AudioFormat.Encoding.PCM_UNSIGNED.equals(encoding)) { encoding = AudioFormat.Encoding.PCM_SIGNED; - sampleSizeInBits=8; - - } else { - - encoding = AudioFormat.Encoding.PCM_SIGNED; - sampleSizeInBits=streamFormat.getSampleSizeInBits(); } + // We always write big endian au files, this is by far the standard + AudioFormat format = new AudioFormat(encoding, + streamFormat.getSampleRate(), + streamFormat.getSampleSizeInBits(), + streamFormat.getChannels(), + streamFormat.getFrameSize(), + streamFormat.getFrameRate(), true); - format = new AudioFormat( encoding, - streamFormat.getSampleRate(), - sampleSizeInBits, - streamFormat.getChannels(), - streamFormat.getFrameSize(), - streamFormat.getFrameRate(), - true); // AU is always big endian - - - if( stream.getFrameLength()!=AudioSystem.NOT_SPECIFIED ) { + int fileSize; + if (stream.getFrameLength() != AudioSystem.NOT_SPECIFIED) { fileSize = (int)stream.getFrameLength()*streamFormat.getFrameSize() + AuFileFormat.AU_HEADERSIZE; } else { fileSize = AudioSystem.NOT_SPECIFIED; } - fileFormat = new AuFileFormat( AudioFileFormat.Type.AU, - fileSize, - format, - (int)stream.getFrameLength() ); - - return fileFormat; + return new AuFileFormat(Type.AU, fileSize, format, + (int) stream.getFrameLength()); } private InputStream getFileStream(AuFileFormat auFileFormat, AudioInputStream audioStream) throws IOException { @@ -212,7 +187,7 @@ public final class AuFileWriter extends SunFileWriter { if (dataSizeInBytes>0x7FFFFFFFl) { dataSizeInBytes=UNKNOWN_SIZE; } - int encoding_local = auFileFormat.getAuType(); + int auType = auFileFormat.getAuType(); int sampleRate = (int)format.getSampleRate(); int channels = format.getChannels(); @@ -222,43 +197,17 @@ public final class AuFileWriter extends SunFileWriter { DataOutputStream dos = null; SequenceInputStream auStream = null; - AudioFormat audioStreamFormat = null; - AudioFormat.Encoding encoding = null; - InputStream codedAudioStream = audioStream; - - // if we need to do any format conversion, do it here. - - codedAudioStream = audioStream; - - audioStreamFormat = audioStream.getFormat(); - encoding = audioStreamFormat.getEncoding(); - + // if we need to do any format conversion, we do it here. //$$ fb 2001-07-13: Bug 4391108 - if( (AudioFormat.Encoding.PCM_UNSIGNED.equals(encoding)) || - (AudioFormat.Encoding.PCM_SIGNED.equals(encoding) - && !audioStreamFormat.isBigEndian()) ) { - // We always write big endian au files, this is by far the standard - codedAudioStream = AudioSystem.getAudioInputStream( new AudioFormat ( - AudioFormat.Encoding.PCM_SIGNED, - audioStreamFormat.getSampleRate(), - audioStreamFormat.getSampleSizeInBits(), - audioStreamFormat.getChannels(), - audioStreamFormat.getFrameSize(), - audioStreamFormat.getFrameRate(), - true), - audioStream ); - - - } + audioStream = AudioSystem.getAudioInputStream(format, audioStream); baos = new ByteArrayOutputStream(); dos = new DataOutputStream(baos); - dos.writeInt(AuFileFormat.AU_SUN_MAGIC); dos.writeInt(headerSize); dos.writeInt((int)dataSizeInBytes); - dos.writeInt(encoding_local); + dos.writeInt(auType); dos.writeInt(sampleRate); dos.writeInt(channels); @@ -269,7 +218,7 @@ public final class AuFileWriter extends SunFileWriter { header = baos.toByteArray(); headerStream = new ByteArrayInputStream( header ); auStream = new SequenceInputStream(headerStream, - new NoCloseInputStream(codedAudioStream)); + new NoCloseInputStream(audioStream)); return auStream; } diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/RIFFReader.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/RIFFReader.java index 93c1a058294..255c42099ec 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/RIFFReader.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/RIFFReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -39,12 +39,12 @@ public final class RIFFReader extends InputStream { private long filepointer = 0; private final String fourcc; private String riff_type = null; - private long ckSize = Integer.MAX_VALUE; + private final long ckSize; private InputStream stream; - private long avail = Integer.MAX_VALUE; + private long avail = 0xffffffffL; // MAX_UNSIGNED_INT private RIFFReader lastiterator = null; - public RIFFReader(InputStream stream) throws IOException { + public RIFFReader(final InputStream stream) throws IOException { if (stream instanceof RIFFReader) { root = ((RIFFReader) stream).root; @@ -63,11 +63,13 @@ public final class RIFFReader extends InputStream { // because it is expected to // always contain a string value riff_type = null; + ckSize = 0; avail = 0; return; } - if (b != 0) + if (b != 0) { break; + } } byte[] fourcc = new byte[4]; @@ -78,9 +80,6 @@ public final class RIFFReader extends InputStream { avail = ckSize; if (getFormat().equals("RIFF") || getFormat().equals("LIST")) { - if (avail > Integer.MAX_VALUE) { - throw new RIFFInvalidDataException("Chunk size too big"); - } byte[] format = new byte[4]; readFully(format); this.riff_type = new String(format, "ascii"); @@ -207,7 +206,7 @@ public final class RIFFReader extends InputStream { @Override public int available() { - return (int)avail; + return avail > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) avail; } public void finish() throws IOException { diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/WaveExtensibleFileReader.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/WaveExtensibleFileReader.java index 9085c58b530..7d6ec18239b 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/WaveExtensibleFileReader.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/WaveExtensibleFileReader.java @@ -184,6 +184,7 @@ public final class WaveExtensibleFileReader extends SunFileReader { // long framerate = 1; int framesize = 1; int bits = 1; + long dataSize = 0; int validBitsPerSample = 1; long channelMask = 0; GUID subFormat = null; @@ -214,6 +215,7 @@ public final class WaveExtensibleFileReader extends SunFileReader { } if (chunk.getFormat().equals("data")) { + dataSize = chunk.getSize(); data_found = true; break; } @@ -247,8 +249,12 @@ public final class WaveExtensibleFileReader extends SunFileReader { } else { throw new UnsupportedAudioFileException(); } + long frameLength = dataSize / audioformat.getFrameSize(); + if (frameLength > Integer.MAX_VALUE) { + frameLength = AudioSystem.NOT_SPECIFIED; + } return new AudioFileFormat(AudioFileFormat.Type.WAVE, audioformat, - AudioSystem.NOT_SPECIFIED); + (int) frameLength); } @Override diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileReader.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileReader.java index 6639cf040e8..284877d1599 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileReader.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileReader.java @@ -59,10 +59,10 @@ public final class WaveFloatFileReader extends SunFileReader { long samplerate = 1; int framesize = 1; int bits = 1; + long dataSize = 0; while (riffiterator.hasNextChunk()) { RIFFReader chunk = riffiterator.nextChunk(); - if (chunk.getFormat().equals("fmt ")) { fmt_found = true; @@ -77,6 +77,7 @@ public final class WaveFloatFileReader extends SunFileReader { bits = chunk.readUnsignedShort(); } if (chunk.getFormat().equals("data")) { + dataSize = chunk.getSize(); data_found = true; break; } @@ -87,8 +88,13 @@ public final class WaveFloatFileReader extends SunFileReader { AudioFormat audioformat = new AudioFormat( Encoding.PCM_FLOAT, samplerate, bits, channels, framesize, samplerate, false); + long frameLength = dataSize / audioformat.getFrameSize(); + if (frameLength > Integer.MAX_VALUE) { + frameLength = AudioSystem.NOT_SPECIFIED; + } + return new AudioFileFormat(AudioFileFormat.Type.WAVE, audioformat, - AudioSystem.NOT_SPECIFIED); + (int) frameLength); } @Override diff --git a/jdk/src/java.desktop/share/classes/java/awt/Desktop.java b/jdk/src/java.desktop/share/classes/java/awt/Desktop.java index 96f3d57e235..2cb38519ed5 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/Desktop.java +++ b/jdk/src/java.desktop/share/classes/java/awt/Desktop.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -25,6 +25,14 @@ package java.awt; +import java.awt.desktop.AboutHandler; +import java.awt.desktop.OpenFilesHandler; +import java.awt.desktop.OpenURIHandler; +import java.awt.desktop.PreferencesHandler; +import java.awt.desktop.PrintFilesHandler; +import java.awt.desktop.QuitHandler; +import java.awt.desktop.QuitStrategy; +import java.awt.desktop.SystemEventListener; import java.awt.peer.DesktopPeer; import java.io.File; import java.io.FilePermission; @@ -35,12 +43,11 @@ import java.net.URISyntaxException; import java.net.URL; import sun.awt.SunToolkit; +import javax.swing.JMenuBar; import sun.security.util.SecurityConstants; /** - * The {@code Desktop} class allows a Java application to launch - * associated applications registered on the native desktop to handle - * a {@link java.net.URI} or a file. + * The {@code Desktop} class allows interact with various desktop capabilities. * *

    Supported operations include: *

      @@ -58,9 +65,11 @@ import sun.security.util.SecurityConstants; * or file. If there is no associated application or the associated * application fails to be launched, an exception is thrown. * - *

      An application is registered to a URI or file type; for - * example, the {@code "sxi"} file extension is typically registered - * to StarOffice. The mechanism of registering, accessing, and + * Please see {@link Desktop.Action} for the full list of supported operations + * and capabilities. + * + *

      An application is registered to a URI or file type. + * The mechanism of registering, accessing, and * launching the associated application is platform-dependent. * *

      Each operation is an action type represented by the {@link @@ -70,6 +79,8 @@ import sun.security.util.SecurityConstants; * application is executed, it will be executed on the same system as * the one on which the Java application was launched. * + * @see Action + * * @since 1.6 * @author Armin Chen * @author George Zhang @@ -106,11 +117,145 @@ public class Desktop { * @see Desktop#mail(java.net.URI) */ MAIL, + /** * Represents a "browse" action. * @see Desktop#browse(java.net.URI) */ - BROWSE + BROWSE, + + /** + * Represents an AppForegroundListener + * @see java.awt.desktop.AppForegroundListener + * @since 9 + */ + APP_EVENT_FOREGROUND, + + /** + * Represents an AppHiddenListener + * @see java.awt.desktop.AppHiddenListener + * @since 9 + */ + APP_EVENT_HIDDEN, + + /** + * Represents an AppReopenedListener + * @see java.awt.desktop.AppReopenedListener + * @since 9 + */ + APP_EVENT_REOPENED, + + /** + * Represents a ScreenSleepListener + * @see java.awt.desktop.ScreenSleepListener + * @since 9 + */ + APP_EVENT_SCREEN_SLEEP, + + /** + * Represents a SystemSleepListener + * @see java.awt.desktop.SystemSleepListener + * @since 9 + */ + APP_EVENT_SYSTEM_SLEEP, + + /** + * Represents a UserSessionListener + * @see java.awt.desktop.UserSessionListener + * @since 9 + */ + APP_EVENT_USER_SESSION, + + /** + * Represents an AboutHandler + * @see #setAboutHandler(java.awt.desktop.AboutHandler) + * @since 9 + */ + APP_ABOUT, + + /** + * Represents a PreferencesHandler + * @see #setPreferencesHandler(java.awt.desktop.PreferencesHandler) + * @since 9 + */ + APP_PREFERENCES, + + /** + * Represents an OpenFilesHandler + * @see #setOpenFileHandler(java.awt.desktop.OpenFilesHandler) + * @since 9 + */ + APP_OPEN_FILE, + + /** + * Represents a PrintFilesHandler + * @see #setPrintFileHandler(java.awt.desktop.PrintFilesHandler) + * @since 9 + */ + APP_PRINT_FILE, + + /** + * Represents an OpenURIHandler + * @see #setOpenURIHandler(java.awt.desktop.OpenURIHandler) + * @since 9 + */ + APP_OPEN_URI, + + /** + * Represents a QuitHandler + * @see #setQuitHandler(java.awt.desktop.QuitHandler) + * @since 9 + */ + APP_QUIT_HANDLER, + + /** + * Represents a QuitStrategy + * @see #setQuitStrategy(java.awt.desktop.QuitStrategy) + * @since 9 + */ + APP_QUIT_STRATEGY, + + /** + * Represents a SuddenTermination + * @see #enableSuddenTermination() + * @since 9 + */ + APP_SUDDEN_TERMINATION, + + /** + * Represents a requestForeground + * @see #requestForeground(boolean) + * @since 9 + */ + APP_REQUEST_FOREGROUND, + + /** + * Represents a HelpViewer + * @see #openHelpViewer() + * @since 9 + */ + APP_HELP_VIEWER, + + /** + * Represents a menu bar + * @see #setDefaultMenuBar(javax.swing.JMenuBar) + * @since 9 + */ + APP_MENU_BAR, + + /** + * Represents a browse file directory + * @see #browseFileDirectory(java.io.File) + * @since 9 + */ + BROWSE_FILE_DIR, + + /** + * Represents a move to trash + * @see #moveToTrash(java.io.File) + * @since 9 + */ + MOVE_TO_TRASH }; private DesktopPeer peer; @@ -128,10 +273,10 @@ public class Desktop { /** * Returns the {@code Desktop} instance of the current - * browser context. On some platforms the Desktop API may not be + * desktop context. On some platforms the Desktop API may not be * supported; use the {@link #isDesktopSupported} method to * determine if the current desktop is supported. - * @return the Desktop instance of the current browser context + * @return the Desktop instance * @throws HeadlessException if {@link * GraphicsEnvironment#isHeadless()} returns {@code true} * @throws UnsupportedOperationException if this class is not @@ -208,7 +353,7 @@ public class Desktop { if (!file.exists()) { throw new IllegalArgumentException("The file: " - + file.getPath() + " doesn't exist."); + + file.getPath() + " doesn't exist."); } file.canRead(); @@ -224,7 +369,7 @@ public class Desktop { private void checkActionSupport(Action actionType){ if (!isSupported(actionType)) { throw new UnsupportedOperationException("The " + actionType.name() - + " action is not supported on the current platform!"); + + " action is not supported on the current platform!"); } } @@ -238,7 +383,7 @@ public class Desktop { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new AWTPermission( - "showWindowWithoutWarningBanner")); + "showWindowWithoutWarningBanner")); } } @@ -479,7 +624,409 @@ public class Desktop { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new FilePermission("<>", - SecurityConstants.FILE_EXECUTE_ACTION)); + SecurityConstants.FILE_EXECUTE_ACTION)); } } + + private void checkRead() throws SecurityException { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new FilePermission("<>", + SecurityConstants.FILE_READ_ACTION)); + } + } + + private void checkDelete() throws SecurityException { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new FilePermission("<>", + SecurityConstants.FILE_DELETE_ACTION)); + } + } + + private void checkQuitPermission() { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkExit(0); + } + } + + /** + * Adds sub-types of {@link SystemEventListener} to listen for notifications + * from the native system. + * + * Has no effect if SystemEventListener's sub-type is unsupported on the current + * platform. + * + * @param listener listener + * + * @throws SecurityException if a security manager exists and it + * denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} + * permission + * + * @see java.awt.desktop.AppForegroundListener + * @see java.awt.desktop.AppHiddenListener + * @see java.awt.desktop.AppReopenedListener + * @see java.awt.desktop.ScreenSleepListener + * @see java.awt.desktop.SystemSleepListener + * @see java.awt.desktop.UserSessionListener + * @since 9 + */ + public void addAppEventListener(final SystemEventListener listener) { + checkAWTPermission(); + peer.addAppEventListener(listener); + } + + /** + * Removes sub-types of {@link SystemEventListener} to listen for notifications + * from the native system. + * + * Has no effect if SystemEventListener's sub-type is unsupported on the current + * platform. + * + * @param listener listener + * + * @throws SecurityException if a security manager exists and it + * denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} + * permission + * + * @see java.awt.desktop.AppForegroundListener + * @see java.awt.desktop.AppHiddenListener + * @see java.awt.desktop.AppReopenedListener + * @see java.awt.desktop.ScreenSleepListener + * @see java.awt.desktop.SystemSleepListener + * @see java.awt.desktop.UserSessionListener + * @since 9 + */ + public void removeAppEventListener(final SystemEventListener listener) { + checkAWTPermission(); + peer.removeAppEventListener(listener); + } + + /** + * Installs a handler to show a custom About window for your application. + *

      + * Setting the {@link java.awt.desktop.AboutHandler} to {@code null} reverts it to the + * default behavior. + * + * @param aboutHandler the handler to respond to the + * {@link java.awt.desktop.AboutHandler#handleAbout} )} message + * + * @throws SecurityException if a security manager exists and it + * denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} + * permission + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Desktop.Action#APP_ABOUT} action + * + * @since 9 + */ + public void setAboutHandler(final AboutHandler aboutHandler) { + checkAWTPermission(); + checkActionSupport(Action.APP_ABOUT); + peer.setAboutHandler(aboutHandler); + } + + /** + * Installs a handler to show a custom Preferences window for your + * application. + *

      + * Setting the {@link PreferencesHandler} to {@code null} reverts it to + * the default behavior + * + * @param preferencesHandler the handler to respond to the + * {@link PreferencesHandler#handlePreferences(PreferencesEvent)} + * + * @throws SecurityException if a security manager exists and it + * denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} + * permission + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Desktop.Action#APP_PREFERENCES} action + * @since 9 + */ + public void setPreferencesHandler(final PreferencesHandler preferencesHandler) { + checkAWTPermission(); + checkActionSupport(Action.APP_PREFERENCES); + peer.setPreferencesHandler(preferencesHandler); + } + + /** + * Installs the handler which is notified when the application is asked to + * open a list of files. + * + * @implNote Please note that for Mac OS, notifications + * are only sent if the Java app is a bundled application, + * with a {@code CFBundleDocumentTypes} array present in its + * Info.plist. See the + * + * Info.plist Key Reference for more information about adding a + * {@code CFBundleDocumentTypes} key to your app's Info.plist. + * + * @param openFileHandler handler + * + * @throws SecurityException if a security manager exists and its + * {@link java.lang.SecurityManager#checkRead(java.lang.String)} + * method denies read access to the files, or it denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} + * permission, or the calling thread is not allowed to create a + * subprocess + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Desktop.Action#APP_OPEN_FILE} action + * @since 9 + */ + public void setOpenFileHandler(final OpenFilesHandler openFileHandler) { + checkAWTPermission(); + checkExec(); + checkRead(); + checkActionSupport(Action.APP_OPEN_FILE); + peer.setOpenFileHandler(openFileHandler); + } + + /** + * Installs the handler which is notified when the application is asked to + * print a list of files. + * + * @implNote Please note that for Mac OS, notifications + * are only sent if the Java app is a bundled application, + * with a {@code CFBundleDocumentTypes} array present in its + * Info.plist. See the + * + * Info.plist Key Reference for more information about adding a + * {@code CFBundleDocumentTypes} key to your app's Info.plist. + * + * @param printFileHandler handler + * @throws SecurityException if a security manager exists and its + * {@link java.lang.SecurityManager#checkPrintJobAccess()} method denies + * the permission to print. + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Desktop.Action#APP_PRINT_FILE} action + * @since 9 + */ + public void setPrintFileHandler(final PrintFilesHandler printFileHandler) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPrintJobAccess(); + } + checkActionSupport(Action.APP_PRINT_FILE); + peer.setPrintFileHandler(printFileHandler); + } + + /** + * Installs the handler which is notified when the application is asked to + * open a URL. + * + * Setting the handler to {@code null} causes all + * {@link OpenURIHandler#openURI(AppEvent.OpenURIEvent)} requests to be + * enqueued until another handler is set. + * + * @implNote Please note that for Mac OS, notifications + * are only sent if the Java app is a bundled application, + * with a {@code CFBundleDocumentTypes} array present in its + * Info.plist. See the + * + * Info.plist Key Reference for more information about adding a + * {@code CFBundleDocumentTypes} key to your app's Info.plist. + * + * @param openURIHandler handler + * + * {@code AWTPermission("showWindowWithoutWarningBanner")} + * permission, or the calling thread is not allowed to create a + * subprocess + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Desktop.Action#APP_OPEN_URI} action + * @since 9 + */ + public void setOpenURIHandler(final OpenURIHandler openURIHandler) { + checkAWTPermission(); + checkExec(); + checkActionSupport(Action.APP_OPEN_URI); + peer.setOpenURIHandler(openURIHandler); + } + + /** + * Installs the handler which determines if the application should quit. The + * handler is passed a one-shot {@link java.awt.desktop.QuitResponse} which can cancel or + * proceed with the quit. Setting the handler to {@code null} causes + * all quit requests to directly perform the default {@link QuitStrategy}. + * + * @param quitHandler the handler that is called when the application is + * asked to quit + * + * @throws SecurityException if a security manager exists and it + * will not allow the caller to invoke {@code System.exit} + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Desktop.Action#APP_QUIT_HANDLER} action + * @since 9 + */ + public void setQuitHandler(final QuitHandler quitHandler) { + checkQuitPermission(); + checkActionSupport(Action.APP_QUIT_HANDLER); + peer.setQuitHandler(quitHandler); + } + + /** + * Sets the default strategy used to quit this application. The default is + * calling SYSTEM_EXIT_0. + * + * @param strategy the way this application should be shutdown + * + * @throws SecurityException if a security manager exists and it + * will not allow the caller to invoke {@code System.exit} + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Desktop.Action#APP_QUIT_STRATEGY} action + * @see QuitStrategy + * @since 9 + */ + public void setQuitStrategy(final QuitStrategy strategy) { + checkQuitPermission(); + checkActionSupport(Action.APP_QUIT_STRATEGY); + peer.setQuitStrategy(strategy); + } + + /** + * Enables this application to be suddenly terminated. + * + * Call this method to indicate your application's state is saved, and + * requires no notification to be terminated. Letting your application + * remain terminatable improves the user experience by avoiding re-paging in + * your application when it's asked to quit. + * + * Note: enabling sudden termination will allow your application to be + * quit without notifying your QuitHandler, or running any shutdown + * hooks. + * E.g. user-initiated Cmd-Q, logout, restart, or shutdown requests will + * effectively "kill -KILL" your application. + * + * @throws SecurityException if a security manager exists and it + * will not allow the caller to invoke {@code System.exit} + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Desktop.Action#APP_SUDDEN_TERMINATION} action + * @see #disableSuddenTermination() + * @since 9 + */ + public void enableSuddenTermination() { + checkQuitPermission(); + checkActionSupport(Action.APP_SUDDEN_TERMINATION); + peer.enableSuddenTermination(); + } + + /** + * Prevents this application from being suddenly terminated. + * + * Call this method to indicate that your application has unsaved state, and + * may not be terminated without notification. + * + * @throws SecurityException if a security manager exists and it + * will not allow the caller to invoke {@code System.exit} + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Desktop.Action#APP_SUDDEN_TERMINATION} action + * @see #enableSuddenTermination() + * @since 9 + */ + public void disableSuddenTermination() { + checkQuitPermission(); + checkActionSupport(Action.APP_SUDDEN_TERMINATION); + peer.disableSuddenTermination(); + } + + /** + * Requests this application to move to the foreground. + * + * @param allWindows if all windows of this application should be moved to + * the foreground, or only the foremost one + * @throws SecurityException if a security manager exists and it denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Desktop.Action#APP_REQUEST_FOREGROUND} action + * @since 9 + */ + public void requestForeground(final boolean allWindows) { + checkAWTPermission(); + checkActionSupport(Action.APP_REQUEST_FOREGROUND); + peer.requestForeground(allWindows); + } + + /** + * Opens the native help viewer application. + * + * @implNote Please note that for Mac OS, it opens the native help viewer + * application if a Help Book has been added to the application bundler + * and registered in the Info.plist with CFBundleHelpBookFolder + * + * @throws SecurityException if a security manager exists and it denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Desktop.Action#APP_HELP_VIEWER} action + * @since 9 + */ + public void openHelpViewer() { + checkAWTPermission(); + checkActionSupport(Action.APP_HELP_VIEWER); + peer.openHelpViewer(); + } + + /** + * Sets the default menu bar to use when there are no active frames. + * + * @implNote Aqua Look and Feel should be active to support this on Mac OS. + * + * @param menuBar to use when no other frames are active + * @throws SecurityException if a security manager exists and it denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Desktop.Action#APP_MENU_BAR} action + * @since 9 + */ + public void setDefaultMenuBar(final JMenuBar menuBar) { + checkAWTPermission(); + checkActionSupport(Action.APP_MENU_BAR); + peer.setDefaultMenuBar(menuBar); + } + + /** + * Opens a folder containing the {@code file} and selects it + * in a default system file manager. + * @param file the file + * @throws SecurityException If a security manager exists and its + * {@link SecurityManager#checkRead(java.lang.String)} method + * denies read access to the file + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Desktop.Action#BROWSE_FILE_DIR} action + * @throws NullPointerException if {@code file} is {@code null} + * @throws IllegalArgumentException if the specified file doesn't + * exist + * @since 9 + */ + public void browseFileDirectory(File file) { + checkRead(); + checkActionSupport(Action.BROWSE_FILE_DIR); + checkFileValidation(file); + peer.browseFileDirectory(file); + } + + /** + * Moves the specified file to the trash. + * + * @param file the file + * @return returns true if successfully moved the file to the trash. + * @throws SecurityException If a security manager exists and its + * {@link SecurityManager#checkWrite(java.lang.String)} method + * denies write access to the file + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Desktop.Action#MOVE_TO_TRASH} action + * @throws NullPointerException if {@code file} is {@code null} + * @throws IllegalArgumentException if the specified file doesn't + * exist + * + * @since 9 + */ + public boolean moveToTrash(final File file) { + checkDelete(); + checkActionSupport(Action.MOVE_TO_TRASH); + checkFileValidation(file); + return peer.moveToTrash(file); + } } diff --git a/jdk/src/java.desktop/share/classes/java/awt/Font.java b/jdk/src/java.desktop/share/classes/java/awt/Font.java index 261ee156acf..8edd2227bad 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/Font.java +++ b/jdk/src/java.desktop/share/classes/java/awt/Font.java @@ -611,8 +611,9 @@ public class Font implements java.io.Serializable * so that when the Font2D is GC'd it can also remove the file. */ FontManager fm = FontManagerFactory.getInstance(); - this.font2DHandle = fm.createFont2D(fontFile, fontFormat, isCopy, - tracker).handle; + Font2D[] fonts = + fm.createFont2D(fontFile, fontFormat, false, isCopy, tracker); + this.font2DHandle = fonts[0].handle; this.name = this.font2DHandle.font2D.getFontName(Locale.getDefault()); this.style = Font.PLAIN; this.size = 1; @@ -841,6 +842,132 @@ public class Font implements java.io.Serializable return hasPerm; } + + /** + * Returns a new array of {@code Font} decoded from the specified stream. + * The returned {@code Font[]} will have at least one element. + *

      + * The explicit purpose of this variation on the + * {@code createFont(int, InputStream)} method is to support font + * sources which represent a TrueType/OpenType font collection and + * be able to return all individual fonts in that collection. + * Consequently this method will throw {@code FontFormatException} + * if the data source does not contain at least one TrueType/OpenType + * font. The same exception will also be thrown if any of the fonts in + * the collection does not contain the required font tables. + *

      + * The condition "at least one", allows for the stream to represent + * a single OpenType/TrueType font. That is, it does not have to be + * a collection. + * Each {@code Font} element of the returned array is + * created with a point size of 1 and style {@link #PLAIN PLAIN}. + * This base font can then be used with the {@code deriveFont} + * methods in this class to derive new {@code Font} objects with + * varying sizes, styles, transforms and font features. + *

      This method does not close the {@link InputStream}. + *

      + * To make each {@code Font} available to Font constructors it + * must be registered in the {@code GraphicsEnvironment} by calling + * {@link GraphicsEnvironment#registerFont(Font) registerFont(Font)}. + * @param fontStream an {@code InputStream} object representing the + * input data for the font or font collection. + * @return a new {@code Font[]}. + * @throws FontFormatException if the {@code fontStream} data does + * not contain the required font tables for any of the elements of + * the collection, or if it contains no fonts at all. + * @throws IOException if the {@code fontStream} cannot be completely read. + * @see GraphicsEnvironment#registerFont(Font) + * @since 9 + */ + public static Font[] createFonts(InputStream fontStream) + throws FontFormatException, IOException { + + final int fontFormat = Font.TRUETYPE_FONT; + if (hasTempPermission()) { + return createFont0(fontFormat, fontStream, true, null); + } + + // Otherwise, be extra conscious of pending temp file creation and + // resourcefully handle the temp file resources, among other things. + CreatedFontTracker tracker = CreatedFontTracker.getTracker(); + boolean acquired = false; + try { + acquired = tracker.acquirePermit(); + if (!acquired) { + throw new IOException("Timed out waiting for resources."); + } + return createFont0(fontFormat, fontStream, true, tracker); + } catch (InterruptedException e) { + throw new IOException("Problem reading font data."); + } finally { + if (acquired) { + tracker.releasePermit(); + } + } + } + + /* used to implement Font.createFont */ + private Font(Font2D font2D) { + + this.createdFont = true; + this.font2DHandle = font2D.handle; + this.name = font2D.getFontName(Locale.getDefault()); + this.style = Font.PLAIN; + this.size = 1; + this.pointSize = 1f; + } + + /** + * Returns a new array of {@code Font} decoded from the specified file. + * The returned {@code Font[]} will have at least one element. + *

      + * The explicit purpose of this variation on the + * {@code createFont(int, File)} method is to support font + * sources which represent a TrueType/OpenType font collection and + * be able to return all individual fonts in that collection. + * Consequently this method will throw {@code FontFormatException} + * if the data source does not contain at least one TrueType/OpenType + * font. The same exception will also be thrown if any of the fonts in + * the collection does not contain the required font tables. + *

      + * The condition "at least one", allows for the stream to represent + * a single OpenType/TrueType font. That is, it does not have to be + * a collection. + * Each {@code Font} element of the returned array is + * created with a point size of 1 and style {@link #PLAIN PLAIN}. + * This base font can then be used with the {@code deriveFont} + * methods in this class to derive new {@code Font} objects with + * varying sizes, styles, transforms and font features. + *

      + * To make each {@code Font} available to Font constructors it + * must be registered in the {@code GraphicsEnvironment} by calling + * {@link GraphicsEnvironment#registerFont(Font) registerFont(Font)}. + * @param fontFile a {@code File} object containing the + * input data for the font or font collection. + * @return a new {@code Font[]}. + * @throws FontFormatException if the {@code File} does + * not contain the required font tables for any of the elements of + * the collection, or if it contains no fonts at all. + * @throws IOException if the {@code fontFile} cannot be read. + * @see GraphicsEnvironment#registerFont(Font) + * @since 9 + */ + public static Font[] createFonts(File fontFile) + throws FontFormatException, IOException + { + int fontFormat = Font.TRUETYPE_FONT; + fontFile = checkFontFile(fontFormat, fontFile); + FontManager fm = FontManagerFactory.getInstance(); + Font2D[] font2DArr = + fm.createFont2D(fontFile, fontFormat, true, false, null); + int num = font2DArr.length; + Font[] fonts = new Font[num]; + for (int i = 0; i < num; i++) { + fonts[i] = new Font(font2DArr[i]); + } + return fonts; + } + /** * Returns a new {@code Font} using the specified font type * and input data. The new {@code Font} is @@ -873,7 +1000,7 @@ public class Font implements java.io.Serializable throws java.awt.FontFormatException, java.io.IOException { if (hasTempPermission()) { - return createFont0(fontFormat, fontStream, null); + return createFont0(fontFormat, fontStream, false, null)[0]; } // Otherwise, be extra conscious of pending temp file creation and @@ -885,7 +1012,7 @@ public class Font implements java.io.Serializable if (!acquired) { throw new IOException("Timed out waiting for resources."); } - return createFont0(fontFormat, fontStream, tracker); + return createFont0(fontFormat, fontStream, false, tracker)[0]; } catch (InterruptedException e) { throw new IOException("Problem reading font data."); } finally { @@ -895,8 +1022,9 @@ public class Font implements java.io.Serializable } } - private static Font createFont0(int fontFormat, InputStream fontStream, - CreatedFontTracker tracker) + private static Font[] createFont0(int fontFormat, InputStream fontStream, + boolean allFonts, + CreatedFontTracker tracker) throws java.awt.FontFormatException, java.io.IOException { if (fontFormat != Font.TRUETYPE_FONT && @@ -965,8 +1093,15 @@ public class Font implements java.io.Serializable * without waiting for the results of that constructor. */ copiedFontData = true; - Font font = new Font(tFile, fontFormat, true, tracker); - return font; + FontManager fm = FontManagerFactory.getInstance(); + Font2D[] font2DArr = + fm.createFont2D(tFile, fontFormat, allFonts, true, tracker); + int num = font2DArr.length; + Font[] fonts = new Font[num]; + for (int i = 0; i < num; i++) { + fonts[i] = new Font(font2DArr[i]); + } + return fonts; } finally { if (tracker != null) { tracker.remove(tFile); @@ -1037,6 +1172,13 @@ public class Font implements java.io.Serializable public static Font createFont(int fontFormat, File fontFile) throws java.awt.FontFormatException, java.io.IOException { + fontFile = checkFontFile(fontFormat, fontFile); + return new Font(fontFile, fontFormat, false, null); + } + + private static File checkFontFile(int fontFormat, File fontFile) + throws FontFormatException, IOException { + fontFile = new File(fontFile.getPath()); if (fontFormat != Font.TRUETYPE_FONT && @@ -1052,7 +1194,7 @@ public class Font implements java.io.Serializable if (!fontFile.canRead()) { throw new IOException("Can't read " + fontFile); } - return new Font(fontFile, fontFormat, false, null); + return fontFile; } /** diff --git a/jdk/src/java.desktop/share/classes/java/awt/Frame.java b/jdk/src/java.desktop/share/classes/java/awt/Frame.java index 973883ac99b..2936ea7048d 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/Frame.java +++ b/jdk/src/java.desktop/share/classes/java/awt/Frame.java @@ -38,6 +38,7 @@ import javax.accessibility.AccessibleContext; import javax.accessibility.AccessibleRole; import javax.accessibility.AccessibleState; import javax.accessibility.AccessibleStateSet; +import javax.swing.WindowConstants; import sun.awt.AWTAccessor; import sun.awt.SunToolkit; diff --git a/jdk/src/java.desktop/share/classes/java/awt/SplashScreen.java b/jdk/src/java.desktop/share/classes/java/awt/SplashScreen.java index 4b6fab00428..952a6dc5bf2 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/SplashScreen.java +++ b/jdk/src/java.desktop/share/classes/java/awt/SplashScreen.java @@ -251,7 +251,7 @@ public final class SplashScreen { assert scale > 0; if (scale > 0 && scale != 1) { bounds.setSize((int) (bounds.getWidth() / scale), - (int) (bounds.getWidth() / scale)); + (int) (bounds.getHeight() / scale)); } return bounds; } diff --git a/jdk/src/java.desktop/share/classes/java/awt/Taskbar.java b/jdk/src/java.desktop/share/classes/java/awt/Taskbar.java new file mode 100644 index 00000000000..64bb2553459 --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/Taskbar.java @@ -0,0 +1,449 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.awt; + +import java.awt.peer.TaskbarPeer; +import sun.awt.SunToolkit; + +/** + * The {@code Taskbar} class allows a Java application to interact with + * the system task area (taskbar, Dock, etc.). + * + *

      + * There are a variety of interactions depending on the current platform such as + * displaying progress of some task, appending user-specified menu to the application + * icon context menu, etc. + * + * @implNote Linux support is currently limited to Unity. However to make these + * features work on Unity, the app should be run from a .desktop file with + * specified {@code java.desktop.appName} system property set to this .desktop + * file name: + * {@code Exec=java -Djava.desktop.appName=MyApp.desktop -jar /path/to/myapp.jar} + * see + * https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles + * + * @since 9 + */ + +public class Taskbar { + + /** + * List of provided features. Each platform supports a different + * set of features. You may use the {@link Taskbar#isSupported} + * method to determine if the given feature is supported by the + * current platform. + */ + public static enum Feature { + + /** + * Represents a textual icon badge feature. + * @see #setIconBadge(java.lang.String) + */ + ICON_BADGE_TEXT, + + /** + * Represents a numerical icon badge feature. + * @see #setIconBadge(java.lang.String) + */ + ICON_BADGE_NUMBER, + + /** + * Represents a graphical icon badge feature for a window. + * @see #setWindowIconBadge(java.awt.Window, java.awt.Image) + */ + ICON_BADGE_IMAGE_WINDOW, + + /** + * Represents an icon feature. + * @see #setIconImage(java.awt.Image) + */ + ICON_IMAGE, + + /** + * Represents a menu feature. + * @see #setMenu(java.awt.PopupMenu) + * @see #getMenu() + */ + MENU, + + /** + * Represents a progress state feature for a specified window. + * @see #setWindowProgressState(java.awt.Window, State) + */ + PROGRESS_STATE_WINDOW, + + /** + * Represents a progress value feature. + * @see #setProgressValue(int) + */ + PROGRESS_VALUE, + + /** + * Represents a progress value feature for a specified window. + * @see #setWindowProgressValue(java.awt.Window, int) + */ + PROGRESS_VALUE_WINDOW, + + /** + * Represents a user attention request feature. + * @see #requestUserAttention(boolean, boolean) + */ + USER_ATTENTION, + + /** + * Represents a user attention request feature for a specified window. + * @see #requestWindowUserAttention(java.awt.Window) + */ + USER_ATTENTION_WINDOW + } + + /** + * Kinds of available window progress states. + * + * @see #setWindowProgressState(java.awt.Window, java.awt.Taskbar.State) + */ + public static enum State { + /** + * Stops displaying the progress. + */ + OFF, + /** + * The progress indicator displays with normal color and determinate + * mode. + */ + NORMAL, + /** + * Shows progress as paused, progress can be resumed by the user. + * Switches to the determinate display. + */ + PAUSED, + /** + * The progress indicator displays activity without specifying what + * proportion of the progress is complete. + */ + INDETERMINATE, + /** + * Shows that an error has occurred. Switches to the determinate + * display. + */ + ERROR + } + + private TaskbarPeer peer; + + /** + * Tests whether a {@code Feature} is supported on the current platform. + * @param feature the specified {@link Feature} + * @return true if the specified feature is supported on the current platform + */ + public boolean isSupported(Feature feature) { + return peer.isSupported(feature); + } + + /** + * Checks if the feature type is supported. + * + * @param featureType the action type in question + * @throws UnsupportedOperationException if the specified action type is not + * supported on the current platform + */ + private void checkFeatureSupport(Feature featureType){ + if (!isSupported(featureType)) { + throw new UnsupportedOperationException("The " + featureType.name() + + " feature is not supported on the current platform!"); + } + } + + /** + * Calls to the security manager's {@code checkPermission} method with + * an {@code AWTPermission("showWindowWithoutWarningBanner")} + * permission. + */ + private void checkAWTPermission(){ + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new AWTPermission( + "showWindowWithoutWarningBanner")); + } + } + + private Taskbar() { + Toolkit defaultToolkit = Toolkit.getDefaultToolkit(); + if (defaultToolkit instanceof SunToolkit) { + peer = ((SunToolkit) defaultToolkit).createTaskbarPeer(this); + } + } + + /** + * Returns the {@code Taskbar} instance of the current + * taskbar context. On some platforms the Taskbar API may not be + * supported; use the {@link #isTaskbarSupported} method to + * determine if the current taskbar is supported. + * @return the Taskbar instance + * @throws HeadlessException if {@link + * GraphicsEnvironment#isHeadless()} returns {@code true} + * @throws UnsupportedOperationException if this class is not + * supported on the current platform + * @see #isTaskbarSupported() + * @see java.awt.GraphicsEnvironment#isHeadless + */ + public static synchronized Taskbar getTaskbar(){ + if (GraphicsEnvironment.isHeadless()) throw new HeadlessException(); + + if (!Taskbar.isTaskbarSupported()) { + throw new UnsupportedOperationException("Taskbar API is not " + + "supported on the current platform"); + } + + sun.awt.AppContext context = sun.awt.AppContext.getAppContext(); + Taskbar taskbar = (Taskbar)context.get(Taskbar.class); + + if (taskbar == null) { + taskbar = new Taskbar(); + context.put(Taskbar.class, taskbar); + } + + return taskbar; + } + + /** + * Tests whether this class is supported on the current platform. + * If it's supported, use {@link #getTaskbar()} to retrieve an + * instance. + * + * @return {@code true} if this class is supported on the + * current platform; {@code false} otherwise + * @see #getTaskbar() + */ + public static boolean isTaskbarSupported(){ + Toolkit defaultToolkit = Toolkit.getDefaultToolkit(); + if (defaultToolkit instanceof SunToolkit) { + return ((SunToolkit)defaultToolkit).isTaskbarSupported(); + } + return false; + } + + /** + * Requests user attention to this application. + * + * Depending on the platform, this may be visually indicated by a bouncing + * or flashing icon in the task area. It may have no effect on an already active + * application. + * + * On some platforms (e.g. Mac OS) this effect may disappear upon app activation + * and cannot be dismissed by setting {@code enabled} to false. + * Other platforms may require an additional call + * {@link #requestUserAttention} to dismiss this request + * with {@code enabled} parameter set to false. + * + * @param enabled disables this request if false + * @param critical if this is an important request + * @throws SecurityException if a security manager exists and it denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Taskbar.Feature#USER_ATTENTION} feature + */ + public void requestUserAttention(final boolean enabled, final boolean critical) { + checkAWTPermission(); + checkFeatureSupport(Feature.USER_ATTENTION); + peer.requestUserAttention(enabled, critical); + } + + /** + * Requests user attention to the specified window until it is activated. + * + * On an already active window requesting attention does nothing. + * + * @param w window + * @throws SecurityException if a security manager exists and it denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Taskbar.Feature#USER_ATTENTION_WINDOW} feature + */ + public void requestWindowUserAttention(Window w) { + checkAWTPermission(); + checkFeatureSupport(Feature.USER_ATTENTION_WINDOW); + peer.requestWindowUserAttention(w); + } + + /** + * Attaches the contents of the provided PopupMenu to the application icon + * in the task area. + * + * @param menu the PopupMenu to attach to this application + * @throws SecurityException if a security manager exists and it denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Taskbar.Feature#MENU} feature + */ + public void setMenu(final PopupMenu menu) { + checkAWTPermission(); + checkFeatureSupport(Feature.MENU); + peer.setMenu(menu); + } + + /** + * Gets PopupMenu used to add items to this application's icon in system task area. + * + * @return the PopupMenu + * @throws SecurityException if a security manager exists and it denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Taskbar.Feature#MENU} feature + */ + public PopupMenu getMenu() { + checkAWTPermission(); + checkFeatureSupport(Feature.MENU); + return peer.getMenu(); + } + + /** + * Changes this application's icon to the provided image. + * + * @param image to change + * @throws SecurityException if a security manager exists and it denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Taskbar.Feature#ICON_IMAGE} feature + */ + public void setIconImage(final Image image) { + checkAWTPermission(); + checkFeatureSupport(Feature.ICON_IMAGE); + peer.setIconImage(image); + } + + /** + * Obtains an image of this application's icon. + * + * @return an image of this application's icon + * @throws SecurityException if a security manager exists and it denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Taskbar.Feature#ICON_IMAGE} feature + */ + public Image getIconImage() { + checkAWTPermission(); + checkFeatureSupport(Feature.ICON_IMAGE); + return peer.getIconImage(); + } + + /** + * Affixes a small system-provided badge to this application's icon. + * Usually a number. + * + * Some platforms do not support string values and accept only integer + * values. In this case, pass an integer represented as a string as parameter. + * This can be tested by {@code Feature.ICON_BADGE_STRING} and + * {@code Feature.ICON_BADGE_NUMBER}. + * + * Passing {@code null} as parameter hides the badge. + * @param badge label to affix to the icon + * @throws SecurityException if a security manager exists and it denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Taskbar.Feature#ICON_BADGE_NUMBER} feature + */ + public void setIconBadge(final String badge) { + checkAWTPermission(); + checkFeatureSupport(Feature.ICON_BADGE_NUMBER); + peer.setIconBadge(badge); + } + + /** + * Affixes a small badge to this application's icon in the task area + * for the specified window. + * It may be disabled by system settings. + * + * @param w window to update + * @param badge image to affix to the icon + * @throws SecurityException if a security manager exists and it denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Taskbar.Feature#ICON_BADGE_IMAGE_WINDOW} feature + */ + public void setWindowIconBadge(Window w, final Image badge) { + checkAWTPermission(); + checkFeatureSupport(Feature.ICON_BADGE_IMAGE_WINDOW); + if (w != null) { + peer.setWindowIconBadge(w, badge); + } + } + + + /** + * Affixes a small system-provided progress bar to this application's icon. + * + * @param value from 0 to 100, other to disable progress indication + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Taskbar.Feature#PROGRESS_VALUE} feature + */ + public void setProgressValue(int value) { + checkAWTPermission(); + checkFeatureSupport(Feature.PROGRESS_VALUE); + peer.setProgressValue(value); + } + + /** + * Displays progress for specified window. + * + * @param w window to update + * @param value from 0 to 100, other to disable progress indication + * @throws SecurityException if a security manager exists and it denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Taskbar.Feature#PROGRESS_VALUE_WINDOW} feature + */ + public void setWindowProgressValue(Window w, int value) { + checkAWTPermission(); + checkFeatureSupport(Feature.PROGRESS_VALUE_WINDOW); + if (w != null) { + peer.setWindowProgressValue(w, value); + } + } + + /** + * Sets a progress state for a specified window. + * + * @param w window + * @param state to change to + * @see State#OFF + * @see State#NORMAL + * @see State#PAUSED + * @see State#INDETERMINATE + * @see State#ERROR + * @throws SecurityException if a security manager exists and it denies the + * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Taskbar.Feature#PROGRESS_STATE_WINDOW} feature + */ + public void setWindowProgressState(Window w, State state) { + checkAWTPermission(); + checkFeatureSupport(Feature.PROGRESS_STATE_WINDOW); + if (w != null) { + peer.setWindowProgressState(w, state); + } + } +} diff --git a/jdk/src/java.base/share/classes/sun/net/spi/nameservice/NameServiceDescriptor.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/AboutEvent.java similarity index 71% rename from jdk/src/java.base/share/classes/sun/net/spi/nameservice/NameServiceDescriptor.java rename to jdk/src/java.desktop/share/classes/java/awt/desktop/AboutEvent.java index 6e246c56a14..5dcc87c2233 100644 --- a/jdk/src/java.base/share/classes/sun/net/spi/nameservice/NameServiceDescriptor.java +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AboutEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,23 +23,23 @@ * questions. */ -package sun.net.spi.nameservice; +package java.awt.desktop; -public interface NameServiceDescriptor { - /** - * Create a new instance of the corresponding name service. - */ - public NameService createNameService () throws Exception ; + +/** + * Event sent when the application is asked to open its about window. + * + * @see AboutHandler#handleAbout + * + * @since 9 + */ +public final class AboutEvent extends AppEvent { + private static final long serialVersionUID = -5987180734802756477L; /** - * Returns this service provider's name - * + * Constructs an {@code AboutEvent} */ - public String getProviderName(); + public AboutEvent() { + } - /** - * Returns this name service type - * "dns" "nis" etc - */ - public String getType(); } diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AboutHandler.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/AboutHandler.java similarity index 74% rename from jdk/src/java.desktop/macosx/classes/com/apple/eawt/AboutHandler.java rename to jdk/src/java.desktop/share/classes/java/awt/desktop/AboutHandler.java index fbc4e363507..b80a0bee1d8 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AboutHandler.java +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AboutHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,21 +23,21 @@ * questions. */ -package com.apple.eawt; - -import com.apple.eawt.AppEvent.AboutEvent; +package java.awt.desktop; /** - * An implementor receives notification when the app is asked to show it's about dialog. + * An implementer receives notification when the app is asked to show its about + * dialog. * - * @see Application#setAboutHandler(AboutHandler) + * @see java.awt.Desktop#setAboutHandler(java.awt.desktop.AboutHandler) * - * @since Java for Mac OS X 10.6 Update 3 - * @since Java for Mac OS X 10.5 Update 8 + * @since 9 */ public interface AboutHandler { + /** - * Called when the application is asked to show it's about dialog. + * Called when the application is asked to show its about dialog. + * * @param e the request to show the about dialog. */ public void handleAbout(final AboutEvent e); diff --git a/jdk/src/java.desktop/share/classes/java/awt/desktop/AppEvent.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppEvent.java new file mode 100644 index 00000000000..0eaabcbbdd5 --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppEvent.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.awt.desktop; + +import java.awt.Desktop; +import java.util.EventObject; + +/** + * AppEvents are sent to listeners and handlers installed on the + * {@link java.awt.Desktop}. + * + * @since 9 + */ +public class AppEvent extends EventObject { + + private static final long serialVersionUID = -5958503993556009432L; + + AppEvent() { + super(Desktop.getDesktop()); + } + +} diff --git a/jdk/src/java.desktop/share/classes/java/awt/desktop/AppForegroundEvent.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppForegroundEvent.java new file mode 100644 index 00000000000..9d7107b84db --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppForegroundEvent.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.awt.desktop; + + +/** + * Event sent when the application has become the foreground app, and when it is + * no longer the foreground app. + * + * @see AppForegroundListener#appRaisedToForeground(AppEvent.AppForegroundEvent) + * @see AppForegroundListener#appMovedToBackground(AppEvent.AppForegroundEvent) + * + * @since 9 + */ +public final class AppForegroundEvent extends AppEvent { + private static final long serialVersionUID = -5513582555740533911L; + + /** + * Constructs an {@code AppForegroundEvent} + */ + public AppForegroundEvent() { + } + +} diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppForegroundListener.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppForegroundListener.java similarity index 64% rename from jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppForegroundListener.java rename to jdk/src/java.desktop/share/classes/java/awt/desktop/AppForegroundListener.java index 3677993e64f..795b7b697df 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppForegroundListener.java +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppForegroundListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,29 +23,28 @@ * questions. */ -package com.apple.eawt; - -import com.apple.eawt.AppEvent.AppForegroundEvent; +package java.awt.desktop; /** - * Implementors are notified when the app becomes the foreground app and when it resigns being the foreground app. - * This notification is useful for hiding and showing transient UI like palette windows which should be hidden when the app is in the background. + * Implementors are notified when the app becomes the foreground app and when it + * is no longer the foreground app. This notification is useful for hiding and + * showing transient UI like palette windows which should be hidden when the app + * is in the background. * - * @see Application#addAppEventListener(AppEventListener) - * - * @since Java for Mac OS X 10.6 Update 3 - * @since Java for Mac OS X 10.5 Update 8 + * @since 9 */ -public interface AppForegroundListener extends AppEventListener { +public interface AppForegroundListener extends SystemEventListener { /** * Called when the app becomes the foreground app. - * @param e the app became foreground notification. + * @param e event */ public void appRaisedToForeground(final AppForegroundEvent e); /** - * Called when the app resigns to the background and another app becomes the foreground app. - * @param e the app resigned foreground notification. + * Called when the app becomes the background app and another app becomes + * the foreground app. + * + * @param e event */ public void appMovedToBackground(final AppForegroundEvent e); } diff --git a/jdk/src/java.desktop/share/classes/java/awt/desktop/AppHiddenEvent.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppHiddenEvent.java new file mode 100644 index 00000000000..1a41cc271a3 --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppHiddenEvent.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.awt.desktop; + + +/** + * Event sent when the application has been hidden or shown. + * + * @see AppHiddenListener#appHidden(AppEvent.AppHiddenEvent) + * @see AppHiddenListener#appUnhidden(AppEvent.AppHiddenEvent) + * + * @since 9 + */ +public final class AppHiddenEvent extends AppEvent { + private static final long serialVersionUID = 2637465279476429224L; + + /** + * Constructs an {@code AppHiddenEvent} + */ + public AppHiddenEvent() { + } + +} diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppHiddenListener.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppHiddenListener.java similarity index 72% rename from jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppHiddenListener.java rename to jdk/src/java.desktop/share/classes/java/awt/desktop/AppHiddenListener.java index e7b237c8611..e60d9b68eaf 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppHiddenListener.java +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppHiddenListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,29 +23,29 @@ * questions. */ -package com.apple.eawt; - -import com.apple.eawt.AppEvent.AppHiddenEvent; +package java.awt.desktop; /** - * Implementors are notified when the app is hidden or shown by the user. - * This notification is helpful for discontinuing a costly animation if it's not visible to the user. + * Implementors are notified when the app is hidden or shown by the user. This + * notification is helpful for discontinuing a costly animation if it's not + * visible to the user. * - * @see Application#addAppEventListener(AppEventListener) - * - * @since Java for Mac OS X 10.6 Update 3 - * @since Java for Mac OS X 10.5 Update 8 + * @since 9 */ -public interface AppHiddenListener extends AppEventListener { +public interface AppHiddenListener extends SystemEventListener { + /** * Called the app is hidden. - * @param e + * + * @param e event */ public void appHidden(final AppHiddenEvent e); /** - * Called when the hidden app is shown again (but not necessarily brought to the foreground). - * @param e + * Called when the hidden app is shown again (but not necessarily brought to + * the foreground). + * + * @param e event */ public void appUnhidden(final AppHiddenEvent e); } diff --git a/jdk/src/java.desktop/share/classes/java/awt/desktop/AppReopenedEvent.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppReopenedEvent.java new file mode 100644 index 00000000000..2e7f9f14be6 --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppReopenedEvent.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.awt.desktop; + + +/** + * Event sent when the application is asked to re-open itself. + * + * @see AppReopenedListener#appReopened(AppEvent.AppReopenedEvent) + * + * @since 9 + */ +public final class AppReopenedEvent extends AppEvent { + private static final long serialVersionUID = 1503238361530407990L; + + /** + * Constructs an {@code AppReopenedEvent} + */ + public AppReopenedEvent() { + } + +} diff --git a/jdk/src/java.desktop/share/classes/java/awt/desktop/AppReopenedListener.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppReopenedListener.java new file mode 100644 index 00000000000..00359640049 --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppReopenedListener.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.awt.desktop; + +/** + * Implementors receive notification when the app has been asked to open again. + * + * This notification is useful for showing a new document when your app has no open windows. + * + * @since 9 + */ +public interface AppReopenedListener extends SystemEventListener { + /** + * Called when the app has been reopened + * @param e the request to reopen the app + */ + public void appReopened(final AppReopenedEvent e); +} diff --git a/jdk/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java new file mode 100644 index 00000000000..aa9b8aa82ad --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.awt.desktop; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + + +/** + * Auxiliary event containing a list of files. + * + * @since 9 + */ +public class FilesEvent extends AppEvent { + private static final long serialVersionUID = 5271763715462312871L; + final List files; + + /** + * Constructs a {@code FilesEvent} + * @param files files + * @param searchTerm searchTerm + */ + FilesEvent(final List files) { + this.files = files; + } + + /** + * Gets the list of files + * @return the list of files + */ + public List getFiles() { + return files == null + ? null + : new ArrayList<>(files); + } + +} diff --git a/jdk/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java new file mode 100644 index 00000000000..6d5d9136ad4 --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.awt.desktop; + +import java.io.File; +import java.util.List; + + +/** + * Event sent when the app is asked to open a list of files. + * + * @see OpenFilesHandler#openFiles + * + * @since 9 + */ +public final class OpenFilesEvent extends FilesEvent { + private static final long serialVersionUID = -3982871005867718956L; + final String searchTerm; + + /** + * Constructs an {@code OpenFilesEvent} + * @param files files + * @param searchTerm searchTerm + */ + public OpenFilesEvent(final List files, final String searchTerm) { + super(files); + this.searchTerm = searchTerm == null + ? "" + : searchTerm; + } + + /** + * Gets the search term. The platform may optionally provide the search + * term that was used to find the files. This is for example the case + * on Mac OS X, when the files were opened using the Spotlight search + * menu or a Finder search window. + * + * This is useful for highlighting the search term in the documents when + * they are opened. + * + * @return the search term used to find the files + */ + public String getSearchTerm() { + return searchTerm; + } + +} diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/OpenFilesHandler.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/OpenFilesHandler.java similarity index 78% rename from jdk/src/java.desktop/macosx/classes/com/apple/eawt/OpenFilesHandler.java rename to jdk/src/java.desktop/share/classes/java/awt/desktop/OpenFilesHandler.java index 1a7959f4e4c..73c6efafdfe 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/OpenFilesHandler.java +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/OpenFilesHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,18 +23,15 @@ * questions. */ -package com.apple.eawt; +package java.awt.desktop; -import com.apple.eawt.AppEvent.OpenFilesEvent; /** * An implementor is notified when the application is asked to open a list of files. - * This message is only sent if the application has registered that it handles CFBundleDocumentTypes in it's Info.plist. * - * @see Application#setOpenFileHandler(OpenFilesHandler) + * @see java.awt.Desktop#setOpenFileHandler(java.awt.desktop.OpenFilesHandler) * - * @since Java for Mac OS X 10.6 Update 3 - * @since Java for Mac OS X 10.5 Update 8 + * @since 9 */ public interface OpenFilesHandler { /** diff --git a/jdk/src/jdk.naming.dns/share/classes/sun/net/spi/nameservice/dns/DNSNameServiceDescriptor.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java similarity index 64% rename from jdk/src/jdk.naming.dns/share/classes/sun/net/spi/nameservice/dns/DNSNameServiceDescriptor.java rename to jdk/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java index b18e4b1bd2b..61b0aae7ee2 100644 --- a/jdk/src/jdk.naming.dns/share/classes/sun/net/spi/nameservice/dns/DNSNameServiceDescriptor.java +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,31 +23,36 @@ * questions. */ -package sun.net.spi.nameservice.dns; +package java.awt.desktop; -import sun.net.spi.nameservice.*; +import java.net.URI; + + +/** + * Event sent when the app is asked to open a {@code URI}. + * + * @see OpenURIHandler#openURI(AppEvent.OpenURIEvent) + * + * @since 9 + */ +public final class OpenURIEvent extends AppEvent { + private static final long serialVersionUID = 221209100935933476L; + final URI uri; -public final class DNSNameServiceDescriptor implements NameServiceDescriptor { /** - * Create a new instance of the corresponding name service. + * Constructs an {@code OpenURIEvent} + * @param uri {@code URI} */ - public NameService createNameService() throws Exception { - return new DNSNameService(); + public OpenURIEvent(final URI uri) { + this.uri = uri; } /** - * Returns this service provider's name - * + * Get the {@code URI} the app was asked to open + * @return the {@code URI} */ - public String getProviderName() { - return "sun"; + public URI getURI() { + return uri; } - /** - * Returns this name service type - * "dns" "nis" etc - */ - public String getType() { - return "dns"; - } } diff --git a/jdk/src/java.desktop/share/classes/java/awt/desktop/OpenURIHandler.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/OpenURIHandler.java new file mode 100644 index 00000000000..8b50d89f652 --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/OpenURIHandler.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.awt.desktop; + +/** + * An implementor is notified when the application is asked to open a URI. + * + * @see java.awt.Desktop#setOpenURIHandler(java.awt.desktop.OpenURIHandler) + * + * @since 9 + */ +public interface OpenURIHandler { + /** + * Called when the application is asked to open a {@code URI} + * @param e the request to open a {@code URI} + */ + public void openURI(final OpenURIEvent e); +} diff --git a/jdk/src/java.desktop/share/classes/java/awt/desktop/PreferencesEvent.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/PreferencesEvent.java new file mode 100644 index 00000000000..7630272c41e --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/PreferencesEvent.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.awt.desktop; + + +/** + * Event sent when the application is asked to open its preferences window. + * + * @see PreferencesHandler#handlePreferences + * + * @since 9 + */ +public final class PreferencesEvent extends AppEvent { + private static final long serialVersionUID = -6398607097086476160L; + + /** + * Constructs a {@code PreferencesEvent} + */ + public PreferencesEvent() { + } + +} diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/PreferencesHandler.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/PreferencesHandler.java similarity index 74% rename from jdk/src/java.desktop/macosx/classes/com/apple/eawt/PreferencesHandler.java rename to jdk/src/java.desktop/share/classes/java/awt/desktop/PreferencesHandler.java index 985ea37e1e2..fe3e0c93c4a 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/PreferencesHandler.java +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/PreferencesHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,21 +23,18 @@ * questions. */ -package com.apple.eawt; - -import com.apple.eawt.AppEvent.PreferencesEvent; +package java.awt.desktop; /** - * An implementor is notified when the app is asked to show it's preferences UI. + * An implementor is notified when the app is asked to show its preferences UI. * - * @see Application#setPreferencesHandler(PreferencesHandler) + * @see java.awt.Desktop#setPreferencesHandler(java.awt.desktop.PreferencesHandler) * - * @since Java for Mac OS X 10.6 Update 3 - * @since Java for Mac OS X 10.5 Update 8 + * @since 9 */ public interface PreferencesHandler { /** - * Called when the app is asked to show it's preferences UI. + * Called when the app is asked to show its preferences UI. * @param e the request to show preferences. */ public void handlePreferences(final PreferencesEvent e); diff --git a/jdk/src/java.desktop/share/classes/java/awt/desktop/PrintFilesEvent.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/PrintFilesEvent.java new file mode 100644 index 00000000000..0ec9d006395 --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/PrintFilesEvent.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package java.awt.desktop; + +import java.io.File; +import java.util.List; + + +/** + * Event sent when the app is asked to print a list of files. + * + * @see PrintFilesHandler#printFiles(AppEvent.PrintFilesEvent) + * @since 9 + */ +public final class PrintFilesEvent extends FilesEvent { + private static final long serialVersionUID = -5752560876153618618L; + + /** + * Constructs a {@code PrintFilesEvent} + * @param files files + */ + public PrintFilesEvent(final List files) { + super(files); + } + +} diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/PrintFilesHandler.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/PrintFilesHandler.java similarity index 83% rename from jdk/src/java.desktop/macosx/classes/com/apple/eawt/PrintFilesHandler.java rename to jdk/src/java.desktop/share/classes/java/awt/desktop/PrintFilesHandler.java index 195c1cd8f36..f91cdb7af89 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/PrintFilesHandler.java +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/PrintFilesHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,17 +23,14 @@ * questions. */ -package com.apple.eawt; - -import com.apple.eawt.AppEvent.PrintFilesEvent; +package java.awt.desktop; /** * An implementor can respond to requests to print documents that the app has been registered to handle. * - * @see Application#setPrintFileHandler(PrintFilesHandler) + * @see java.awt.Desktop#setPrintFileHandler(java.awt.desktop.PrintFilesHandler) * - * @since Java for Mac OS X 10.6 Update 3 - * @since Java for Mac OS X 10.5 Update 8 + * @since 9 */ public interface PrintFilesHandler { /** diff --git a/jdk/src/java.desktop/share/classes/java/awt/desktop/QuitEvent.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/QuitEvent.java new file mode 100644 index 00000000000..ea9f4b48d7c --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/QuitEvent.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.awt.desktop; + +/** + * Event sent when the application is asked to quit. + * + * @see QuitHandler#handleQuitRequestWith(AppEvent.QuitEvent, QuitResponse) + * + * @since 9 + */ +public final class QuitEvent extends AppEvent { + + private static final long serialVersionUID = -256100795532403146L; + + /** + * Constructs a {@code QuitEvent} + */ + public QuitEvent() { + } +} diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/QuitHandler.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/QuitHandler.java similarity index 87% rename from jdk/src/java.desktop/macosx/classes/com/apple/eawt/QuitHandler.java rename to jdk/src/java.desktop/share/classes/java/awt/desktop/QuitHandler.java index d1292dace8f..19e84422706 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/QuitHandler.java +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/QuitHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,18 +23,15 @@ * questions. */ -package com.apple.eawt; - -import com.apple.eawt.AppEvent.QuitEvent; +package java.awt.desktop; /** * An implementor determines if requests to quit this application should proceed or cancel. * - * @see Application#setQuitHandler(QuitHandler) - * @see Application#setQuitStrategy(QuitStrategy) + * @see java.awt.Desktop#setQuitHandler(java.awt.desktop.QuitHandler) + * @see java.awt.Desktop#setQuitStrategy(java.awt.desktop.QuitStrategy) * - * @since Java for Mac OS X 10.6 Update 3 - * @since Java for Mac OS X 10.5 Update 8 + * @since 9 */ public interface QuitHandler { /** diff --git a/jdk/src/java.desktop/share/classes/java/awt/desktop/QuitResponse.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/QuitResponse.java new file mode 100644 index 00000000000..74d685c31b0 --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/QuitResponse.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.awt.desktop; + +/** + * Used to respond to a request to quit the application. + * + * @see java.awt.Desktop#setQuitHandler(java.awt.desktop.QuitHandler) + * @see java.awt.desktop.QuitHandler + * @see java.awt.Desktop#setQuitStrategy(java.awt.desktop.QuitStrategy) + * + * @since 9 + */ +public interface QuitResponse { + + /** + * Notifies the external quit requester that the quit will proceed, and performs the default {@link java.awt.desktop.QuitStrategy}. + */ + public void performQuit(); + + /** + * Notifies the external quit requester that the user has explicitly canceled the pending quit, and leaves the application running. + * Note: this will cancel a pending log-out, restart, or shutdown. + */ + public void cancelQuit(); +} diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/QuitStrategy.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/QuitStrategy.java similarity index 74% rename from jdk/src/java.desktop/macosx/classes/com/apple/eawt/QuitStrategy.java rename to jdk/src/java.desktop/share/classes/java/awt/desktop/QuitStrategy.java index a0140d9ba78..4a0f1feae43 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/QuitStrategy.java +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/QuitStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,24 +23,23 @@ * questions. */ -package com.apple.eawt; +package java.awt.desktop; /** - * The strategy use to shut down the application, if Sudden Termination is not enabled. + * The strategy used to shut down the application, if Sudden Termination is not enabled. * - * @see Application#setQuitHandler(QuitHandler) - * @see Application#setQuitStrategy(QuitStrategy) - * @see Application#enableSuddenTermination() - * @see Application#disableSuddenTermination() + * @see java.awt.Desktop#setQuitHandler(java.awt.desktop.QuitHandler) + * @see java.awt.Desktop#setQuitStrategy(java.awt.desktop.QuitStrategy) + * @see java.awt.Desktop#enableSuddenTermination() + * @see java.awt.Desktop#disableSuddenTermination() * - * @since Java for Mac OS X 10.6 Update 3 - * @since Java for Mac OS X 10.5 Update 8 + * @since 9 */ public enum QuitStrategy { /** * Shuts down the application by calling {@code System.exit(0)}. This is the default strategy. */ - SYSTEM_EXIT_0, + NORMAL_EXIT, /** * Shuts down the application by closing each window from back-to-front. diff --git a/jdk/src/java.desktop/share/classes/java/awt/desktop/ScreenSleepEvent.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/ScreenSleepEvent.java new file mode 100644 index 00000000000..880187878e8 --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/ScreenSleepEvent.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.awt.desktop; + +/** + * Event sent when the displays attached to the system enter and exit power save + * sleep. + * + * @see ScreenSleepListener#screenAboutToSleep(AppEvent.ScreenSleepEvent) + * @see ScreenSleepListener#screenAwoke(AppEvent.ScreenSleepEvent) + * + * @since 9 + */ +public final class ScreenSleepEvent extends AppEvent { + + private static final long serialVersionUID = 7521606180376544150L; + + /** + * Constructs a ScreenSleepEvent + */ + public ScreenSleepEvent() { + } +} diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ScreenSleepListener.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/ScreenSleepListener.java similarity index 77% rename from jdk/src/java.desktop/macosx/classes/com/apple/eawt/ScreenSleepListener.java rename to jdk/src/java.desktop/share/classes/java/awt/desktop/ScreenSleepListener.java index 1953d28a71d..3a927d98cf8 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ScreenSleepListener.java +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/ScreenSleepListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,23 +23,17 @@ * questions. */ -package com.apple.eawt; - -import com.apple.eawt.AppEvent.ScreenSleepEvent; +package java.awt.desktop; /** * Implementors receive notification when the displays attached to the system have entered power save sleep. * * This notification is useful for discontinuing a costly animation, or indicating that the user is no longer present on a network service. * - * This message is not sent on Mac OS X versions prior to 10.6. - * - * @see Application#addAppEventListener(AppEventListener) - * - * @since Java for Mac OS X 10.6 Update 3 - * @since Java for Mac OS X 10.5 Update 8 + * @since 9 */ -public interface ScreenSleepListener extends AppEventListener { +public interface ScreenSleepListener extends SystemEventListener { + /** * Called when the system displays have entered power save sleep. * @param e the screen sleep event @@ -47,7 +41,7 @@ public interface ScreenSleepListener extends AppEventListener { public void screenAboutToSleep(final ScreenSleepEvent e); /** - * Called when the system displays have awoke from power save sleep. + * Called when the system displays have awoken from power save sleep. * @param e the screen sleep event */ public void screenAwoke(final ScreenSleepEvent e); diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppEventListener.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/SystemEventListener.java similarity index 71% rename from jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppEventListener.java rename to jdk/src/java.desktop/share/classes/java/awt/desktop/SystemEventListener.java index 77a901b7531..4ee696ecb96 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppEventListener.java +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/SystemEventListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,20 +23,18 @@ * questions. */ -package com.apple.eawt; +package java.awt.desktop; + +import java.util.EventListener; /** * Common interface for all event listener sub-types. - * Implementors may implement multiple sub-types, but only need to call {@link Application#addAppEventListener(AppEventListener)} once to receive all notifications. * - * @see AppReOpenedListener - * @see AppForegroundListener - * @see AppHiddenListener - * @see ScreenSleepListener - * @see SystemSleepListener - * @see UserSessionListener + * Implementors may implement multiple sub-types, but only need to call + * {@link java.awt.Desktop#addAppEventListener(SystemEventListener)} once to + * receive all notifications. * - * @since Java for Mac OS X 10.6 Update 3 - * @since Java for Mac OS X 10.5 Update 8 + * @since 9 */ -public interface AppEventListener { } +public interface SystemEventListener extends EventListener { +} diff --git a/jdk/src/java.desktop/share/classes/java/awt/desktop/SystemSleepEvent.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/SystemSleepEvent.java new file mode 100644 index 00000000000..b9fab3bd137 --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/SystemSleepEvent.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.awt.desktop; + +/** + * Event sent when the system enters and exits power save sleep. + * + * @see SystemSleepListener#systemAboutToSleep(AppEvent.SystemSleepEvent) + * @see SystemSleepListener#systemAwoke(AppEvent.SystemSleepEvent) + * + * @since 9 + */ +public final class SystemSleepEvent extends AppEvent { + + private static final long serialVersionUID = 11372269824930549L; + + /** + * Constructs a SystemSleepEvent + */ + public SystemSleepEvent() { + } +} diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/SystemSleepListener.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/SystemSleepListener.java similarity index 66% rename from jdk/src/java.desktop/macosx/classes/com/apple/eawt/SystemSleepListener.java rename to jdk/src/java.desktop/share/classes/java/awt/desktop/SystemSleepListener.java index 0b2aa92c58f..c834c6a08c3 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/SystemSleepListener.java +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/SystemSleepListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,30 +23,32 @@ * questions. */ -package com.apple.eawt; - -import com.apple.eawt.AppEvent.SystemSleepEvent; +package java.awt.desktop; /** - * Implementors receive notification as the system is entering sleep, and after the system wakes. + * Implementors receive notification as the system is entering sleep, and after + * the system wakes. * - * This notification is useful for disconnecting from network services prior to sleep, or re-establishing a connection if the network configuration has changed during sleep. + * This notification is useful for disconnecting from network services prior to + * sleep, or re-establishing a connection if the network configuration has + * changed during sleep. * - * @see Application#addAppEventListener(AppEventListener) - * - * @since Java for Mac OS X 10.6 Update 3 - * @since Java for Mac OS X 10.5 Update 8 + * @since 9 */ -public interface SystemSleepListener extends AppEventListener { +public interface SystemSleepListener extends SystemEventListener { + /** - * Called when the system is about to sleep. - * Note: This message may not be delivered prior to the actual system sleep, and may be processed after the corresponding wake has occurred. + * Called when the system is about to sleep. Note: This message may not be + * delivered prior to the actual system sleep, and may be processed after + * the corresponding wake has occurred. + * * @param e the system sleep event */ public void systemAboutToSleep(final SystemSleepEvent e); /** - * Called after the system has awoke from sleeping. + * Called after the system has awoken from sleeping. + * * @param e the system sleep event */ public void systemAwoke(final SystemSleepEvent e); diff --git a/jdk/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java new file mode 100644 index 00000000000..5daca855d3e --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.awt.desktop; + +/** + * Event sent when the user session has been changed. + * + * Some systems may provide a reason of a user session change. + * + * @see UserSessionListener#userSessionActivated(AppEvent.UserSessionEvent) + * @see UserSessionListener#userSessionDeactivated(AppEvent.UserSessionEvent) + * + * @since 9 + */ +public final class UserSessionEvent extends AppEvent { + + private static final long serialVersionUID = 6747138462796569055L; + + private final Reason reason; + + /** + * Kinds of available reasons of user session change. + */ + public static enum Reason { + /** + * The system does not provide a reason for a session change. + */ + UNSPECIFIED, + + /** + * The session was connected/disconnected to the console terminal. + */ + CONSOLE, + + /** + * The session was connected/disconnected to the remote terminal. + */ + REMOTE, + + /** + * The session has been locked/unlocked. + */ + LOCK + } + + /** + * Constructs a {@code UserSessionEvent} + * + * @param reason of session change + */ + public UserSessionEvent(Reason reason) { + this.reason = reason; + } + + /** + * Gets a reason of the user session change. + * + * @return reason a reason + * @see Reason#UNSPECIFIED + * @see Reason#CONSOLE + * @see Reason#REMOTE + * @see Reason#LOCK + */ + public Reason getReason() { + return reason; + } +} diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/UserSessionListener.java b/jdk/src/java.desktop/share/classes/java/awt/desktop/UserSessionListener.java similarity index 74% rename from jdk/src/java.desktop/macosx/classes/com/apple/eawt/UserSessionListener.java rename to jdk/src/java.desktop/share/classes/java/awt/desktop/UserSessionListener.java index 5d706a5697b..0c45275fe5e 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/UserSessionListener.java +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/UserSessionListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,21 +23,25 @@ * questions. */ -package com.apple.eawt; +package java.awt.desktop; -import com.apple.eawt.AppEvent.UserSessionEvent; /** - * Implementors receive notification when Fast User Switching changes the user session. + * Implementors receive notification when the user session changes. * - * This notification is useful for discontinuing a costly animation, or indicating that the user is no longer present on a network service. + * This notification is useful for discontinuing a costly animation, + * or indicating that the user is no longer present on a network service. * - * @see Application#addAppEventListener(AppEventListener) + * Some systems may provide a reason of the user session change. * - * @since Java for Mac OS X 10.6 Update 3 - * @since Java for Mac OS X 10.5 Update 8 + * @see UserSessionEvent.Reason#UNSPECIFIED + * @see UserSessionEvent.Reason#CONSOLE + * @see UserSessionEvent.Reason#REMOTE + * @see UserSessionEvent.Reason#LOCK + * + * @since 9 */ -public interface UserSessionListener extends AppEventListener { +public interface UserSessionListener extends SystemEventListener { /** * Called when the user session has been switched away. * @param e the user session switch event diff --git a/jdk/test/java/awt/TextArea/UsingWithMouse/SelectionAutoscrollTest.html b/jdk/src/java.desktop/share/classes/java/awt/desktop/package.html similarity index 59% rename from jdk/test/java/awt/TextArea/UsingWithMouse/SelectionAutoscrollTest.html rename to jdk/src/java.desktop/share/classes/java/awt/desktop/package.html index f3492dcad33..c0043f4fc64 100644 --- a/jdk/test/java/awt/TextArea/UsingWithMouse/SelectionAutoscrollTest.html +++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/package.html @@ -1,10 +1,12 @@ + - - - - - + + -

      SelectionAutoscrollTest
      Bug ID: 6497109

      +Provides interfaces and classes for interaction with various +desktop capabilities. -

      This is an AUTOMATIC test, simply wait for completion

      - - +@since 9 diff --git a/jdk/src/java.desktop/share/classes/java/awt/image/SampleModel.java b/jdk/src/java.desktop/share/classes/java/awt/image/SampleModel.java index d5a8085dc17..d79ecb4af34 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/image/SampleModel.java +++ b/jdk/src/java.desktop/share/classes/java/awt/image/SampleModel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -126,7 +126,7 @@ public abstract class SampleModel throw new IllegalArgumentException("Width ("+w+") and height ("+ h+") must be > 0"); } - if (size >= Integer.MAX_VALUE) { + if (size > Integer.MAX_VALUE) { throw new IllegalArgumentException("Dimensions (width="+w+ " height="+h+") are too large"); } diff --git a/jdk/src/java.desktop/share/classes/java/awt/peer/DesktopPeer.java b/jdk/src/java.desktop/share/classes/java/awt/peer/DesktopPeer.java index 61c83b6f00e..9751458cf07 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/peer/DesktopPeer.java +++ b/jdk/src/java.desktop/share/classes/java/awt/peer/DesktopPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -22,14 +22,21 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ - package java.awt.peer; - import java.io.File; import java.io.IOException; import java.net.URI; import java.awt.Desktop.Action; +import java.awt.desktop.AboutHandler; +import java.awt.desktop.SystemEventListener; +import java.awt.desktop.OpenFilesHandler; +import java.awt.desktop.OpenURIHandler; +import java.awt.desktop.PreferencesHandler; +import java.awt.desktop.PrintFilesHandler; +import java.awt.desktop.QuitHandler; +import java.awt.desktop.QuitStrategy; +import javax.swing.JMenuBar; /** * The {@code DesktopPeer} interface provides methods for the operation @@ -104,4 +111,168 @@ public interface DesktopPeer { * or it fails to be launched. */ void browse(URI uri) throws IOException; + + /** + * Adds sub-types of {@link SystemEventListener} to listen for notifications + * from the native system. + * + * @param listener listener + * @see java.awt.desktop.AppForegroundListener + * @see java.awt.desktop.AppHiddenListener + * @see java.awt.desktop.AppReopenedListener + * @see java.awt.desktop.ScreenSleepListener + * @see java.awt.desktop.SystemSleepListener + * @see java.awt.desktop.UserSessionListener + */ + default void addAppEventListener(final SystemEventListener listener) { + } + + /** + * Removes sub-types of {@link SystemEventListener} to listen for notifications + * from the native system. + * + * @param listener listener + * @see java.awt.desktop.AppForegroundListener + * @see java.awt.desktop.AppHiddenListener + * @see java.awt.desktop.AppReopenedListener + * @see java.awt.desktop.ScreenSleepListener + * @see java.awt.desktop.SystemSleepListener + * @see java.awt.desktop.UserSessionListener + */ + default void removeAppEventListener(final SystemEventListener listener) { + } + + /** + * Installs a handler to show a custom About window for your application. + *

      + * Setting the {@link AboutHandler} to {@code null} reverts it to the + * default behavior. + * + * @param aboutHandler the handler to respond to the + * {@link AboutHandler#handleAbout} )} message + */ + default void setAboutHandler(final AboutHandler aboutHandler) { + } + + /** + * Installs a handler to show a custom Preferences window for your + * application. + *

      + * Setting the {@link PreferencesHandler} to {@code null} reverts it to + * the default behavior + * + * @param preferencesHandler the handler to respond to the + * {@link java.awt.desktop.PreferencesHandler#handlePreferences(java.awt.PreferencesEvent) } + */ + default void setPreferencesHandler(final PreferencesHandler preferencesHandler) { + } + + /** + * Installs the handler which is notified when the application is asked to + * open a list of files. + * + * @param openFileHandler handler + * + */ + default void setOpenFileHandler(final OpenFilesHandler openFileHandler) { + } + + /** + * Installs the handler which is notified when the application is asked to + * print a list of files. + * + * @param printFileHandler handler + */ + default void setPrintFileHandler(final PrintFilesHandler printFileHandler) { + } + + /** + * Installs the handler which is notified when the application is asked to + * open a URL. + * + * Setting the handler to {@code null} causes all + * {@link OpenURIHandler#openURI(AppEvent.OpenURIEvent)} requests to be + * enqueued until another handler is set. + * + * @param openURIHandler handler + */ + default void setOpenURIHandler(final OpenURIHandler openURIHandler) { + } + + /** + * Installs the handler which determines if the application should quit. + * + * @param quitHandler the handler that is called when the application is + * asked to quit + * @see java.awt.Desktop#setQuitHandler(java.awt.desktop.QuitHandler) + */ + default void setQuitHandler(final QuitHandler quitHandler) { + } + + /** + * Sets the default strategy used to quit this application. The default is + * calling SYSTEM_EXIT_0. + * + * @param strategy the way this application should be shutdown + */ + default void setQuitStrategy(final QuitStrategy strategy) { + } + + /** + * Enables this application to be suddenly terminated. + * + * @see java.awt.Desktop#disableSuddenTermination() + */ + default void enableSuddenTermination() { + } + + /** + * Prevents this application from being suddenly terminated. + * + * @see java.awt.Desktop#enableSuddenTermination() + */ + default void disableSuddenTermination() { + } + + /** + * Requests this application to move to the foreground. + * + * @param allWindows if all windows of this application should be moved to + * the foreground, or only the foremost one + */ + default void requestForeground(final boolean allWindows) { + } + + /** + * Opens the native help viewer application. + */ + default void openHelpViewer() { + } + + /** + * Sets the default menu bar to use when there are no active frames. + * + * @param menuBar to use when no other frames are active + */ + default void setDefaultMenuBar(final JMenuBar menuBar) { + } + + /** + * Opens a folder containing the {@code file} in a default system file manager. + * @param file the file + * @return returns true if successfully opened + */ + default boolean browseFileDirectory(File file) { + return false; + } + /** + * Moves the specified file to the trash. + * + * @param file the file + * @return returns true if successfully moved the file to the trash. + */ + default boolean moveToTrash(File file) { + return false; + } + } diff --git a/jdk/src/java.desktop/share/classes/java/awt/peer/TaskbarPeer.java b/jdk/src/java.desktop/share/classes/java/awt/peer/TaskbarPeer.java new file mode 100644 index 00000000000..934a1c01538 --- /dev/null +++ b/jdk/src/java.desktop/share/classes/java/awt/peer/TaskbarPeer.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.awt.peer; + +import java.awt.Image; +import java.awt.PopupMenu; +import java.awt.Taskbar; +import java.awt.Taskbar.Feature; +import java.awt.Taskbar.State; +import java.awt.Window; + + +/** + * The {@code TaskbarPeer} interface provides methods for interacting with + * system task area. + */ +public interface TaskbarPeer { + + /** + * Requests user attention to this application. + * + * @param enabled disables this request if false + * @param critical if this is an important request + * @see Taskbar#requestUserAttention + */ + default void requestUserAttention(boolean enabled, final boolean critical) {} + + /** + * Requests user attention to the specified window until it is activated. + * + * On an already active window requesting attention does nothing. + * + * @param w window + */ + default void requestWindowUserAttention(Window w) {} + + /** + * Attaches the contents of the provided PopupMenu to the application icon + * in system task area. + * + * @param menu the PopupMenu to attach to this application + */ + default void setMenu(final PopupMenu menu) {} + + /** + * Gets PopupMenu used to add items to this application's icon in system task area. + * + * @return the PopupMenu + */ + default PopupMenu getMenu() { return null; } + + /** + * Changes this application's icon to the provided image. + * + * @param image to change + */ + default void setIconImage(final Image image) {} + + /** + * Obtains an image of this application's icon. + * + * @return an image of this application's icon + */ + default Image getIconImage() { return null; } + + /** + * Affixes a small system-provided badge to this application's icon. + * Usually a number. + * + * @param badge label to affix to the icon + */ + default void setIconBadge(final String badge) {} + + /** + * Affixes a small badge to this application's icon in task area + * for the specified window. + * + * @param w window to update + * @param badge image to affix to the icon + */ + default void setWindowIconBadge(Window w, final Image badge) {} + + /** + * Displays progress for specified window. + * + * @param w window to update + * @param value from 0 to 100, other to disable progress indication + */ + default void setWindowProgressValue(Window w, int value) {} + + /** + * Sets a progress state for a specified window. + * + * @param w window + * @param state to change to + * @see Taskbar#setWindowProgressState + */ + default void setWindowProgressState(Window w, State state) {} + + /** + * Affixes a small system-provided progress bar to this application's icon. + * + * @param value from 0 to 100, other to disable progress indication + */ + default void setProgressValue(int value) {} + + /** + * Tests support of {@code Feature} on current platform. + * @param f feature to test + * @return true if feature supported supported + */ + default public boolean isSupported(Feature f) { return false; } +} diff --git a/jdk/src/java.desktop/share/classes/javax/imageio/ImageTypeSpecifier.java b/jdk/src/java.desktop/share/classes/javax/imageio/ImageTypeSpecifier.java index 82e6e1a8756..e50958f1757 100644 --- a/jdk/src/java.desktop/share/classes/javax/imageio/ImageTypeSpecifier.java +++ b/jdk/src/java.desktop/share/classes/javax/imageio/ImageTypeSpecifier.java @@ -997,7 +997,7 @@ public class ImageTypeSpecifier { * negative or greater than the largest band index. */ public int getBitsPerBand(int band) { - if (band < 0 | band >= getNumBands()) { + if (band < 0 || band >= getNumBands()) { throw new IllegalArgumentException("band out of range!"); } return sampleModel.getSampleSize(band); diff --git a/jdk/src/java.desktop/share/classes/javax/sound/sampled/AudioInputStream.java b/jdk/src/java.desktop/share/classes/javax/sound/sampled/AudioInputStream.java index 716b9902331..242a3157d99 100644 --- a/jdk/src/java.desktop/share/classes/javax/sound/sampled/AudioInputStream.java +++ b/jdk/src/java.desktop/share/classes/javax/sound/sampled/AudioInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -249,10 +249,10 @@ public class AudioInputStream extends InputStream { */ @Override public int read(byte[] b, int off, int len) throws IOException { - // make sure we don't read fractions of a frame. - if( (len%frameSize) != 0 ) { - len -= (len%frameSize); + final int reminder = len % frameSize; + if (reminder != 0) { + len -= reminder; if (len == 0) { return 0; } @@ -312,6 +312,10 @@ public class AudioInputStream extends InputStream { /** * Skips over and discards a specified number of bytes from this audio input * stream. + *

      + * This method will always skip an integral number of frames. If {@code n} + * does not specify an integral number of frames, a maximum of + * {@code n - (n % frameSize)} bytes will be skipped. * * @param n the requested number of bytes to be skipped * @return the actual number of bytes skipped @@ -321,15 +325,14 @@ public class AudioInputStream extends InputStream { */ @Override public long skip(long n) throws IOException { - if (n <= 0) { - return 0; - } - // make sure not to skip fractional frames final long reminder = n % frameSize; if (reminder != 0) { n -= reminder; } + if (n <= 0) { + return 0; + } if (frameLength != AudioSystem.NOT_SPECIFIED) { // don't skip more than our set length in frames. diff --git a/jdk/src/java.desktop/share/classes/javax/swing/DefaultDesktopManager.java b/jdk/src/java.desktop/share/classes/javax/swing/DefaultDesktopManager.java index 74778d50267..0a41c36d9a0 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/DefaultDesktopManager.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/DefaultDesktopManager.java @@ -129,8 +129,12 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab } catch (PropertyVetoException e2) { } } else { + Container c = f.getParent(); + if (c == null) { + return; + } f.setNormalBounds(f.getBounds()); - Rectangle desktopBounds = f.getParent().getBounds(); + Rectangle desktopBounds = c.getBounds(); setBoundsForFrame(f, 0, 0, desktopBounds.width, desktopBounds.height); } diff --git a/jdk/src/java.desktop/share/classes/javax/swing/DefaultRowSorter.java b/jdk/src/java.desktop/share/classes/javax/swing/DefaultRowSorter.java index 4634b2b4d4a..3334f5f8342 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/DefaultRowSorter.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/DefaultRowSorter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -30,7 +30,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; -import javax.swing.SortOrder; /** * An implementation of RowSorter that provides sorting and @@ -495,7 +494,7 @@ public abstract class DefaultRowSorter extends RowSorter { */ public int convertRowIndexToView(int index) { if (modelToView == null) { - if (index < 0 || index >= getModelWrapper().getRowCount()) { + if (index < 0 || index >= modelRowCount) { throw new IndexOutOfBoundsException("Invalid index"); } return index; @@ -510,7 +509,7 @@ public abstract class DefaultRowSorter extends RowSorter { */ public int convertRowIndexToModel(int index) { if (viewToModel == null) { - if (index < 0 || index >= getModelWrapper().getRowCount()) { + if (index < 0 || index >= modelRowCount) { throw new IndexOutOfBoundsException("Invalid index"); } return index; @@ -814,7 +813,7 @@ public abstract class DefaultRowSorter extends RowSorter { // When filtering this may differ from getModelWrapper().getRowCount() return viewToModel.length; } - return getModelWrapper().getRowCount(); + return Math.max(getModelWrapper().getRowCount(), modelRowCount); } /** diff --git a/jdk/src/java.desktop/share/classes/javax/swing/JTable.java b/jdk/src/java.desktop/share/classes/javax/swing/JTable.java index f00473866a7..a0111c36c0d 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/JTable.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/JTable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -4401,13 +4401,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable } if (sortManager != null) { - List sortKeys = - sortManager.sorter.getSortKeys(); - if (sortKeys.size() != 0 && - sortKeys.get(0).getSortOrder() != SortOrder.UNSORTED) { - sortedTableChanged(null, e); - return; - } + sortedTableChanged(null, e); + return; } // The totalRowHeight calculated below will be incorrect if diff --git a/jdk/make/data/swingbeaninfo/images/AbstractButtonColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/AbstractButtonColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/AbstractButtonColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/AbstractButtonColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/BorderColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/BorderColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/BorderColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/BorderColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/BoxColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/BoxColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/BoxColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/BoxColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/BoxColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/BoxColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/BoxColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/BoxColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/BoxMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/BoxMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/BoxMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/BoxMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/BoxMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/BoxMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/BoxMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/BoxMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JAppletColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JAppletColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JAppletColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JAppletColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JAppletColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JAppletColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JAppletColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JAppletColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JAppletMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JAppletMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JAppletMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JAppletMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JAppletMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JAppletMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JAppletMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JAppletMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JButtonColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JButtonColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JButtonColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JButtonColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JButtonColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JButtonColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JButtonColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JButtonColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JButtonMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JButtonMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JButtonMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JButtonMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JButtonMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JButtonMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JButtonMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JButtonMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JCheckBoxColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JCheckBoxColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JCheckBoxColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JCheckBoxColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JCheckBoxMenuItemColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMenuItemColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JCheckBoxMenuItemColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMenuItemColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JCheckBoxMenuItemColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMenuItemColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JCheckBoxMenuItemColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMenuItemColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JCheckBoxMenuItemMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMenuItemMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JCheckBoxMenuItemMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMenuItemMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JCheckBoxMenuItemMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMenuItemMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JCheckBoxMenuItemMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMenuItemMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JCheckBoxMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JCheckBoxMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JCheckBoxMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JCheckBoxMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JColorChooserColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JColorChooserColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JColorChooserColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JColorChooserColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JColorChooserColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JColorChooserColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JColorChooserColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JColorChooserColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JColorChooserMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JColorChooserMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JColorChooserMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JColorChooserMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JColorChooserMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JColorChooserMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JColorChooserMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JColorChooserMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JComboBoxColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JComboBoxColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JComboBoxColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JComboBoxColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JComboBoxColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JComboBoxColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JComboBoxColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JComboBoxColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JComboBoxMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JComboBoxMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JComboBoxMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JComboBoxMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JComboBoxMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JComboBoxMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JComboBoxMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JComboBoxMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JComponentColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JComponentColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JComponentColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JComponentColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JDesktopPaneColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDesktopPaneColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JDesktopPaneColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDesktopPaneColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JDesktopPaneColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDesktopPaneColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JDesktopPaneColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDesktopPaneColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JDesktopPaneMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDesktopPaneMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JDesktopPaneMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDesktopPaneMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JDesktopPaneMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDesktopPaneMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JDesktopPaneMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDesktopPaneMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JDialogColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDialogColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JDialogColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDialogColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JDialogColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDialogColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JDialogColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDialogColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JDialogMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDialogMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JDialogMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDialogMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JDialogMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDialogMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JDialogMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDialogMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JEditorPaneColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JEditorPaneColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JEditorPaneColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JEditorPaneColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JEditorPaneColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JEditorPaneColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JEditorPaneColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JEditorPaneColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JEditorPaneMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JEditorPaneMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JEditorPaneMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JEditorPaneMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JEditorPaneMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JEditorPaneMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JEditorPaneMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JEditorPaneMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JFileChooserColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFileChooserColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JFileChooserColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFileChooserColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JFileChooserColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFileChooserColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JFileChooserColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFileChooserColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JFileChooserMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFileChooserMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JFileChooserMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFileChooserMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JFileChooserMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFileChooserMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JFileChooserMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFileChooserMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JFormattedTextFieldColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFormattedTextFieldColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JFormattedTextFieldColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFormattedTextFieldColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JFormattedTextFieldColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFormattedTextFieldColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JFormattedTextFieldColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFormattedTextFieldColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JFormattedTextFieldMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFormattedTextFieldMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JFormattedTextFieldMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFormattedTextFieldMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JFormattedTextFieldMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFormattedTextFieldMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JFormattedTextFieldMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFormattedTextFieldMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JFrameColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFrameColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JFrameColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFrameColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JFrameColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFrameColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JFrameColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFrameColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JFrameMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFrameMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JFrameMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFrameMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JFrameMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFrameMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JFrameMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFrameMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JInternalFrameColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JInternalFrameColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JInternalFrameColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JInternalFrameColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JInternalFrameColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JInternalFrameColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JInternalFrameColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JInternalFrameColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JInternalFrameMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JInternalFrameMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JInternalFrameMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JInternalFrameMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JInternalFrameMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JInternalFrameMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JInternalFrameMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JInternalFrameMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JLabelColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLabelColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JLabelColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLabelColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JLabelColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLabelColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JLabelColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLabelColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JLabelMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLabelMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JLabelMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLabelMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JLabelMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLabelMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JLabelMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLabelMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JLayeredPaneColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLayeredPaneColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JLayeredPaneColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLayeredPaneColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JLayeredPaneColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLayeredPaneColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JLayeredPaneColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLayeredPaneColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JLayeredPaneMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLayeredPaneMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JLayeredPaneMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLayeredPaneMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JLayeredPaneMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLayeredPaneMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JLayeredPaneMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLayeredPaneMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JListColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JListColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JListColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JListColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JListColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JListColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JListColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JListColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JListMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JListMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JListMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JListMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JListMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JListMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JListMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JListMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JMenuBarColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuBarColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JMenuBarColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuBarColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JMenuBarColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuBarColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JMenuBarColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuBarColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JMenuBarMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuBarMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JMenuBarMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuBarMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JMenuBarMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuBarMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JMenuBarMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuBarMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JMenuColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JMenuColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JMenuColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JMenuColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JMenuItemColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuItemColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JMenuItemColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuItemColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JMenuItemColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuItemColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JMenuItemColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuItemColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JMenuItemMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuItemMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JMenuItemMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuItemMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JMenuItemMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuItemMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JMenuItemMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuItemMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JMenuMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JMenuMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JMenuMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JMenuMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JOptionPaneColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JOptionPaneColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JOptionPaneColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JOptionPaneColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JOptionPaneColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JOptionPaneColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JOptionPaneColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JOptionPaneColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JOptionPaneMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JOptionPaneMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JOptionPaneMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JOptionPaneMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JOptionPaneMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JOptionPaneMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JOptionPaneMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JOptionPaneMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JPanelColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPanelColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JPanelColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPanelColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JPanelColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPanelColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JPanelColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPanelColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JPanelMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPanelMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JPanelMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPanelMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JPanelMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPanelMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JPanelMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPanelMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JPasswordFieldColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPasswordFieldColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JPasswordFieldColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPasswordFieldColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JPasswordFieldColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPasswordFieldColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JPasswordFieldColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPasswordFieldColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JPasswordFieldMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPasswordFieldMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JPasswordFieldMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPasswordFieldMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JPasswordFieldMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPasswordFieldMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JPasswordFieldMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPasswordFieldMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JPopupMenuColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPopupMenuColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JPopupMenuColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPopupMenuColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JPopupMenuColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPopupMenuColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JPopupMenuColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPopupMenuColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JPopupMenuMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPopupMenuMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JPopupMenuMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPopupMenuMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JPopupMenuMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPopupMenuMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JPopupMenuMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPopupMenuMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JProgressBarColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JProgressBarColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JProgressBarColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JProgressBarColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JProgressBarColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JProgressBarColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JProgressBarColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JProgressBarColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JProgressBarMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JProgressBarMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JProgressBarMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JProgressBarMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JProgressBarMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JProgressBarMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JProgressBarMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JProgressBarMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JRadioButtonColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JRadioButtonColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JRadioButtonColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JRadioButtonColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JRadioButtonMenuItemColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMenuItemColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JRadioButtonMenuItemColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMenuItemColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JRadioButtonMenuItemColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMenuItemColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JRadioButtonMenuItemColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMenuItemColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JRadioButtonMenuItemMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMenuItemMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JRadioButtonMenuItemMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMenuItemMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JRadioButtonMenuItemMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMenuItemMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JRadioButtonMenuItemMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMenuItemMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JRadioButtonMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JRadioButtonMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JRadioButtonMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JRadioButtonMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JRootPaneColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRootPaneColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JRootPaneColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRootPaneColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JRootPaneColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRootPaneColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JRootPaneColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRootPaneColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JRootPaneMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRootPaneMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JRootPaneMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRootPaneMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JRootPaneMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRootPaneMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JRootPaneMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRootPaneMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JScrollBarColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollBarColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JScrollBarColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollBarColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JScrollBarColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollBarColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JScrollBarColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollBarColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JScrollBarMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollBarMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JScrollBarMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollBarMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JScrollBarMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollBarMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JScrollBarMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollBarMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JScrollPaneColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollPaneColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JScrollPaneColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollPaneColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JScrollPaneColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollPaneColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JScrollPaneColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollPaneColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JScrollPaneMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollPaneMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JScrollPaneMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollPaneMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JScrollPaneMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollPaneMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JScrollPaneMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollPaneMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSeparatorColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSeparatorColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSeparatorColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSeparatorColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSeparatorColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSeparatorColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSeparatorColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSeparatorColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSeparatorMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSeparatorMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSeparatorMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSeparatorMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSeparatorMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSeparatorMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSeparatorMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSeparatorMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSliderColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSliderColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSliderColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSliderColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSliderColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSliderColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSliderColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSliderColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSliderMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSliderMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSliderMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSliderMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSliderMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSliderMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSliderMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSliderMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSpinnerColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSpinnerColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSpinnerColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSpinnerColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSpinnerColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSpinnerColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSpinnerColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSpinnerColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSpinnerMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSpinnerMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSpinnerMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSpinnerMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSpinnerMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSpinnerMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSpinnerMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSpinnerMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSplitPaneColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSplitPaneColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSplitPaneColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSplitPaneColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSplitPaneColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSplitPaneColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSplitPaneColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSplitPaneColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSplitPaneMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSplitPaneMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSplitPaneMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSplitPaneMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JSplitPaneMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSplitPaneMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JSplitPaneMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSplitPaneMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTabbedPaneColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTabbedPaneColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTabbedPaneColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTabbedPaneColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTabbedPaneColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTabbedPaneColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTabbedPaneColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTabbedPaneColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTabbedPaneMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTabbedPaneMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTabbedPaneMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTabbedPaneMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTabbedPaneMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTabbedPaneMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTabbedPaneMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTabbedPaneMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTableColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTableColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTableColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTableColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTableColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTableColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTableColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTableColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTableMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTableMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTableMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTableMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTableMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTableMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTableMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTableMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTextAreaColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextAreaColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTextAreaColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextAreaColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTextAreaColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextAreaColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTextAreaColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextAreaColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTextAreaMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextAreaMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTextAreaMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextAreaMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTextAreaMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextAreaMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTextAreaMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextAreaMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTextFieldColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextFieldColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTextFieldColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextFieldColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTextFieldColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextFieldColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTextFieldColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextFieldColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTextFieldMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextFieldMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTextFieldMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextFieldMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTextFieldMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextFieldMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTextFieldMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextFieldMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTextPaneColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextPaneColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTextPaneColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextPaneColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTextPaneColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextPaneColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTextPaneColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextPaneColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTextPaneMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextPaneMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTextPaneMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextPaneMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTextPaneMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextPaneMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTextPaneMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextPaneMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JToggleButtonColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToggleButtonColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JToggleButtonColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToggleButtonColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JToggleButtonColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToggleButtonColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JToggleButtonColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToggleButtonColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JToggleButtonMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToggleButtonMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JToggleButtonMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToggleButtonMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JToggleButtonMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToggleButtonMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JToggleButtonMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToggleButtonMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JToolBarColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToolBarColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JToolBarColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToolBarColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JToolBarColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToolBarColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JToolBarColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToolBarColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JToolBarMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToolBarMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JToolBarMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToolBarMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JToolBarMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToolBarMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JToolBarMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToolBarMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTreeColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTreeColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTreeColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTreeColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTreeColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTreeColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTreeColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTreeColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTreeMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTreeMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTreeMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTreeMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JTreeMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTreeMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JTreeMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTreeMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JViewportColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JViewportColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JViewportColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JViewportColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JViewportColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JViewportColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JViewportColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JViewportColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JViewportMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JViewportMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JViewportMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JViewportMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JViewportMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JViewportMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JViewportMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JViewportMono32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JWindowColor16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JWindowColor16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JWindowColor16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JWindowColor16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JWindowColor32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JWindowColor32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JWindowColor32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JWindowColor32.gif diff --git a/jdk/make/data/swingbeaninfo/images/JWindowMono16.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JWindowMono16.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JWindowMono16.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JWindowMono16.gif diff --git a/jdk/make/data/swingbeaninfo/images/JWindowMono32.gif b/jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JWindowMono32.gif similarity index 100% rename from jdk/make/data/swingbeaninfo/images/JWindowMono32.gif rename to jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JWindowMono32.gif diff --git a/jdk/src/java.desktop/share/classes/javax/swing/border/TitledBorder.java b/jdk/src/java.desktop/share/classes/javax/swing/border/TitledBorder.java index 2732cb9cde3..4933d03c65b 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/border/TitledBorder.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/border/TitledBorder.java @@ -34,6 +34,9 @@ import java.awt.Insets; import java.awt.Rectangle; import java.awt.geom.Path2D; import java.beans.ConstructorProperties; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.lang.ref.WeakReference; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.UIManager; @@ -246,6 +249,7 @@ public class TitledBorder extends AbstractBorder this.label = new JLabel(); this.label.setOpaque(false); this.label.putClientProperty(BasicHTML.propertyKey, null); + installPropertyChangeListeners(); } /** @@ -752,4 +756,25 @@ public class TitledBorder extends AbstractBorder } return insets; } + + private void installPropertyChangeListeners() { + final WeakReference weakReference = new WeakReference(this); + final PropertyChangeListener listener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (weakReference.get() == null) { + UIManager.removePropertyChangeListener(this); + UIManager.getDefaults().removePropertyChangeListener(this); + } else { + String prop = evt.getPropertyName(); + if ("lookAndFeel".equals(prop) || "LabelUI".equals(prop)) { + label.updateUI(); + } + } + } + }; + + UIManager.addPropertyChangeListener(listener); + UIManager.getDefaults().addPropertyChangeListener(listener); + } } diff --git a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java index bcae2e3f8e8..dbcfb308b7c 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java @@ -1719,6 +1719,9 @@ public class BasicInternalFrameUI extends InternalFrameUI if ((frame.getParent() != null) && !componentListenerAdded) { f.getParent().addComponentListener(componentListener); componentListenerAdded = true; + if (f.isMaximum()) { + maximizeFrame(f); + } } } else if (JInternalFrame.TITLE_PROPERTY == prop || prop == "closable" || prop == "iconable" || diff --git a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthButtonUI.java b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthButtonUI.java index 4bfa159602c..a85cf146849 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthButtonUI.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthButtonUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -357,7 +357,7 @@ public class SynthButtonUI extends BasicButtonUI implements * This method will return the icon that should be used for a button. We * only want to use the synth icon defined by the style if the specific * icon has not been defined for the button state and the backup icon is a - * UIResource (we set it, not the developer). + * UIResource (we set it, not the developer) or {@code null}. * * @param b button * @param specificIcon icon returned from the button for the specific state @@ -368,7 +368,7 @@ public class SynthButtonUI extends BasicButtonUI implements int state) { Icon icon = specificIcon; if (icon == null) { - if (defaultIcon instanceof UIResource) { + if (defaultIcon == null || defaultIcon instanceof UIResource) { icon = getSynthIcon(b, state); if (icon == null) { icon = defaultIcon; @@ -398,11 +398,16 @@ public class SynthButtonUI extends BasicButtonUI implements private Icon getRolloverIcon(AbstractButton b, Icon defaultIcon) { ButtonModel model = b.getModel(); - Icon icon; + Icon icon = null; if (model.isSelected()) { - icon = getIcon(b, b.getRolloverSelectedIcon(), defaultIcon, + icon = getIcon(b, b.getRolloverSelectedIcon(), null, SynthConstants.MOUSE_OVER | SynthConstants.SELECTED); - } else { + if (icon == null) { + icon = getIcon(b, b.getSelectedIcon(), null, + SynthConstants.SELECTED); + } + } + if (icon == null) { icon = getIcon(b, b.getRolloverIcon(), defaultIcon, SynthConstants.MOUSE_OVER); } @@ -416,11 +421,16 @@ public class SynthButtonUI extends BasicButtonUI implements private Icon getSynthDisabledIcon(AbstractButton b, Icon defaultIcon) { ButtonModel model = b.getModel(); - Icon icon; + Icon icon = null; if (model.isSelected()) { - icon = getIcon(b, b.getDisabledSelectedIcon(), defaultIcon, + icon = getIcon(b, b.getDisabledSelectedIcon(), null, SynthConstants.DISABLED | SynthConstants.SELECTED); - } else { + if (icon == null) { + icon = getIcon(b, b.getSelectedIcon(), null, + SynthConstants.SELECTED); + } + } + if (icon == null) { icon = getIcon(b, b.getDisabledIcon(), defaultIcon, SynthConstants.DISABLED); } diff --git a/jdk/src/java.desktop/share/classes/javax/swing/text/AbstractWriter.java b/jdk/src/java.desktop/share/classes/javax/swing/text/AbstractWriter.java index 1625964b562..0ca0fecb5a8 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/text/AbstractWriter.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/text/AbstractWriter.java @@ -441,7 +441,7 @@ public abstract class AbstractWriter { --offsetIndent; } else { - indentLevel = indentLevel > 0 ? indentLevel-- : 0; + indentLevel--; } } diff --git a/jdk/src/java.desktop/share/classes/javax/swing/text/CompositeView.java b/jdk/src/java.desktop/share/classes/javax/swing/text/CompositeView.java index b3fcef3338d..e08c75a1da8 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/text/CompositeView.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/text/CompositeView.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -24,7 +24,7 @@ */ package javax.swing.text; -import java.util.Vector; +import java.util.*; import java.awt.*; import javax.swing.event.*; import javax.swing.SwingConstants; @@ -182,9 +182,11 @@ public abstract class CompositeView extends View { views = ZERO; } + Set set = new HashSet<>(Arrays.asList(views)); // update parent reference on removed views for (int i = offset; i < offset + length; i++) { - if (children[i].getParent() == this) { + View child = children[i]; + if (child.getParent() == this && !set.contains(child)) { // in FlowView.java view might be referenced // from two super-views as a child. see logicalView children[i].setParent(null); diff --git a/jdk/src/java.desktop/share/classes/javax/swing/text/html/HTMLWriter.java b/jdk/src/java.desktop/share/classes/javax/swing/text/html/HTMLWriter.java index a1e3813ac25..f8a9558505c 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/text/html/HTMLWriter.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/text/html/HTMLWriter.java @@ -178,7 +178,8 @@ public class HTMLWriter extends AbstractWriter { if (!synthesizedElement(top)) { AttributeSet attrs = top.getAttributes(); if (!matchNameAttribute(attrs, HTML.Tag.PRE) && - !isFormElementWithContent(attrs)) { + !isFormElementWithContent(attrs) && + !isPreTagWithParagraphTag(attrs)) { decrIndent(); } endTag(top); @@ -223,7 +224,8 @@ public class HTMLWriter extends AbstractWriter { if (!synthesizedElement(current)) { AttributeSet attrs = current.getAttributes(); if (!matchNameAttribute(attrs, HTML.Tag.PRE) && - !isFormElementWithContent(attrs)) { + !isFormElementWithContent(attrs) && + !isPreTagWithParagraphTag(attrs)) { decrIndent(); } endTag(current); @@ -830,6 +832,14 @@ public class HTMLWriter extends AbstractWriter { matchNameAttribute(attr, HTML.Tag.SELECT); } + /** + * Determines if the element associated with the attributeset + * is a P tag and it is within Pre tag. If true, returns true else + * false + */ + private boolean isPreTagWithParagraphTag(AttributeSet attr) { + return inPre && matchNameAttribute(attr, HTML.Tag.P); + } /** * Determines whether a the indentation needs to be diff --git a/jdk/src/java.desktop/share/classes/javax/swing/text/rtf/RTFGenerator.java b/jdk/src/java.desktop/share/classes/javax/swing/text/rtf/RTFGenerator.java index 0a67b87b674..226080f999a 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/text/rtf/RTFGenerator.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/text/rtf/RTFGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -491,7 +491,10 @@ protected void checkControlWord(MutableAttributeSet currentAttributes, word.swingName(), MagicToken)) != null) { if (parm == MagicToken) parm = null; - word.writeValue(parm, this, true); + if (!word.writeValue(parm, this, true) && + word instanceof RTFAttributes.AssertiveAttribute ) { + currentAttributes.removeAttribute(word.swingName()); + } } } diff --git a/jdk/src/java.desktop/share/classes/module-info.java b/jdk/src/java.desktop/share/classes/module-info.java index 78af9bf8826..5cf785de71f 100644 --- a/jdk/src/java.desktop/share/classes/module-info.java +++ b/jdk/src/java.desktop/share/classes/module-info.java @@ -27,10 +27,13 @@ module java.desktop { requires public java.datatransfer; requires public java.xml; requires java.prefs; + // 8147544 + requires jdk.unsupported; exports java.applet; exports java.awt; exports java.awt.color; + exports java.awt.desktop; exports java.awt.dnd; exports java.awt.event; exports java.awt.font; diff --git a/jdk/src/java.desktop/share/classes/sun/awt/ComponentFactory.java b/jdk/src/java.desktop/share/classes/sun/awt/ComponentFactory.java index b3450354875..b2e8af875ec 100644 --- a/jdk/src/java.desktop/share/classes/sun/awt/ComponentFactory.java +++ b/jdk/src/java.desktop/share/classes/sun/awt/ComponentFactory.java @@ -25,6 +25,7 @@ package sun.awt; +import java.awt.peer.TaskbarPeer; import java.awt.*; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.InvalidDnDOperationException; @@ -74,6 +75,23 @@ public interface ComponentFactory { throw new HeadlessException(); } + /** + * Creates this toolkit's implementation of the {@code Taskbar} using the + * specified peer interface. + * + * @param target the taskbar to be implemented + * @return this toolkit's implementation of the {@code Taskbar} + * @throws HeadlessException if GraphicsEnvironment.isHeadless() returns + * true + * @see java.awt.GraphicsEnvironment#isHeadless + * @see java.awt.Taskbar + * @see java.awt.peer.TaskbarPeer + * @since 9 + */ + default TaskbarPeer createTaskbarPeer(Taskbar target) { + throw new HeadlessException(); + } + /** * Creates this toolkit's implementation of {@code Button} using the * specified peer interface. diff --git a/jdk/src/java.desktop/share/classes/sun/awt/HToolkit.java b/jdk/src/java.desktop/share/classes/sun/awt/HToolkit.java index dd93654f573..fb569e3b56b 100644 --- a/jdk/src/java.desktop/share/classes/sun/awt/HToolkit.java +++ b/jdk/src/java.desktop/share/classes/sun/awt/HToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -286,6 +286,11 @@ public final class HToolkit extends SunToolkit implements ComponentFactory { return false; } + @Override + public boolean isTaskbarSupported() { + return false; + } + public boolean isWindowOpacityControlSupported() { return false; } diff --git a/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java b/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java index a1c89a41067..fdaeb1ea7ad 100644 --- a/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java +++ b/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -1781,6 +1781,7 @@ public abstract class SunToolkit extends Toolkit public abstract boolean isDesktopSupported(); + public abstract boolean isTaskbarSupported(); /* * consumeNextKeyTyped() method is not currently used, diff --git a/jdk/src/java.desktop/share/classes/sun/font/FileFont.java b/jdk/src/java.desktop/share/classes/sun/font/FileFont.java index 60b2377c9da..6764c309851 100644 --- a/jdk/src/java.desktop/share/classes/sun/font/FileFont.java +++ b/jdk/src/java.desktop/share/classes/sun/font/FileFont.java @@ -36,6 +36,7 @@ import sun.java2d.Disposer; import sun.java2d.DisposerRecord; import java.io.IOException; +import java.util.List; import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; @@ -116,17 +117,17 @@ public abstract class FileFont extends PhysicalFont { return true; } - void setFileToRemove(File file, CreatedFontTracker tracker) { - Disposer.addObjectRecord(this, - new CreatedFontFileDisposerRecord(file, tracker)); - } + static void setFileToRemove(List fonts, + File file, int cnt, + CreatedFontTracker tracker) + { + CreatedFontFileDisposerRecord dr = + new CreatedFontFileDisposerRecord(file, cnt, tracker); - // MACOSX begin -- Make this static so that we can pass in CFont - static void setFileToRemove(Object font, File file, CreatedFontTracker tracker) { - Disposer.addObjectRecord(font, - new CreatedFontFileDisposerRecord(file, tracker)); + for (Font2D f : fonts) { + Disposer.addObjectRecord(f, dr); + } } - // MACOSX - end /* This is called when a font scaler is determined to * be unusable (ie bad). @@ -251,11 +252,13 @@ public abstract class FileFont extends PhysicalFont { implements DisposerRecord { File fontFile = null; + int count = 0; // number of fonts referencing this file object. CreatedFontTracker tracker; - private CreatedFontFileDisposerRecord(File file, + private CreatedFontFileDisposerRecord(File file, int cnt, CreatedFontTracker tracker) { fontFile = file; + count = (cnt > 0) ? cnt : 1; this.tracker = tracker; } @@ -263,6 +266,12 @@ public abstract class FileFont extends PhysicalFont { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { + synchronized (fontFile) { + count--; + if (count > 0) { + return null; + } + } if (fontFile != null) { try { if (tracker != null) { diff --git a/jdk/src/java.desktop/share/classes/sun/font/FontManager.java b/jdk/src/java.desktop/share/classes/sun/font/FontManager.java index 1e496271a16..455daf69cfa 100644 --- a/jdk/src/java.desktop/share/classes/sun/font/FontManager.java +++ b/jdk/src/java.desktop/share/classes/sun/font/FontManager.java @@ -81,13 +81,15 @@ public interface FontManager { * * @param fontFile the file holding the font data * @param fontFormat the expected font format + * @param all whether to retrieve all fonts in the resource or + * just the first one. * @param isCopy {@code true} if the file is a copy and needs to be * deleted, {@code false} otherwise * * @return the created Font2D instance */ - public Font2D createFont2D(File fontFile, int fontFormat, - boolean isCopy, CreatedFontTracker tracker) + public Font2D[] createFont2D(File fontFile, int fontFormat, boolean all, + boolean isCopy, CreatedFontTracker tracker) throws FontFormatException; /** diff --git a/jdk/src/java.desktop/share/classes/sun/font/SunFontManager.java b/jdk/src/java.desktop/share/classes/sun/font/SunFontManager.java index 7f5626194fe..67bb3fd383a 100644 --- a/jdk/src/java.desktop/share/classes/sun/font/SunFontManager.java +++ b/jdk/src/java.desktop/share/classes/sun/font/SunFontManager.java @@ -40,6 +40,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; @@ -2420,15 +2421,15 @@ public abstract class SunFontManager implements FontSupport, FontManagerForSGE { protected abstract String getFontPath(boolean noType1Fonts); - // MACOSX begin -- need to access this in subclass - protected Thread fileCloser = null; - // MACOSX end + Thread fileCloser = null; Vector tmpFontFiles = null; - public Font2D createFont2D(File fontFile, int fontFormat, - boolean isCopy, CreatedFontTracker tracker) + public Font2D[] createFont2D(File fontFile, int fontFormat, boolean all, + boolean isCopy, CreatedFontTracker tracker) throws FontFormatException { + List fList = new ArrayList(); + int cnt = 1; String fontFilePath = fontFile.getPath(); FileFont font2D = null; final File fFile = fontFile; @@ -2437,9 +2438,19 @@ public abstract class SunFontManager implements FontSupport, FontManagerForSGE { switch (fontFormat) { case Font.TRUETYPE_FONT: font2D = new TrueTypeFont(fontFilePath, null, 0, true); + fList.add(font2D); + if (!all) { + break; + } + cnt = ((TrueTypeFont)font2D).getFontCount(); + int index = 1; + while (index < cnt) { + fList.add(new TrueTypeFont(fontFilePath, null, index++, true)); + } break; case Font.TYPE1_FONT: font2D = new Type1Font(fontFilePath, null, isCopy); + fList.add(font2D); break; default: throw new FontFormatException("Unrecognised Font Format"); @@ -2460,7 +2471,7 @@ public abstract class SunFontManager implements FontSupport, FontManagerForSGE { throw(e); } if (isCopy) { - font2D.setFileToRemove(fontFile, tracker); + FileFont.setFileToRemove(fList, fontFile, cnt, tracker); synchronized (FontManager.class) { if (tmpFontFiles == null) { @@ -2511,7 +2522,7 @@ public abstract class SunFontManager implements FontSupport, FontManagerForSGE { } } } - return font2D; + return fList.toArray(new Font2D[0]); } /* remind: used in X11GraphicsEnvironment and called often enough diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java b/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java index 967077d6585..8207213e3e5 100644 --- a/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java +++ b/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java @@ -2101,13 +2101,39 @@ public final class SunGraphics2D if (w <= 0 || h <= 0) { return; } + + if (transformState == SunGraphics2D.TRANSFORM_ISIDENT) { + // do nothing + } else if (transformState <= SunGraphics2D.TRANSFORM_ANY_TRANSLATE) { + x += transX; + y += transY; + } else if (transformState == SunGraphics2D.TRANSFORM_TRANSLATESCALE) { + final double[] coords = {x, y, x + w, y + h, x + dx, y + dy}; + transform.transform(coords, 0, coords, 0, 3); + x = (int) Math.ceil(coords[0] - 0.5); + y = (int) Math.ceil(coords[1] - 0.5); + w = ((int) Math.ceil(coords[2] - 0.5)) - x; + h = ((int) Math.ceil(coords[3] - 0.5)) - y; + dx = ((int) Math.ceil(coords[4] - 0.5)) - x; + dy = ((int) Math.ceil(coords[5] - 0.5)) - y; + // In case of negative scale transform, reflect the rect coords. + if (w < 0) { + w = -w; + x -= w; + } + if (h < 0) { + h = -h; + y -= h; + } + } else { + throw new InternalError("transformed copyArea not implemented yet"); + } + SurfaceData theData = surfaceData; if (theData.copyArea(this, x, y, w, h, dx, dy)) { return; } - if (transformState > TRANSFORM_TRANSLATESCALE) { - throw new InternalError("transformed copyArea not implemented yet"); - } + // REMIND: This method does not deal with missing data from the // source object (i.e. it does not send exposure events...) @@ -2126,26 +2152,6 @@ public final class SunGraphics2D lastCAcomp = comp; } - double[] coords = {x, y, x + w, y + h, x + dx, y + dy}; - transform.transform(coords, 0, coords, 0, 3); - - x = (int)Math.ceil(coords[0] - 0.5); - y = (int)Math.ceil(coords[1] - 0.5); - w = ((int)Math.ceil(coords[2] - 0.5)) - x; - h = ((int)Math.ceil(coords[3] - 0.5)) - y; - dx = ((int)Math.ceil(coords[4] - 0.5)) - x; - dy = ((int)Math.ceil(coords[5] - 0.5)) - y; - - // In case of negative scale transform, reflect the rect coords. - if (w < 0) { - w *= -1; - x -= w; - } - if (h < 0) { - h *= -1; - y -= h; - } - Blit ob = lastCAblit; if (dy == 0 && dx > 0 && dx < w) { while (w > 0) { @@ -2167,7 +2173,7 @@ public final class SunGraphics2D } return; } - ob.Blit(theData, theData, comp, clip, x, y, x+dx, y+dy, w, h); + ob.Blit(theData, theData, comp, clip, x, y, x+dx, y+dy, w, h); } /* diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java b/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java index ce14dfa569d..1e1fd3e42e1 100644 --- a/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java +++ b/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java @@ -208,9 +208,9 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment * to use Mincho instead of Gothic for dialoginput in JA locales * on windows. Not needed on other platforms. * - * DO NOT MOVE OR RENAME OR OTHERWISE ALTER THIS METHOD. - * ITS USED BY SOME NON-JRE INTERNAL CODE. + * @deprecated as of JDK9. To be removed in a future release */ + @Deprecated public static void useAlternateFontforJALocales() { getFontManagerForSGE().useAlternateFontforJALocales(); } diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/SurfaceData.java b/jdk/src/java.desktop/share/classes/sun/java2d/SurfaceData.java index 4de1a1fc576..806bf05bced 100644 --- a/jdk/src/java.desktop/share/classes/sun/java2d/SurfaceData.java +++ b/jdk/src/java.desktop/share/classes/sun/java2d/SurfaceData.java @@ -1039,6 +1039,11 @@ public abstract class SurfaceData * Performs a copyarea within this surface. Returns * false if there is no algorithm to perform the copyarea * given the current settings of the SunGraphics2D. + * + * @param x the x coordinate of the area in device space + * @param y the y coordinate of the area in device space + * @param w the width of the area in device space + * @param h the height of the area in device space */ public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy) diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinRenderingEngine.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinRenderingEngine.java index e01a5e77f9c..b794d8c6004 100644 --- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinRenderingEngine.java +++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinRenderingEngine.java @@ -51,6 +51,9 @@ public class MarlinRenderingEngine extends RenderingEngine private static final float MIN_PEN_SIZE = 1f / NORM_SUBPIXELS; + static final float UPPER_BND = Float.MAX_VALUE / 2.0f; + static final float LOWER_BND = -UPPER_BND; + /** * Public constructor */ @@ -279,7 +282,7 @@ public class MarlinRenderingEngine extends RenderingEngine float dashphase, PathConsumer2D pc2d) { - // We use strokerat and outat so that in Stroker and Dasher we can work only + // We use strokerat so that in Stroker and Dasher we can work only // with the pre-transformation coordinates. This will repeat a lot of // computations done in the path iterator, but the alternative is to // work with transformed paths and compute untransformed coordinates @@ -289,15 +292,11 @@ public class MarlinRenderingEngine extends RenderingEngine // However, if a path's width is constant after a transformation, // we can skip all this untransforming. - // If normalization is off we save some transformations by not - // transforming the input to pisces. Instead, we apply the - // transformation after the path processing has been done. - // We can't do this if normalization is on, because it isn't a good - // idea to normalize before the transformation is applied. + // As pathTo() will check transformed coordinates for invalid values + // (NaN / Infinity) to ignore such points, it is necessary to apply the + // transformation before the path processing. AffineTransform strokerat = null; - AffineTransform outat = null; - PathIterator pi; int dashLen = -1; boolean recycleDashes = false; @@ -333,6 +332,7 @@ public class MarlinRenderingEngine extends RenderingEngine // leave a bit of room for error. if (nearZero(a*b + c*d) && nearZero(a*a + c*c - (b*b + d*d))) { final float scale = (float) Math.sqrt(a*a + c*c); + if (dashes != null) { recycleDashes = true; dashLen = dashes.length; @@ -349,48 +349,35 @@ public class MarlinRenderingEngine extends RenderingEngine System.arraycopy(dashes, 0, newDashes, 0, dashLen); dashes = newDashes; for (int i = 0; i < dashLen; i++) { - dashes[i] = scale * dashes[i]; + dashes[i] *= scale; } - dashphase = scale * dashphase; + dashphase *= scale; } - width = scale * width; - pi = getNormalizingPathIterator(rdrCtx, normalize, - src.getPathIterator(at)); + width *= scale; - // by now strokerat == null && outat == null. Input paths to + // by now strokerat == null. Input paths to // stroker (and maybe dasher) will have the full transform at // applied to them and nothing will happen to the output paths. } else { - if (normalize != NormMode.OFF) { - strokerat = at; - pi = getNormalizingPathIterator(rdrCtx, normalize, - src.getPathIterator(at)); + strokerat = at; - // by now strokerat == at && outat == null. Input paths to - // stroker (and maybe dasher) will have the full transform at - // applied to them, then they will be normalized, and then - // the inverse of *only the non translation part of at* will - // be applied to the normalized paths. This won't cause problems - // in stroker, because, suppose at = T*A, where T is just the - // translation part of at, and A is the rest. T*A has already - // been applied to Stroker/Dasher's input. Then Ainv will be - // applied. Ainv*T*A is not equal to T, but it is a translation, - // which means that none of stroker's assumptions about its - // input will be violated. After all this, A will be applied - // to stroker's output. - } else { - outat = at; - pi = src.getPathIterator(null); - // outat == at && strokerat == null. This is because if no - // normalization is done, we can just apply all our - // transformations to stroker's output. - } + // by now strokerat == at. Input paths to + // stroker (and maybe dasher) will have the full transform at + // applied to them, then they will be normalized, and then + // the inverse of *only the non translation part of at* will + // be applied to the normalized paths. This won't cause problems + // in stroker, because, suppose at = T*A, where T is just the + // translation part of at, and A is the rest. T*A has already + // been applied to Stroker/Dasher's input. Then Ainv will be + // applied. Ainv*T*A is not equal to T, but it is a translation, + // which means that none of stroker's assumptions about its + // input will be violated. After all this, A will be applied + // to stroker's output. } } else { // either at is null or it's the identity. In either case // we don't transform the path. - pi = getNormalizingPathIterator(rdrCtx, normalize, - src.getPathIterator(null)); + at = null; } if (useSimplifier) { @@ -399,12 +386,7 @@ public class MarlinRenderingEngine extends RenderingEngine pc2d = rdrCtx.simplifier.init(pc2d); } - // by now, at least one of outat and strokerat will be null. Unless at is not - // a constant multiple of an orthogonal transformation, they will both be - // null. In other cases, outat == at if normalization is off, and if - // normalization is on, strokerat == at. final TransformingPathConsumer2D transformerPC2D = rdrCtx.transformerPC2D; - pc2d = transformerPC2D.transformConsumer(pc2d, outat); pc2d = transformerPC2D.deltaTransformConsumer(pc2d, strokerat); pc2d = rdrCtx.stroker.init(pc2d, width, caps, join, miterlimit); @@ -417,18 +399,22 @@ public class MarlinRenderingEngine extends RenderingEngine recycleDashes); } pc2d = transformerPC2D.inverseDeltaTransformConsumer(pc2d, strokerat); + + final PathIterator pi = getNormalizingPathIterator(rdrCtx, normalize, + src.getPathIterator(at)); + pathTo(rdrCtx, pi, pc2d); /* * Pipeline seems to be: - * shape.getPathIterator - * -> NormalizingPathIterator - * -> inverseDeltaTransformConsumer - * -> Dasher + * shape.getPathIterator(at) + * -> (NormalizingPathIterator) + * -> (inverseDeltaTransformConsumer) + * -> (Dasher) * -> Stroker - * -> deltaTransformConsumer OR transformConsumer + * -> (deltaTransformConsumer) * - * -> CollinearSimplifier to remove redundant segments + * -> (CollinearSimplifier) to remove redundant segments * * -> pc2d = Renderer (bounding box) */ @@ -642,27 +628,109 @@ public class MarlinRenderingEngine extends RenderingEngine private static void pathToLoop(final float[] coords, final PathIterator pi, final PathConsumer2D pc2d) { + // ported from DuctusRenderingEngine.feedConsumer() but simplified: + // - removed skip flag = !subpathStarted + // - removed pathClosed (ie subpathStarted not set to false) + boolean subpathStarted = false; + for (; !pi.isDone(); pi.next()) { switch (pi.currentSegment(coords)) { - case PathIterator.SEG_MOVETO: + case PathIterator.SEG_MOVETO: + /* Checking SEG_MOVETO coordinates if they are out of the + * [LOWER_BND, UPPER_BND] range. This check also handles NaN + * and Infinity values. Skipping next path segment in case of + * invalid data. + */ + if (coords[0] < UPPER_BND && coords[0] > LOWER_BND && + coords[1] < UPPER_BND && coords[1] > LOWER_BND) + { pc2d.moveTo(coords[0], coords[1]); - continue; - case PathIterator.SEG_LINETO: - pc2d.lineTo(coords[0], coords[1]); - continue; - case PathIterator.SEG_QUADTO: - pc2d.quadTo(coords[0], coords[1], - coords[2], coords[3]); - continue; - case PathIterator.SEG_CUBICTO: - pc2d.curveTo(coords[0], coords[1], - coords[2], coords[3], - coords[4], coords[5]); - continue; - case PathIterator.SEG_CLOSE: + subpathStarted = true; + } + break; + case PathIterator.SEG_LINETO: + /* Checking SEG_LINETO coordinates if they are out of the + * [LOWER_BND, UPPER_BND] range. This check also handles NaN + * and Infinity values. Ignoring current path segment in case + * of invalid data. If segment is skipped its endpoint + * (if valid) is used to begin new subpath. + */ + if (coords[0] < UPPER_BND && coords[0] > LOWER_BND && + coords[1] < UPPER_BND && coords[1] > LOWER_BND) + { + if (subpathStarted) { + pc2d.lineTo(coords[0], coords[1]); + } else { + pc2d.moveTo(coords[0], coords[1]); + subpathStarted = true; + } + } + break; + case PathIterator.SEG_QUADTO: + // Quadratic curves take two points + /* Checking SEG_QUADTO coordinates if they are out of the + * [LOWER_BND, UPPER_BND] range. This check also handles NaN + * and Infinity values. Ignoring current path segment in case + * of invalid endpoints's data. Equivalent to the SEG_LINETO + * if endpoint coordinates are valid but there are invalid data + * among other coordinates + */ + if (coords[2] < UPPER_BND && coords[2] > LOWER_BND && + coords[3] < UPPER_BND && coords[3] > LOWER_BND) + { + if (subpathStarted) { + if (coords[0] < UPPER_BND && coords[0] > LOWER_BND && + coords[1] < UPPER_BND && coords[1] > LOWER_BND) + { + pc2d.quadTo(coords[0], coords[1], + coords[2], coords[3]); + } else { + pc2d.lineTo(coords[2], coords[3]); + } + } else { + pc2d.moveTo(coords[2], coords[3]); + subpathStarted = true; + } + } + break; + case PathIterator.SEG_CUBICTO: + // Cubic curves take three points + /* Checking SEG_CUBICTO coordinates if they are out of the + * [LOWER_BND, UPPER_BND] range. This check also handles NaN + * and Infinity values. Ignoring current path segment in case + * of invalid endpoints's data. Equivalent to the SEG_LINETO + * if endpoint coordinates are valid but there are invalid data + * among other coordinates + */ + if (coords[4] < UPPER_BND && coords[4] > LOWER_BND && + coords[5] < UPPER_BND && coords[5] > LOWER_BND) + { + if (subpathStarted) { + if (coords[0] < UPPER_BND && coords[0] > LOWER_BND && + coords[1] < UPPER_BND && coords[1] > LOWER_BND && + coords[2] < UPPER_BND && coords[2] > LOWER_BND && + coords[3] < UPPER_BND && coords[3] > LOWER_BND) + { + pc2d.curveTo(coords[0], coords[1], + coords[2], coords[3], + coords[4], coords[5]); + } else { + pc2d.lineTo(coords[4], coords[5]); + } + } else { + pc2d.moveTo(coords[4], coords[5]); + subpathStarted = true; + } + } + break; + case PathIterator.SEG_CLOSE: + if (subpathStarted) { pc2d.closePath(); - continue; - default: + // do not set subpathStarted to false + // in case of missing moveTo() after close() + } + break; + default: } } pc2d.pathDone(); diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java index 2946eda28f0..54c7ec32300 100644 --- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java +++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java @@ -338,11 +338,6 @@ final class Stroker implements PathConsumer2D, MarlinConst { } private void drawRoundCap(float cx, float cy, float mx, float my) { - // the first and second arguments of the following two calls - // are really will be ignored by emitCurveTo (because of the false), - // but we put them in anyway, as opposed to just giving it 4 zeroes, - // because it's just 4 additions and it's not good to rely on this - // sort of assumption (right now it's true, but that may change). emitCurveTo(cx+mx-C*my, cy+my+C*mx, cx-my+C*mx, cy+mx+C*my, cx-my, cy+mx); diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/TransformingPathConsumer2D.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/TransformingPathConsumer2D.java index 6258d8dfae6..db8f8dd6391 100644 --- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/TransformingPathConsumer2D.java +++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/TransformingPathConsumer2D.java @@ -35,7 +35,7 @@ final class TransformingPathConsumer2D { // used by RendererContext } - // recycled PathConsumer2D instance from transformConsumer() + // recycled PathConsumer2D instance from wrapPath2d() private final Path2DWrapper wp_Path2DWrapper = new Path2DWrapper(); PathConsumer2D wrapPath2d(Path2D.Float p2d) @@ -43,46 +43,6 @@ final class TransformingPathConsumer2D { return wp_Path2DWrapper.init(p2d); } - // recycled PathConsumer2D instances from transformConsumer() - private final TranslateFilter tx_TranslateFilter = new TranslateFilter(); - private final DeltaScaleFilter tx_DeltaScaleFilter = new DeltaScaleFilter(); - private final ScaleFilter tx_ScaleFilter = new ScaleFilter(); - private final DeltaTransformFilter tx_DeltaTransformFilter = new DeltaTransformFilter(); - private final TransformFilter tx_TransformFilter = new TransformFilter(); - - PathConsumer2D transformConsumer(PathConsumer2D out, - AffineTransform at) - { - if (at == null) { - return out; - } - float mxx = (float) at.getScaleX(); - float mxy = (float) at.getShearX(); - float mxt = (float) at.getTranslateX(); - float myx = (float) at.getShearY(); - float myy = (float) at.getScaleY(); - float myt = (float) at.getTranslateY(); - if (mxy == 0f && myx == 0f) { - if (mxx == 1f && myy == 1f) { - if (mxt == 0f && myt == 0f) { - return out; - } else { - return tx_TranslateFilter.init(out, mxt, myt); - } - } else { - if (mxt == 0f && myt == 0f) { - return tx_DeltaScaleFilter.init(out, mxx, myy); - } else { - return tx_ScaleFilter.init(out, mxx, myy, mxt, myt); - } - } - } else if (mxt == 0f && myt == 0f) { - return tx_DeltaTransformFilter.init(out, mxx, mxy, myx, myy); - } else { - return tx_TransformFilter.init(out, mxx, mxy, mxt, myx, myy, myt); - } - } - // recycled PathConsumer2D instances from deltaTransformConsumer() private final DeltaScaleFilter dt_DeltaScaleFilter = new DeltaScaleFilter(); private final DeltaTransformFilter dt_DeltaTransformFilter = new DeltaTransformFilter(); @@ -97,6 +57,7 @@ final class TransformingPathConsumer2D { float mxy = (float) at.getShearX(); float myx = (float) at.getShearY(); float myy = (float) at.getScaleY(); + if (mxy == 0f && myx == 0f) { if (mxx == 1f && myy == 1f) { return out; @@ -122,6 +83,7 @@ final class TransformingPathConsumer2D { float mxy = (float) at.getShearX(); float myx = (float) at.getShearY(); float myy = (float) at.getScaleY(); + if (mxy == 0f && myx == 0f) { if (mxx == 1f && myy == 1f) { return out; @@ -138,197 +100,6 @@ final class TransformingPathConsumer2D { } } - static final class TranslateFilter implements PathConsumer2D { - private PathConsumer2D out; - private float tx, ty; - - TranslateFilter() {} - - TranslateFilter init(PathConsumer2D out, - float tx, float ty) - { - this.out = out; - this.tx = tx; - this.ty = ty; - return this; // fluent API - } - - @Override - public void moveTo(float x0, float y0) { - out.moveTo(x0 + tx, y0 + ty); - } - - @Override - public void lineTo(float x1, float y1) { - out.lineTo(x1 + tx, y1 + ty); - } - - @Override - public void quadTo(float x1, float y1, - float x2, float y2) - { - out.quadTo(x1 + tx, y1 + ty, - x2 + tx, y2 + ty); - } - - @Override - public void curveTo(float x1, float y1, - float x2, float y2, - float x3, float y3) - { - out.curveTo(x1 + tx, y1 + ty, - x2 + tx, y2 + ty, - x3 + tx, y3 + ty); - } - - @Override - public void closePath() { - out.closePath(); - } - - @Override - public void pathDone() { - out.pathDone(); - } - - @Override - public long getNativeConsumer() { - return 0; - } - } - - static final class ScaleFilter implements PathConsumer2D { - private PathConsumer2D out; - private float sx, sy, tx, ty; - - ScaleFilter() {} - - ScaleFilter init(PathConsumer2D out, - float sx, float sy, - float tx, float ty) - { - this.out = out; - this.sx = sx; - this.sy = sy; - this.tx = tx; - this.ty = ty; - return this; // fluent API - } - - @Override - public void moveTo(float x0, float y0) { - out.moveTo(x0 * sx + tx, y0 * sy + ty); - } - - @Override - public void lineTo(float x1, float y1) { - out.lineTo(x1 * sx + tx, y1 * sy + ty); - } - - @Override - public void quadTo(float x1, float y1, - float x2, float y2) - { - out.quadTo(x1 * sx + tx, y1 * sy + ty, - x2 * sx + tx, y2 * sy + ty); - } - - @Override - public void curveTo(float x1, float y1, - float x2, float y2, - float x3, float y3) - { - out.curveTo(x1 * sx + tx, y1 * sy + ty, - x2 * sx + tx, y2 * sy + ty, - x3 * sx + tx, y3 * sy + ty); - } - - @Override - public void closePath() { - out.closePath(); - } - - @Override - public void pathDone() { - out.pathDone(); - } - - @Override - public long getNativeConsumer() { - return 0; - } - } - - static final class TransformFilter implements PathConsumer2D { - private PathConsumer2D out; - private float mxx, mxy, mxt, myx, myy, myt; - - TransformFilter() {} - - TransformFilter init(PathConsumer2D out, - float mxx, float mxy, float mxt, - float myx, float myy, float myt) - { - this.out = out; - this.mxx = mxx; - this.mxy = mxy; - this.mxt = mxt; - this.myx = myx; - this.myy = myy; - this.myt = myt; - return this; // fluent API - } - - @Override - public void moveTo(float x0, float y0) { - out.moveTo(x0 * mxx + y0 * mxy + mxt, - x0 * myx + y0 * myy + myt); - } - - @Override - public void lineTo(float x1, float y1) { - out.lineTo(x1 * mxx + y1 * mxy + mxt, - x1 * myx + y1 * myy + myt); - } - - @Override - public void quadTo(float x1, float y1, - float x2, float y2) - { - out.quadTo(x1 * mxx + y1 * mxy + mxt, - x1 * myx + y1 * myy + myt, - x2 * mxx + y2 * mxy + mxt, - x2 * myx + y2 * myy + myt); - } - - @Override - public void curveTo(float x1, float y1, - float x2, float y2, - float x3, float y3) - { - out.curveTo(x1 * mxx + y1 * mxy + mxt, - x1 * myx + y1 * myy + myt, - x2 * mxx + y2 * mxy + mxt, - x2 * myx + y2 * myy + myt, - x3 * mxx + y3 * mxy + mxt, - x3 * myx + y3 * myy + myt); - } - - @Override - public void closePath() { - out.closePath(); - } - - @Override - public void pathDone() { - out.pathDone(); - } - - @Override - public long getNativeConsumer() { - return 0; - } - } static final class DeltaScaleFilter implements PathConsumer2D { private PathConsumer2D out; diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Version.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Version.java index 1d144169376..9bd0498f7da 100644 --- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Version.java +++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Version.java @@ -27,7 +27,7 @@ package sun.java2d.marlin; public final class Version { - private static final String version = "marlin-0.7.3.2-Unsafe-OpenJDK"; + private static final String version = "marlin-0.7.3.3-Unsafe-OpenJDK"; public static String getVersion() { return version; diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLSurfaceData.java b/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLSurfaceData.java index 914b97aba05..5e6f802da14 100644 --- a/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLSurfaceData.java +++ b/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLSurfaceData.java @@ -542,20 +542,14 @@ public abstract class OGLSurfaceData extends SurfaceData return super.getMaskFill(sg2d); } - public boolean copyArea(SunGraphics2D sg2d, - int x, int y, int w, int h, int dx, int dy) - { - if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE && - sg2d.compositeState < SunGraphics2D.COMP_XOR) - { - x += sg2d.transX; - y += sg2d.transY; - - oglRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy); - - return true; + @Override + public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, + int dx, int dy) { + if (sg2d.compositeState >= SunGraphics2D.COMP_XOR) { + return false; } - return false; + oglRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy); + return true; } public void flush() { diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/AAShapePipe.java b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/AAShapePipe.java index 3046ff69c60..0aa5e54195f 100644 --- a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/AAShapePipe.java +++ b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/AAShapePipe.java @@ -28,7 +28,6 @@ import java.awt.BasicStroke; import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.Rectangle2D; -import java.util.concurrent.ConcurrentLinkedQueue; import sun.awt.SunHints; import sun.java2d.ReentrantContext; import sun.java2d.ReentrantContextProvider; diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java index 728a5823e4d..b1ebb0136e9 100644 --- a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java +++ b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java @@ -340,8 +340,8 @@ public class DrawImage implements DrawImagePipe *
    • Image will be used only once and acceleration caching wouldn't help * */ - BufferedImage makeBufferedImage(Image img, Color bgColor, int type, - int sx1, int sy1, int sx2, int sy2) + private BufferedImage makeBufferedImage(Image img, Color bgColor, int type, + int sx1, int sy1, int sx2, int sy2) { final int width = sx2 - sx1; final int height = sy2 - sy1; @@ -430,10 +430,16 @@ public class DrawImage implements DrawImagePipe if (isBgOperation(srcData, bgColor)) { // We cannot perform bg operations during transform so make - // an opaque temp image with the appropriate background - // and work from there. - img = makeBufferedImage(img, bgColor, BufferedImage.TYPE_INT_RGB, - sx1, sy1, sx2, sy2); + // a temp image with the appropriate background based on + // background alpha value and work from there. If background + // alpha is opaque use INT_RGB else use INT_ARGB so that we + // will not lose translucency of background. + + int bgAlpha = bgColor.getAlpha(); + int type = ((bgAlpha == 255) + ? BufferedImage.TYPE_INT_RGB + : BufferedImage.TYPE_INT_ARGB); + img = makeBufferedImage(img, bgColor, type, sx1, sy1, sx2, sy2); // Temp image has appropriate subimage at 0,0 now. sx2 -= sx1; sy2 -= sy1; diff --git a/jdk/src/java.desktop/share/classes/sun/print/PrintJob2D.java b/jdk/src/java.desktop/share/classes/sun/print/PrintJob2D.java index 975e52ab86d..0d3df28921c 100644 --- a/jdk/src/java.desktop/share/classes/sun/print/PrintJob2D.java +++ b/jdk/src/java.desktop/share/classes/sun/print/PrintJob2D.java @@ -995,6 +995,7 @@ public class PrintJob2D extends PrintJob implements Printable, Runnable { public void run() { try { + attributes.remove(PageRanges.class); printerJob.print(attributes); } catch (PrinterException e) { //REMIND: need to store this away and not rethrow it. diff --git a/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java b/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java index 7ba84ab1630..b5d8f0daa8f 100644 --- a/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java +++ b/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java @@ -1212,6 +1212,7 @@ public abstract class RasterPrinterJob extends PrinterJob { pageRangesAttr = (PageRanges)attributes.get(PageRanges.class); if (!isSupportedValue(pageRangesAttr, attributes)) { pageRangesAttr = null; + setPageRange(-1, -1); } else { if ((SunPageSelection)attributes.get(SunPageSelection.class) == SunPageSelection.RANGE) { diff --git a/jdk/src/java.desktop/share/classes/sun/swing/FilePane.java b/jdk/src/java.desktop/share/classes/sun/swing/FilePane.java index 778e40cc052..28cdf4205f2 100644 --- a/jdk/src/java.desktop/share/classes/sun/swing/FilePane.java +++ b/jdk/src/java.desktop/share/classes/sun/swing/FilePane.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -913,7 +913,15 @@ public class FilePane extends JPanel implements PropertyChangeListener { private class DetailsTableRowSorter extends TableRowSorter { public DetailsTableRowSorter() { - setModelWrapper(new SorterModelWrapper()); + SorterModelWrapper modelWrapper = new SorterModelWrapper(); + setModelWrapper(modelWrapper); + modelWrapper.getModel().addTableModelListener( + new TableModelListener() { + @Override + public void tableChanged(TableModelEvent e) { + modelStructureChanged(); + } + }); } public void updateComparators(ShellFolderColumnInfo [] columns) { diff --git a/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc b/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc index 194731f4e7e..1727bb80ea3 100644 --- a/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc +++ b/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc @@ -293,7 +293,7 @@ reference_table(hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) { return NULL; } length = env->GetArrayLength(tableBytes); - buffer = new jbyte[length]; + buffer = (jbyte *)calloc(length, sizeof(jbyte)); env->GetByteArrayRegion(tableBytes, 0, length, buffer); return hb_blob_create((const char *)buffer, length, diff --git a/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.c b/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.c index ad30a9a3f8b..77a00c0b675 100644 --- a/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.c +++ b/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.c @@ -389,3 +389,8 @@ int SplashStreamInitMemory(SplashStream * pStream, void* pData, int size) { pStream->close = closeMem; return 1; } + +SPLASHEXPORT int +SplashGetScaledImgNameMaxPstfixLen(const char *fileName){ + return strlen(fileName) + strlen(".java-scale-200") + 1; +} diff --git a/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.h b/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.h index d26a4cb6be7..1f2d2aed4b0 100644 --- a/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.h +++ b/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.h @@ -28,6 +28,7 @@ #include "splashscreen_config.h" #include "splashscreen_gfx.h" +#include "jni.h" SPLASHEXPORT int SplashLoadMemory(void *pdata, int size); /* requires preloading the file */ SPLASHEXPORT int SplashLoadFile(const char *filename); // FIXME: range checking for SplashLoadMemory @@ -36,11 +37,14 @@ SPLASHEXPORT void SplashInit(void); SPLASHEXPORT void SplashClose(void); SPLASHEXPORT void SplashSetScaleFactor(float); -SPLASHEXPORT char* SplashGetScaledImageName(const char*, const char*, float*); +SPLASHEXPORT jboolean SplashGetScaledImageName(const char*, const char*, + float*, char*, const size_t scaledImageNameLength); SPLASHEXPORT void SplashSetFileJarName(const char* fileName, const char* jarName); +SPLASHEXPORT int +SplashGetScaledImgNameMaxPstfixLen(const char*); typedef struct SplashImage { rgbquad_t *bitmapBits; @@ -119,9 +123,9 @@ void SplashDonePlatform(Splash * splash); unsigned SplashTime(); char* SplashConvertStringAlloc(const char* in, int *size); -char* SplashGetScaledImageName(const char* jarName, - const char* fileName, float *scaleFactor); - +jboolean SplashGetScaledImageName(const char* jarName, + const char* fileName, float *scaleFactor, + char *scaleImageName, const size_t scaledImageNameLength); void SplashLock(Splash * splash); void SplashUnlock(Splash * splash); @@ -145,7 +149,7 @@ void SplashUpdateScreenData(Splash * splash); void SplashCleanup(Splash * splash); void SplashSetScaleFactor(float scaleFactor); - +int SplashGetScaledImgNameMaxPstfixLen(const char *fileName); typedef struct SplashStream { int (*read)(void* pStream, void* pData, int nBytes); diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTaskbarPeer.java b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTaskbarPeer.java new file mode 100644 index 00000000000..bfb964c9b7c --- /dev/null +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTaskbarPeer.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package sun.awt.X11; + +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.awt.Taskbar.Feature; +import java.awt.peer.TaskbarPeer; +import java.awt.event.ActionEvent; +import sun.misc.ManagedLocalsThread; +import java.security.AccessController; +import sun.security.action.GetPropertyAction; + +final class XTaskbarPeer implements TaskbarPeer { + + private static boolean nativeLibraryLoaded = false; + private static boolean initExecuted = false; + + private PopupMenu menu = null; + + private static void initWithLock() { + XToolkit.awtLock(); + try { + if (!initExecuted) { + String dname = AccessController.doPrivileged( + new GetPropertyAction("java.desktop.appName", "")); + nativeLibraryLoaded = init(dname); + if (nativeLibraryLoaded) { + ManagedLocalsThread t + = new ManagedLocalsThread(() -> { + runloop(); + }); + t.setDaemon(true); + t.start(); + } + } + } finally { + initExecuted = true; + XToolkit.awtUnlock(); + } + } + + XTaskbarPeer() { + initWithLock(); + } + + static boolean isTaskbarSupported() { + initWithLock(); + return nativeLibraryLoaded; + } + + @Override + public boolean isSupported(Feature feature) { + switch (feature) { + case ICON_BADGE_NUMBER: + case MENU: + case PROGRESS_VALUE: + case USER_ATTENTION: + return true; + default: + return false; + } + } + + @Override + public void setProgressValue(int value) { + boolean visible + = value >= 0 + && value <= 100; + + double v = visible + ? (double) value / 100 + : 0d; + + updateProgress(v, visible); + } + + @Override + public void setIconBadge(String badge) { + boolean visible = false; + long val = 0; + if (badge != null) { + try { + val = Long.parseLong(badge); + visible = true; + } catch (NumberFormatException e) { + } + } + setBadge(val, visible); + } + + @Override + public PopupMenu getMenu() { + return menu; + } + + @Override + public synchronized void setMenu(PopupMenu m) { + this.menu = m; + + if (menu != null && menu.getItemCount() > 0) { + int msize = menu.getItemCount(); + MenuItem[] items = new MenuItem[msize]; + for (int i = 0; i < msize; i++) { + items[i] = menu.getItem(i); + } + setNativeMenu(items); + } else { + setNativeMenu(null); + } + } + + @Override + public void requestUserAttention(boolean enabled, boolean critical) { + setUrgent(enabled); + } + + private static void menuItemCallback(MenuItem mi) { + if (mi != null) { + ActionEvent ae = new ActionEvent(mi, ActionEvent.ACTION_PERFORMED, + mi.getActionCommand()); + try { + XToolkit.awtLock(); + XToolkit.postEvent(XToolkit.targetToAppContext(ae.getSource()), ae); + } finally { + XToolkit.awtUnlock(); + } + } + } + + private static native boolean init(String name); + + private static native void runloop(); + + private native void setBadge(long value, boolean visible); + + private native void updateProgress(double value, boolean visible); + + private native void setUrgent(boolean urgent); + + private native void setNativeMenu(MenuItem[] items); +} diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java index d79df149f6d..f1904e07626 100644 --- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -24,6 +24,7 @@ */ package sun.awt.X11; +import java.awt.peer.TaskbarPeer; import java.awt.*; import java.awt.event.InputEvent; import java.awt.event.MouseEvent; @@ -769,17 +770,20 @@ public final class XToolkit extends UNIXToolkit implements Runnable { GraphicsEnvironment.getLocalGraphicsEnvironment(); if (!x11ge.runningXinerama()) { - Rectangle workArea = XToolkit.getWorkArea(root, scale); - if (workArea != null) - { - return new Insets(workArea.y, - workArea.x, - rootBounds.height - workArea.height - workArea.y, - rootBounds.width - workArea.width - workArea.x); - } + Insets screenInsets = getInsets(root, rootBounds, scale); + if (screenInsets != null) return screenInsets; } - return getScreenInsetsManually(root, rootBounds, gc.getBounds(), scale); + Insets insets = getScreenInsetsManually(root, rootBounds, + gc.getBounds(), scale); + if ((insets.left | insets.top | insets.bottom | insets.right) == 0 + && rootBounds != null ) { + root = XlibWrapper.RootWindow(XToolkit.getDisplay(), + x11gd.getScreen()); + Insets screenInsets = getInsets(root, rootBounds, scale); + if (screenInsets != null) return screenInsets; + } + return insets; } finally { @@ -787,6 +791,16 @@ public final class XToolkit extends UNIXToolkit implements Runnable { } } + private Insets getInsets(long root, Rectangle rootBounds, int scale) { + Rectangle workArea = XToolkit.getWorkArea(root, scale); + if (workArea == null) { + return null; + } + return new Insets(workArea.y, workArea.x, + rootBounds.height - workArea.height - workArea.y, + rootBounds.width - workArea.width - workArea.x); + } + /* * Manual calculation of screen insets: get all the windows with * _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL hints and add these @@ -2567,6 +2581,16 @@ public final class XToolkit extends UNIXToolkit implements Runnable { return new XDesktopPeer(); } + @Override + public boolean isTaskbarSupported(){ + return XTaskbarPeer.isTaskbarSupported(); + } + + @Override + public TaskbarPeer createTaskbarPeer(Taskbar target){ + return new XTaskbarPeer(); + } + @Override public boolean areExtraMouseButtonsEnabled() throws HeadlessException { return areExtraMouseButtonsEnabled; diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java index b431c14d9d1..907446ad81c 100644 --- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java @@ -1008,13 +1008,10 @@ class XWindow extends XBaseWindow implements X11ComponentPeer { // if ( Check if it's a resize, a move, or a stacking order change ) // { Rectangle bounds = getBounds(); - final ComponentAccessor acc = AWTAccessor.getComponentAccessor(); if (!bounds.getSize().equals(oldBounds.getSize())) { - acc.setSize(target, bounds.width, bounds.height); postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_RESIZED)); } if (!bounds.getLocation().equals(oldBounds.getLocation())) { - acc.setLocation(target, bounds.x, bounds.y); postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_MOVED)); } // } diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java index 862508ccfcf..3dad9f30728 100644 --- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -87,7 +87,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, // used for modal blocking to keep existing z-order protected XWindowPeer prevTransientFor, nextTransientFor; // value of WM_TRANSIENT_FOR hint set on this window - private XWindowPeer curRealTransientFor; + private XBaseWindow curRealTransientFor; private boolean grab = false; // Whether to do a grab during showing @@ -803,23 +803,31 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, */ @Override public void handleConfigureNotifyEvent(XEvent xev) { + assert (SunToolkit.isAWTLockHeldByCurrentThread()); XConfigureEvent xe = xev.get_xconfigure(); - /* - * Correct window location which could be wrong in some cases. - * See getNewLocation() for the details. - */ - Point newLocation = getNewLocation(xe, 0, 0); - xe.set_x(scaleUp(newLocation.x)); - xe.set_y(scaleUp(newLocation.y)); - checkIfOnNewScreen(new Rectangle(newLocation.x, - newLocation.y, - scaleDown(xe.get_width()), - scaleDown(xe.get_height()))); + if (insLog.isLoggable(PlatformLogger.Level.FINE)) { + insLog.fine(xe.toString()); + } + checkIfOnNewScreen(toGlobal(new Rectangle(scaleDown(xe.get_x()), + scaleDown(xe.get_y()), + scaleDown(xe.get_width()), + scaleDown(xe.get_height())))); - // Don't call super until we've handled a screen change. Otherwise - // there could be a race condition in which a ComponentListener could - // see the old screen. - super.handleConfigureNotifyEvent(xev); + Rectangle oldBounds = getBounds(); + + x = scaleDown(xe.get_x()); + y = scaleDown(xe.get_y()); + width = scaleDown(xe.get_width()); + height = scaleDown(xe.get_height()); + + if (!getBounds().getSize().equals(oldBounds.getSize())) { + AWTAccessor.getComponentAccessor().setSize(target, width, height); + postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_RESIZED)); + } + if (!getBounds().getLocation().equals(oldBounds.getLocation())) { + AWTAccessor.getComponentAccessor().setLocation(target, x, y); + postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED)); + } repositionSecurityWarning(); } @@ -1057,13 +1065,23 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, log.fine("Promoting always-on-top state {0}", Boolean.valueOf(alwaysOnTop)); } XWM.getWM().setLayer(this, - alwaysOnTop ? - XLayerProtocol.LAYER_ALWAYS_ON_TOP : - XLayerProtocol.LAYER_NORMAL); + alwaysOnTop ? + XLayerProtocol.LAYER_ALWAYS_ON_TOP : + XLayerProtocol.LAYER_NORMAL); } public void updateAlwaysOnTopState() { this.alwaysOnTop = ((Window) this.target).isAlwaysOnTop(); + if (ownerPeer != null) { + XToolkit.awtLock(); + try { + restoreTransientFor(this); + applyWindowType(); + } + finally { + XToolkit.awtUnlock(); + } + } updateAlwaysOnTop(); } @@ -1107,7 +1125,27 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, if (!vis && warningWindow != null) { warningWindow.setSecurityWarningVisible(false, false); } + boolean refreshChildsTransientFor = isVisible() != vis; super.setVisible(vis); + if (refreshChildsTransientFor) { + for (Window child : ((Window) target).getOwnedWindows()) { + XToolkit.awtLock(); + try { + if(!child.isLightweight() && child.isVisible()) { + ComponentPeer childPeer = AWTAccessor. + getComponentAccessor().getPeer(child); + if(childPeer instanceof XWindowPeer) { + XWindowPeer windowPeer = (XWindowPeer) childPeer; + restoreTransientFor(windowPeer); + windowPeer.applyWindowType(); + } + } + } + finally { + XToolkit.awtUnlock(); + } + } + } if (!vis && !isWithdrawn()) { // ICCCM, 4.1.4. Changing Window State: // "Iconic -> Withdrawn - The client should unmap the window and follow it @@ -1636,9 +1674,6 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, window.prevTransientFor = transientForWindow; transientForWindow.nextTransientFor = window; } - if (window.curRealTransientFor == transientForWindow) { - return; - } if (!allStates && (window.getWMState() != transientForWindow.getWMState())) { return; } @@ -1650,11 +1685,14 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, bpw = XlibUtil.getParentWindow(bpw); } long tpw = transientForWindow.getWindow(); - while (!XlibUtil.isToplevelWindow(tpw) && !XlibUtil.isXAWTToplevelWindow(tpw)) { + XBaseWindow parent = transientForWindow; + while (tpw != 0 && ((!XlibUtil.isToplevelWindow(tpw) && + !XlibUtil.isXAWTToplevelWindow(tpw)) || !parent.isVisible())) { tpw = XlibUtil.getParentWindow(tpw); + parent = XToolkit.windowToXWindow(tpw); } XlibWrapper.XSetTransientFor(XToolkit.getDisplay(), bpw, tpw); - window.curRealTransientFor = transientForWindow; + window.curRealTransientFor = parent; } /* @@ -1948,7 +1986,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, switch (getWindowType()) { case NORMAL: - typeAtom = (ownerPeer == null) ? + typeAtom = curRealTransientFor == null ? protocol.XA_NET_WM_WINDOW_TYPE_NORMAL : protocol.XA_NET_WM_WINDOW_TYPE_DIALOG; break; diff --git a/jdk/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java b/jdk/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java index 1d83b65a876..3ce34effd39 100644 --- a/jdk/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java +++ b/jdk/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java @@ -487,12 +487,9 @@ public abstract class X11SurfaceData extends XSurfaceData { makePipes(); } CompositeType comptype = sg2d.imageComp; - if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE && - (CompositeType.SrcOverNoEa.equals(comptype) || + if ((CompositeType.SrcOverNoEa.equals(comptype) || CompositeType.SrcNoEa.equals(comptype))) { - x += sg2d.transX; - y += sg2d.transY; SunToolkit.awtLock(); try { boolean needExposures = canSourceSendExposures(x, y, w, h); diff --git a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java index aabdda0db1e..b88c5507984 100644 --- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java +++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java @@ -365,12 +365,9 @@ public abstract class XRSurfaceData extends XSurfaceData { makePipes(); } CompositeType comptype = sg2d.imageComp; - if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE && - (CompositeType.SrcOverNoEa.equals(comptype) || - CompositeType.SrcNoEa.equals(comptype))) + if (CompositeType.SrcOverNoEa.equals(comptype) || + CompositeType.SrcNoEa.equals(comptype)) { - x += sg2d.transX; - y += sg2d.transY; try { SunToolkit.awtLock(); boolean needExposures = canSourceSendExposures(x, y, w, h); diff --git a/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java b/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java index 9587067a750..ea89e9027aa 100644 --- a/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java +++ b/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java @@ -929,6 +929,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { DocFlavor[] flavor = new DocFlavor[2]; flavor[0] = DocFlavor.SERVICE_FORMATTED.PAGEABLE; flavor[1] = DocFlavor.SERVICE_FORMATTED.PRINTABLE; + supportedDocFlavors = flavor; return flavor; } diff --git a/jdk/src/java.desktop/unix/native/common/awt/systemscale/systemScale.c b/jdk/src/java.desktop/unix/native/common/awt/systemscale/systemScale.c new file mode 100644 index 00000000000..fd574a89621 --- /dev/null +++ b/jdk/src/java.desktop/unix/native/common/awt/systemscale/systemScale.c @@ -0,0 +1,52 @@ +/* +* Copyright (c) 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. +*/ + +#include "systemScale.h" +#include + +int getNativeScaleFactor() { + + static int scale = -2.0; + + if (scale == -2) { + scale = getScale("J2D_UISCALE"); + } + + if (scale >= 1) { + return (int) scale; + } + return getScale("GDK_SCALE"); +} + +int getScale(const char *name) { + char *uiScale = getenv(name); + if (uiScale != NULL) { + double scale = strtod(uiScale, NULL); + if (scale < 1) { + return -1; + } + return (int) scale; + } + return -1; +} + diff --git a/jdk/src/java.desktop/unix/native/common/awt/systemscale/systemScale.h b/jdk/src/java.desktop/unix/native/common/awt/systemscale/systemScale.h new file mode 100644 index 00000000000..a45d18ccdab --- /dev/null +++ b/jdk/src/java.desktop/unix/native/common/awt/systemscale/systemScale.h @@ -0,0 +1,33 @@ +/* +* Copyright (c) 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. +*/ +#ifndef _AWT_SYSTEMSCALE_H +#define _AWT_SYSTEMSCALE_H + +#include +#include + +int getNativeScaleFactor(); +int getScale(const char *uiScale); + +#endif + diff --git a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c index 6c9c2b49f01..7d2b8b0dbd0 100644 --- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c +++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c @@ -43,7 +43,7 @@ #include #include #include - +#include "systemScale.h" #include #include "awt_GraphicsEnv.h" @@ -2083,17 +2083,6 @@ Java_sun_awt_X11GraphicsDevice_exitFullScreenExclusive * End DisplayMode/FullScreen support */ -int getScale(const char *name) { - char *uiScale = getenv(name); - if (uiScale != NULL) { - double scale = strtod(uiScale, NULL); - if (errno == ERANGE || scale < 1) { - return -1; - } - return (int) scale; - } - return -1; -} /* * Class: sun_awt_X11GraphicsDevice @@ -2104,16 +2093,5 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11GraphicsDevice_getNativeScaleFactor (JNIEnv *env, jobject this, jint screen) { - // for debug purposes - static int scale = -2.0; - - if (scale == -2) { - scale = getScale("J2D_UISCALE"); - } - - if (scale >= 1) { - return scale; - } - - return getScale("GDK_SCALE"); + return getNativeScaleFactor(); } diff --git a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c index 3fa9151fb40..ef58feccd9b 100644 --- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c +++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -831,6 +831,10 @@ gboolean gtk2_load(JNIEnv *env) fp_gtk_separator_tool_item_new = dl_symbol("gtk_vseparator_new"); } + + fp_g_list_append = dl_symbol("g_list_append"); + fp_g_list_free = dl_symbol("g_list_free"); + fp_g_list_free_full = dl_symbol("g_list_free_full"); } /* Now we have only one kind of exceptions: NO_SYMBOL_EXCEPTION * Otherwise we can check the return value of setjmp method. diff --git a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h index 10f32dc3e36..c94749ecb51 100644 --- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h +++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -289,6 +289,15 @@ struct _GSList GSList *next; }; +typedef struct _GList GList; + +struct _GList +{ + gpointer data; + GList *next; + GList *prev; +}; + typedef void GdkColormap; typedef void GdkDrawable; typedef void GdkGC; @@ -841,6 +850,11 @@ guint (*fp_gtk_main_level)(void); gchar* (*fp_g_path_get_dirname) (const gchar *file_name); XID (*fp_gdk_x11_drawable_get_xid) (GdkWindow *drawable); + +GList* (*fp_g_list_append) (GList *list, gpointer data); +void (*fp_g_list_free) (GList *list); +void (*fp_g_list_free_full) (GList *list, GDestroyNotify free_func); + /** * This function is available for GLIB > 2.20, so it MUST be * called within GLIB_CHECK_VERSION(2, 20, 0) check. diff --git a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.c b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.c new file mode 100644 index 00000000000..643cc888b51 --- /dev/null +++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.c @@ -0,0 +1,260 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include "jvm_md.h" +#include +#include + +#include "jni_util.h" +#include "awt_Taskbar.h" + + +extern JavaVM *jvm; + +#define NO_SYMBOL_EXCEPTION 1 + +#define UNITY_LIB_VERSIONED VERSIONED_JNI_LIB_NAME("unity", "9") +#define UNITY_LIB JNI_LIB_NAME("unity") + +static jmp_buf j; + +static void *unity_libhandle = NULL; + +static DbusmenuMenuitem* menu = NULL; +UnityLauncherEntry* entry = NULL; + +static jclass jTaskbarCls = NULL; +static jmethodID jTaskbarCallback = NULL; +static jmethodID jMenuItemGetLabel = NULL; + +GList* globalRefs = NULL; + +static void* dl_symbol(const char* name) { + void* result = dlsym(unity_libhandle, name); + if (!result) + longjmp(j, NO_SYMBOL_EXCEPTION); + + return result; +} + +static gboolean unity_load() { + unity_libhandle = dlopen(UNITY_LIB_VERSIONED, RTLD_LAZY | RTLD_LOCAL); + if (unity_libhandle == NULL) { + unity_libhandle = dlopen(UNITY_LIB, RTLD_LAZY | RTLD_LOCAL); + if (unity_libhandle == NULL) { + return FALSE; + } + } + if (setjmp(j) == 0) { + fp_unity_launcher_entry_get_for_desktop_file = dl_symbol("unity_launcher_entry_get_for_desktop_file"); + fp_unity_launcher_entry_set_count = dl_symbol("unity_launcher_entry_set_count"); + fp_unity_launcher_entry_set_count_visible = dl_symbol("unity_launcher_entry_set_count_visible"); + fp_unity_launcher_entry_set_urgent = dl_symbol("unity_launcher_entry_set_urgent"); + fp_unity_launcher_entry_set_progress = dl_symbol("unity_launcher_entry_set_progress"); + fp_unity_launcher_entry_set_progress_visible = dl_symbol("unity_launcher_entry_set_progress_visible"); + + fp_dbusmenu_menuitem_new = dl_symbol("dbusmenu_menuitem_new"); + fp_dbusmenu_menuitem_property_set = dl_symbol("dbusmenu_menuitem_property_set"); + fp_dbusmenu_menuitem_property_set_int = dl_symbol("dbusmenu_menuitem_property_set_int"); + fp_dbusmenu_menuitem_property_get_int = dl_symbol("dbusmenu_menuitem_property_get_int"); + fp_dbusmenu_menuitem_property_set = dl_symbol("dbusmenu_menuitem_property_set"); + fp_dbusmenu_menuitem_child_append = dl_symbol("dbusmenu_menuitem_child_append"); + fp_dbusmenu_menuitem_child_delete = dl_symbol("dbusmenu_menuitem_child_delete"); + fp_dbusmenu_menuitem_take_children = dl_symbol("dbusmenu_menuitem_take_children"); + fp_dbusmenu_menuitem_foreach = dl_symbol("dbusmenu_menuitem_foreach"); + fp_unity_launcher_entry_set_quicklist = dl_symbol("unity_launcher_entry_set_quicklist"); + fp_unity_launcher_entry_get_quicklist = dl_symbol("unity_launcher_entry_get_quicklist"); + } else { + dlclose(unity_libhandle); + unity_libhandle = NULL; + return FALSE; + } + return TRUE; +} + +void callback(DbusmenuMenuitem* mi, guint ts, jobject data) { + JNIEnv* env = (JNIEnv*) JNU_GetEnv(jvm, JNI_VERSION_1_2); + (*env)->CallStaticVoidMethod(env, jTaskbarCls, jTaskbarCallback, data, + fp_dbusmenu_menuitem_property_get_int(mi, "toggle-state") + ? JNI_FALSE + : JNI_TRUE); +} + +/* + * Class: sun_awt_X11_XTaskbarPeer + * Method: init + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XTaskbarPeer_init +(JNIEnv *env, jclass cls, jstring jname) { + jclass clazz; + + jTaskbarCls = (*env)->NewGlobalRef(env, cls); + + CHECK_NULL_RETURN(jTaskbarCallback = + (*env)->GetStaticMethodID(env, cls, "menuItemCallback", "(Ljava/awt/MenuItem;)V"), JNI_FALSE); + CHECK_NULL_RETURN( + clazz = (*env)->FindClass(env, "java/awt/MenuItem"), JNI_FALSE); + CHECK_NULL_RETURN( + jMenuItemGetLabel = (*env)->GetMethodID(env, clazz, "getLabel", "()Ljava/lang/String;"), JNI_FALSE); + + if (gtk2_load(env) && unity_load()) { + const gchar* name = (*env)->GetStringUTFChars(env, jname, NULL); + if (name) { + entry = fp_unity_launcher_entry_get_for_desktop_file(name); + (*env)->ReleaseStringUTFChars(env, jname, name); + return JNI_TRUE; + } + } + return JNI_FALSE; +} + +/* + * Class: sun_awt_X11_XTaskbarPeer + * Method: runloop + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_runloop +(JNIEnv *env, jclass cls) { + fp_gdk_threads_enter(); + fp_gtk_main(); + fp_gdk_threads_leave(); +} + +/* + * Class: sun_awt_X11_XTaskbarPeer + * Method: setBadge + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_setBadge +(JNIEnv *env, jobject obj, jlong value, jboolean visible) { + fp_gdk_threads_enter(); + fp_unity_launcher_entry_set_count(entry, value); + fp_unity_launcher_entry_set_count_visible(entry, visible); + DbusmenuMenuitem* m; + if (m = fp_unity_launcher_entry_get_quicklist(entry)) { + fp_unity_launcher_entry_set_quicklist(entry, m); + } + fp_gdk_threads_leave(); +} + +/* + * Class: sun_awt_X11_XTaskbarPeer + * Method: setUrgent + * Signature: (Z)V + */ +JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_setUrgent +(JNIEnv *env, jobject obj, jboolean urgent) { + fp_gdk_threads_enter(); + fp_unity_launcher_entry_set_urgent(entry, urgent); + DbusmenuMenuitem* m; + if (m = fp_unity_launcher_entry_get_quicklist(entry)) { + fp_unity_launcher_entry_set_quicklist(entry, m); + } + fp_gdk_threads_leave(); +} + +/* + * Class: sun_awt_X11_XTaskbarPeer + * Method: updateProgress + * Signature: (DZ)V + */ +JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_updateProgress +(JNIEnv *env, jobject obj, jdouble value, jboolean visible) { + fp_gdk_threads_enter(); + fp_unity_launcher_entry_set_progress(entry, value); + fp_unity_launcher_entry_set_progress_visible(entry, visible); + DbusmenuMenuitem* m; + if (m = fp_unity_launcher_entry_get_quicklist(entry)) { + fp_unity_launcher_entry_set_quicklist(entry, m); + } + fp_gdk_threads_leave(); +} + +void deleteGlobalRef(gpointer data) { + JNIEnv* env = (JNIEnv*) JNU_GetEnv(jvm, JNI_VERSION_1_2); + (*env)->DeleteGlobalRef(env, data); +} + +void fill_menu(JNIEnv *env, jobjectArray items) { + int index; + jsize length = (*env)->GetArrayLength(env, items); + for (index = 0; index < length; index++) { + jobject elem = (*env)->GetObjectArrayElement(env, items, index); + if ((*env)->ExceptionCheck(env)) { + break; + } + elem = (*env)->NewGlobalRef(env, elem); + + globalRefs = fp_g_list_append(globalRefs, elem); + + jstring jlabel = (jstring) (*env)->CallObjectMethod(env, elem, jMenuItemGetLabel); + if (!(*env)->ExceptionCheck(env) && jlabel) { + const gchar* label = (*env)->GetStringUTFChars(env, jlabel, NULL); + if (label) { + DbusmenuMenuitem* mi = fp_dbusmenu_menuitem_new(); + if (!strcmp(label, "-")) { + fp_dbusmenu_menuitem_property_set(mi, "type", "separator"); + } else { + fp_dbusmenu_menuitem_property_set(mi, "label", label); + } + + (*env)->ReleaseStringUTFChars(env, jlabel, label); + fp_dbusmenu_menuitem_child_append(menu, mi); + fp_g_signal_connect(mi, "item_activated", G_CALLBACK(callback), elem); + } + } + } +} + +/* + * Class: sun_awt_X11_XTaskbarPeer + * Method: setNativeMenu + * Signature: ([Ljava/awt/MenuItem;)V + */ +JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_setNativeMenu +(JNIEnv *env, jobject obj, jobjectArray items) { + + fp_gdk_threads_enter(); + + if (!menu) { + menu = fp_dbusmenu_menuitem_new(); + } + + fp_unity_launcher_entry_set_quicklist(entry, menu); + + GList* list = fp_dbusmenu_menuitem_take_children(menu); + fp_g_list_free_full(list, fp_g_object_unref); + + fp_g_list_free_full(globalRefs, deleteGlobalRef); + globalRefs = NULL; + + if (items) { + fill_menu(env, items); + } + + fp_gdk_threads_leave(); +} diff --git a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.h b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.h new file mode 100644 index 00000000000..00b8d86dd1f --- /dev/null +++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 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. 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 thats + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef AWT_TASKBAR_H +#define AWT_TASKBAR_H + +#include "gtk2_interface.h" + +typedef void UnityLauncherEntry; +typedef void DbusmenuMenuitem; + +static UnityLauncherEntry* (*fp_unity_launcher_entry_get_for_desktop_file) (const gchar* desktop_file); + +static void (*fp_unity_launcher_entry_set_count) (UnityLauncherEntry* self, gint64 value); +static void (*fp_unity_launcher_entry_set_count_visible) (UnityLauncherEntry* self, gboolean value); + +static void (*fp_unity_launcher_entry_set_urgent) (UnityLauncherEntry* self, gboolean value); + +static void (*fp_unity_launcher_entry_set_progress) (UnityLauncherEntry* self, gdouble value); +static void (*fp_unity_launcher_entry_set_progress_visible) (UnityLauncherEntry* self, gboolean value); + + +static DbusmenuMenuitem* (*fp_dbusmenu_menuitem_new) (void); +static gboolean (*fp_dbusmenu_menuitem_property_set) (DbusmenuMenuitem* mi, const gchar* property, const gchar* value); +static gboolean (*fp_dbusmenu_menuitem_property_set_int) (DbusmenuMenuitem * mi, const gchar * property, const gint value); +static gint (*fp_dbusmenu_menuitem_property_get_int) (const DbusmenuMenuitem * mi, const gchar * property); +static gboolean (*fp_dbusmenu_menuitem_child_append) (DbusmenuMenuitem* mi, DbusmenuMenuitem* child); +static gboolean (*fp_dbusmenu_menuitem_child_delete) (DbusmenuMenuitem * mi, DbusmenuMenuitem * child); +static GList * (*fp_dbusmenu_menuitem_take_children) (DbusmenuMenuitem * mi); +static void (*fp_dbusmenu_menuitem_foreach) (DbusmenuMenuitem * mi, void (*func) (DbusmenuMenuitem * mi, gpointer data), gpointer data); +static void (*fp_unity_launcher_entry_set_quicklist) (UnityLauncherEntry* self, DbusmenuMenuitem* value); +static DbusmenuMenuitem* (*fp_unity_launcher_entry_get_quicklist) (UnityLauncherEntry* self); + + +#endif /* AWT_TASKBAR_H */ + diff --git a/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_config.h b/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_config.h index 9d8255bdb27..927261d9444 100644 --- a/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_config.h +++ b/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_config.h @@ -39,6 +39,7 @@ #include #include #include +#include "systemScale.h" typedef uint32_t rgbquad_t; typedef uint16_t word_t; @@ -57,5 +58,4 @@ typedef XRectangle RECT_T; #define INLINE static #define SPLASHEXPORT - #endif diff --git a/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c b/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c index ed3bfaa1108..11b979f4264 100644 --- a/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c +++ b/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c @@ -797,10 +797,60 @@ SplashReconfigure(Splash * splash) { sendctl(splash, SPLASHCTL_RECONFIGURE); } -SPLASHEXPORT char* +SPLASHEXPORT jboolean SplashGetScaledImageName(const char* jarName, const char* fileName, - float *scaleFactor) + float *scaleFactor, char *scaledImgName, + const size_t scaledImageNameLength) { *scaleFactor = 1; - return NULL; +#ifndef __linux__ + return JNI_FALSE; +#endif + *scaleFactor = getNativeScaleFactor(); + if (*scaleFactor == 2.0) { + size_t length = 0; + char *stringToAppend = ".java-scale2x"; + char *dupFileName = strdup(fileName); + char *fileExtension = strrchr(dupFileName, '.'); + if (fileExtension == NULL) { + length = strlen(dupFileName) + strlen(stringToAppend) + 1; + if (length > scaledImageNameLength) { + *scaleFactor = 1; + free(dupFileName); + return JNI_FALSE; + } + int retVal = snprintf(scaledImgName, length, "%s%s", + dupFileName, stringToAppend); + if (retVal < 0 || (retVal != length - 1)) { + free(dupFileName); + *scaleFactor = 1; + return JNI_FALSE; + } + } else { + int length_without_ext = fileExtension - dupFileName; + length = length_without_ext + + strlen(stringToAppend) + strlen(fileExtension) + 1; + if (length > scaledImageNameLength) { + *scaleFactor = 1; + free(dupFileName); + return JNI_FALSE; + } + int retVal = snprintf(scaledImgName, length, "%.*s%s%s", + length_without_ext, dupFileName, stringToAppend, fileExtension); + if (retVal < 0 || retVal != length - 1) { + free(dupFileName); + *scaleFactor = 1; + return JNI_FALSE; + } + } + free(dupFileName); + FILE *fp; + if (!(fp = fopen(scaledImgName, "r"))) { + *scaleFactor = 1; + return JNI_FALSE; + } + fclose(fp); + return JNI_TRUE; + } + return JNI_FALSE; } diff --git a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WDesktopPeer.java b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WDesktopPeer.java index b745e9d41ae..2f0ee538ae9 100644 --- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WDesktopPeer.java +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WDesktopPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -27,10 +27,19 @@ package sun.awt.windows; import java.awt.Desktop.Action; +import java.awt.EventQueue; +import java.awt.desktop.SystemEventListener; +import java.awt.desktop.SystemSleepEvent; +import java.awt.desktop.SystemSleepListener; +import java.awt.desktop.UserSessionEvent; +import java.awt.desktop.UserSessionEvent.Reason; +import java.awt.desktop.UserSessionListener; import java.awt.peer.DesktopPeer; import java.io.File; import java.io.IOException; import java.net.URI; +import javax.swing.event.EventListenerList; +import sun.awt.OSInfo; /** @@ -45,10 +54,33 @@ final class WDesktopPeer implements DesktopPeer { private static String ACTION_EDIT_VERB = "edit"; private static String ACTION_PRINT_VERB = "print"; + private static boolean isEventUserSessionSupported = false; + + private static native void init(); + + WDesktopPeer() { + init(); + isEventUserSessionSupported = OSInfo.getWindowsVersion() + .compareTo(OSInfo.WINDOWS_VISTA) >= 0; + } + @Override public boolean isSupported(Action action) { - // OPEN, EDIT, PRINT, MAIL, BROWSE all supported on windows. - return true; + switch(action) { + case OPEN: + case EDIT: + case PRINT: + case MAIL: + case BROWSE: + case MOVE_TO_TRASH: + case APP_SUDDEN_TERMINATION: + case APP_EVENT_SYSTEM_SLEEP: + return true; + case APP_EVENT_USER_SESSION: + return isEventUserSessionSupported; + default: + return false; + } } @Override @@ -94,4 +126,70 @@ final class WDesktopPeer implements DesktopPeer { private static native String ShellExecute(String fileOrUri, String verb); + private static final EventListenerList listenerList = new EventListenerList(); + + @Override + public void disableSuddenTermination() { + setSuddenTerminationEnabled(false); + } + + @Override + public void enableSuddenTermination() { + setSuddenTerminationEnabled(true); + } + + private static native void setSuddenTerminationEnabled(boolean enable); + + @Override + public void addAppEventListener(final SystemEventListener listener) { + if (listener instanceof UserSessionListener) { + listenerList.add(UserSessionListener.class, (UserSessionListener) listener); + } + if (listener instanceof SystemSleepListener) { + listenerList.add(SystemSleepListener.class, (SystemSleepListener) listener); + } + } + + @Override + public void removeAppEventListener(final SystemEventListener listener) { + if (listener instanceof UserSessionListener) { + listenerList.remove(UserSessionListener.class, (UserSessionListener) listener); + } + if (listener instanceof SystemSleepListener) { + listenerList.remove(SystemSleepListener.class, (SystemSleepListener) listener); + } + } + + private static void userSessionCallback(boolean activated, Reason reason) { + UserSessionListener[] listeners = listenerList.getListeners(UserSessionListener.class); + for (UserSessionListener use : listeners) { + EventQueue.invokeLater(() -> { + if (activated) { + use.userSessionActivated(new UserSessionEvent(reason)); + } else { + use.userSessionDeactivated(new UserSessionEvent(reason)); + } + }); + } + } + + private static void systemSleepCallback(boolean resumed) { + SystemSleepListener[] listeners = listenerList.getListeners(SystemSleepListener.class); + for (SystemSleepListener ssl : listeners) { + EventQueue.invokeLater(() -> { + if (resumed) { + ssl.systemAwoke(new SystemSleepEvent()); + } else { + ssl.systemAboutToSleep(new SystemSleepEvent()); + } + }); + } + } + + @Override + public boolean moveToTrash(File file) { + return moveToTrash(file.getAbsolutePath()); + } + private static native boolean moveToTrash(String file); + } diff --git a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WTaskbarPeer.java b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WTaskbarPeer.java new file mode 100644 index 00000000000..98abeff562f --- /dev/null +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WTaskbarPeer.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package sun.awt.windows; + +import java.awt.AlphaComposite; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Taskbar.Feature; +import java.awt.Taskbar.State; +import java.awt.peer.TaskbarPeer; +import java.awt.Window; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferInt; +import sun.awt.AWTAccessor; +import sun.awt.OSInfo; +import sun.awt.shell.ShellFolder; + +final class WTaskbarPeer implements TaskbarPeer { + + private static boolean supported = false; + private static boolean initExecuted = false; + + private static synchronized void init() { + if (!initExecuted) { + supported = OSInfo.getWindowsVersion() + .compareTo(OSInfo.WINDOWS_7) >= 0 + && ShellFolder.invoke(() -> nativeInit()); + } + initExecuted = true; + } + + static boolean isTaskbarSupported() { + init(); + return supported; + } + + WTaskbarPeer() { + init(); + } + + @Override + public boolean isSupported(Feature feature) { + switch(feature) { + case ICON_BADGE_IMAGE_WINDOW: + case PROGRESS_STATE_WINDOW: + case PROGRESS_VALUE_WINDOW: + return supported; + case USER_ATTENTION_WINDOW: + return true; + default: + return false; + } + } + + private static int[] imageToArray(Image image) { + if (image == null) { + return null; + } + + int w = image.getWidth(null); + int h = image.getHeight(null); + + if (w < 0 || h < 0) { + return null; + } + + BufferedImage bimg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE); + Graphics2D g2 = bimg.createGraphics(); + g2.setComposite(AlphaComposite.Src); + g2.drawImage(image, 0, 0, null); + g2.dispose(); + + return ((DataBufferInt) bimg.getRaster().getDataBuffer()).getData(); + } + + @Override + public void setWindowIconBadge(Window window, final Image image) { + WWindowPeer wp = AWTAccessor.getComponentAccessor().getPeer(window); + if (wp != null) { + int[] buffer = imageToArray(image); + ShellFolder.invoke(() -> { + setOverlayIcon(wp.getHWnd(), buffer, + buffer != null ? image.getWidth(null) : 0, + buffer != null ? image.getHeight(null) : 0); + return null; + }); + } + } + + @Override + public void requestWindowUserAttention(Window window) { + WWindowPeer wp = AWTAccessor.getComponentAccessor().getPeer(window); + if (wp != null) { + flashWindow(wp.getHWnd()); + } + } + + @Override + public void setWindowProgressValue(Window window, int value) { + WWindowPeer wp = AWTAccessor.getComponentAccessor().getPeer(window); + if (wp != null) { + ShellFolder.invoke(() -> { + setProgressValue(wp.getHWnd(), value); + return null; + }); + } + } + + @Override + public void setWindowProgressState(Window window, State state) { + WWindowPeer wp = AWTAccessor.getComponentAccessor().getPeer(window); + if (wp != null) { + ShellFolder.invoke(() -> { + setProgressState(wp.getHWnd(), state); + return null; + }); + } + } + + private static native boolean nativeInit(); + + private native void setProgressValue(long hwnd, int value); + + private native void setProgressState(long hwnd, State state); + + private native void setOverlayIcon(long hwnd, int[] badge, int width, int height); + + private native void flashWindow(long hWnd); + +} diff --git a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java index 66d8338be29..8fb6f386474 100644 --- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -25,6 +25,7 @@ package sun.awt.windows; +import java.awt.peer.TaskbarPeer; import java.awt.*; import java.awt.im.InputMethodHighlight; import java.awt.im.spi.InputMethodDescriptor; @@ -1131,6 +1132,7 @@ public final class WToolkit extends SunToolkit implements Runnable { @Override public native boolean syncNativeQueue(final long timeout); + @Override public boolean isDesktopSupported() { return true; @@ -1141,6 +1143,16 @@ public final class WToolkit extends SunToolkit implements Runnable { return new WDesktopPeer(); } + @Override + public boolean isTaskbarSupported() { + return WTaskbarPeer.isTaskbarSupported(); + } + + @Override + public TaskbarPeer createTaskbarPeer(Taskbar target) { + return new WTaskbarPeer(); + } + private static native void setExtraMouseButtonsEnabledNative(boolean enable); @Override diff --git a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DSurfaceData.java b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DSurfaceData.java index c6b25970951..e2b08016e56 100644 --- a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DSurfaceData.java +++ b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DSurfaceData.java @@ -703,20 +703,13 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface { } @Override - public boolean copyArea(SunGraphics2D sg2d, - int x, int y, int w, int h, int dx, int dy) - { - if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE && - sg2d.compositeState < SunGraphics2D.COMP_XOR) - { - x += sg2d.transX; - y += sg2d.transY; - - d3dRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy); - - return true; + public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, + int dx, int dy) { + if (sg2d.compositeState >= SunGraphics2D.COMP_XOR) { + return false; } - return false; + d3dRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy); + return true; } @Override diff --git a/jdk/src/java.desktop/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java b/jdk/src/java.desktop/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java index 2ba2b11aa59..ad211ab473c 100644 --- a/jdk/src/java.desktop/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java +++ b/jdk/src/java.desktop/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java @@ -311,13 +311,10 @@ public class GDIWindowSurfaceData extends SurfaceData { int x, int y, int w, int h, int dx, int dy) { CompositeType comptype = sg2d.imageComp; - if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE && - sg2d.clipState != SunGraphics2D.CLIP_SHAPE && + if (sg2d.clipState != SunGraphics2D.CLIP_SHAPE && (CompositeType.SrcOverNoEa.equals(comptype) || CompositeType.SrcNoEa.equals(comptype))) { - x += sg2d.transX; - y += sg2d.transY; int dstx1 = x + dx; int dsty1 = y + dy; int dstx2 = dstx1 + w; diff --git a/jdk/src/java.desktop/windows/native/common/awt/systemscale/systemScale.cpp b/jdk/src/java.desktop/windows/native/common/awt/systemscale/systemScale.cpp new file mode 100644 index 00000000000..60eecd74437 --- /dev/null +++ b/jdk/src/java.desktop/windows/native/common/awt/systemscale/systemScale.cpp @@ -0,0 +1,89 @@ +/* +* Copyright (c) 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. +*/ +#include "systemScale.h" +#include +#pragma comment(lib, "d2d1") +#include +#ifndef MDT_EFFECTIVE_DPI +#define MDT_EFFECTIVE_DPI 0 +#endif + +void GetScreenDpi(HMONITOR hmon, float *dpiX, float *dpiY) +{ + unsigned x = 0; + unsigned y = 0; + + // for debug purposes + static float scale = -2.0f; + if (scale == -2) { + scale = -1; + char *uiScale = getenv("J2D_UISCALE"); + if (uiScale != NULL) { + scale = (float)strtod(uiScale, NULL); + if (errno == ERANGE || scale <= 0) { + scale = -1; + } + } + } + + if (scale > 0) { + *dpiX = *dpiY = scale; + return; + } + + typedef HRESULT(WINAPI GetDpiForMonitorFunc)(HMONITOR, int, UINT*, UINT*); + static HMODULE hLibSHCoreDll = NULL; + static GetDpiForMonitorFunc *lpGetDpiForMonitor = NULL; + + if (hLibSHCoreDll == NULL) { + hLibSHCoreDll = JDK_LoadSystemLibrary("shcore.dll"); + if (hLibSHCoreDll != NULL) { + lpGetDpiForMonitor = (GetDpiForMonitorFunc*)GetProcAddress( + hLibSHCoreDll, "GetDpiForMonitor"); + } + } + + if (lpGetDpiForMonitor != NULL) { + HRESULT hResult = lpGetDpiForMonitor(hmon, + MDT_EFFECTIVE_DPI, &x, &y); + if (hResult == S_OK) { + *dpiX = static_cast(x); + *dpiY = static_cast(y); + } + } else { + ID2D1Factory* m_pDirect2dFactory; + HRESULT res = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, + &m_pDirect2dFactory); + if (res == S_OK) { + m_pDirect2dFactory->GetDesktopDpi(dpiX, dpiY); + m_pDirect2dFactory->Release(); + } + } + return; +} + +HMONITOR WINAPI getPrimaryMonitor() +{ + const POINT point = { 0, 0 }; + return MonitorFromPoint(point, MONITOR_DEFAULTTOPRIMARY); +} diff --git a/jdk/src/java.desktop/windows/native/common/awt/systemscale/systemScale.h b/jdk/src/java.desktop/windows/native/common/awt/systemscale/systemScale.h new file mode 100644 index 00000000000..cc3cb8878c9 --- /dev/null +++ b/jdk/src/java.desktop/windows/native/common/awt/systemscale/systemScale.h @@ -0,0 +1,34 @@ +/* +* Copyright (c) 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. +*/ +#ifndef _AWT_SYSTEM_SCALE_H +#define _AWT_SYSTEM_SCALE_H +#include +#ifdef __cplusplus +extern "C" { +#endif + void GetScreenDpi(HMONITOR mon, float *dpiX, float *dpiY); + HMONITOR WINAPI getPrimaryMonitor(); +#ifdef __cplusplus +} +#endif +#endif diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp index ef677750b3d..b3d3e09ed65 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp @@ -31,6 +31,8 @@ #include "awt_Object.h" #include "awt_Component.h" +#include "math.h" + // Important note about VC6 and VC7 (or XP Platform SDK) ! // // These type definitions have been imported from UxTheme.h @@ -68,6 +70,11 @@ typedef struct _MARGINS #define TMT_TRANSPARENT 2201 #endif // _UXTHEME_H_ +#if defined(_MSC_VER) && _MSC_VER >= 1800 +# define ROUND_TO_INT(num) ((int) round(num)) +#else +# define ROUND_TO_INT(num) ((int) floor((num) + 0.5)) +#endif #define ALPHA_MASK 0xff000000 #define RED_MASK 0xff0000 @@ -745,6 +752,23 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPosition return NULL; } +void rescale(SIZE *size) { + HWND hWnd = ::GetDesktopWindow(); + HDC hDC = ::GetDC(hWnd); + int dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX); + int dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY); + + if (dpiX !=0 && dpiX != 96) { + float invScaleX = 96.0f / dpiX; + size->cx = ROUND_TO_INT(size->cx * invScaleX); + } + if (dpiY != 0 && dpiY != 96) { + float invScaleY = 96.0f / dpiY; + size->cy = ROUND_TO_INT(size->cy * invScaleY); + } + ::ReleaseDC(hWnd, hDC); +} + /* * Class: sun_awt_windows_ThemeReader * Method: getPartSize @@ -770,6 +794,8 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPartSize dimMID = env->GetMethodID(dimClassID, "", "(II)V"); CHECK_NULL_RETURN(dimMID, NULL); } + + rescale(&size); jobject dimObj = env->NewObject(dimClassID, dimMID, size.cx, size.cy); if (safe_ExceptionOccurred(env)) { env->ExceptionDescribe(); diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Desktop.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Desktop.cpp index 36b54670642..7f5c0d62062 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Desktop.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Desktop.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -28,11 +28,45 @@ #include #include #include +#include +#include "awt_Toolkit.h" + +#define BUFFER_LIMIT MAX_PATH+1 + +#define NOTIFY_FOR_ALL_SESSIONS 1 +#define NOTIFY_FOR_THIS_SESSION 0 + +typedef BOOL (WINAPI *WTSRegisterSessionNotification)(HWND,DWORD); +static WTSRegisterSessionNotification fn_WTSRegisterSessionNotification; + +BOOL isSuddenTerminationEnabled = TRUE; #ifdef __cplusplus extern "C" { #endif +/* + * Class: sun_awt_windows_WDesktopPeer + * Method: init + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_sun_awt_windows_WDesktopPeer_init + (JNIEnv *, jclass) { + static HMODULE libWtsapi32 = NULL; + if (libWtsapi32 == NULL) { + libWtsapi32 = JDK_LoadSystemLibrary("Wtsapi32.dll"); + if (libWtsapi32) { + fn_WTSRegisterSessionNotification = (WTSRegisterSessionNotification) + GetProcAddress(libWtsapi32, "WTSRegisterSessionNotification"); + if (fn_WTSRegisterSessionNotification) { + HWND hwnd = AwtToolkit::GetInstance().GetHWnd(); + //used for UserSessionListener + fn_WTSRegisterSessionNotification(hwnd, NOTIFY_FOR_THIS_SESSION); + } + } + } +} + /* * Class: sun_awt_windows_WDesktopPeer * Method: ShellExecute @@ -82,6 +116,53 @@ JNIEXPORT jstring JNICALL Java_sun_awt_windows_WDesktopPeer_ShellExecute return NULL; } +/* + * Class: sun_awt_windows_WDesktopPeer + * Method: moveToTrash + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WDesktopPeer_moveToTrash + (JNIEnv *env, jclass, jstring jpath) +{ + LPCTSTR pathStr = JNU_GetStringPlatformChars(env, jpath, (jboolean *)NULL); + if (pathStr) { + try { + LPTSTR fileBuffer = new TCHAR[BUFFER_LIMIT]; + memset(fileBuffer, 0, BUFFER_LIMIT * sizeof(TCHAR)); + // the fileBuffer is double null terminated string + _tcsncpy(fileBuffer, pathStr, BUFFER_LIMIT - 2); + + SHFILEOPSTRUCT fop; + memset(&fop, 0, sizeof(SHFILEOPSTRUCT)); + fop.hwnd = NULL; + fop.wFunc = FO_DELETE; + fop.pFrom = fileBuffer; + fop.fFlags = FOF_ALLOWUNDO; + + int res = SHFileOperation(&fop); + + delete[] fileBuffer; + JNU_ReleaseStringPlatformChars(env, jpath, pathStr); + + return !res ? JNI_TRUE : JNI_FALSE; + } catch (std::bad_alloc&) { + JNU_ReleaseStringPlatformChars(env, jpath, pathStr); + } + } + return JNI_FALSE; +} + +/* + * Class: sun_awt_windows_WDesktopPeer + * Method: setSuddenTerminationEnabled + * Signature: (Z)V + */ +JNIEXPORT void JNICALL Java_sun_awt_windows_WDesktopPeer_setSuddenTerminationEnabled + (JNIEnv *, jclass, jboolean enabled) +{ + isSuddenTerminationEnabled = enabled; +} + #ifdef __cplusplus } #endif diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp index 454a2fe74e4..497d35dc350 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp @@ -35,6 +35,14 @@ #include #include +#include "math.h" + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +# define ROUND_TO_INT(num) ((int) round(num)) +#else +# define ROUND_TO_INT(num) ((int) floor((num) + 0.5)) +#endif + // WDesktopProperties fields jfieldID AwtDesktopProperties::pDataID = 0; jmethodID AwtDesktopProperties::setBooleanPropertyID = 0; @@ -79,18 +87,35 @@ void AwtDesktopProperties::GetWindowsParameters() { } } +void getInvScale(float &invScaleX, float &invScaleY) { + HWND hWnd = ::GetDesktopWindow(); + HDC hDC = ::GetDC(hWnd); + int dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX); + int dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY); + ::ReleaseDC(hWnd, hDC); + invScaleX = (dpiX == 0.0f) ? 1.0f : 96.0f / dpiX; + invScaleY = (dpiY == 0.0f) ? 1.0f : 96.0f / dpiY; +} + +int rescale(int value, float invScale){ + return invScale == 1.0f ? value : ROUND_TO_INT(value * invScale); +} + void AwtDesktopProperties::GetSystemProperties() { HDC dc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); if (dc != NULL) { try { - SetFontProperty(dc, ANSI_FIXED_FONT, TEXT("win.ansiFixed.font")); - SetFontProperty(dc, ANSI_VAR_FONT, TEXT("win.ansiVar.font")); - SetFontProperty(dc, DEVICE_DEFAULT_FONT, TEXT("win.deviceDefault.font")); - SetFontProperty(dc, DEFAULT_GUI_FONT, TEXT("win.defaultGUI.font")); - SetFontProperty(dc, OEM_FIXED_FONT, TEXT("win.oemFixed.font")); - SetFontProperty(dc, SYSTEM_FONT, TEXT("win.system.font")); - SetFontProperty(dc, SYSTEM_FIXED_FONT, TEXT("win.systemFixed.font")); + float invScaleX; + float invScaleY; + getInvScale(invScaleX, invScaleY); + SetFontProperty(dc, ANSI_FIXED_FONT, TEXT("win.ansiFixed.font"), 1.0f); + SetFontProperty(dc, ANSI_VAR_FONT, TEXT("win.ansiVar.font"), 1.0f); + SetFontProperty(dc, DEVICE_DEFAULT_FONT, TEXT("win.deviceDefault.font"), 1.0f); + SetFontProperty(dc, DEFAULT_GUI_FONT, TEXT("win.defaultGUI.font"), invScaleY); + SetFontProperty(dc, OEM_FIXED_FONT, TEXT("win.oemFixed.font"), 1.0f); + SetFontProperty(dc, SYSTEM_FONT, TEXT("win.system.font"), 1.0f); + SetFontProperty(dc, SYSTEM_FIXED_FONT, TEXT("win.systemFixed.font"), 1.0f); } catch (std::bad_alloc&) { DeleteDC(dc); @@ -266,31 +291,35 @@ void AwtDesktopProperties::GetNonClientParameters() { } VERIFY( SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncmetrics.cbSize, &ncmetrics, FALSE) ); - SetFontProperty( TEXT("win.frame.captionFont"), ncmetrics.lfCaptionFont ); - SetIntegerProperty( TEXT("win.frame.captionHeight"), ncmetrics.iCaptionHeight ); - SetIntegerProperty( TEXT("win.frame.captionButtonWidth"), ncmetrics.iCaptionWidth ); - SetIntegerProperty( TEXT("win.frame.captionButtonHeight"), ncmetrics.iCaptionHeight ); - SetFontProperty( TEXT("win.frame.smallCaptionFont"), ncmetrics.lfSmCaptionFont ); - SetIntegerProperty( TEXT("win.frame.smallCaptionHeight"), ncmetrics.iSmCaptionHeight ); - SetIntegerProperty( TEXT("win.frame.smallCaptionButtonWidth"), ncmetrics.iSmCaptionWidth ); - SetIntegerProperty( TEXT("win.frame.smallCaptionButtonHeight"), ncmetrics.iSmCaptionHeight ); - SetIntegerProperty( TEXT("win.frame.sizingBorderWidth"), ncmetrics.iBorderWidth ); + float invScaleX; + float invScaleY; + getInvScale(invScaleX, invScaleY); + + SetFontProperty(TEXT("win.frame.captionFont"), ncmetrics.lfCaptionFont, invScaleY); + SetIntegerProperty(TEXT("win.frame.captionHeight"), rescale(ncmetrics.iCaptionHeight, invScaleY)); + SetIntegerProperty(TEXT("win.frame.captionButtonWidth"), rescale(ncmetrics.iCaptionWidth, invScaleX)); + SetIntegerProperty(TEXT("win.frame.captionButtonHeight"), rescale(ncmetrics.iCaptionHeight, invScaleY)); + SetFontProperty(TEXT("win.frame.smallCaptionFont"), ncmetrics.lfSmCaptionFont, invScaleY); + SetIntegerProperty(TEXT("win.frame.smallCaptionHeight"), rescale(ncmetrics.iSmCaptionHeight, invScaleY)); + SetIntegerProperty(TEXT("win.frame.smallCaptionButtonWidth"), rescale(ncmetrics.iSmCaptionWidth, invScaleX)); + SetIntegerProperty(TEXT("win.frame.smallCaptionButtonHeight"), rescale(ncmetrics.iSmCaptionHeight, invScaleY)); + SetIntegerProperty(TEXT("win.frame.sizingBorderWidth"), rescale(ncmetrics.iBorderWidth, invScaleX)); // menu properties - SetFontProperty( TEXT("win.menu.font"), ncmetrics.lfMenuFont ); - SetIntegerProperty( TEXT("win.menu.height"), ncmetrics.iMenuHeight ); - SetIntegerProperty( TEXT("win.menu.buttonWidth"), ncmetrics.iMenuWidth ); + SetFontProperty(TEXT("win.menu.font"), ncmetrics.lfMenuFont, invScaleY); + SetIntegerProperty(TEXT("win.menu.height"), rescale(ncmetrics.iMenuHeight, invScaleY)); + SetIntegerProperty(TEXT("win.menu.buttonWidth"), rescale(ncmetrics.iMenuWidth, invScaleX)); // scrollbar properties - SetIntegerProperty( TEXT("win.scrollbar.width"), ncmetrics.iScrollWidth ); - SetIntegerProperty( TEXT("win.scrollbar.height"), ncmetrics.iScrollHeight ); + SetIntegerProperty(TEXT("win.scrollbar.width"), rescale(ncmetrics.iScrollWidth, invScaleX)); + SetIntegerProperty(TEXT("win.scrollbar.height"), rescale(ncmetrics.iScrollHeight, invScaleY)); // status bar and tooltip properties - SetFontProperty( TEXT("win.status.font"), ncmetrics.lfStatusFont ); - SetFontProperty( TEXT("win.tooltip.font"), ncmetrics.lfStatusFont ); + SetFontProperty(TEXT("win.status.font"), ncmetrics.lfStatusFont, invScaleY); + SetFontProperty(TEXT("win.tooltip.font"), ncmetrics.lfStatusFont, invScaleY); // message box properties - SetFontProperty( TEXT("win.messagebox.font"), ncmetrics.lfMessageFont ); + SetFontProperty(TEXT("win.messagebox.font"), ncmetrics.lfMessageFont, invScaleY); } void AwtDesktopProperties::GetIconParameters() { @@ -302,10 +331,13 @@ void AwtDesktopProperties::GetIconParameters() { iconmetrics.cbSize = sizeof(iconmetrics); VERIFY( SystemParametersInfo(SPI_GETICONMETRICS, iconmetrics.cbSize, &iconmetrics, FALSE) ); - SetIntegerProperty(TEXT("win.icon.hspacing"), iconmetrics.iHorzSpacing); - SetIntegerProperty(TEXT("win.icon.vspacing"), iconmetrics.iVertSpacing); + float invScaleX; + float invScaleY; + getInvScale(invScaleX, invScaleY); + SetIntegerProperty(TEXT("win.icon.hspacing"), rescale(iconmetrics.iHorzSpacing, invScaleX)); + SetIntegerProperty(TEXT("win.icon.vspacing"), rescale(iconmetrics.iVertSpacing, invScaleY)); SetBooleanProperty(TEXT("win.icon.titleWrappingOn"), iconmetrics.iTitleWrap != 0); - SetFontProperty(TEXT("win.icon.font"), iconmetrics.lfFont); + SetFontProperty(TEXT("win.icon.font"), iconmetrics.lfFont, invScaleY); } /* Windows settings for these are also in the registry @@ -718,6 +750,7 @@ void AwtDesktopProperties::SetStringProperty(LPCTSTR propName, LPTSTR value) { } void AwtDesktopProperties::SetIntegerProperty(LPCTSTR propName, int value) { + jstring key = JNU_NewStringPlatform(GetEnv(), propName); if (key == NULL) { throw std::bad_alloc(); @@ -752,8 +785,8 @@ void AwtDesktopProperties::SetColorProperty(LPCTSTR propName, DWORD value) { } void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID, - LPCTSTR propName) { - HGDIOBJ font = GetStockObject(fontID); + LPCTSTR propName, float invScale) { + HGDIOBJ font = GetStockObject(fontID); if (font != NULL && SelectObject(dc, font) != NULL) { int length = GetTextFace(dc, 0, NULL); @@ -789,8 +822,8 @@ void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID, throw std::bad_alloc(); } - jint pointSize = metrics.tmHeight - - metrics.tmInternalLeading; + jint pointSize = rescale(metrics.tmHeight - + metrics.tmInternalLeading, invScale); jint style = java_awt_Font_PLAIN; if (metrics.tmWeight >= FW_BOLD) { @@ -818,7 +851,8 @@ void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID, } } -void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & font) { +void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & font, + float invScale) { jstring fontName; jint pointSize; jint style; @@ -836,7 +870,7 @@ void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & fon ReleaseDC(NULL, hdc); #endif // Java uses point sizes, but assumes 1 pixel = 1 point - pointSize = -font.lfHeight; + pointSize = rescale(-font.lfHeight, invScale); // convert Windows font style to Java style style = java_awt_Font_PLAIN; diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.h b/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.h index e93530ef208..70f0bf895de 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.h +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.h @@ -73,8 +73,8 @@ class AwtDesktopProperties { void SetIntegerProperty(LPCTSTR, int); void SetStringProperty(LPCTSTR, LPTSTR); void SetColorProperty(LPCTSTR, DWORD); - void SetFontProperty(HDC, int, LPCTSTR); - void SetFontProperty(LPCTSTR, const LOGFONT &); + void SetFontProperty(HDC, int, LPCTSTR, float invScale); + void SetFontProperty(LPCTSTR, const LOGFONT &, float invScale); void SetSoundProperty(LPCTSTR, LPCTSTR); JNIEnv * GetEnv() { diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_DnDDT.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_DnDDT.cpp index 8739fc8f576..908b459111e 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_DnDDT.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_DnDDT.cpp @@ -127,6 +127,16 @@ ULONG __stdcall AwtDropTarget::Release() { return (ULONG)refs; } +void ScaleDown(POINT &cp, HWND m_window) { + int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(m_window); + Devices::InstanceAccess devices; + AwtWin32GraphicsDevice* device = devices->GetDevice(screen); + if (device) { + cp.x = device->ScaleDownX(cp.x); + cp.y = device->ScaleDownY(cp.y); + } +} + /** * DragEnter */ @@ -176,6 +186,7 @@ HRESULT __stdcall AwtDropTarget::DragEnter(IDataObject __RPC_FAR *pDataObj, DWOR cp.x = pt.x - wr.left; cp.y = pt.y - wr.top; + ScaleDown(cp, m_window); jint actions = call_dTCenter(env, m_dtcp, m_target, (jint)cp.x, (jint)cp.y, @@ -237,6 +248,7 @@ HRESULT __stdcall AwtDropTarget::DragOver(DWORD grfKeyState, POINTL pt, DWORD __ cp.x = pt.x - wr.left; cp.y = pt.y - wr.top; + ScaleDown(cp, m_window); actions = call_dTCmotion(env, m_dtcp, m_target,(jint)cp.x, (jint)cp.y, ::convertDROPEFFECTToActions(mapModsToDROPEFFECT(*pdwEffect, grfKeyState)), @@ -336,6 +348,7 @@ HRESULT __stdcall AwtDropTarget::Drop(IDataObject __RPC_FAR *pDataObj, DWORD grf cp.x = pt.x - wr.left; cp.y = pt.y - wr.top; + ScaleDown(cp, m_window); m_dropActions = java_awt_dnd_DnDConstants_ACTION_NONE; diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp index 1d87c3d6dc0..94965e74893 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp @@ -770,6 +770,10 @@ BOOL AwtPrintControl::InitPrintDialog(JNIEnv *env, AwtPrintControl::getMinPageID); jint maxPage = env->CallIntMethod(printCtrl, AwtPrintControl::getMaxPageID); + + jint selectType = env->CallIntMethod(printCtrl, + AwtPrintControl::getSelectID); + pd.nMaxPage = (maxPage <= (jint)((WORD)-1)) ? (WORD)maxPage : (WORD)-1; // In the event that the application displays the dialog before // installing a Printable, but sets a page range, then max page will be 1 @@ -779,8 +783,12 @@ BOOL AwtPrintControl::InitPrintDialog(JNIEnv *env, // So if we detect this fix up such a problem here. if (pd.nMinPage > pd.nFromPage) pd.nMinPage = pd.nFromPage; if (pd.nMaxPage < pd.nToPage) pd.nMaxPage = pd.nToPage; - if (pd.nFromPage > pd.nMinPage || pd.nToPage < pd.nMaxPage) { - pd.Flags |= PD_PAGENUMS; + if (selectType != 0 && (pd.nFromPage > pd.nMinPage || pd.nToPage < pd.nMaxPage)) { + if (selectType == PD_SELECTION) { + pd.Flags |= PD_SELECTION; + } else { + pd.Flags |= PD_PAGENUMS; + } } if (env->CallBooleanMethod(printCtrl, @@ -788,9 +796,6 @@ BOOL AwtPrintControl::InitPrintDialog(JNIEnv *env, pd.Flags |= PD_PRINTTOFILE; } - jint selectType = env->CallIntMethod(printCtrl, - AwtPrintControl::getSelectID); - // selectType identifies whether No selection (2D) or // SunPageSelection (AWT) if (selectType != 0) { diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Taskbar.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Taskbar.cpp new file mode 100644 index 00000000000..50c1ba85c2a --- /dev/null +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Taskbar.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "jni_util.h" +#include "awt.h" +#include +#include "awt_Taskbar.h" +#include "awt_Window.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Class: sun_awt_windows_WTaskbarPeer + * Method: nativeInit + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WTaskbarPeer_nativeInit + (JNIEnv *env, jclass) +{ + if (SUCCEEDED(::CoCreateInstance(CLSID_TaskbarList, NULL, + CLSCTX_INPROC_SERVER, IID_ITaskbarList, (LPVOID *)&m_Taskbar))) { + return JNI_TRUE; + } else { + return JNI_FALSE; + } +} + +/* + * Class: sun_awt_windows_WTaskbarPeer + * Method: setProgressValue + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_sun_awt_windows_WTaskbarPeer_setProgressValue + (JNIEnv *, jobject, jlong window, jint value) +{ + m_Taskbar->SetProgressValue((HWND)window, value, 100); +} + + + +/* + * Class: sun_awt_windows_WTaskbarPeer + * Method: setProgressState + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_sun_awt_windows_WTaskbarPeer_setProgressState + (JNIEnv *env, jobject, jlong window, jobject state) +{ + TBPFLAG flag = TBPF_NOPROGRESS; + + static jmethodID nameMID = NULL; + if (!nameMID) { + jclass stateCls = env->FindClass("java/awt/Taskbar$State"); + CHECK_NULL(stateCls); + nameMID = env->GetMethodID(stateCls, "name", "()Ljava/lang/String;"); + CHECK_NULL(nameMID); + } + jstring value = (jstring) env->CallObjectMethod(state, nameMID); + CHECK_NULL(value); + const char* valueNative = env->GetStringUTFChars(value, 0); + if (valueNative) { + if (strcmp(valueNative, "OFF") == 0) { + flag = TBPF_NOPROGRESS; + } else if (strcmp(valueNative, "NORMAL") == 0) { + flag = TBPF_NORMAL; + } else if (strcmp(valueNative, "PAUSED") == 0) { + flag = TBPF_PAUSED; + } else if (strcmp(valueNative, "INDETERMINATE") == 0) { + flag = TBPF_INDETERMINATE; + } else if (strcmp(valueNative, "ERROR") == 0) { + flag = TBPF_ERROR; + } + env->ReleaseStringUTFChars(value, valueNative); + m_Taskbar->SetProgressState((HWND)window, flag); + } +} + +/* + * Class: sun_awt_windows_WTaskbarPeer + * Method: flashWindow + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_sun_awt_windows_WTaskbarPeer_flashWindow + (JNIEnv *, jobject, jlong window) +{ + AwtWindow::FlashWindowEx((HWND) window, 3, 0, FLASHW_TIMERNOFG); +} + +/* + * Class: sun_awt_windows_WTaskbarPeer + * Method: setOverlayIcon + * Signature: (J[III)V + */ +JNIEXPORT void JNICALL Java_sun_awt_windows_WTaskbarPeer_setOverlayIcon + (JNIEnv *env, jobject, jlong window, jintArray buf, jint w, jint h) +{ + HICON icon = CreateIconFromRaster(env, buf, w, h); + m_Taskbar->SetOverlayIcon((HWND)window, icon, NULL); + ::DestroyIcon(icon); +} +#ifdef __cplusplus +} +#endif diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Taskbar.h b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Taskbar.h new file mode 100644 index 00000000000..d6f1e242f80 --- /dev/null +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Taskbar.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 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. 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. + */ + +#ifndef AWT_TASKBAR_H +#define AWT_TASKBAR_H + +#include +#include + + +#ifndef __ITaskbarList_INTERFACE_DEFINED__ +#define __ITaskbarList_INTERFACE_DEFINED__ +extern "C" { + const GUID CLSID_TaskbarList = {0x56FDF344, 0xFD6D, 0x11D0, + {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}}; + const GUID IID_ITaskbarList = {0x56FDF342, 0xFD6D, 0x11D0, + {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}}; +} + +class ITaskbarList : public IUnknown { +public: + virtual HRESULT STDMETHODCALLTYPE HrInit(void) = 0; + virtual HRESULT STDMETHODCALLTYPE AddTab(HWND hwnd) = 0; + virtual HRESULT STDMETHODCALLTYPE DeleteTab(HWND hwnd) = 0; + virtual HRESULT STDMETHODCALLTYPE ActivateTab(HWND hwnd) = 0; + virtual HRESULT STDMETHODCALLTYPE SetActiveAlt(HWND hwnd) = 0; +}; +#endif /* ITaskbarList */ + +#ifndef __ITaskbarList2_INTERFACE_DEFINED__ +#define __ITaskbarList2_INTERFACE_DEFINED__ + +class ITaskbarList2 : public ITaskbarList { +public: + virtual HRESULT STDMETHODCALLTYPE MarkFullscreenWindow(HWND hwnd, BOOL fFullscreen) = 0; +}; +#endif /* ITaskbarList2 */ + +#ifndef __ITaskbarList3_INTERFACE_DEFINED__ +#define __ITaskbarList3_INTERFACE_DEFINED__ + +typedef enum THUMBBUTTONFLAGS { + THBF_ENABLED = 0, THBF_DISABLED = 0x1, THBF_DISMISSONCLICK = 0x2, THBF_NOBACKGROUND = 0x4, THBF_HIDDEN = 0x8, THBF_NONINTERACTIVE = 0x10 +} THUMBBUTTONFLAGS; + +typedef enum THUMBBUTTONMASK { + THB_BITMAP = 0x1, THB_ICON = 0x2, THB_TOOLTIP = 0x4, THB_FLAGS = 0x8 +} THUMBBUTTONMASK; + +typedef struct THUMBBUTTON { + THUMBBUTTONMASK dwMask; + UINT iId; + UINT iBitmap; + HICON hIcon; + WCHAR szTip[260]; + THUMBBUTTONFLAGS dwFlags; +} THUMBBUTTON; + +typedef enum TBPFLAG { + TBPF_NOPROGRESS = 0, TBPF_INDETERMINATE = 0x1, TBPF_NORMAL = 0x2, TBPF_ERROR = 0x4, TBPF_PAUSED = 0x8 +} TBPFLAG; +#define THBN_CLICKED 0x1800 + +class ITaskbarList3 : public ITaskbarList2 { +public: + virtual HRESULT STDMETHODCALLTYPE SetProgressValue(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal) = 0; + virtual HRESULT STDMETHODCALLTYPE SetProgressState(HWND hwnd, TBPFLAG tbpFlags) = 0; + virtual HRESULT STDMETHODCALLTYPE RegisterTab(HWND hwndTab, HWND hwndMDI) = 0; + virtual HRESULT STDMETHODCALLTYPE UnregisterTab(HWND hwndTab) = 0; + virtual HRESULT STDMETHODCALLTYPE SetTabOrder(HWND hwndTab, HWND hwndInsertBefore) = 0; + virtual HRESULT STDMETHODCALLTYPE SetTabActive(HWND hwndTab, HWND hwndMDI, DWORD dwReserved) = 0; + virtual HRESULT STDMETHODCALLTYPE ThumbBarAddButtons(HWND hwnd, UINT cButtons, THUMBBUTTON * pButton) = 0; + virtual HRESULT STDMETHODCALLTYPE ThumbBarUpdateButtons(HWND hwnd, UINT cButtons, THUMBBUTTON * pButton) = 0; + virtual HRESULT STDMETHODCALLTYPE ThumbBarSetImageList(HWND hwnd, HIMAGELIST himl) = 0; + virtual HRESULT STDMETHODCALLTYPE SetOverlayIcon(HWND hwnd, HICON hIcon, LPCWSTR pszDescription) = 0; + virtual HRESULT STDMETHODCALLTYPE SetThumbnailTooltip(HWND hwnd, LPCWSTR pszTip) = 0; + virtual HRESULT STDMETHODCALLTYPE SetThumbnailClip(HWND hwnd, RECT *prcClip) = 0; +}; +#endif /* ITaskbarList3 */ + + +ITaskbarList3 * m_Taskbar; + + +#endif /* AWT_TASKBAR_H */ + diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextArea.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextArea.cpp index 0b96ad99a4b..7ec74314bfd 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextArea.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextArea.cpp @@ -225,31 +225,18 @@ AwtTextArea::HandleEvent(MSG *msg, BOOL synthetic) /* * We consume WM_MOUSEMOVE while the left mouse button is pressed, - * so we have to simulate autoscrolling when mouse is moved outside - * of the client area. + * so we have to simulate selection autoscrolling when mouse is moved + * outside of the client area. */ POINT p; RECT r; - BOOL bScrollLeft = FALSE; - BOOL bScrollRight = FALSE; - BOOL bScrollUp = FALSE; BOOL bScrollDown = FALSE; p.x = msg->pt.x; p.y = msg->pt.y; VERIFY(::GetClientRect(GetHWnd(), &r)); - if (p.x < 0) { - bScrollLeft = TRUE; - p.x = 0; - } else if (p.x > r.right) { - bScrollRight = TRUE; - p.x = r.right - 1; - } - if (p.y < 0) { - bScrollUp = TRUE; - p.y = 0; - } else if (p.y > r.bottom) { + if (p.y > r.bottom) { bScrollDown = TRUE; p.y = r.bottom - 1; } @@ -269,32 +256,7 @@ AwtTextArea::HandleEvent(MSG *msg, BOOL synthetic) EditSetSel(cr); } - - if (bScrollLeft == TRUE || bScrollRight == TRUE) { - SCROLLINFO si; - memset(&si, 0, sizeof(si)); - si.cbSize = sizeof(si); - si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; - - VERIFY(::GetScrollInfo(GetHWnd(), SB_HORZ, &si)); - if (bScrollLeft == TRUE) { - si.nPos = si.nPos - si.nPage / 2; - si.nPos = max(si.nMin, si.nPos); - } else if (bScrollRight == TRUE) { - si.nPos = si.nPos + si.nPage / 2; - si.nPos = min(si.nPos, si.nMax); - } - /* - * Okay to use 16-bit position since RichEdit control adjusts - * its scrollbars so that their range is always 16-bit. - */ - DASSERT(abs(si.nPos) < 0x8000); - SendMessage(WM_HSCROLL, - MAKEWPARAM(SB_THUMBPOSITION, LOWORD(si.nPos))); - } - if (bScrollUp == TRUE) { - SendMessage(EM_LINESCROLL, 0, -1); - } else if (bScrollDown == TRUE) { + if (bScrollDown == TRUE) { SendMessage(EM_LINESCROLL, 0, 1); } delete msg; diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextField.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextField.cpp index 1c966aaf065..01c73f068ee 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextField.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextField.cpp @@ -157,27 +157,12 @@ AwtTextField::HandleEvent(MSG *msg, BOOL synthetic) /* * We consume WM_MOUSEMOVE while the left mouse button is pressed, - * so we have to simulate autoscrolling when mouse is moved outside - * of the client area. + * so we have to simulate selection autoscrolling when mouse is moved + * outside of the client area. */ POINT p; - RECT r; - BOOL bScrollLeft = FALSE; - BOOL bScrollRight = FALSE; - BOOL bScrollUp = FALSE; - BOOL bScrollDown = FALSE; - p.x = msg->pt.x; p.y = msg->pt.y; - VERIFY(::GetClientRect(GetHWnd(), &r)); - - if (p.x < 0) { - bScrollLeft = TRUE; - p.x = 0; - } else if (p.x > r.right) { - bScrollRight = TRUE; - p.x = r.right - 1; - } LONG lCurPos = EditGetCharFromPos(p); if (GetStartSelectionPos() != -1 && @@ -193,32 +178,6 @@ AwtTextField::HandleEvent(MSG *msg, BOOL synthetic) EditSetSel(cr); } - - if (bScrollLeft == TRUE || bScrollRight == TRUE) { - SCROLLINFO si; - memset(&si, 0, sizeof(si)); - si.cbSize = sizeof(si); - si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; - - SendMessage(EM_SHOWSCROLLBAR, SB_HORZ, TRUE); - VERIFY(::GetScrollInfo(GetHWnd(), SB_HORZ, &si)); - SendMessage(EM_SHOWSCROLLBAR, SB_HORZ, FALSE); - - if (bScrollLeft == TRUE) { - si.nPos = si.nPos - si.nPage / 2; - si.nPos = max(si.nMin, si.nPos); - } else if (bScrollRight == TRUE) { - si.nPos = si.nPos + si.nPage / 2; - si.nPos = min(si.nPos, si.nMax); - } - /* - * Okay to use 16-bit position since RichEdit control adjusts - * its scrollbars so that their range is always 16-bit. - */ - DASSERT(abs(si.nPos) < 0x8000); - SendMessage(WM_HSCROLL, - MAKEWPARAM(SB_THUMBPOSITION, LOWORD(si.nPos))); - } delete msg; return mrConsume; } else if (msg->message == WM_KEYDOWN) { diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp index f4240ee41ce..ca8a3deb321 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -80,6 +80,16 @@ extern jfieldID jawtPDataID; extern jfieldID jawtSDataID; extern jfieldID jawtSMgrID; +jobject reasonUnspecified; +jobject reasonConsole; +jobject reasonRemote; +jobject reasonLock; + +extern jobject GetStaticObject(JNIEnv *env, jclass wfClass, const char *fieldName, + const char *signature); + +extern BOOL isSuddenTerminationEnabled; + extern void DWMResetCompositionEnabled(); /************************************************************************ @@ -269,6 +279,9 @@ AwtToolkit AwtToolkit::theInstance; /* ids for WToolkit fields accessed from native code */ jmethodID AwtToolkit::windowsSettingChangeMID; jmethodID AwtToolkit::displayChangeMID; + +jmethodID AwtToolkit::userSessionMID; +jmethodID AwtToolkit::systemSleepMID; /* ids for Toolkit methods */ jmethodID AwtToolkit::getDefaultToolkitMID; jmethodID AwtToolkit::getFontMetricsMID; @@ -1046,6 +1059,9 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message, /* Session management */ case WM_QUERYENDSESSION: { /* Shut down cleanly */ + if (!isSuddenTerminationEnabled) { + return FALSE; + } if (JVM_RaiseSignal(SIGTERM)) { AwtToolkit::GetInstance().m_vmSignalled = TRUE; } @@ -1075,6 +1091,69 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message, DASSERT(FALSE); break; } +#ifndef WM_WTSSESSION_CHANGE +#define WM_WTSSESSION_CHANGE 0x02B1 +#define WTS_CONSOLE_CONNECT 0x1 +#define WTS_CONSOLE_DISCONNECT 0x2 +#define WTS_REMOTE_CONNECT 0x3 +#define WTS_REMOTE_DISCONNECT 0x4 +#define WTS_SESSION_LOGON 0x5 +#define WTS_SESSION_LOGOFF 0x6 +#define WTS_SESSION_LOCK 0x7 +#define WTS_SESSION_UNLOCK 0x8 +#define WTS_SESSION_REMOTE_CONTROL 0x9 +#endif // WM_WTSSESSION_CHANGE + case WM_WTSSESSION_CHANGE: { + jclass clzz = env->FindClass("sun/awt/windows/WDesktopPeer"); + DASSERT(clzz != NULL); + if (!clzz) throw std::bad_alloc(); + + if (wParam == WTS_CONSOLE_CONNECT + || wParam == WTS_CONSOLE_DISCONNECT + || wParam == WTS_REMOTE_CONNECT + || wParam == WTS_REMOTE_DISCONNECT + || wParam == WTS_SESSION_UNLOCK + || wParam == WTS_SESSION_LOCK) { + + BOOL activate = wParam == WTS_CONSOLE_CONNECT + || wParam == WTS_REMOTE_CONNECT + || wParam == WTS_SESSION_UNLOCK; + jobject reason = reasonUnspecified; + + switch (wParam) { + case WTS_CONSOLE_CONNECT: + case WTS_CONSOLE_DISCONNECT: + reason = reasonConsole; + break; + case WTS_REMOTE_CONNECT: + case WTS_REMOTE_DISCONNECT: + reason = reasonRemote; + break; + case WTS_SESSION_UNLOCK: + case WTS_SESSION_LOCK: + reason = reasonLock; + } + + env->CallStaticVoidMethod(clzz, AwtToolkit::userSessionMID, + activate + ? JNI_TRUE + : JNI_FALSE, reason); + } + break; + } + case WM_POWERBROADCAST: { + jclass clzz = env->FindClass("sun/awt/windows/WDesktopPeer"); + DASSERT(clzz != NULL); + if (!clzz) throw std::bad_alloc(); + + if (wParam == PBT_APMSUSPEND || wParam == PBT_APMRESUMEAUTOMATIC) { + env->CallStaticVoidMethod(clzz, AwtToolkit::systemSleepMID, + wParam == PBT_APMRESUMEAUTOMATIC + ? JNI_TRUE + : JNI_FALSE); + } + break; + } case WM_SYNC_WAIT: SetEvent(AwtToolkit::GetInstance().m_waitEvent); break; @@ -2133,6 +2212,45 @@ Java_sun_awt_windows_WToolkit_initIDs(JNIEnv *env, jclass cls) CHECK_NULL(jawtVImgClass); jawtComponentClass = (jclass)env->NewGlobalRef(componentClassLocal); + jclass dPeerClassLocal = env->FindClass("sun/awt/windows/WDesktopPeer"); + DASSERT(dPeerClassLocal != 0); + CHECK_NULL(dPeerClassLocal); + + jclass reasonClassLocal = env->FindClass("java/awt/desktop/UserSessionEvent$Reason"); + CHECK_NULL(reasonClassLocal); + + reasonUnspecified = GetStaticObject(env, reasonClassLocal, "UNSPECIFIED", + "Ljava/awt/desktop/UserSessionEvent$Reason;"); + CHECK_NULL (reasonUnspecified); + reasonUnspecified = env->NewGlobalRef(reasonUnspecified); + + reasonConsole = GetStaticObject(env, reasonClassLocal, "CONSOLE", + "Ljava/awt/desktop/UserSessionEvent$Reason;"); + CHECK_NULL (reasonConsole); + reasonConsole = env->NewGlobalRef(reasonConsole); + + reasonRemote = GetStaticObject(env, reasonClassLocal, "REMOTE", + "Ljava/awt/desktop/UserSessionEvent$Reason;"); + CHECK_NULL (reasonRemote); + reasonRemote = env->NewGlobalRef(reasonRemote); + + reasonLock = GetStaticObject(env, reasonClassLocal, "LOCK", + "Ljava/awt/desktop/UserSessionEvent$Reason;"); + CHECK_NULL (reasonLock); + reasonLock = env->NewGlobalRef(reasonLock); + + + AwtToolkit::userSessionMID = + env->GetStaticMethodID(dPeerClassLocal, "userSessionCallback", + "(ZLjava/awt/desktop/UserSessionEvent$Reason;)V"); + DASSERT(AwtToolkit::userSessionMID != 0); + CHECK_NULL(AwtToolkit::userSessionMID); + + AwtToolkit::systemSleepMID = + env->GetStaticMethodID(dPeerClassLocal, "systemSleepCallback", "(Z)V"); + DASSERT(AwtToolkit::systemSleepMID != 0); + CHECK_NULL(AwtToolkit::systemSleepMID); + CATCH_BAD_ALLOC; } diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h index 56b723211a6..254c89241d2 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -171,12 +171,15 @@ public: /* java.awt.Toolkit method ids */ static jmethodID getDefaultToolkitMID; static jmethodID getFontMetricsMID; - static jmethodID insetsMID; + static jmethodID insetsMID; /* sun.awt.windows.WToolkit ids */ static jmethodID windowsSettingChangeMID; static jmethodID displayChangeMID; + static jmethodID userSessionMID; + static jmethodID systemSleepMID; + BOOL m_isDynamicLayoutSet; AwtToolkit(); diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp index 95f1b73e930..970f061267c 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp @@ -51,10 +51,7 @@ #include "Devices.h" #include #pragma comment(lib, "d2d1") - -#ifndef MDT_Effective_DPI -#define MDT_Effective_DPI 0 -#endif +#include "systemScale.h" uns_ordered_dither_array img_oda_alpha; @@ -655,58 +652,9 @@ int AwtWin32GraphicsDevice::ScaleDownY(int y) void AwtWin32GraphicsDevice::InitDesktopScales() { - unsigned x = 0; - unsigned y = 0; float dpiX = -1.0f; float dpiY = -1.0f; - - // for debug purposes - static float scale = -2.0f; - if (scale == -2) { - scale = -1; - char *uiScale = getenv("J2D_UISCALE"); - if (uiScale != NULL) { - scale = (float)strtod(uiScale, NULL); - if (errno == ERANGE || scale <= 0) { - scale = -1; - } - } - } - - if (scale > 0) { - SetScale(scale, scale); - return; - } - - typedef HRESULT(WINAPI GetDpiForMonitorFunc)(HMONITOR, int, UINT*, UINT*); - static HMODULE hLibSHCoreDll = NULL; - static GetDpiForMonitorFunc *lpGetDpiForMonitor = NULL; - - if (hLibSHCoreDll == NULL) { - hLibSHCoreDll = JDK_LoadSystemLibrary("shcore.dll"); - if (hLibSHCoreDll != NULL) { - lpGetDpiForMonitor = (GetDpiForMonitorFunc*)GetProcAddress( - hLibSHCoreDll, "GetDpiForMonitor"); - } - } - - if (lpGetDpiForMonitor != NULL) { - HRESULT hResult = lpGetDpiForMonitor(GetMonitor(), - MDT_Effective_DPI, &x, &y); - if (hResult == S_OK) { - dpiX = static_cast(x); - dpiY = static_cast(y); - } - } else { - ID2D1Factory* m_pDirect2dFactory; - HRESULT res = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, - &m_pDirect2dFactory); - if (res == S_OK) { - m_pDirect2dFactory->GetDesktopDpi(&dpiX, &dpiY); - m_pDirect2dFactory->Release(); - } - } - + GetScreenDpi(GetMonitor(), &dpiX, &dpiY); if (dpiX > 0 && dpiY > 0) { SetScale(dpiX / 96, dpiY / 96); } @@ -1471,4 +1419,5 @@ Java_sun_awt_Win32GraphicsDevice_initNativeScale if (device != NULL) { device->InitDesktopScales(); } -} \ No newline at end of file +} + diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp index 8e066a3396b..6ca1641655d 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -1154,6 +1154,7 @@ BOOL AwtWindow::IsOneOfOwnersOf(AwtWindow * wnd) { void AwtWindow::InitOwner(AwtWindow *owner) { DASSERT(owner != NULL); + AwtWindow *initialOwner = owner; while (owner != NULL && owner->IsSimpleWindow()) { HWND ownerOwnerHWND = ::GetWindow(owner->GetHWnd(), GW_OWNER); @@ -1163,6 +1164,9 @@ void AwtWindow::InitOwner(AwtWindow *owner) } owner = (AwtWindow *)AwtComponent::GetComponent(ownerOwnerHWND); } + if (!owner) { + owner = initialOwner->GetOwningFrameOrDialog(); + } m_owningFrameDialog = (AwtFrame *)owner; } diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.h b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.h index c1ce65be4e4..9dd91a97423 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.h +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -398,4 +398,6 @@ public: inline bool IsAlwaysOnTop() { return m_alwaysOnTop; } }; +HICON CreateIconFromRaster(JNIEnv* env, jintArray iconRaster, jint w, jint h); + #endif /* AWT_WINDOW_H */ diff --git a/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_config.h b/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_config.h index df12ffc6455..1c8680d3fa6 100644 --- a/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_config.h +++ b/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_config.h @@ -41,6 +41,7 @@ #include #include #include +#include "systemScale.h" typedef DWORD rgbquad_t; typedef WORD word_t; @@ -56,5 +57,4 @@ typedef RECT RECT_T; #define SPLASHEXPORT __declspec(dllexport) - #endif diff --git a/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c b/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c index 3c1fe7f5091..89ee3f476fb 100644 --- a/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c +++ b/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c @@ -58,6 +58,8 @@ #define WM_SPLASHUPDATE WM_USER+1 #define WM_SPLASHRECONFIGURE WM_USER+2 +#define BUFF_SIZE 1024 + /* Could use npt but decided to cut down on linked code size */ char* SplashConvertStringAlloc(const char* in, int *size) { int len, outChars, rc; @@ -569,10 +571,66 @@ SplashReconfigure(Splash * splash) PostMessage(splash->hWnd, WM_SPLASHRECONFIGURE, 0, 0); } -SPLASHEXPORT char* +jboolean SplashGetScaledImageName(const char* jarName, const char* fileName, - float *scaleFactor) + float *scaleFactor, char *scaleImageName, + const size_t scaledImageLength) { - *scaleFactor = 1; - return NULL; + float dpiScaleX = -1.0f; + float dpiScaleY = -1.0f; + FILE *fp = NULL; + *scaleFactor = 1.0; + GetScreenDpi(getPrimaryMonitor(), &dpiScaleX, &dpiScaleY); + *scaleFactor = dpiScaleX > 0 ? dpiScaleX / 96 : *scaleFactor; + if (*scaleFactor > 1.0) { + char strDpi[BUFF_SIZE]; + char *dupFileName = strdup(fileName); + char *fileExtension = strrchr(dupFileName, '.'); + char *nameToAppend = ".scale-"; + size_t length = 0; + int retVal = 0; + _snprintf(strDpi, BUFF_SIZE, "%d", (int)dpiScaleX); + /*File is missing extension */ + if (fileExtension == NULL) { + length = strlen(dupFileName) + strlen(nameToAppend) + + strlen(strDpi) + 1; + if (length > scaledImageLength) { + *scaleFactor = 1; + free(dupFileName); + return JNI_FALSE; + } + retVal = _snprintf(scaleImageName, length, "%s%s%s", dupFileName, + nameToAppend, strDpi); + if (retVal < 0 || (retVal != length - 1)) { + *scaleFactor = 1; + free(dupFileName); + return JNI_FALSE; + } + } + else { + size_t length_Without_Ext = fileExtension - dupFileName; + length = length_Without_Ext + strlen(nameToAppend) + strlen(strDpi) + + strlen(fileExtension) + 1; + if (length > scaledImageLength) { + *scaleFactor = 1; + free(dupFileName); + return JNI_FALSE; + } + retVal = _snprintf(scaleImageName, length, "%.*s%s%s%s", + length_Without_Ext, dupFileName, nameToAppend, strDpi, fileExtension); + if (retVal < 0 || (retVal != length - 1)) { + *scaleFactor = 1; + free(dupFileName); + return JNI_FALSE; + } + } + free(dupFileName); + if (!(fp = fopen(scaleImageName, "r"))) { + *scaleFactor = 1; + return JNI_FALSE; + } + fclose(fp); + return JNI_TRUE; + } + return JNI_FALSE; } diff --git a/jdk/src/java.logging/share/classes/module-info.java b/jdk/src/java.logging/share/classes/module-info.java index 47456e5ef5b..0deda7677b5 100644 --- a/jdk/src/java.logging/share/classes/module-info.java +++ b/jdk/src/java.logging/share/classes/module-info.java @@ -24,6 +24,8 @@ */ module java.logging { + // 8153158 + requires jdk.unsupported; exports java.util.logging; provides jdk.internal.logger.DefaultLoggerFinder with sun.util.logging.internal.LoggingProviderImpl; diff --git a/jdk/src/java.management/share/classes/module-info.java b/jdk/src/java.management/share/classes/module-info.java index 8f7bd1b909e..811c2de91bd 100644 --- a/jdk/src/java.management/share/classes/module-info.java +++ b/jdk/src/java.management/share/classes/module-info.java @@ -27,6 +27,8 @@ module java.management { requires public java.rmi; requires java.logging; requires java.naming; + // 8147553 + requires jdk.unsupported; exports java.lang.management; exports javax.management; diff --git a/jdk/src/java.management/share/classes/sun/management/Agent.java b/jdk/src/java.management/share/classes/sun/management/Agent.java index 5582b428f87..be68601ce0e 100644 --- a/jdk/src/java.management/share/classes/sun/management/Agent.java +++ b/jdk/src/java.management/share/classes/sun/management/Agent.java @@ -52,7 +52,7 @@ import static sun.management.AgentConfigurationError.*; import sun.management.jmxremote.ConnectorBootstrap; import sun.management.jdp.JdpController; import sun.management.jdp.JdpException; -import sun.misc.VMSupport; +import jdk.internal.vm.VMSupport; /** * This Agent is started by the VM when -Dcom.sun.management.snmp or diff --git a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java index 0e44f735a97..5308478c9f9 100644 --- a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java +++ b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java @@ -2978,7 +2978,8 @@ final public class LdapCtx extends ComponentDirContext r = new LdapReferralException(resolvedName, resolvedObj, remainName, msg, envprops, fullDN, handleReferrals, reqCtls); // only one set of URLs is present - r.setReferralInfo(res.referrals.elementAt(0), false); + r.setReferralInfo(res.referrals == null ? null : + res.referrals.elementAt(0), false); if (hopCount > 1) { r.setHopCount(hopCount); @@ -3047,7 +3048,7 @@ final public class LdapCtx extends ComponentDirContext * assume name resolution has not yet completed. */ if (((res.entries == null) || (res.entries.isEmpty())) && - (res.referrals.size() == 1)) { + ((res.referrals != null) && (res.referrals.size() == 1))) { r.setReferralInfo(res.referrals, false); diff --git a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapReferralException.java b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapReferralException.java index 4b3e06d9285..62437c77657 100644 --- a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapReferralException.java +++ b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapReferralException.java @@ -217,13 +217,15 @@ final public class LdapReferralException extends System.out.println("LdapReferralException.setReferralInfo"); this.referrals = referrals; - if (referrals != null) { - referralCount = referrals.size(); - } + referralCount = (referrals == null) ? 0 : referrals.size(); if (debug) { - for (int i = 0; i < referralCount; i++) { - System.out.println(" [" + i + "] " + referrals.elementAt(i)); + if (referrals != null) { + for (int i = 0; i < referralCount; i++) { + System.out.println(" [" + i + "] " + referrals.elementAt(i)); + } + } else { + System.out.println("setReferralInfo : referrals == null"); } } } diff --git a/jdk/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java b/jdk/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java index eaa62e97e61..71fc403dd54 100644 --- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java +++ b/jdk/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java @@ -41,7 +41,6 @@ import java.rmi.dgc.DGC; import java.rmi.dgc.Lease; import java.rmi.dgc.VMID; import java.rmi.server.ObjID; -import sun.misc.GC; import sun.rmi.runtime.NewThreadAction; import sun.rmi.server.UnicastRef; import sun.rmi.server.Util; diff --git a/jdk/src/java.base/share/classes/sun/misc/GC.java b/jdk/src/java.rmi/share/classes/sun/rmi/transport/GC.java similarity index 97% rename from jdk/src/java.base/share/classes/sun/misc/GC.java rename to jdk/src/java.rmi/share/classes/sun/rmi/transport/GC.java index 084f41b506a..1708518c04c 100644 --- a/jdk/src/java.base/share/classes/sun/misc/GC.java +++ b/jdk/src/java.rmi/share/classes/sun/rmi/transport/GC.java @@ -23,7 +23,7 @@ * questions. */ -package sun.misc; +package sun.rmi.transport; import java.security.AccessController; import java.security.PrivilegedAction; @@ -38,7 +38,7 @@ import java.util.TreeSet; * @since 1.2 */ -public class GC { +class GC { private GC() { } /* To prevent instantiation */ @@ -82,6 +82,14 @@ public class GC { */ public static native long maxObjectInspectionAge(); + static { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + System.loadLibrary("rmi"); + return null; + }}); + } + private static class Daemon extends Thread { public void run() { diff --git a/jdk/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java b/jdk/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java index cdb13122ded..1f238c9e937 100644 --- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java +++ b/jdk/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java @@ -34,7 +34,6 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.util.HashMap; import java.util.Map; -import sun.misc.GC; import sun.rmi.runtime.Log; import sun.rmi.runtime.NewThreadAction; diff --git a/jdk/src/java.base/share/native/libjava/GC.c b/jdk/src/java.rmi/share/native/librmi/GC.c similarity index 92% rename from jdk/src/java.base/share/native/libjava/GC.c rename to jdk/src/java.rmi/share/native/librmi/GC.c index 48f732a14b7..820184bcf46 100644 --- a/jdk/src/java.base/share/native/libjava/GC.c +++ b/jdk/src/java.rmi/share/native/librmi/GC.c @@ -25,11 +25,11 @@ #include #include -#include "sun_misc_GC.h" +#include "sun_rmi_transport_GC.h" JNIEXPORT jlong JNICALL -Java_sun_misc_GC_maxObjectInspectionAge(JNIEnv *env, jclass cls) +Java_sun_rmi_transport_GC_maxObjectInspectionAge(JNIEnv *env, jclass cls) { return JVM_MaxObjectInspectionAge(); } diff --git a/jdk/src/java.se/share/classes/module-info.java b/jdk/src/java.se/share/classes/module-info.java index af159f4391b..73d5d05c093 100644 --- a/jdk/src/java.se/share/classes/module-info.java +++ b/jdk/src/java.se/share/classes/module-info.java @@ -27,4 +27,5 @@ module java.se { requires public java.compact3; requires public java.datatransfer; requires public java.desktop; + requires public java.httpclient; } diff --git a/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java b/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java index 5ab82f3aa2c..acd7323cd1b 100644 --- a/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java +++ b/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -1408,7 +1408,9 @@ final public class AccessBridge { s.indexOf(AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US)) == -1) { // Indicate whether this component manages its own // children - AccessibleRole role = ac.getAccessibleRole(); + AccessibleRole role = InvocationUtils.invokeAndWait(() -> { + return ac.getAccessibleRole(); + }, ac); if (role == AccessibleRole.LIST || role == AccessibleRole.TABLE || role == AccessibleRole.TREE) { @@ -1666,7 +1668,9 @@ final public class AccessBridge { */ private AccessibleComponent getAccessibleComponentFromContext(AccessibleContext ac) { if (ac != null) { - AccessibleComponent acmp = ac.getAccessibleComponent(); + AccessibleComponent acmp = InvocationUtils.invokeAndWait(() -> { + return ac.getAccessibleComponent(); + }, ac); if (acmp != null) { debugString("Returning AccessibleComponent Context"); return acmp; diff --git a/jdk/src/jdk.crypto.pkcs11/share/classes/module-info.java b/jdk/src/jdk.crypto.pkcs11/share/classes/module-info.java index e74bfdbc838..065b8d2f000 100644 --- a/jdk/src/jdk.crypto.pkcs11/share/classes/module-info.java +++ b/jdk/src/jdk.crypto.pkcs11/share/classes/module-info.java @@ -26,6 +26,8 @@ module jdk.crypto.pkcs11 { // Depends on SunEC provider for EC related functionality requires jdk.crypto.ec; + // 8153371 + requires jdk.unsupported; provides java.security.Provider with sun.security.pkcs11.SunPKCS11; } diff --git a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Key.java b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Key.java index f35d3fed959..2ecfd85186c 100644 --- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Key.java +++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Key.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -45,6 +45,7 @@ import sun.security.internal.interfaces.TlsMasterSecret; import sun.security.pkcs11.wrapper.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*; +import sun.security.util.Debug; import sun.security.util.DerValue; import sun.security.util.Length; import sun.security.util.ECUtil; @@ -1110,11 +1111,41 @@ final class SessionKeyRef extends PhantomReference } private static void drainRefQueueBounded() { + Session sess = null; + Token tkn = null; while (true) { SessionKeyRef next = (SessionKeyRef) refQueue.poll(); - if (next == null) break; + if (next == null) { + break; + } + + // If the token is still valid, try to remove the object + if (next.session.token.isValid()) { + // If this key's token is the same as the previous key, the + // same session can be used for C_DestroyObject. + try { + if (next.session.token != tkn || sess == null) { + // Release session if not using previous token + if (tkn != null && sess != null) { + tkn.releaseSession(sess); + sess = null; + } + + tkn = next.session.token; + sess = tkn.getOpSession(); + } + next.disposeNative(sess); + } catch (PKCS11Exception e) { + // ignore + } + } + // Regardless of native results, dispose of java references next.dispose(); } + + if (tkn != null && sess != null) { + tkn.releaseSession(sess); + } } // handle to the native key @@ -1127,25 +1158,17 @@ final class SessionKeyRef extends PhantomReference this.session = session; this.session.addObject(); refList.add(this); - // TBD: run at some interval and not every time? drainRefQueueBounded(); } + private void disposeNative(Session s) throws PKCS11Exception { + session.token.p11.C_DestroyObject(s.id(), keyID); + } + private void dispose() { refList.remove(this); - if (session.token.isValid()) { - Session newSession = null; - try { - newSession = session.token.getOpSession(); - session.token.p11.C_DestroyObject(newSession.id(), keyID); - } catch (PKCS11Exception e) { - // ignore - } finally { - this.clear(); - session.token.releaseSession(newSession); - session.removeObject(); - } - } + this.clear(); + session.removeObject(); } public int compareTo(SessionKeyRef other) { diff --git a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SessionManager.java b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SessionManager.java index 571f001cfac..6b2fdb19ef6 100644 --- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SessionManager.java +++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SessionManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -34,7 +34,7 @@ import sun.security.util.Debug; import sun.security.pkcs11.wrapper.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*; -import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicInteger; /** @@ -112,8 +112,8 @@ final class SessionManager { } maxSessions = (int)Math.min(n, Integer.MAX_VALUE); this.token = token; - this.objSessions = new Pool(this); - this.opSessions = new Pool(this); + this.objSessions = new Pool(this, true); + this.opSessions = new Pool(this, false); if (debug != null) { maxActiveSessionsLock = new Object(); } @@ -236,12 +236,18 @@ final class SessionManager { public static final class Pool { private final SessionManager mgr; + private final AbstractQueue pool; + private final int SESSION_MAX = 5; - private final ConcurrentLinkedDeque pool; - - Pool(SessionManager mgr) { - this.mgr = mgr; - pool = new ConcurrentLinkedDeque(); + // Object session pools can contain unlimited sessions. + // Operation session pools are limited and enforced by the queue. + Pool(SessionManager mgr, boolean obj) { + this.mgr = mgr; + if (obj) { + pool = new LinkedBlockingQueue(); + } else { + pool = new LinkedBlockingQueue(SESSION_MAX); + } } boolean remove(Session session) { @@ -249,24 +255,24 @@ final class SessionManager { } Session poll() { - return pool.pollLast(); + return pool.poll(); } void release(Session session) { - pool.offer(session); - if (session.hasObjects()) { - return; - } - - int n = pool.size(); - if (n < 5) { - return; + // Object session pools never return false, only Operation ones + if (!pool.offer(session)) { + mgr.closeSession(session); + free(); } + } + // Free any old operation session if this queue is full + void free() { + int n = SESSION_MAX; + int i = 0; Session oldestSession; long time = System.currentTimeMillis(); - int i = 0; - // Check if the session head is too old and continue through queue + // Check if the session head is too old and continue through pool // until only one is left. do { oldestSession = pool.peek(); diff --git a/jdk/src/jdk.httpserver/share/classes/module-info.java b/jdk/src/jdk.httpserver/share/classes/module-info.java index 395662831b0..e71e6a3f3c8 100644 --- a/jdk/src/jdk.httpserver/share/classes/module-info.java +++ b/jdk/src/jdk.httpserver/share/classes/module-info.java @@ -25,6 +25,8 @@ module jdk.httpserver { requires java.logging; + // 8153372 + requires jdk.unsupported; exports com.sun.net.httpserver; exports com.sun.net.httpserver.spi; uses com.sun.net.httpserver.spi.HttpServerProvider; diff --git a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/util.c b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/util.c index a870db14eda..dc428db0186 100644 --- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/util.c +++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/util.c @@ -257,9 +257,9 @@ util_initialize(JNIEnv *env) gdata->property_user_dir = getPropertyUTF8(env, "user.dir"); - /* Get agent properties: invoke sun.misc.VMSupport.getAgentProperties */ + /* Get agent properties: invoke VMSupport.getAgentProperties */ localVMSupportClass = JNI_FUNC_PTR(env,FindClass) - (env, "sun/misc/VMSupport"); + (env, "jdk/internal/vm/VMSupport"); if (localVMSupportClass == NULL) { gdata->agent_properties = NULL; if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) { @@ -276,7 +276,7 @@ util_initialize(JNIEnv *env) if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) { JNI_FUNC_PTR(env,ExceptionClear)(env); EXIT_ERROR(AGENT_ERROR_INTERNAL, - "Exception occurred calling sun.misc.VMSupport.getAgentProperties"); + "Exception occurred calling VMSupport.getAgentProperties"); } } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java index b373f85b935..4630d0992eb 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java @@ -41,12 +41,13 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.tools.jlink.plugin.TransformerPlugin; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.internal.ResourcePrevisitor; import jdk.tools.jlink.internal.StringTable; import jdk.tools.jlink.internal.Utils; +import jdk.tools.jlink.plugin.PluginException; +import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.Pool.ModuleDataType; +import jdk.tools.jlink.plugin.TransformerPlugin; /** * Plugin to explicitly specify the locale data included in jdk.localedata @@ -84,8 +85,8 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr private static final String METAINFONAME = "LocaleDataMetaInfo"; private static final String META_FILES = "*module-info.class," + - "*LocaleDataProvider*," + - "*" + METAINFONAME + "*,"; + "*LocaleDataProvider.class," + + "*" + METAINFONAME + ".class,"; private static final String INCLUDE_LOCALE_FILES = "*sun/text/resources/ext/[^\\/]+_%%.class," + "*sun/util/resources/ext/[^\\/]+_%%.class," + @@ -116,7 +117,8 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr if (resource.getModule().equals(MODULENAME)) { String path = resource.getPath(); resource = predicate.test(path) ? resource: null; - if (resource != null) { + if (resource != null && + resource.getType().equals(ModuleDataType.CLASS_OR_RESOURCE)) { byte[] bytes = resource.getBytes(); ClassReader cr = new ClassReader(bytes); if (Arrays.stream(cr.getInterfaces()) @@ -249,10 +251,10 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr files += INCLUDE_LOCALE_FILES.replaceAll("%%", isoSpecial + "_[0-9]{3}"); } - // Add Thai BreakIterator related files + // Add Thai BreakIterator related data files if (lang.equals("th")) { files += "*sun/text/resources/thai_dict," + - "*sun/text/resources/[^\\/]+_th,"; + "*sun/text/resources/[^\\/]+BreakIteratorData_th,"; } // Add Taiwan resource bundles for Hong Kong diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java index d7e839ef4fa..b5564ed99a7 100644 --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java @@ -27,6 +27,7 @@ package sun.jvmstat.perfdata.monitor.protocol.local; import java.io.File; import java.io.FilenameFilter; +import jdk.internal.vm.VMSupport; /** * Class to provide translations from the local Vm Identifier @@ -291,7 +292,7 @@ public class PerfDataFile { * the same directory. Instead of guessing which directory the * VM is using, we will ask. */ - String tmpdir = sun.misc.VMSupport.getVMTemporaryDirectory(); + String tmpdir = VMSupport.getVMTemporaryDirectory(); /* * Assure that the string returned has a trailing File.separator diff --git a/jdk/src/jdk.naming.dns/share/classes/module-info.java b/jdk/src/jdk.naming.dns/share/classes/module-info.java index 852291f782f..1d367eed0d0 100644 --- a/jdk/src/jdk.naming.dns/share/classes/module-info.java +++ b/jdk/src/jdk.naming.dns/share/classes/module-info.java @@ -31,7 +31,5 @@ module jdk.naming.dns { provides javax.naming.spi.InitialContextFactory with com.sun.jndi.dns.DnsContextFactory; - provides sun.net.spi.nameservice.NameServiceDescriptor - with sun.net.spi.nameservice.dns.DNSNameServiceDescriptor; } diff --git a/jdk/src/jdk.naming.dns/share/classes/sun/net/spi/nameservice/dns/DNSNameService.java b/jdk/src/jdk.naming.dns/share/classes/sun/net/spi/nameservice/dns/DNSNameService.java deleted file mode 100644 index 647ef007c2f..00000000000 --- a/jdk/src/jdk.naming.dns/share/classes/sun/net/spi/nameservice/dns/DNSNameService.java +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. - * 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.net.spi.nameservice.dns; - -import java.lang.ref.SoftReference; -import java.net.InetAddress; -import java.net.UnknownHostException; -import javax.naming.*; -import javax.naming.directory.*; -import javax.naming.spi.NamingManager; -import java.util.*; -import sun.net.util.IPAddressUtil; -import sun.net.dns.ResolverConfiguration; -import sun.net.spi.nameservice.*; -import java.security.AccessController; -import java.security.PrivilegedAction; - -/* - * A name service provider based on JNDI-DNS. - */ - -public final class DNSNameService implements NameService { - - // List of domains specified by property - private LinkedList domainList = null; - - // JNDI-DNS URL for name servers specified via property - private String nameProviderUrl = null; - - // Per-thread soft cache of the last temporary context - private static ThreadLocal> contextRef = - new ThreadLocal<>(); - - // Simple class to encapsulate the temporary context - private static class ThreadContext { - private DirContext dirCtxt; - private List nsList; - - public ThreadContext(DirContext dirCtxt, List nsList) { - this.dirCtxt = dirCtxt; - this.nsList = nsList; - } - - public DirContext dirContext() { - return dirCtxt; - } - - public List nameservers() { - return nsList; - } - } - - // Returns a per-thread DirContext - private DirContext getTemporaryContext() throws NamingException { - SoftReference ref = contextRef.get(); - ThreadContext thrCtxt = null; - List nsList = null; - - // if no property specified we need to obtain the list of servers - // - if (nameProviderUrl == null) - nsList = ResolverConfiguration.open().nameservers(); - - // if soft reference hasn't been gc'ed no property has been - // specified then we need to check if the DNS configuration - // has changed. - // - if ((ref != null) && ((thrCtxt = ref.get()) != null)) { - if (nameProviderUrl == null) { - if (!thrCtxt.nameservers().equals(nsList)) { - // DNS configuration has changed - thrCtxt = null; - } - } - } - - // new thread context needs to be created - if (thrCtxt == null) { - final Hashtable env = new Hashtable<>(); - env.put("java.naming.factory.initial", - "com.sun.jndi.dns.DnsContextFactory"); - - // If no nameservers property specified we create provider URL - // based on system configured name servers - // - String provUrl = nameProviderUrl; - if (provUrl == null) { - provUrl = createProviderURL(nsList); - if (provUrl.length() == 0) { - throw new RuntimeException("bad nameserver configuration"); - } - } - env.put("java.naming.provider.url", provUrl); - - // Need to create directory context in privileged block - // as JNDI-DNS needs to resolve the name servers. - // - DirContext dirCtxt; - try { - dirCtxt = java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public DirContext run() throws NamingException { - // Create the DNS context using NamingManager rather than using - // the initial context constructor. This avoids having the initial - // context constructor call itself. - Context ctx = NamingManager.getInitialContext(env); - if (!(ctx instanceof DirContext)) { - return null; // cannot create a DNS context - } - return (DirContext)ctx; - } - }); - } catch (java.security.PrivilegedActionException pae) { - throw (NamingException)pae.getException(); - } - - // create new soft reference to our thread context - // - thrCtxt = new ThreadContext(dirCtxt, nsList); - contextRef.set(new SoftReference(thrCtxt)); - } - - return thrCtxt.dirContext(); - } - - /** - * Resolves the specified entry in DNS. - * - * Canonical name records are recursively resolved (to a maximum - * of 5 to avoid performance hit and potential CNAME loops). - * - * @param ctx JNDI directory context - * @param name name to resolve - * @param ids record types to search - * @param depth call depth - pass as 0. - * - * @return array list with results (will have at least on entry) - * - * @throws UnknownHostException if lookup fails or other error. - */ - private ArrayList resolve(final DirContext ctx, final String name, - final String[] ids, int depth) - throws UnknownHostException - { - ArrayList results = new ArrayList<>(); - Attributes attrs; - - // do the query - try { - attrs = java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Attributes run() throws NamingException { - return ctx.getAttributes(name, ids); - } - }); - } catch (java.security.PrivilegedActionException pae) { - throw new UnknownHostException(pae.getException().getMessage()); - } - - // non-requested type returned so enumeration is empty - NamingEnumeration ne = attrs.getAll(); - if (!ne.hasMoreElements()) { - throw new UnknownHostException("DNS record not found"); - } - - // iterate through the returned attributes - UnknownHostException uhe = null; - try { - while (ne.hasMoreElements()) { - Attribute attr = ne.next(); - String attrID = attr.getID(); - - for (NamingEnumeration e = attr.getAll(); e.hasMoreElements();) { - String addr = (String)e.next(); - - // for canoncical name records do recursive lookup - // - also check for CNAME loops to avoid stack overflow - - if (attrID.equals("CNAME")) { - if (depth > 4) { - throw new UnknownHostException(name + ": possible CNAME loop"); - } - try { - results.addAll(resolve(ctx, addr, ids, depth+1)); - } catch (UnknownHostException x) { - // canonical name can't be resolved. - if (uhe == null) - uhe = x; - } - } else { - results.add(addr); - } - } - } - } catch (NamingException nx) { - throw new UnknownHostException(nx.getMessage()); - } - - // pending exception as canonical name could not be resolved. - if (results.isEmpty() && uhe != null) { - throw uhe; - } - - return results; - } - - public DNSNameService() throws Exception { - - // default domain - String domain = AccessController.doPrivileged( - (PrivilegedAction) () -> System.getProperty("sun.net.spi.nameservice.domain")); - if (domain != null && domain.length() > 0) { - domainList = new LinkedList(); - domainList.add(domain); - } - - // name servers - String nameservers = AccessController.doPrivileged( - (PrivilegedAction) () -> System.getProperty("sun.net.spi.nameservice.nameservers")); - if (nameservers != null && nameservers.length() > 0) { - nameProviderUrl = createProviderURL(nameservers); - if (nameProviderUrl.length() == 0) { - throw new RuntimeException("malformed nameservers property"); - } - - } else { - - // no property specified so check host DNS resolver configured - // with at least one nameserver in dotted notation. - // - List nsList = ResolverConfiguration.open().nameservers(); - if (nsList.isEmpty()) { - throw new RuntimeException("no nameservers provided"); - } - boolean found = false; - for (String addr: nsList) { - if (IPAddressUtil.isIPv4LiteralAddress(addr) || - IPAddressUtil.isIPv6LiteralAddress(addr)) { - found = true; - break; - } - } - if (!found) { - throw new RuntimeException("bad nameserver configuration"); - } - } - } - - public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException { - - // DNS records that we search for - String[] ids = {"A", "AAAA", "CNAME"}; - - // first get directory context - DirContext ctx; - try { - ctx = getTemporaryContext(); - } catch (NamingException nx) { - throw new Error(nx); - } - - ArrayList results = null; - UnknownHostException uhe = null; - - // If host already contains a domain name then just look it up - if (host.indexOf('.') >= 0) { - try { - results = resolve(ctx, host, ids, 0); - } catch (UnknownHostException x) { - uhe = x; - } - } - - // Here we try to resolve the host using the domain suffix or - // the domain suffix search list. If the host cannot be resolved - // using the domain suffix then we attempt devolution of - // the suffix - eg: if we are searching for "foo" and our - // domain suffix is "eng.sun.com" we will try to resolve - // "foo.eng.sun.com" and "foo.sun.com". - // It's not normal to attempt devolation with domains on the - // domain suffix search list - however as ResolverConfiguration - // doesn't distinguish domain or search list in the list it - // returns we approximate by doing devolution on the domain - // suffix if the list has one entry. - - if (results == null) { - List searchList = null; - Iterator i; - boolean usingSearchList = false; - - if (domainList != null) { - i = domainList.iterator(); - } else { - searchList = ResolverConfiguration.open().searchlist(); - if (searchList.size() > 1) { - usingSearchList = true; - } - i = searchList.iterator(); - } - - // iterator through each domain suffix - while (i.hasNext()) { - String parentDomain = i.next(); - int start = 0; - while ((start = parentDomain.indexOf('.')) != -1 - && start < parentDomain.length() -1) { - try { - results = resolve(ctx, host+"."+parentDomain, ids, 0); - break; - } catch (UnknownHostException x) { - uhe = x; - if (usingSearchList) { - break; - } - - // devolve - parentDomain = parentDomain.substring(start+1); - } - } - if (results != null) { - break; - } - } - } - - // finally try the host if it doesn't have a domain name - if (results == null && (host.indexOf('.') < 0)) { - results = resolve(ctx, host, ids, 0); - } - - // if not found then throw the (last) exception thrown. - if (results == null) { - assert uhe != null; - throw uhe; - } - - /** - * Convert the array list into a byte aray list - this - * filters out any invalid IPv4/IPv6 addresses. - */ - assert results.size() > 0; - InetAddress[] addrs = new InetAddress[results.size()]; - int count = 0; - for (int i=0; i results = null; - try { - ctx = getTemporaryContext(); - } catch (NamingException nx) { - throw new Error(nx); - } - if (addr.length == 4) { // IPv4 Address - for (int i = addr.length-1; i >= 0; i--) { - literalip += (addr[i] & 0xff) +"."; - } - literalip += "IN-ADDR.ARPA."; - - results = resolve(ctx, literalip, ids, 0); - host = results.get(0); - } else if (addr.length == 16) { // IPv6 Address - /** - * Because RFC 3152 changed the root domain name for reverse - * lookups from IP6.INT. to IP6.ARPA., we need to check - * both. I.E. first the new one, IP6.ARPA, then if it fails - * the older one, IP6.INT - */ - - for (int i = addr.length-1; i >= 0; i--) { - literalip += Integer.toHexString((addr[i] & 0x0f)) +"." - +Integer.toHexString((addr[i] & 0xf0) >> 4) +"."; - } - String ip6lit = literalip + "IP6.ARPA."; - - try { - results = resolve(ctx, ip6lit, ids, 0); - host = results.get(0); - } catch (UnknownHostException e) { - host = null; - } - if (host == null) { - // IP6.ARPA lookup failed, let's try the older IP6.INT - ip6lit = literalip + "IP6.INT."; - results = resolve(ctx, ip6lit, ids, 0); - host = results.get(0); - } - } - } catch (Exception e) { - throw new UnknownHostException(e.getMessage()); - } - // Either we couldn't find it or the address was neither IPv4 or IPv6 - if (host == null) - throw new UnknownHostException(); - // remove trailing dot - if (host.endsWith(".")) { - host = host.substring(0, host.length() - 1); - } - return host; - } - - - // --------- - - private static void appendIfLiteralAddress(String addr, StringBuilder sb) { - if (IPAddressUtil.isIPv4LiteralAddress(addr)) { - sb.append("dns://").append(addr).append(' '); - } else { - if (IPAddressUtil.isIPv6LiteralAddress(addr)) { - sb.append("dns://[").append(addr).append("] "); - } - } - } - - /* - * @return String containing the JNDI-DNS provider URL - * corresponding to the supplied List of nameservers. - */ - private static String createProviderURL(List nsList) { - StringBuilder sb = new StringBuilder(); - for (String s: nsList) { - appendIfLiteralAddress(s, sb); - } - return sb.toString(); - } - - /* - * @return String containing the JNDI-DNS provider URL - * corresponding to the list of nameservers - * contained in the provided str. - */ - private static String createProviderURL(String str) { - StringBuilder sb = new StringBuilder(); - StringTokenizer st = new StringTokenizer(str, ","); - while (st.hasMoreTokens()) { - appendIfLiteralAddress(st.nextToken(), sb); - } - return sb.toString(); - } -} diff --git a/jdk/src/jdk.pack200/share/native/common-unpack/defines.h b/jdk/src/jdk.pack200/share/native/common-unpack/defines.h index 3d98dd11466..8843bf4d2f1 100644 --- a/jdk/src/jdk.pack200/share/native/common-unpack/defines.h +++ b/jdk/src/jdk.pack200/share/native/common-unpack/defines.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -90,6 +90,12 @@ extern int assert_failed(const char*); #define U_NEW(T, n) (T*) u->alloc(scale_size(n, sizeof(T))) #define T_NEW(T, n) (T*) u->temp_alloc(scale_size(n, sizeof(T))) +// Dealing with big-endian arch +#ifdef _BIG_ENDIAN +#define SWAP_INT(a) (((a>>24)&0xff) | ((a<<8)&0xff0000) | ((a>>8)&0xff00) | ((a<<24)&0xff000000)) +#else +#define SWAP_INT(a) (a) +#endif // bytes and byte arrays diff --git a/jdk/src/jdk.pack200/share/native/common-unpack/unpack.h b/jdk/src/jdk.pack200/share/native/common-unpack/unpack.h index ba3b7d5ad69..0357ff457b1 100644 --- a/jdk/src/jdk.pack200/share/native/common-unpack/unpack.h +++ b/jdk/src/jdk.pack200/share/native/common-unpack/unpack.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -171,7 +171,6 @@ struct unpacker { bytes inbytes; // direct gunzip* gzin; // gunzip filter, if any jar* jarout; // output JAR file - uint gzcrc; // CRC gathered from gzip content #ifndef PRODUCT int nowrite; diff --git a/jdk/src/jdk.pack200/share/native/common-unpack/zip.cpp b/jdk/src/jdk.pack200/share/native/common-unpack/zip.cpp index a540ab42d3d..f64740e91e3 100644 --- a/jdk/src/jdk.pack200/share/native/common-unpack/zip.cpp +++ b/jdk/src/jdk.pack200/share/native/common-unpack/zip.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -341,6 +341,7 @@ void jar::write_central_directory() { void jar::openJarFile(const char* fname) { if (!jarfp) { PRINTCR((1, "jar::openJarFile: opening %s\n",fname)); + jarname = fname; jarfp = fopen(fname, "wb"); if (!jarfp) { fprintf(u->errstrm, "Error: Could not open jar file: %s\n",fname); @@ -551,7 +552,8 @@ static jlong read_input_via_gzip(unpacker* u, break; } int nr = readlen - zs.avail_out; - u->gzcrc = crc32(u->gzcrc, (const unsigned char *)bufptr, nr); + u->gzin->gzlen += nr; + u->gzin->gzcrc = crc32(u->gzin->gzcrc, (const unsigned char *)bufptr, nr); numread += nr; bufptr += nr; assert(numread <= maxlen); @@ -562,15 +564,44 @@ static jlong read_input_via_gzip(unpacker* u, zs.avail_in -= TRAILER_LEN; } else { // Bug: 5023768,we read past the TRAILER_LEN to see if there is - // any extraneous data, as we don't support concatenated .gz - // files just yet. + // any extraneous data, as we don't support concatenated .gz files. int extra = (int) read_gzin_fn(u, inbuf, 1, inbuflen); zs.avail_in += extra - TRAILER_LEN; } - // %%% should check final CRC and length here // %%% should check for concatenated *.gz files here if (zs.avail_in > 0) u->abort("garbage after end of deflated input stream"); + + // at this point we know there are no trailing bytes, + // we are safe to get the crc and len. + if (u->gzin->gzcrc != 0) { + // Read the CRC information from the gzip container + fseek(u->infileptr, -TRAILER_LEN, SEEK_END); + uint filecrc; + uint filelen; + fread(&filecrc, sizeof(filecrc), 1, u->infileptr); + fread(&filelen, sizeof(filelen), 1, u->infileptr); + filecrc = SWAP_INT(filecrc); + filelen = SWAP_INT(filelen); + if (u->gzin->gzcrc != filecrc || + // rfc1952; ISIZE is the input size modulo 2^32 + u->gzin->gzlen != (filelen & 0xffffffff)) { // CRC error + + PRINTCR((1, "crc: 0x%x 0x%x\n", u->gzin->gzcrc, filecrc)); + PRINTCR((1, "len: 0x%x 0x%x\n", u->gzin->gzlen, filelen)); + + if (u->jarout != null) { + // save the file name first, if any + const char* outfile = u->jarout->jarname; + u->jarout->closeJarFile(false); + if (outfile != null) { + remove(outfile); + } + } + // Print out the error and exit with return code != 0 + u->abort("CRC error, invalid compressed data."); + } + } // pop this filter off: u->gzin->free(); break; @@ -590,7 +621,8 @@ void gunzip::init(unpacker* u_) { zstream = NEW(z_stream, 1); u->gzin = this; u->read_input_fn = read_input_via_gzip; - u->gzcrc = crc32(0, Z_NULL, 0); + u->gzin->gzcrc = crc32(0, Z_NULL, 0); + u->gzin->gzlen = 0; } void gunzip::start(int magic) { diff --git a/jdk/src/jdk.pack200/share/native/common-unpack/zip.h b/jdk/src/jdk.pack200/share/native/common-unpack/zip.h index 9877f6f68ca..6581f3ca1d6 100644 --- a/jdk/src/jdk.pack200/share/native/common-unpack/zip.h +++ b/jdk/src/jdk.pack200/share/native/common-unpack/zip.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -34,6 +34,8 @@ struct jar { FILE* jarfp; int default_modtime; + const char* jarname; + // Used by unix2dostime: int modtime_cache; uLong dostime_cache; @@ -98,6 +100,9 @@ struct gunzip { void* zstream; // inflater state char inbuf[1 << 14]; // input buffer + uint gzcrc; // CRC gathered from gzip *container* content + uint gzlen; // CRC gathered length + void init(unpacker* u_); // pushes new value on u->read_input_fn void free(); diff --git a/jdk/src/jdk.pack200/share/native/unpack200/main.cpp b/jdk/src/jdk.pack200/share/native/unpack200/main.cpp index d03db583c38..558a1ce72c7 100644 --- a/jdk/src/jdk.pack200/share/native/unpack200/main.cpp +++ b/jdk/src/jdk.pack200/share/native/unpack200/main.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -62,13 +62,6 @@ int main(int argc, char **argv) { return unpacker::run(argc, argv); } -// Dealing with big-endian arch -#ifdef _BIG_ENDIAN -#define SWAP_INT(a) (((a>>24)&0xff) | ((a<<8)&0xff0000) | ((a>>8)&0xff00) | ((a<<24)&0xff000000)) -#else -#define SWAP_INT(a) (a) -#endif - // Single-threaded, implementation, not reentrant. // Includes a weak error check against MT access. #ifndef THREAD_SELF @@ -366,6 +359,7 @@ int unpacker::run(int argc, char **argv) { if (strcmp(destination_file, "-") == 0) { jarout.jarfp = stdout; + jarout.jarname = null; if (u.errstrm == stdout) // do not mix output u.set_option(UNPACK_LOG_FILE, LOGFILE_STDERR); } else { @@ -385,11 +379,12 @@ int unpacker::run(int argc, char **argv) { // Oops; must slap an input filter on this data. setup_gzin(&u); u.gzin->start(magic); + u.gzin->gzcrc = 0; + u.gzin->gzlen = 0; if (!u.aborting()) { u.start(); } } else { - u.gzcrc = 0; u.start(peek, sizeof(peek)); } @@ -422,31 +417,13 @@ int unpacker::run(int argc, char **argv) { u.start(peek, sizeof(peek)); } - - int status = 0; if (u.aborting()) { fprintf(u.errstrm, "Error: %s\n", u.get_abort_message()); status = 1; } - if (!u.aborting() && u.infileptr != null) { - if (u.gzcrc != 0) { - // Read the CRC information from the gzip container - fseek(u.infileptr, -8, SEEK_END); - uint filecrc; - fread(&filecrc, sizeof(filecrc), 1, u.infileptr); - if (u.gzcrc != SWAP_INT(filecrc)) { // CRC error - if (strcmp(destination_file, "-") != 0) { - // Output is not stdout, remove it, it's broken - if (u.jarout != null) - u.jarout->closeJarFile(false); - remove(destination_file); - } - // Print out the error and exit with return code != 0 - u.abort("CRC error, invalid compressed data."); - } - } + if (u.infileptr != null) { fclose(u.infileptr); u.infileptr = null; } diff --git a/jdk/src/java.base/share/classes/sun/net/spi/nameservice/NameService.java b/jdk/src/jdk.unsupported/share/classes/module-info.java similarity index 76% rename from jdk/src/java.base/share/classes/sun/net/spi/nameservice/NameService.java rename to jdk/src/jdk.unsupported/share/classes/module-info.java index 902ea874c7b..e83c5012b69 100644 --- a/jdk/src/java.base/share/classes/sun/net/spi/nameservice/NameService.java +++ b/jdk/src/jdk.unsupported/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,11 +23,8 @@ * questions. */ -package sun.net.spi.nameservice; - -import java.net.UnknownHostException; - -public interface NameService { - public java.net.InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException; - public String getHostByAddr(byte[] addr) throws UnknownHostException; +module jdk.unsupported { + exports sun.misc; + //exports sun.reflect; } + diff --git a/jdk/src/java.base/share/classes/sun/misc/ManagedLocalsThread.java b/jdk/src/jdk.unsupported/share/classes/sun/misc/ManagedLocalsThread.java similarity index 100% rename from jdk/src/java.base/share/classes/sun/misc/ManagedLocalsThread.java rename to jdk/src/jdk.unsupported/share/classes/sun/misc/ManagedLocalsThread.java diff --git a/jdk/src/java.base/share/classes/sun/misc/Signal.java b/jdk/src/jdk.unsupported/share/classes/sun/misc/Signal.java similarity index 100% rename from jdk/src/java.base/share/classes/sun/misc/Signal.java rename to jdk/src/jdk.unsupported/share/classes/sun/misc/Signal.java diff --git a/jdk/src/java.base/share/classes/sun/misc/SignalHandler.java b/jdk/src/jdk.unsupported/share/classes/sun/misc/SignalHandler.java similarity index 100% rename from jdk/src/java.base/share/classes/sun/misc/SignalHandler.java rename to jdk/src/jdk.unsupported/share/classes/sun/misc/SignalHandler.java diff --git a/jdk/src/java.base/share/classes/sun/misc/SoftCache.java b/jdk/src/jdk.unsupported/share/classes/sun/misc/SoftCache.java similarity index 100% rename from jdk/src/java.base/share/classes/sun/misc/SoftCache.java rename to jdk/src/jdk.unsupported/share/classes/sun/misc/SoftCache.java diff --git a/jdk/src/java.base/share/classes/sun/misc/Unsafe.java b/jdk/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java similarity index 99% rename from jdk/src/java.base/share/classes/sun/misc/Unsafe.java rename to jdk/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java index 15ba929c32f..c69b66020ab 100644 --- a/jdk/src/java.base/share/classes/sun/misc/Unsafe.java +++ b/jdk/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java @@ -1068,19 +1068,19 @@ public final class Unsafe { */ @ForceInline public void putOrderedObject(Object o, long offset, Object x) { - theInternalUnsafe.putOrderedObject(o, offset, x); + theInternalUnsafe.putObjectRelease(o, offset, x); } /** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)} */ @ForceInline public void putOrderedInt(Object o, long offset, int x) { - theInternalUnsafe.putOrderedInt(o, offset, x); + theInternalUnsafe.putIntRelease(o, offset, x); } /** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)} */ @ForceInline public void putOrderedLong(Object o, long offset, long x) { - theInternalUnsafe.putOrderedLong(o, offset, x); + theInternalUnsafe.putLongRelease(o, offset, x); } /** diff --git a/jdk/src/java.base/unix/classes/sun/misc/GThreadHelper.java b/jdk/src/jdk.unsupported/unix/classes/sun/misc/GThreadHelper.java similarity index 100% rename from jdk/src/java.base/unix/classes/sun/misc/GThreadHelper.java rename to jdk/src/jdk.unsupported/unix/classes/sun/misc/GThreadHelper.java diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 971a0b8b0aa..c0398b8d0ce 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -159,8 +159,6 @@ sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java 8147985 generic- # jdk_net -sun/net/InetAddress/nameservice/simple/CacheTest.java 7148829 generic-all -sun/net/InetAddress/nameservice/simple/DefaultCaching.java 7148829 generic-all java/net/MulticastSocket/NoLoopbackPackets.java 7122846 macosx-all java/net/MulticastSocket/SetLoopbackMode.java 7122846 macosx-all @@ -238,7 +236,7 @@ sun/security/pkcs11/MessageDigest/DigestKAT.java 8077138,8023434 sun/security/pkcs11/MessageDigest/ReinitDigest.java 8077138,8023434 windows-all sun/security/pkcs11/MessageDigest/TestCloning.java 8077138,8023434 windows-all sun/security/pkcs11/Provider/ConfigQuotedString.sh 8077138,8023434 windows-all -sun/security/pkcs11/Provider/Login.sh 8077138,8023434 windows-all +sun/security/pkcs11/Provider/Login.sh 8077138,8023434,8153545 windows-all,linux-all sun/security/pkcs11/SampleTest.java 8077138,8023434 windows-all sun/security/pkcs11/Secmod/AddPrivateKey.java 8077138,8023434 windows-all sun/security/pkcs11/Secmod/AddTrustedCert.java 8077138,8023434 windows-all @@ -282,11 +280,16 @@ sun/security/krb5/auto/HttpNegotiateServer.java 8038079 generic- sun/security/tools/keytool/autotest.sh 8130302 generic-all +sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java 8137255 generic-all + +sun/security/x509/URICertStore/ExtensionsWithLDAP.java 8134577 generic-all + ############################################################################ # jdk_sound javax/sound/midi/Gervill/SoftProvider/GetDevice.java 8059743 generic-all +javax/sound/sampled/DirectAudio/bug6400879.java 8148915 linux-all ############################################################################ @@ -307,6 +310,7 @@ javax/imageio/plugins/tiff/WriteToSequenceAfterAbort.java 8148454 generic- # jdk_time + ############################################################################ # jdk_tools @@ -315,8 +319,6 @@ tools/pack200/CommandLineTests.java 7143279,8059906 tools/pack200/Pack200Test.java 8059906,8151901 generic-all -tools/pack200/Pack200Props.java 8152622 macosx-all - tools/launcher/FXLauncherTest.java 8068049 linux-all,macosx-all ############################################################################ diff --git a/jdk/test/com/sun/jdi/cds/CDSBreakpointTest.java b/jdk/test/com/sun/jdi/cds/CDSBreakpointTest.java index cf597cc527d..0849a4feb80 100644 --- a/jdk/test/com/sun/jdi/cds/CDSBreakpointTest.java +++ b/jdk/test/com/sun/jdi/cds/CDSBreakpointTest.java @@ -26,7 +26,6 @@ * @bug 8054386 * @summary java debugging test for CDS * @modules jdk.jdi - * java.base/sun.misc * java.management * jdk.jartool/sun.tools.jar * @library /lib/testlibrary diff --git a/jdk/test/com/sun/jdi/cds/CDSDeleteAllBkptsTest.java b/jdk/test/com/sun/jdi/cds/CDSDeleteAllBkptsTest.java index 0bc2eb3b3fc..3dbb91bedf1 100644 --- a/jdk/test/com/sun/jdi/cds/CDSDeleteAllBkptsTest.java +++ b/jdk/test/com/sun/jdi/cds/CDSDeleteAllBkptsTest.java @@ -26,7 +26,6 @@ * @bug 8054386 * @summary java debugging test for CDS * @modules jdk.jdi - * java.base/sun.misc * java.management * jdk.jartool/sun.tools.jar * @library /lib/testlibrary diff --git a/jdk/test/com/sun/jdi/cds/CDSFieldWatchpoints.java b/jdk/test/com/sun/jdi/cds/CDSFieldWatchpoints.java index 1b5a5e44b95..e3d2ba4c80a 100644 --- a/jdk/test/com/sun/jdi/cds/CDSFieldWatchpoints.java +++ b/jdk/test/com/sun/jdi/cds/CDSFieldWatchpoints.java @@ -26,7 +26,6 @@ * @bug 8054386 * @summary java debugging test for CDS * @modules jdk.jdi - * java.base/sun.misc * java.management * jdk.jartool/sun.tools.jar * @library /lib/testlibrary diff --git a/jdk/test/java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.html b/jdk/test/java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.html deleted file mode 100644 index 7aeced5cfc3..00000000000 --- a/jdk/test/java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - -MouseClickRequestFocusRaceTest - - - -

      MouseClickRequestFocusRaceTest
      Bug ID: 5028014

      - -

      See the dialog box (usually in upper left corner) for instructions

      - - - - diff --git a/jdk/test/java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.java b/jdk/test/java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.java index f3a9d8f61ee..c5abf9c0712 100644 --- a/jdk/test/java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.java +++ b/jdk/test/java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -21,57 +21,59 @@ * questions. */ -/* - test - @bug 5028014 - @summary Focus request & mouse click performed nearly synchronously shouldn't lead to a focus race. - @author anton.tarasov@sun.com: area=awt-focus - @run applet MouseClickRequestFocusRaceTest.html -*/ +import java.awt.AWTException; +import java.awt.FlowLayout; +import java.awt.KeyboardFocusManager; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; -import java.awt.*; -import javax.swing.*; -import java.awt.event.*; -import java.applet.Applet; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.WindowConstants; -public class MouseClickRequestFocusRaceTest extends Applet { - Robot robot; - JFrame frame1 = new JFrame("Frame-1") { +import jdk.testlibrary.OSInfo; + +/** + * @test + * @bug 5028014 + * @summary Focus request & mouse click being performed nearly synchronously + * shouldn't break the focus subsystem + * @author anton.tarasov@sun.com: area=awt-focus + * @library ../../../../lib/testlibrary + * @build jdk.testlibrary.OSInfo + * @run main MouseClickRequestFocusRaceTest + */ +public class MouseClickRequestFocusRaceTest { + static Robot robot; + static JFrame frame1 = new JFrame("Frame-1") { public String toString() { return "Frame-1";} }; - JFrame frame2 = new JFrame("Frame-2") { + static JFrame frame2 = new JFrame("Frame-2") { public String toString() { return "Frame-2";} }; - JButton button1 = new JButton("button-1") { + static JButton button1 = new JButton("button-1") { public String toString() { return "button-1";} }; - JButton button2 = new JButton("button-2") { + static JButton button2 = new JButton("button-2") { public String toString() { return "button-2";} }; - JPopupMenu popup = new JPopupMenu(); + static JPopupMenu popup = new JPopupMenu(); public static void main(String[] args) { - MouseClickRequestFocusRaceTest app = new MouseClickRequestFocusRaceTest(); - app.init(); - app.start(); - } - - public void init() { try { robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(100); } catch (AWTException e) { throw new RuntimeException("Error: unable to create robot", e); } - // Create instructions for the user here, as well as set up - // the environment -- set the layout manager, add buttons, - // etc. - this.setLayout (new BorderLayout ()); - Sysout.createDialogWithInstructions(new String[] - {"Automatic test. Simply wait until it is done." - }); - } - - public void start() { frame1.add(button1); frame2.add(button2); frame1.setBounds(0, 0, 200, 300); @@ -110,198 +112,64 @@ public class MouseClickRequestFocusRaceTest extends Applet { frame1.setVisible(true); frame2.setVisible(true); -// ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); - robot.delay(1000); - test(); + robot.delay(1000); + try { + test(); + } finally { + frame1.dispose(); + frame2.dispose(); + } } - public void test() { + public static void test() { // Right click Frame-1 robot.mouseMove(frame1.getLocation().x + 100, frame1.getLocation().y + 200); robot.mousePress(InputEvent.BUTTON3_MASK); - robot.delay(100); robot.mouseRelease(InputEvent.BUTTON3_MASK); -// ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); robot.delay(1000); // Left click Frame-2 robot.mouseMove(frame2.getLocation().x + 100, frame1.getLocation().y + 200); robot.mousePress(InputEvent.BUTTON1_MASK); - robot.delay(100); robot.mouseRelease(InputEvent.BUTTON1_MASK); -// ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); robot.delay(1000); JComponent focusOwner = (JComponent)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); JFrame focusedWindow = (JFrame)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow(); - Sysout.println("focus owner: " + focusOwner); - Sysout.println("focused window: " + focusedWindow); + System.out.println("focus owner: " + focusOwner); + System.out.println("focused window: " + focusedWindow); // Verify that the focused window is the ancestor of the focus owner if (!focusedWindow.isAncestorOf(focusOwner)) { - throw new TestFailedException("The focus owner is not in the focused window!"); + throw new RuntimeException("The focus owner is not in the focused window!"); } - // Try to close native focused window - robot.keyPress(KeyEvent.VK_ALT); - robot.keyPress(KeyEvent.VK_F4); - robot.keyRelease(KeyEvent.VK_F4); - robot.keyRelease(KeyEvent.VK_ALT); - -// ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); - robot.delay(1000); - - // Verify that the Java focused window really mapped the native focused window. - if (focusedWindow.isVisible()) { - throw new TestFailedException("The focused window is different on Java and on the native level."); - } - } - - class TestFailedException extends RuntimeException { - public TestFailedException(String cause) { - super("Test failed."); - Sysout.println(cause); + if (!OSInfo.getOSType().equals(OSInfo.OSType.MACOSX)) { + // Try to close native focused window + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_F4); + robot.keyRelease(KeyEvent.VK_F4); + robot.keyRelease(KeyEvent.VK_ALT); + robot.delay(1000); + // Verify that the Java focused window really mapped the native focused window. + if (focusedWindow.isVisible()) { + throw new RuntimeException("The focused window is different on Java and on the native level."); + } + } else { + // Try to move native focus to previous window + robot.keyPress(KeyEvent.VK_CONTROL); + robot.keyPress(KeyEvent.VK_F4); + robot.keyRelease(KeyEvent.VK_F4); + robot.keyRelease(KeyEvent.VK_CONTROL); + robot.delay(1000); + // Verify that the Java focused window really mapped the native focused window. + if (focusedWindow.isFocused()) { + throw new RuntimeException("The focused window is different on Java and on the native level."); + } } } } - -/**************************************************** - Standard Test Machinery - DO NOT modify anything below -- it's a standard - chunk of code whose purpose is to make user - interaction uniform, and thereby make it simpler - to read and understand someone else's test. - ****************************************************/ - -/** - This is part of the standard test machinery. - It creates a dialog (with the instructions), and is the interface - for sending text messages to the user. - To print the instructions, send an array of strings to Sysout.createDialog - WithInstructions method. Put one line of instructions per array entry. - To display a message for the tester to see, simply call Sysout.println - with the string to be displayed. - This mimics System.out.println but works within the test harness as well - as standalone. - */ - -class Sysout -{ - static TestDialog dialog; - - public static void createDialogWithInstructions( String[] instructions ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - dialog.printInstructions( instructions ); -// dialog.setVisible(true); - println( "Any messages for the tester will display here." ); - } - - public static void createDialog( ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - String[] defInstr = { "Instructions will appear here. ", "" } ; - dialog.printInstructions( defInstr ); -// dialog.setVisible(true); - println( "Any messages for the tester will display here." ); - } - - - public static void printInstructions( String[] instructions ) - { - dialog.printInstructions( instructions ); - } - - - public static void println( String messageIn ) - { - dialog.displayMessage( messageIn ); - } - -}// Sysout class - -/** - This is part of the standard test machinery. It provides a place for the - test instructions to be displayed, and a place for interactive messages - to the user to be displayed. - To have the test instructions displayed, see Sysout. - To have a message to the user be displayed, see Sysout. - Do not call anything in this dialog directly. - */ -class TestDialog extends Dialog -{ - - TextArea instructionsText; - TextArea messageText; - int maxStringLength = 80; - - //DO NOT call this directly, go through Sysout - public TestDialog( Frame frame, String name ) - { - super( frame, name ); - int scrollBoth = TextArea.SCROLLBARS_BOTH; - instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); - add( "North", instructionsText ); - - messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); - add("Center", messageText); - - pack(); - -// setVisible(true); - }// TestDialog() - - //DO NOT call this directly, go through Sysout - public void printInstructions( String[] instructions ) - { - //Clear out any current instructions - instructionsText.setText( "" ); - - //Go down array of instruction strings - - String printStr, remainingStr; - for( int i=0; i < instructions.length; i++ ) - { - //chop up each into pieces maxSringLength long - remainingStr = instructions[ i ]; - while( remainingStr.length() > 0 ) - { - //if longer than max then chop off first max chars to print - if( remainingStr.length() >= maxStringLength ) - { - //Try to chop on a word boundary - int posOfSpace = remainingStr. - lastIndexOf( ' ', maxStringLength - 1 ); - - if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; - - printStr = remainingStr.substring( 0, posOfSpace + 1 ); - remainingStr = remainingStr.substring( posOfSpace + 1 ); - } - //else just print - else - { - printStr = remainingStr; - remainingStr = ""; - } - - instructionsText.append( printStr + "\n" ); - - }// while - - }// for - - }//printInstructions() - - //DO NOT call this directly, go through Sysout - public void displayMessage( String messageIn ) - { - messageText.append( messageIn + "\n" ); - System.out.println(messageIn); - } - -}// TestDialog class diff --git a/jdk/test/java/awt/FontClass/CreateFont/BigFont.java b/jdk/test/java/awt/FontClass/CreateFont/BigFont.java index fb765bd7656..ddcf8fc1b0b 100644 --- a/jdk/test/java/awt/FontClass/CreateFont/BigFont.java +++ b/jdk/test/java/awt/FontClass/CreateFont/BigFont.java @@ -60,12 +60,16 @@ public class BigFont extends Applet { System.out.println("Applet " + id + " "+ Thread.currentThread().getThreadGroup()); + if (System.getSecurityManager() == null) { + System.setSecurityManager(new SecurityManager()); + } // Larger than size for a single font. int fontSize = 64 * 1000 * 1000; SizedInputStream sis = new SizedInputStream(fontSize); try { Font font = Font.createFont(Font.TRUETYPE_FONT, sis); } catch (Throwable t) { + t.printStackTrace(); if (t instanceof FontFormatException || fontSize <= sis.getCurrentSize()) { diff --git a/jdk/test/java/awt/FontClass/CreateFont/CreateFontArrayTest.java b/jdk/test/java/awt/FontClass/CreateFont/CreateFontArrayTest.java new file mode 100644 index 00000000000..d68b2e4409f --- /dev/null +++ b/jdk/test/java/awt/FontClass/CreateFont/CreateFontArrayTest.java @@ -0,0 +1,181 @@ +/* + * Copyright (c) 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 + * @bug 8055463 + * @summary Test createFont APIs + * @run CreateFontArrayTest + */ + +import java.awt.Font; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +/* + * This test pokes around in platform folders/directories to try + * to find some fonts with which to test. It will do different things + * on different platforms and may not do anything at all if the platform + * directories aren't where it expects. For example if /usr/share/fonts + * is not used on a particular Linux distro or on Windows the fonts are + * not in c:\windows\fonts (which would be the right place on 99.99% of + * systems you will find today. + * It ought to be very reliable but it is not 100% guaranteed. + * Failure to find fonts to test is 'not a product bug'. + * Fonts on a system having different content than we expect based on + * file extension is also 'not a product bug'. + * The former will cause silent success, the latter may cause 'noisy' failure + * and the test would then need to be dialled back to be more cautious. + */ + +public class CreateFontArrayTest { + + public static void main(String[] args) throws Exception { + test(".ttc", 2, -1, true); + test(".ttf", 1, 1, true); + test(".otf", 1, 1, true); + test(".pfa", 0, 0, false); + test(".pfb", 0, 0, false); + } + + static File getPlatformFontFolder(String ext) throws Exception { + boolean recurse = false; + String folder = null; + String os = System.getProperty("os.name"); + if (os.startsWith("Win")) { + folder = "c:\\windows\\fonts"; + } else if (os.startsWith("Linux")) { + folder = "/usr/share/fonts"; + recurse = true; // need to dig to find fonts. + } else if (os.startsWith("Mac")) { + // Disabled until createFont can handle mac font names. + //folder = "/Library/Fonts"; + } + if (folder == null) { + return null; + } + File dir = new File(folder); + if (!dir.exists() || !dir.isDirectory()) { + return null; + } + // Have a root. + if (!recurse) { + return dir; + } + + // If "recurse" is set, try to find a sub-folder which contains + // fonts with the specified extension + return findSubFolder(dir, ext); + } + + static File findSubFolder(File folder, String ext) { + File[] files = + folder.listFiles(f -> f.getName().toLowerCase().endsWith(ext)); + if (files != null && files.length > 0) { + return folder; + } + File[] subdirs = folder.listFiles(f -> f.isDirectory()); + for (File f : subdirs) { + File subfolder = findSubFolder(f, ext); + if (subfolder != null) { + return subfolder; + } + } + return null; + } + + static void test(String ext, int min, int max, + boolean expectSuccess ) throws Exception { + + File dir = getPlatformFontFolder(ext); + if (dir == null) { + System.out.println("No folder to test for " + ext); + return; + } + File[] files = + dir.listFiles(f -> f.getName().toLowerCase().endsWith(ext)); + if (files == null || files.length == 0) { + System.out.println("No files to test for " + ext); + return; + } + System.out.println("Create from file " + files[0]); + Font[] fonts = null; + try { + fonts = Font.createFonts(files[0]); + System.out.println("createFont from file returned " + fonts); + } catch (Exception e) { + if (expectSuccess) { + throw new RuntimeException("Unexpected exception", e); + } else { + System.out.println("Got expected exception " + e); + return; + } + } + for (Font f : fonts) { + System.out.println(ext + " component : " + f); + } + if (fonts.length < min) { + throw new RuntimeException("Expected at least " + min + + " but got " + fonts.length); + } + if (max > 0 && fonts.length > max) { + throw new RuntimeException("Expected no more than " + max + + " but got " + fonts.length); + } + FileInputStream fis = null; + try { + System.out.println("Create from stream " + files[0]); + fis = new FileInputStream(files[0]); + InputStream s = new BufferedInputStream(fis); + fonts = null; + try { + fonts = Font.createFonts(s); + System.out.println("createFont from stream returned " + fonts); + } catch (Exception e) { + if (expectSuccess) { + throw new RuntimeException("Unexpected exception", e); + } else { + System.out.println("Got expected exception " + e); + return; + } + } + for (Font f : fonts) { + System.out.println(ext + " component : " + f); + } + if (fonts.length < min) { + throw new RuntimeException("Expected at least " + min + + " but got " + fonts.length); + } + if (max > 0 && fonts.length > max) { + throw new RuntimeException("Expected no more than " + max + + " but got " + fonts.length); + } + } finally { + if (fis != null) { + fis.close(); + } + } + } +} diff --git a/jdk/test/java/awt/Graphics/CopyScaledArea/CopyScaledAreaTest.java b/jdk/test/java/awt/Graphics/CopyScaledArea/CopyScaledAreaTest.java new file mode 100644 index 00000000000..92d8540787c --- /dev/null +++ b/jdk/test/java/awt/Graphics/CopyScaledArea/CopyScaledAreaTest.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 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. + */ + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; +import static sun.awt.OSInfo.*; + +/** + * @test + * @bug 8069348 + * @summary SunGraphics2D.copyArea() does not properly work for scaled graphics + * @modules java.desktop/sun.awt + * @run main/othervm -Dsun.java2d.uiScale=2 CopyScaledAreaTest + * @run main/othervm -Dsun.java2d.opengl=true -Dsun.java2d.uiScale=2 CopyScaledAreaTest + * @run main/othervm -Dsun.java2d.d3d=true -Dsun.java2d.uiScale=2 CopyScaledAreaTest + * @run main/othervm -Dsun.java2d.d3d=false -Dsun.java2d.opengl=false + * -Dsun.java2d.uiScale=2 CopyScaledAreaTest + */ +public class CopyScaledAreaTest { + + private static final int IMAGE_WIDTH = 800; + private static final int IMAGE_HEIGHT = 800; + private static final int X = 50; + private static final int Y = 50; + private static final int W = 100; + private static final int H = 75; + private static final int DX = 15; + private static final int DY = 10; + private static final int N = 3; + private static final Color BACKGROUND_COLOR = Color.YELLOW; + private static final Color FILL_COLOR = Color.ORANGE; + private static final double[][] SCALES = {{1.3, 1.4}, {0.3, 2.3}, {2.7, 0.1}}; + + private static boolean isSupported() { + String d3d = System.getProperty("sun.java2d.d3d"); + return !Boolean.getBoolean(d3d) || getOSType() == OSType.WINDOWS; + } + + private static int scale(int x, double scale) { + return (int) Math.floor(x * scale); + } + + private static VolatileImage createVolatileImage(GraphicsConfiguration conf) { + return conf.createCompatibleVolatileImage(IMAGE_WIDTH, IMAGE_HEIGHT); + } + + // rendering to the image + private static void renderOffscreen(VolatileImage vImg, + GraphicsConfiguration conf, + double scaleX, + double scaleY) + { + int attempts = 0; + do { + + if (attempts > 10) { + throw new RuntimeException("Too many attempts!"); + } + + if (vImg.validate(conf) == VolatileImage.IMAGE_INCOMPATIBLE) { + // old vImg doesn't work with new GraphicsConfig; re-create it + vImg = createVolatileImage(conf); + } + Graphics2D g = vImg.createGraphics(); + // + // miscellaneous rendering commands... + // + g.setColor(BACKGROUND_COLOR); + g.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT); + g.scale(scaleX, scaleY); + + g.setColor(FILL_COLOR); + g.fillRect(X, Y, W, H); + + for (int i = 0; i < N; i++) { + g.copyArea(X + i * DX, Y + i * DY, W, H, DX, DY); + } + g.dispose(); + attempts++; + } while (vImg.contentsLost()); + } + + public static void main(String[] args) throws Exception { + + if (!isSupported()) { + return; + } + + GraphicsConfiguration graphicsConfiguration = + GraphicsEnvironment.getLocalGraphicsEnvironment() + .getDefaultScreenDevice().getDefaultConfiguration(); + + for(double[] scales: SCALES){ + testScale(scales[0], scales[1], graphicsConfiguration); + } + } + + private static void testScale(double scaleX, double scaleY, + GraphicsConfiguration gc) throws Exception + { + + BufferedImage buffImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, + BufferedImage.TYPE_INT_RGB); + Graphics g = buffImage.createGraphics(); + + VolatileImage vImg = createVolatileImage(gc); + + int attempts = 0; + do { + + if (attempts > 10) { + throw new RuntimeException("Too many attempts!"); + } + + int returnCode = vImg.validate(gc); + if (returnCode == VolatileImage.IMAGE_RESTORED) { + // Contents need to be restored + renderOffscreen(vImg, gc, scaleX, scaleY); // restore contents + } else if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) { + // old vImg doesn't work with new GraphicsConfig; re-create it + vImg = createVolatileImage(gc); + renderOffscreen(vImg, gc, scaleX, scaleY); + } + g.drawImage(vImg, 0, 0, null); + attempts++; + } while (vImg.contentsLost()); + + g.dispose(); + + int x = scale(X + N * DX, scaleX) + 1; + int y = scale(Y + N * DY, scaleY) + 1; + int w = scale(W, scaleX) - 2; + int h = scale(H, scaleY) - 2; + + for (int i = x; i < x + w; i++) { + for (int j = y; j < y + h; j++) { + if (buffImage.getRGB(i, j) != FILL_COLOR.getRGB()) { + throw new RuntimeException("Wrong rectangle color!"); + } + } + } + } +} diff --git a/jdk/test/java/awt/Mixing/AWT_Mixing/ViewportOverlapping.java b/jdk/test/java/awt/Mixing/AWT_Mixing/ViewportOverlapping.java index 2cfb251a6af..17e6c55c4ce 100644 --- a/jdk/test/java/awt/Mixing/AWT_Mixing/ViewportOverlapping.java +++ b/jdk/test/java/awt/Mixing/AWT_Mixing/ViewportOverlapping.java @@ -50,9 +50,10 @@ import test.java.awt.regtesthelpers.Util; @bug 6778882 @summary Viewport overlapping test for each AWT component @author sergey.grinev@oracle.com: area=awt.mixing -@library ../../regtesthelpers +@library /java/awt/patchlib ../../regtesthelpers @modules java.desktop/sun.awt java.desktop/java.awt.peer +@build java.desktop/java.awt.Helper @build Util @run main ViewportOverlapping */ diff --git a/jdk/test/java/awt/MouseInfo/PointerInfoCrashTest.java b/jdk/test/java/awt/MouseInfo/PointerInfoCrashTest.java index 8386b40621b..8221bb80e7b 100644 --- a/jdk/test/java/awt/MouseInfo/PointerInfoCrashTest.java +++ b/jdk/test/java/awt/MouseInfo/PointerInfoCrashTest.java @@ -32,7 +32,7 @@ import sun.awt.ComponentFactory; * @test * @bug 8143316 * @modules java.desktop/java.awt.peer - * java.desktop/sun.awt.peer + * java.desktop/sun.awt * @summary Crash Trend in 1.9.0-ea-b93 (sun.awt.DefaultMouseInfoPeer.fillPointWithCoords) */ public class PointerInfoCrashTest { diff --git a/jdk/test/java/awt/PrintJob/HighResTest.java b/jdk/test/java/awt/PrintJob/HighResTest.java new file mode 100644 index 00000000000..e802214fdaf --- /dev/null +++ b/jdk/test/java/awt/PrintJob/HighResTest.java @@ -0,0 +1,412 @@ +/* + * Copyright (c) 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 + @bug 4227128 8066139 + @summary Test printing at resolutions > 72dpi + @author dpm: area=awt.print + @run main/manual HighResTest + */ +import java.awt.Button; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.JobAttributes; +import java.awt.PageAttributes; +import java.awt.PrintJob; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.JobAttributes.DialogType; +import java.awt.JobAttributes.SidesType; +import java.awt.PageAttributes.OrientationRequestedType; +import java.awt.PageAttributes.OriginType; +import java.awt.Dialog; +import java.awt.Panel; +import java.awt.TextArea; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class HighResTest { + static Frame f = new Frame(); + + private static void init() { + String[] instructions = { + "To be able to run this test it is required to have a default", + "printer configured in your user environment.", + "If no default printer exists, then test passes.", + " ", + "There will be 2 print dialogs. The first dialog should show", + "portrait as the selected orientation. The 2nd dialog should show", + "landscape as the selected orientation.", + " ", + "Visual inspection of the printed pages is needed. A passing", + "test will print 2 pages in portrait and 2 pages in landscape.", + "The pages have on the center of the page the text \"Center\"", + "2 rectangles will appear above and below it, the one below is", + "filled." + }; + Sysout.createDialog(); + Sysout.printInstructions(instructions); + + PrintJob job = null; + Dimension dim = null; + JobAttributes jobAttributes = new JobAttributes(); + PageAttributes pageAttributes = new PageAttributes(); + String center = "Center"; + Font font = new Font("SansSerif", Font.PLAIN, 200); + FontMetrics metrics = null; + int width = 0; + Graphics g = null; + + jobAttributes.setDialog(DialogType.NATIVE); + pageAttributes.setOrigin(OriginType.PRINTABLE); + pageAttributes.setPrinterResolution(new int[]{1200, 1200, 3}); + pageAttributes.setOrientationRequested( + OrientationRequestedType.PORTRAIT); + jobAttributes.setSides(SidesType.TWO_SIDED_LONG_EDGE); + + job = f.getToolkit().getPrintJob(f, "Portrait Test", jobAttributes, + pageAttributes); + if (job != null) { + dim = job.getPageDimension(); + for (int i = 0; i < 2; i++) { + g = job.getGraphics(); + + g.drawLine(0, 0, dim.width, 0); + g.drawLine(dim.width, 0, dim.width, dim.height); + g.drawLine(dim.width, dim.height, 0, dim.height); + g.drawLine(0, dim.height, 0, 0); + + g.drawRect(dim.width / 2 - 200, dim.height / 3 - 300, 400, 600); + g.fillRect(dim.width / 2 - 200, 2 * dim.height / 3 - 300, 400, 600); + + g.setFont(font); + metrics = g.getFontMetrics(); + width = metrics.stringWidth(center); + g.setColor(Color.black); + g.drawString(center, (dim.width / 2) - (width / 2), dim.height / 2); + + g.dispose(); + } + job.end(); + job = null; + } + + pageAttributes.setOrientationRequested( + OrientationRequestedType.LANDSCAPE); + + job = f.getToolkit().getPrintJob(f, "Landscape Test", jobAttributes, + pageAttributes); + if (job != null) { + dim = job.getPageDimension(); + for (int i = 0; i < 2; i++) { + g = job.getGraphics(); + g.drawLine(0, 0, dim.width, 0); + g.drawLine(dim.width, 0, dim.width, dim.height); + g.drawLine(dim.width, dim.height, 0, dim.height); + g.drawLine(0, dim.height, 0, 0); + + g.drawRect(dim.width / 2 - 200, dim.height / 3 - 300, 400, 600); + g.fillRect(dim.width / 2 - 200, 2 * dim.height / 3 - 300, 400, 600); + + g.setFont(font); + metrics = g.getFontMetrics(); + width = metrics.stringWidth(center); + g.setColor(Color.black); + g.drawString(center, (dim.width / 2) - (width / 2), dim.height / 2); + + g.dispose(); + } + job.end(); + job = null; + } + System.out.println("done"); + } + + + + /** + * *************************************************** + * Standard Test Machinery Section DO NOT modify anything in this section -- it's a + standard chunk of code which has all of the + synchronisation necessary for the test harness. + By keeping it the same in all tests, it is easier + to read and understand someone else's test, as + well as insuring that all tests behave correctly + with the test harness. + There is a section following this for test-defined + classes + ***************************************************** + */ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main(String args[]) throws InterruptedException { + mainThread = Thread.currentThread(); + try { + init(); + } catch (TestPassedException e) { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try { + Thread.sleep(sleepTime); + //Timed out, so fail the test + throw new RuntimeException("Timed out after " + sleepTime / 1000 + " seconds"); + } catch (InterruptedException e) { + if (!testGeneratedInterrupt) { + throw e; + } + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if (theTestPassed == false) { + throw new RuntimeException(failureMessage); + } + } + + }//main + + public static synchronized void setTimeoutTo(int seconds) { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() { + Sysout.println("The test passed."); + //first check if this is executing in main thread + if (mainThread == Thread.currentThread()) { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + Sysout.dispose(); + }//pass() + + public static synchronized void fail() { + //test writer didn't specify why test failed, so give generic + fail("it just plain failed! :-)"); + } + + public static synchronized void fail(String whyFailed) { + Sysout.println("The test failed: " + whyFailed); + //check if this called from main thread + if (mainThread == Thread.currentThread()) { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException(whyFailed); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + Sysout.dispose(); + }//fail() + + }// class HighResTest + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException + { + } + +//*********** End Standard Test Machinery Section ********** + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout { + private static TestDialog dialog; + + public static void createDialogWithInstructions(String[] instructions) { + dialog = new TestDialog(new Frame(), "Instructions"); + dialog.printInstructions(instructions); + println("Any messages for the tester will display here."); + } + + public static void createDialog() { + dialog = new TestDialog(new Frame(), "Instructions"); + String[] defInstr = {"Instructions will appear here. ", ""}; + dialog.printInstructions(defInstr); + println("Any messages for the tester will display here."); + } + + + public static void printInstructions(String[] instructions) { + dialog.printInstructions(instructions); + } + + + public static void println(String messageIn) { + dialog.displayMessage(messageIn); + } + + public static void dispose() { + Sysout.println("Shutting down the Java process.."); + HighResTest.f.dispose(); + dialog.dispose(); + } + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button("pass"); + Button failB = new Button("fail"); + + //DO NOT call this directly, go through Sysout + public TestDialog(Frame frame, String name) { + super(frame, name); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); + add("North", instructionsText); + + messageText = new TextArea("", 5, maxStringLength, scrollBoth); + add("Center", messageText); + + passB = new Button("pass"); + passB.setActionCommand("pass"); + passB.addActionListener(this); + buttonP.add("East", passB); + + failB = new Button("fail"); + failB.setActionCommand("fail"); + failB.addActionListener(this); + buttonP.add("West", failB); + + add("South", buttonP); + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions(String[] instructions) { + //Clear out any current instructions + instructionsText.setText(""); + + //Go down array of instruction strings + + String printStr, remainingStr; + for (int i = 0; i < instructions.length; i++) { + //chop up each into pieces maxSringLength long + remainingStr = instructions[i]; + while (remainingStr.length() > 0) { + //if longer than max then chop off first max chars to print + if (remainingStr.length() >= maxStringLength) { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf(' ', maxStringLength - 1); + + if (posOfSpace <= 0) { + posOfSpace = maxStringLength - 1; + } + + printStr = remainingStr.substring(0, posOfSpace + 1); + remainingStr = remainingStr.substring(posOfSpace + 1); + } //else just print + else { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append(printStr + "\n"); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage(String messageIn) { + messageText.append(messageIn + "\n"); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //HighResTest + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand() == "pass") { + HighResTest.pass(); + } else { + HighResTest.fail(); + } + } +}// TestDialog class diff --git a/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java b/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java index de72cfd7bf7..824fce4e99f 100644 --- a/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java +++ b/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java @@ -26,6 +26,7 @@ import java.awt.Dialog; import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; +import java.awt.GraphicsEnvironment; import java.awt.Panel; import java.awt.Rectangle; import java.awt.Robot; @@ -38,12 +39,11 @@ import java.io.File; import javax.imageio.ImageIO; import sun.java2d.SunGraphics2D; + /** * @test - * @bug 8043869 8075244 8078082 - * @author Alexander Scherbatiy - * @summary [macosx] java -splash does not honor 2x hi dpi notation for retina - * support + * @bug 8043869 8075244 8078082 8145173 + * @summary Tests the HiDPI splash screen support for windows and MAC * @modules java.desktop/sun.java2d * @run main MultiResolutionSplashTest GENERATE_IMAGES * @run main/othervm -splash:splash1.png MultiResolutionSplashTest TEST_SPLASH 0 @@ -56,16 +56,26 @@ public class MultiResolutionSplashTest { private static final int IMAGE_WIDTH = 300; private static final int IMAGE_HEIGHT = 200; - private static final ImageInfo[] tests = { + private static final ImageInfo[] macTests = { new ImageInfo("splash1.png", "splash1@2x.png", Color.BLUE, Color.GREEN), new ImageInfo("splash2", "splash2@2x", Color.WHITE, Color.BLACK), new ImageInfo("splash3.", "splash3@2x.", Color.YELLOW, Color.RED) }; + private static final ImageInfo[] windowsTests = { + new ImageInfo("splash1.png", "splash1.scale-120.png", Color.BLUE, Color.GREEN), + new ImageInfo("splash2", "splash2.scale-120", Color.WHITE, Color.BLACK), + new ImageInfo("splash3.", "splash3.scale-120.", Color.YELLOW, Color.RED) + }; + private static ImageInfo[] tests; public static void main(String[] args) throws Exception { String test = args[0]; - + tests = windowsTests; + String osName = System.getProperty("os.name"); + if (osName.contains("OS X")) { + tests = macTests; + } switch (test) { case "GENERATE_IMAGES": generateImages(); @@ -156,7 +166,10 @@ public class MultiResolutionSplashTest { public void paint(Graphics g) { float scaleFactor = 1; if (g instanceof SunGraphics2D) { - scaleFactor = ((SunGraphics2D) g).surfaceData.getDefaultScale(); + scaleFactor = (float)GraphicsEnvironment. + getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getDefaultConfiguration(). + getDefaultTransform().getScaleX(); } scaleFactors[0] = scaleFactor; dialog.setVisible(false); diff --git a/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java b/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java new file mode 100644 index 00000000000..bf836973223 --- /dev/null +++ b/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java @@ -0,0 +1,241 @@ +/* + * Copyright (c) 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. + */ + +import java.awt.Color; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Panel; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.SplashScreen; +import java.awt.TextField; +import java.awt.Window; +import java.awt.event.KeyEvent; +import java.awt.image.BufferedImage; +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.imageio.ImageIO; + +/** + * @test @bug 8145174 + * @summary HiDPI splash screen support on Linux + * @modules java.desktop/sun.java2d + * @run main UnixMultiResolutionSplashTest + */ +public class UnixMultiResolutionSplashTest { + + private static final int IMAGE_WIDTH = 300; + private static final int IMAGE_HEIGHT = 200; + private static int inx = 0; + private static final ImageInfo[] tests = { + new ImageInfo("splash1.png", "splash1.java-scale2x.png", Color.BLUE, Color.GREEN), + new ImageInfo("splash2", "splash2.java-scale2x", Color.WHITE, Color.BLACK), + new ImageInfo("splash3.", "splash3.java-scale2x.", Color.YELLOW, Color.RED) + }; + + public static void main(String[] args) throws Exception { + + if (args.length == 0) { + generateImages(); + for (ImageInfo test : tests) { + createChildProcess(test); + } + } else { + int index = Integer.parseInt(args[0]); + testSplash(tests[index]); + } + } + + static void createChildProcess(ImageInfo test) { + String javaPath = System.getProperty("java.home"); + File file = new File(test.name1x); + String classPathDir = System.getProperty("java.class.path"); + Map env = new HashMap(); + env.put("GDK_SCALE", "2"); + int exitValue = doExec(env, javaPath + File.separator + "bin" + File.separator + + "java", "-splash:" + file.getAbsolutePath(), "-cp", + classPathDir, "UnixMultiResolutionSplashTest", String.valueOf(inx++)); + if (exitValue != 0) { + throw new RuntimeException("Test Failed"); + } + } + + static void testSplash(ImageInfo test) throws Exception { + SplashScreen splashScreen = SplashScreen.getSplashScreen(); + if (splashScreen == null) { + throw new RuntimeException("Splash screen is not shown!"); + } + Graphics2D g = splashScreen.createGraphics(); + Rectangle splashBounds = splashScreen.getBounds(); + int screenX = (int) splashBounds.getCenterX(); + int screenY = (int) splashBounds.getCenterY(); + System.out.println(screenX); + System.out.println(screenY); + Robot robot = new Robot(); + Color splashScreenColor = robot.getPixelColor(screenX, screenY); + + float scaleFactor = getScaleFactor(); + Color testColor = (1 < scaleFactor) ? test.color2x : test.color1x; + if (!compare(testColor, splashScreenColor)) { + throw new RuntimeException( + "Image with wrong resolution is used for splash screen!"); + } + } + + static int doExec(Map envToSet, String... cmds) { + Process p = null; + ProcessBuilder pb = new ProcessBuilder(cmds); + Map env = pb.environment(); + for (String cmd : cmds) { + System.out.print(cmd + " "); + } + System.out.println(); + if (envToSet != null) { + env.putAll(envToSet); + } + BufferedReader rdr = null; + try { + List outputList = new ArrayList<>(); + pb.redirectErrorStream(true); + p = pb.start(); + rdr = new BufferedReader(new InputStreamReader(p.getInputStream())); + String in = rdr.readLine(); + while (in != null) { + outputList.add(in); + in = rdr.readLine(); + System.out.println(in); + } + p.waitFor(); + p.destroy(); + } catch (Exception ex) { + ex.printStackTrace(); + } + return p.exitValue(); + } + + static void testFocus() throws Exception { + + System.out.println("Focus Test!"); + Robot robot = new Robot(); + robot.setAutoDelay(50); + Frame frame = new Frame(); + frame.setSize(100, 100); + String test = "123"; + TextField textField = new TextField(test); + textField.selectAll(); + frame.add(textField); + frame.setVisible(true); + robot.waitForIdle(); + + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + robot.keyPress(KeyEvent.VK_B); + robot.keyRelease(KeyEvent.VK_B); + robot.waitForIdle(); + + frame.dispose(); + if (!textField.getText().equals("ab")) { + throw new RuntimeException("Focus is lost!"); + } + } + + static boolean compare(Color c1, Color c2) { + return compare(c1.getRed(), c2.getRed()) + && compare(c1.getGreen(), c2.getGreen()) + && compare(c1.getBlue(), c2.getBlue()); + } + + static boolean compare(int n, int m) { + return Math.abs(n - m) <= 50; + } + + static float getScaleFactor() { + + final Dialog dialog = new Dialog((Window) null); + dialog.setSize(100, 100); + dialog.setModal(true); + float[] scaleFactors = new float[1]; + Panel panel = new Panel() { + + @Override + public void paint(Graphics g) { + String scaleStr = System.getenv("GDK_SCALE"); + if (scaleStr != null && !scaleStr.equals("")) { + try { + scaleFactors[0] = Float.valueOf(scaleStr); + } catch (NumberFormatException ex) { + scaleFactors[0] = 1.0f; + } + } + dialog.setVisible(false); + } + }; + dialog.add(panel); + dialog.setVisible(true); + dialog.dispose(); + return scaleFactors[0]; + } + + static void generateImages() throws Exception { + for (ImageInfo test : tests) { + generateImage(test.name1x, test.color1x, 1); + generateImage(test.name2x, test.color2x, 2); + } + } + + static void generateImage(String name, Color color, int scale) throws Exception { + File file = new File(name); + if (file.exists()) { + return; + } + BufferedImage image = new BufferedImage(scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT, + BufferedImage.TYPE_INT_RGB); + Graphics g = image.getGraphics(); + g.setColor(color); + g.fillRect(0, 0, scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT); + ImageIO.write(image, "png", file); + } + + static class ImageInfo { + + final String name1x; + final String name2x; + final Color color1x; + final Color color2x; + + public ImageInfo(String name1x, String name2x, Color color1x, Color color2x) { + this.name1x = name1x; + this.name2x = name2x; + this.color1x = color1x; + this.color2x = color2x; + } + } +} + diff --git a/jdk/test/java/awt/TextArea/OverScrollTest/OverScrollTest.java b/jdk/test/java/awt/TextArea/OverScrollTest/OverScrollTest.java new file mode 100644 index 00000000000..6dbf975c6d9 --- /dev/null +++ b/jdk/test/java/awt/TextArea/OverScrollTest/OverScrollTest.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 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 + @bug 8149636 + @summary TextArea over scrolls to right when selecting text towards right. + @requires os.family == "windows" + @run main OverScrollTest + */ + +import java.awt.Frame; +import java.awt.FlowLayout; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.TextArea; +import java.awt.event.InputEvent; + +public class OverScrollTest { + Frame mainFrame; + TextArea textArea; + Robot robot; + + OverScrollTest() { + try { + robot = new Robot(); + } catch (Exception ex) { + throw new RuntimeException(ex.getMessage()); + } + + mainFrame = new Frame(); + mainFrame.setSize(400, 200); + mainFrame.setLocation(200, 200); + mainFrame.setLayout(new FlowLayout()); + + textArea = new TextArea(2, 10); + textArea.setSize(300, 100); + textArea.setText("123456 789123"); + mainFrame.add(textArea); + mainFrame.setVisible(true); + textArea.requestFocusInWindow(); + } + + public void dispose() { + if (mainFrame != null) { + mainFrame.dispose(); + } + } + + public void performTest() { + Point loc = textArea.getLocationOnScreen(); + Rectangle textAreaBounds = new Rectangle(); + textArea.getBounds(textAreaBounds); + + // Move mouse at center in first row of TextArea. + robot.mouseMove(loc.x + textAreaBounds.width / 2, loc.y + 5); + + // Perform selection by scrolling to right from end of char sequence. + robot.mousePress(InputEvent.BUTTON1_MASK); + for (int i = 0; i < textAreaBounds.width; i += 15) { + robot.mouseMove(i + loc.x + textAreaBounds.width / 2, loc.y + 5); + robot.delay(10); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + + // Perform double click on beginning word of TextArea + robot.mouseMove(loc.x + 5, loc.y + 5); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.delay(100); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + + dispose(); + if (!textArea.getSelectedText().contains("123456")) { + throw new RuntimeException ("TextArea over scrolled towards right. " + + "Selected text should contain: '123456' " + + "Actual selected test: '" + textArea.getSelectedText() + "'"); + } + } + + public static void main(String argv[]) throws RuntimeException { + OverScrollTest test = new OverScrollTest(); + test.performTest(); + } +} diff --git a/jdk/test/java/awt/TextArea/UsingWithMouse/SelectionAutoscrollTest.java b/jdk/test/java/awt/TextArea/UsingWithMouse/SelectionAutoscrollTest.java index 09df308ba23..6acb430a378 100644 --- a/jdk/test/java/awt/TextArea/UsingWithMouse/SelectionAutoscrollTest.java +++ b/jdk/test/java/awt/TextArea/UsingWithMouse/SelectionAutoscrollTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -22,11 +22,13 @@ */ /* - test - @bug 6497109 + @test + @bug 6497109 6734341 @summary TextArea must have selection expanding, and also be autoscrolled, if mouse is dragged from inside. + @library ../../regtesthelpers + @build Util @author Konstantin Voloshin: area=TextArea - @run applet SelectionAutoscrollTest.html + @run main SelectionAutoscrollTest */ /** @@ -38,12 +40,10 @@ */ -import java.applet.Applet; import java.awt.Frame; import java.awt.Panel; import java.awt.GridLayout; import java.awt.TextArea; - import java.awt.Point; import java.awt.Dimension; import java.awt.event.MouseEvent; @@ -52,16 +52,18 @@ import java.awt.Toolkit; import test.java.awt.regtesthelpers.Util; -public class SelectionAutoscrollTest extends Applet { +public class SelectionAutoscrollTest { TextArea textArea; Robot robot; final int desiredSelectionEnd = ('z'-'a'+1)*2; // 52 final static int SCROLL_DELAY = 10; // ms - public void start () { - createObjects(); - manipulateMouse(); - checkResults(); + public static void main(String[] args) { + SelectionAutoscrollTest selectionAutoscrollTest + = new SelectionAutoscrollTest(); + selectionAutoscrollTest.createObjects(); + selectionAutoscrollTest.manipulateMouse(); + selectionAutoscrollTest.checkResults(); } void createObjects() { @@ -102,7 +104,7 @@ public class SelectionAutoscrollTest extends Applet { robot.mousePress( MouseEvent.BUTTON1_MASK ); Util.waitForIdle( robot ); - for( int tremble=0; tremble < desiredSelectionEnd; ++tremble ) { + for( int tremble=0; tremble < 10; ++tremble ) { // Mouse is moved repeatedly here (with conservatively chosen // ammount of times), to give some time/chance for TextArea to // autoscroll and for text-selection to expand to the end. @@ -125,7 +127,7 @@ public class SelectionAutoscrollTest extends Applet { // and this is probably a bug). But, starting with 2nd iteration, // all events received will be mouse-dragged events. - moveMouseBelowTextArea( tremble%2!=0 ); + moveMouseBelowTextArea( tremble ); Util.waitForIdle( robot ); // it is needed to add some small delay on Gnome waitUntilScrollIsPerformed(robot); @@ -138,16 +140,28 @@ public class SelectionAutoscrollTest extends Applet { void moveMouseToCenterOfTextArea() { Dimension d = textArea.getSize(); Point l = textArea.getLocationOnScreen(); - robot.mouseMove( (int)(l.x+d.width*.5), (int)(l.y+d.height*.5) ); + Util.mouseMove(robot, l, new Point((int) (l.x + d.width * .5), + (int) (l.y + d.height * .5))); } - void moveMouseBelowTextArea( boolean shift ) { + void moveMouseBelowTextArea(int tremble) { Dimension d = textArea.getSize(); Point l = textArea.getLocationOnScreen(); - int x = (int)(l.x+d.width*.5); - int y = (int)(l.y+d.height*1.5); - if( shift ) y+=15; - robot.mouseMove( x, y ); + Point p1; + if (tremble == 0) { + p1 = new Point((int) (l.x + d.width * .5), + (int) (l.y + d.height * 0.5)); + } else { + p1 = new Point((int) (l.x + d.width * .5), + (int) (l.y + d.height * 1.5)); + } + Point p2 = new Point((int) (l.x + d.width * .5), + (int) (l.y + d.height * 1.5) + 15); + if (tremble % 2 == 0) { + Util.mouseMove(robot, p1, p2); + } else { + Util.mouseMove(robot, p2, p1); + } } void waitUntilScrollIsPerformed(Robot robot) { @@ -160,15 +174,11 @@ public class SelectionAutoscrollTest extends Applet { } void checkResults() { - //try { Thread.sleep( 30*1000 ); } - //catch( Exception e ) { throw new RuntimeException( e ); } - final int currentSelectionEnd = textArea.getSelectionEnd(); - System.out.println( - "TEST: Selection range after test is: ( " - + textArea.getSelectionStart() + ", " - + currentSelectionEnd + " )" + "TEST: Selection range after test is: ( " + + textArea.getSelectionStart() + ", " + + currentSelectionEnd + " )" ); boolean resultOk = ( currentSelectionEnd == desiredSelectionEnd ); diff --git a/jdk/test/java/awt/TextField/OverScrollTest/OverScrollTest.java b/jdk/test/java/awt/TextField/OverScrollTest/OverScrollTest.java new file mode 100644 index 00000000000..c156d900e98 --- /dev/null +++ b/jdk/test/java/awt/TextField/OverScrollTest/OverScrollTest.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 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 + @bug 8149636 + @summary TextField over scrolls to right when selecting text towards right. + @requires os.family == "windows" + @run main OverScrollTest + */ + +import java.awt.Frame; +import java.awt.FlowLayout; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.TextField; +import java.awt.event.InputEvent; + +public class OverScrollTest { + Frame mainFrame; + TextField textField; + Robot robot; + + OverScrollTest() { + try { + robot = new Robot(); + } catch (Exception ex) { + throw new RuntimeException(ex.getMessage()); + } + + mainFrame = new Frame(); + mainFrame.setSize(400, 200); + mainFrame.setLocation(200, 200); + mainFrame.setLayout(new FlowLayout()); + + textField = new TextField(10); + textField.setSize(300, 100); + textField.setText("123456 789123"); + mainFrame.add(textField); + mainFrame.setVisible(true); + textField.requestFocusInWindow(); + } + + public void dispose() { + if (mainFrame != null) { + mainFrame.dispose(); + } + } + + public void performTest() { + Point loc = textField.getLocationOnScreen(); + Rectangle textFieldBounds = new Rectangle(); + textField.getBounds(textFieldBounds); + + // Move mouse at center in first row of TextField. + robot.mouseMove(loc.x + textFieldBounds.width / 2, loc.y + 5); + + // Perform selection by scrolling to right from end of char sequence. + robot.mousePress(InputEvent.BUTTON1_MASK); + for (int i = 0; i < textFieldBounds.width; i += 15) { + robot.mouseMove(i + loc.x + textFieldBounds.width / 2, loc.y + 5); + robot.delay(10); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + + // Perform double click on beginning word of TextField + robot.mouseMove(loc.x + 5, loc.y + 5); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.delay(100); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + + dispose(); + if (!textField.getSelectedText().contains("123456")) { + throw new RuntimeException ("TextField over scrolled towards right. " + + "Selected text should contain: '123456' " + + "Actual selected test: '" + textField.getSelectedText() + "'"); + } + } + + public static void main(String argv[]) throws RuntimeException { + OverScrollTest test = new OverScrollTest(); + test.performTest(); + } +} diff --git a/jdk/test/java/awt/TextField/ScrollSelectionTest/ScrollSelectionTest.java b/jdk/test/java/awt/TextField/ScrollSelectionTest/ScrollSelectionTest.java index 482a31245ed..2d38c9ab96f 100644 --- a/jdk/test/java/awt/TextField/ScrollSelectionTest/ScrollSelectionTest.java +++ b/jdk/test/java/awt/TextField/ScrollSelectionTest/ScrollSelectionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -22,193 +22,240 @@ */ /* - test - @bug 4118621 - @summary tests that selected text isn't scrolled when there is enough room. - @author prs: area=TextField - @run applet/manual=yesno ScrollSelectionTest.html -*/ - -/** - * ScrollSelectionTest.java - * - * summary: tests that selected text isn't scrolled when there is enough room. + @test + @bug 4118621 8149636 + @summary Test the selection scrolling in TextField. + @run main/manual ScrollSelectionTest */ - -import java.applet.Applet; +import java.awt.Button; import java.awt.Dialog; +import java.awt.FlowLayout; import java.awt.Frame; -import java.awt.TextField; +import java.awt.Panel; import java.awt.TextArea; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; -public class ScrollSelectionTest extends Applet - { +public class ScrollSelectionTest { - Frame frame = new Frame("ScrollSelectionTest frame"); - TextField tf = new TextField(40); + static Frame mainFrame; + static TextField textField; - public void init() - { - tf.setText("abcdefghijklmnopqrstuvwxyz"); - frame.add(tf); - tf.select(0, 20); + private static void init() throws Exception { + String[] instructions + = { + "INSTRUCTIONS: There are 2 Tests", + "Test1: Text visibility with Scroll", + "This is a test for a win32 specific problem", + "If you see all the letters from 'a' to 'z' and", + "letters from 'a' to 't' are selected then test passes.", + "You may have to activate the frame to see the selection", + "highlighted (e.g. by clicking on frame's title).", + ".", + "Test2: Flicker with selection scroll", + "Mouse press on the TextField text.", + "Move mouse towards left or right with selecting text.", + "Move mouse away outside the bounds of TextField.", + "No flicker should be observed.", + }; - String[] instructions = { - "INSTRUCTIONS:", - "This is a test for a win32 specific problem", - "If you see all the letters from 'a' to 'z' and", - "letters from 'a' to 't' are selected then test passes.", - "You may have to activate the frame to see the selection" - + " highlighted (e.g. by clicking on frame's title)." - }; - Sysout.createDialogWithInstructions( instructions ); + Sysout.createDialog(); + Sysout.printInstructions(instructions); + } - }// init() + public static void initTestWindow() { + mainFrame = new Frame("ScrollSelectionTest frame"); + mainFrame.setBounds(500, 0, 400, 200); - public void start () - { - setSize (300,300); - setVisible(true); + textField = new TextField(40); + textField.setText("abcdefghijklmnopqrstuvwxyz"); + mainFrame.add(textField); + mainFrame.setLayout(new FlowLayout()); + textField.select(0, 20); + mainFrame.setVisible(true); + } - frame.setVisible(true); - frame.setBounds (400, 0, 300, 300); + public static void dispose() { + Sysout.dispose(); + mainFrame.dispose(); + } - }// start() + /** + * *************************************************** + * Standard Test Machinery Section DO NOT modify anything in this section -- + * it's a standard chunk of code which has all of the synchronization + * necessary for the test harness. By keeping it the same in all tests, it + * is easier to read and understand someone else's test, as well as insuring + * that all tests behave correctly with the test harness. There is a section + * following this for test-defined classes + * **************************************************** + */ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + private static Thread mainThread = null; + final private static int sleepTime = 300000; - }// class ScrollSelectionTest + public static void main(String args[]) throws Exception { + mainThread = Thread.currentThread(); + try { + init(); + initTestWindow(); + } catch (Exception e) { + e.printStackTrace(); + } + try { + mainThread.sleep(sleepTime); + } catch (InterruptedException e) { + dispose(); + if (testGeneratedInterrupt && !theTestPassed) { + throw new Exception(failureMessage); + } + } + if (!testGeneratedInterrupt) { + dispose(); + throw new RuntimeException("Timed out after " + sleepTime / 1000 + + " seconds"); + } + } -/**************************************************** - Standard Test Machinery - DO NOT modify anything below -- it's a standard - chunk of code whose purpose is to make user - interaction uniform, and thereby make it simpler - to read and understand someone else's test. - ****************************************************/ + public static synchronized void pass() { + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + public static synchronized void fail(String whyFailed) { + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + } +} + +// *********** End Standard Test Machinery Section ********** /** - This is part of the standard test machinery. - It creates a dialog (with the instructions), and is the interface - for sending text messages to the user. - To print the instructions, send an array of strings to Sysout.createDialog - WithInstructions method. Put one line of instructions per array entry. - To display a message for the tester to see, simply call Sysout.println - with the string to be displayed. - This mimics System.out.println but works within the test harness as well - as standalone. + * ************************************************** + * Standard Test Machinery DO NOT modify anything below -- it's a standard chunk + * of code whose purpose is to make user interaction uniform, and thereby make + * it simpler to read and understand someone else's test. + * ************************************************** */ +/** + * This is part of the standard test machinery. It creates a dialog (with the + * instructions), and is the interface for sending text messages to the user. To + * print the instructions, send an array of strings to Sysout.createDialog + * WithInstructions method. Put one line of instructions per array entry. To + * display a message for the tester to see, simply call Sysout.println with the + * string to be displayed. This mimics System.out.println but works within the + * test harness as well as standalone. + */ +class Sysout { + private static TestDialog dialog; + private static Frame frame; -class Sysout - { - private static TestDialog dialog; - - public static void createDialogWithInstructions( String[] instructions ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - dialog.printInstructions( instructions ); - dialog.show(); - println( "Any messages for the tester will display here." ); + public static void createDialog() { + frame = new Frame(); + dialog = new TestDialog(frame, "Instructions"); + String[] defInstr = {"Instructions will appear here. ", ""}; + dialog.printInstructions(defInstr); + dialog.setVisible(true); + println("Any messages for the tester will display here."); } - public static void createDialog( ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - String[] defInstr = { "Instructions will appear here. ", "" } ; - dialog.printInstructions( defInstr ); - dialog.show(); - println( "Any messages for the tester will display here." ); + public static void printInstructions(String[] instructions) { + dialog.printInstructions(instructions); } - - public static void printInstructions( String[] instructions ) - { - dialog.printInstructions( instructions ); + public static void println(String messageIn) { + dialog.displayMessage(messageIn); } - - public static void println( String messageIn ) - { - dialog.displayMessage( messageIn ); + public static void dispose() { + dialog.dispose(); + frame.dispose(); } - - }// Sysout class +} /** - This is part of the standard test machinery. It provides a place for the - test instructions to be displayed, and a place for interactive messages - to the user to be displayed. - To have the test instructions displayed, see Sysout. - To have a message to the user be displayed, see Sysout. - Do not call anything in this dialog directly. - */ -class TestDialog extends Dialog - { + * This is part of the standard test machinery. It provides a place for the test + * instructions to be displayed, and a place for interactive messages to the + * user to be displayed. To have the test instructions displayed, see Sysout. To + * have a message to the user be displayed, see Sysout. Do not call anything in + * this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener { + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP; + Button failB; + Button passB; - TextArea instructionsText; - TextArea messageText; - int maxStringLength = 80; + // DO NOT call this directly, go through Sysout + public TestDialog(Frame frame, String name) { + super(frame, name); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); + add("North", instructionsText); - //DO NOT call this directly, go through Sysout - public TestDialog( Frame frame, String name ) - { - super( frame, name ); - int scrollBoth = TextArea.SCROLLBARS_BOTH; - instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); - add( "North", instructionsText ); + messageText = new TextArea("", 5, maxStringLength, scrollBoth); + add("Center", messageText); - messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); - add("South", messageText); + buttonP = new Panel(); + passB = new Button("pass"); + passB.setActionCommand("pass"); + passB.addActionListener(this); + buttonP.add("East", passB); - pack(); + failB = new Button("Fail"); + failB.setActionCommand("fail"); + failB.addActionListener(this); + buttonP.add("West", failB); - show(); - }// TestDialog() - - //DO NOT call this directly, go through Sysout - public void printInstructions( String[] instructions ) - { - //Clear out any current instructions - instructionsText.setText( "" ); - - //Go down array of instruction strings - - String printStr, remainingStr; - for( int i=0; i < instructions.length; i++ ) - { - //chop up each into pieces maxSringLength long - remainingStr = instructions[ i ]; - while( remainingStr.length() > 0 ) - { - //if longer than max then chop off first max chars to print - if( remainingStr.length() >= maxStringLength ) - { - //Try to chop on a word boundary - int posOfSpace = remainingStr. - lastIndexOf( ' ', maxStringLength - 1 ); - - if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; - - printStr = remainingStr.substring( 0, posOfSpace + 1 ); - remainingStr = remainingStr.substring( posOfSpace + 1 ); - } - //else just print - else - { - printStr = remainingStr; - remainingStr = ""; - } - - instructionsText.append( printStr + "\n" ); - - }// while - - }// for - - }//printInstructions() - - //DO NOT call this directly, go through Sysout - public void displayMessage( String messageIn ) - { - messageText.append( messageIn + "\n" ); + add("South", buttonP); + pack(); + setVisible(true); } - }// TestDialog class + // DO NOT call this directly, go through Sysout + public void printInstructions(String[] instructions) { + instructionsText.setText(""); + String printStr, remainingStr; + for (int i = 0; i < instructions.length; i++) { + remainingStr = instructions[i]; + while (remainingStr.length() > 0) { + if (remainingStr.length() >= maxStringLength) { + int posOfSpace = remainingStr. + lastIndexOf(' ', maxStringLength - 1); + + if (posOfSpace <= 0) { + posOfSpace = maxStringLength - 1; + } + + printStr = remainingStr.substring(0, posOfSpace + 1); + remainingStr = remainingStr.substring(posOfSpace + 1); + } + else { + printStr = remainingStr; + remainingStr = ""; + } + instructionsText.append(printStr + "\n"); + } + } + } + + public void displayMessage(String messageIn) { + messageText.append(messageIn + "\n"); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("pass")) { + ScrollSelectionTest.pass(); + } else { + ScrollSelectionTest.fail("User Clicked Fail"); + } + } +} diff --git a/jdk/test/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh b/jdk/test/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh index e243f871742..b1930f0a728 100644 --- a/jdk/test/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh +++ b/jdk/test/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh @@ -105,17 +105,6 @@ if [ -z "${TESTJAVA}" ] ; then fi echo "JDK under test is: $TESTJAVA" -##Deal with .class files: -#if [ -n "${STANDALONE}" ] ; then -# # then compile all .java files (if there are any) into .class files -# if [ -a *.java ]; then -# ${TESTJAVA}/bin/javac$ ./*.java ; -# fi -# # else in harness so copy all the class files from where jtreg put them -# # over to the scratch directory this test is running in. -# else cp ${TESTCLASSES}/*.class . ; -#fi -# #if in test harness, then copy the entire directory that the test is in over # to the scratch directory. This catches any support files needed by the test. if [ -z "${STANDALONE}" ] ; @@ -124,7 +113,8 @@ fi case "$OS" in Windows* | CYGWIN* ) ${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} \ - -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \ + -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \ + -XaddExports:java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \ *.java status=$? if [ ! $status -eq "0" ]; then @@ -134,7 +124,8 @@ case "$OS" in SunOS | Linux ) ${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} \ - -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \ + -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \ + -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \ *.java status=$? if [ ! $status -eq "0" ]; then @@ -144,7 +135,8 @@ case "$OS" in Darwin) ${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} \ - -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \ + -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \ + -XaddExports:java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \ *.java status=$? if [ ! $status -eq "0" ]; then @@ -162,14 +154,16 @@ chmod 777 ./* case "$OS" in Windows* | CYGWIN* ) ${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \ - -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \ + -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \ + -XaddExports:java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \ TestWrapped sun.awt.windows.WToolkit status=$? if [ ! $status -eq "0" ]; then fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.awt.windows.WToolkit"; fi ${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \ - -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \ + -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \ + -XaddExports:java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \ -Dawt.toolkit=sun.awt.windows.WToolkit \ TestWrapped sun.awt.windows.WToolkit status=$? @@ -180,7 +174,8 @@ case "$OS" in SunOS | Linux ) ${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \ - -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \ + -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \ + -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \ -Dawt.toolkit=sun.awt.X11.XToolkit \ TestWrapped sun.awt.X11.XToolkit status=$? @@ -188,7 +183,8 @@ case "$OS" in fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.awt.xawt.XToolkit"; fi AWT_TOOLKIT=XToolkit ${TESTJAVA}/bin/java ${TESTVMOPTS} \ - -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \ + -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \ + -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \ -Djava.awt.headless=true \ TestWrapped sun.awt.X11.XToolkit status=$? @@ -199,14 +195,16 @@ case "$OS" in Darwin) ${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \ - -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \ + -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \ + -XaddExports:java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \ TestWrapped sun.lwawt.macosx.LWCToolkit status=$? if [ ! $status -eq "0" ]; then fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.lwawt.macosx.LWCToolkit"; fi ${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \ - -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \ + -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \ + -XaddExports:java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \ -Dawt.toolkit=sun.lwawt.macosx.LWCToolkit \ TestWrapped sun.lwawt.macosx.LWCToolkit status=$? diff --git a/jdk/test/java/awt/TrayIcon/MouseMovedTest/MouseMovedTest.java b/jdk/test/java/awt/TrayIcon/MouseMovedTest/MouseMovedTest.java index d6e6d760f79..692778ace8e 100644 --- a/jdk/test/java/awt/TrayIcon/MouseMovedTest/MouseMovedTest.java +++ b/jdk/test/java/awt/TrayIcon/MouseMovedTest/MouseMovedTest.java @@ -30,7 +30,7 @@ import java.awt.image.BufferedImage; * @bug 7153700 * @summary Check for mouseMoved event for java.awt.TrayIcon * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com) - * @library ../../../../lib/testlibrary + * @library ../../../../lib/testlibrary ../ * @build ExtendedRobot SystemTrayIconHelper * @run main MouseMovedTest */ diff --git a/jdk/test/java/awt/TextField/ScrollSelectionTest/ScrollSelectionTest.html b/jdk/test/java/awt/Window/FindOwner/FindOwnerTest.html similarity index 66% rename from jdk/test/java/awt/TextField/ScrollSelectionTest/ScrollSelectionTest.html rename to jdk/test/java/awt/Window/FindOwner/FindOwnerTest.html index 0c99a555a69..f0f8e47af77 100644 --- a/jdk/test/java/awt/TextField/ScrollSelectionTest/ScrollSelectionTest.html +++ b/jdk/test/java/awt/Window/FindOwner/FindOwnerTest.html @@ -1,5 +1,5 @@ - - ScrollSelectionTest + Testing Menus - -

      ScrollSelectionTest
      4118621:

      - -

      See the dialog box (usually in upper left corner) for instructions

      - - + + - + \ No newline at end of file diff --git a/jdk/test/java/awt/Window/FindOwner/FindOwnerTest.java b/jdk/test/java/awt/Window/FindOwner/FindOwnerTest.java new file mode 100644 index 00000000000..8c09faa6b8a --- /dev/null +++ b/jdk/test/java/awt/Window/FindOwner/FindOwnerTest.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2015, 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. + */ + +/* @bug 8139227 + @summary Text fields in JPopupMenu structure do not receive focus in hosted + Applets + @author Semyon Sadetsky +*/ + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +public class FindOwnerTest extends Applet +{ + + private boolean gained; + + public void init() { + super.init(); + } + + @Override + public void start() { + Window owner = SwingUtilities.windowForComponent(this); + + Window window1 = new Window(owner); + window1.setVisible(true); + + Window window2 = new Window(window1); + window2.setFocusable(true); + JTextField field = new JTextField("JTextField"); + field.addFocusListener(new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + gained = true; + } + + @Override + public void focusLost(FocusEvent e) { + } + }); + window2.setBounds(100, 100, 200, 200); + window2.add(field); + window2.setVisible(true); + + try { + gained = false; + Robot robot = new Robot(); + robot.setAutoDelay(50); + robot.waitForIdle(); + robot.delay(200); + + Point p = field.getLocationOnScreen(); + System.out.println(p); + robot.mouseMove(p.x + 1, p.y + 1); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + robot.delay(200); + + if (!gained) { + throw new Exception("Focus is not gained upon mouse click"); + } + System.out.println("ok"); + } catch (SecurityException e) { + + JOptionPane optionPane = new JOptionPane( + "You are in the browser so test is manual. Try to " + + "click \"JTextField\" in the opened window then press OK " + + "below", + JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION); + JDialog dialog = + optionPane.createDialog(null,"FindOwnerTest instruction"); + dialog.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL); + dialog.setVisible(true); + if (!gained) { + throw new RuntimeException( + "Focus is not gained upon mouse click"); + } + System.out.println("ok"); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + window1.dispose(); + stop(); + } + } +} \ No newline at end of file diff --git a/jdk/test/java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java b/jdk/test/java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java new file mode 100644 index 00000000000..2fae159733f --- /dev/null +++ b/jdk/test/java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 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 @summary setAlwaysOnTop doesn't behave correctly in Linux/Solaris under + * certain scenarios + * @bug 8021961 + * @author Semyon Sadetsky + * @run main ChildAlwaysOnTopTest + */ + +import javax.swing.*; +import java.awt.*; + +public class ChildAlwaysOnTopTest { + + private static Window win1; + private static Window win2; + private static Point point; + + public static void main(String[] args) throws Exception { + if( Toolkit.getDefaultToolkit().isAlwaysOnTopSupported() ) { + + + test(null); + + Window f = new Frame(); + f.setBackground(Color.darkGray); + f.setSize(500, 500); + try { + test(f); + } finally { + f.dispose(); + } + + f = new Frame(); + f.setBackground(Color.darkGray); + f.setSize(500, 500); + f.setVisible(true); + f = new Dialog((Frame)f); + try { + test(f); + } finally { + ((Frame)f.getParent()).dispose(); + } + } + System.out.println("ok"); + } + + public static void test(Window parent) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + win1 = parent == null ? new JDialog() : new JDialog(parent); + win1.setName("top"); + win2 = parent == null ? new JDialog() : new JDialog(parent); + win2.setName("behind"); + win1.setSize(200, 200); + Panel panel = new Panel(); + panel.setBackground(Color.GREEN); + win1.add(panel); + panel = new Panel(); + panel.setBackground(Color.RED); + win2.add(panel); + win1.setAlwaysOnTop(true); + win2.setAlwaysOnTop(false); + win1.setVisible(true); + } + }); + + Robot robot = new Robot(); + robot.delay(200); + robot.waitForIdle(); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + point = win1.getLocationOnScreen(); + win2.setBounds(win1.getBounds()); + win2.setVisible(true); + } + }); + + robot.delay(200); + robot.waitForIdle(); + + Color color = robot.getPixelColor(point.x + 100, point.y + 100); + if(!color.equals(Color.GREEN)) { + win1.dispose(); + win2.dispose(); + throw new RuntimeException("alawaysOnTop window is sent back by " + + "another child window setVisible(). " + color); + } + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + win2.toFront(); + if (parent != null) { + parent.setLocation(win1.getLocation()); + parent.toFront(); + } + } + }); + + robot.delay(200); + robot.waitForIdle(); + + color = robot.getPixelColor(point.x + 100, point.y + 100); + if(!color.equals(Color.GREEN)) { + win1.dispose(); + win2.dispose(); + throw new RuntimeException("alawaysOnTop window is sent back by " + + "another child window toFront(). " + color); + } + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + win1.setAlwaysOnTop(false); + if (parent != null) { + parent.setVisible(false); + parent.setVisible(true); + } + win2.toFront(); + } + }); + + robot.delay(200); + robot.waitForIdle(); + + color = robot.getPixelColor(point.x + 100, point.y + 100); + if(!color.equals(Color.RED)) { + throw new RuntimeException("Failed to unset alawaysOnTop " + color); + } + + win1.dispose(); + win2.dispose(); + } +} diff --git a/jdk/test/java/awt/font/FontNames/GetLCIDFromLocale.java b/jdk/test/java/awt/font/FontNames/GetLCIDFromLocale.java index fc5aed23401..ef220b90775 100644 --- a/jdk/test/java/awt/font/FontNames/GetLCIDFromLocale.java +++ b/jdk/test/java/awt/font/FontNames/GetLCIDFromLocale.java @@ -4,9 +4,7 @@ * * 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. + * 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 diff --git a/jdk/test/sun/net/InetAddress/nameservice/deadlock/Hang.java b/jdk/test/java/awt/font/FontScaling/FontScalingTest.java similarity index 52% rename from jdk/test/sun/net/InetAddress/nameservice/deadlock/Hang.java rename to jdk/test/java/awt/font/FontScaling/FontScalingTest.java index 2ea0b0dcc69..4c100ac8ca4 100644 --- a/jdk/test/sun/net/InetAddress/nameservice/deadlock/Hang.java +++ b/jdk/test/java/awt/font/FontScaling/FontScalingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -21,27 +21,38 @@ * questions. */ -/** +import javax.swing.JButton; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.plaf.metal.MetalLookAndFeel; + +/* * @test - * @bug 7012768 - * @modules java.base/sun.net.spi.nameservice - * @compile -XDignore.symbol.file=true ThrowingNameService.java - * ThrowingNameServiceDescriptor.java - * @run main/othervm/timeout=30 -Dsun.net.spi.nameservice.provider.1=throwing,sun Hang - * @summary InetAddress lookupTable leaks/deadlocks when using unsupported - * name service spi + * @bug 8076545 + * @summary Text size is twice bigger under Windows L&F on Win 8.1 with + * HiDPI display */ +public class FontScalingTest { -import java.net.InetAddress; - -public class Hang { public static void main(String[] args) throws Exception { - try { - // 1st attempt - IllegalStateException caught below - InetAddress.getByName("host.company.com"); - } catch (IllegalStateException e) { } + int metalFontSize = getFontSize(MetalLookAndFeel.class.getName()); + int systemFontSize = getFontSize(UIManager.getSystemLookAndFeelClassName()); - // 2nd attempt - Stuck here forever if bug exists - InetAddress.getByName("host.company.com"); + if (Math.abs(systemFontSize - metalFontSize) > 8) { + throw new RuntimeException("System L&F is too big!"); + } } -} + + private static int getFontSize(String laf) throws Exception { + + UIManager.setLookAndFeel(laf); + final int[] sizes = new int[1]; + + SwingUtilities.invokeAndWait(() -> { + JButton button = new JButton("Test"); + sizes[0] = button.getFont().getSize(); + }); + + return sizes[0]; + } +} \ No newline at end of file diff --git a/jdk/test/java/awt/hidpi/properties/HiDPIPropertiesLinuxTest.java b/jdk/test/java/awt/hidpi/properties/HiDPIPropertiesUnixTest.java similarity index 85% rename from jdk/test/java/awt/hidpi/properties/HiDPIPropertiesLinuxTest.java rename to jdk/test/java/awt/hidpi/properties/HiDPIPropertiesUnixTest.java index aba2dc1f87c..d123398c36e 100644 --- a/jdk/test/java/awt/hidpi/properties/HiDPIPropertiesLinuxTest.java +++ b/jdk/test/java/awt/hidpi/properties/HiDPIPropertiesUnixTest.java @@ -32,27 +32,21 @@ import javax.swing.UIManager; * @bug 8137571 * @summary Linux HiDPI Graphics support * @author Alexander Scherbatiy - * @requires (os.family == "linux") + * @requires (os.family == "linux" | os.family == "mac") * @run main/othervm -Dsun.java2d.uiScale.enabled=false * -Dsun.java2d.uiScale=2 - * HiDPIPropertiesLinuxTest UISCALE_DISABLED - * HiDPIPropertiesTest UISCALE_DISABLED + * HiDPIPropertiesUnixTest UISCALE_DISABLED * @run main/othervm -Dsun.java2d.uiScale.enabled=true * -Dsun.java2d.uiScale=3 - * HiDPIPropertiesLinuxTest UISCALE_3 + * HiDPIPropertiesUnixTest UISCALE_3 * @run main/othervm -Dsun.java2d.uiScale=4 - * HiDPIPropertiesLinuxTest UISCALE_4 + * HiDPIPropertiesUnixTest UISCALE_4 */ -public class HiDPIPropertiesLinuxTest { +public class HiDPIPropertiesUnixTest { public static void main(String[] args) throws Exception { - try { - UIManager.setLookAndFeel( - "com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); - } catch (Exception e) { - return; - } + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); String testCase = args[0]; switch (testCase) { diff --git a/jdk/test/java/awt/image/DrawImage/ScaledImageAlphaTest.java b/jdk/test/java/awt/image/DrawImage/ScaledImageAlphaTest.java new file mode 100644 index 00000000000..0be030a8737 --- /dev/null +++ b/jdk/test/java/awt/image/DrawImage/ScaledImageAlphaTest.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 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 + * @bug 8139183 + * @summary Test verifies whether alpha channel of a translucent + * image is proper or not after scaling through drawImage. + * @run main ScaledImageAlphaTest + */ + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.Transparency; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; + +public class ScaledImageAlphaTest { + + static final int translucentAlpha = 128, opaqueAlpha = 255; + static final int[] translucentVariants = new int[] { + BufferedImage.TYPE_INT_ARGB, + BufferedImage.TYPE_INT_ARGB_PRE, + BufferedImage.TYPE_4BYTE_ABGR, + BufferedImage.TYPE_4BYTE_ABGR_PRE + }; + static final int[] alphaValues = new int[] { + translucentAlpha, + opaqueAlpha + }; + static int width = 50, height = 50; + static int scaleX = 5, scaleY = 5, scaleWidth = 40, scaleHeight = 40; + + private static void verifyAlpha(Color color, int alpha) { + + /* if extracted alpha value is equal alpha that we set + * for background color, alpha channel is not lost + * while scaling otherwise we have lost alpha channel. + */ + int extractedAlpha = color.getAlpha(); + + if (extractedAlpha != alpha) { + throw new RuntimeException("Alpha channel for background" + + " is lost while scaling"); + } + } + + private static void validateBufferedImageAlpha() { + + Color backgroundColor, extractedColor; + // verify for all translucent buffered image types + for (int type : translucentVariants) { + // verify for both opaque and translucent background color + for (int alpha : alphaValues) { + // create BufferedImage of dimension (50,50) + BufferedImage img = new + BufferedImage(width, height, type); + Graphics2D imgGraphics = (Graphics2D)img.getGraphics(); + /* scale image to smaller dimension and set any + * background color with alpha. + */ + backgroundColor = new Color(0, 255, 0, alpha); + imgGraphics. + drawImage(img, scaleX, scaleY, scaleWidth, scaleHeight, + backgroundColor, null); + imgGraphics.dispose(); + + /* get pixel information for background color with + * scaled coordinates. + */ + extractedColor = new Color(img.getRGB(scaleX, scaleY), true); + verifyAlpha(extractedColor, alpha); + } + } + } + + private static void validateVolatileImageAlpha() { + + Color backgroundColor, extractedColor; + VolatileImage img; + BufferedImage bufImg = new + BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + for (int alpha : alphaValues) { + backgroundColor = new Color(0, 255, 0, alpha); + do { + img = createVolatileImage(width, height, + Transparency.TRANSLUCENT); + Graphics2D imgGraphics = (Graphics2D)img.getGraphics(); + // clear VolatileImage as by default it has white opaque image + imgGraphics.setComposite(AlphaComposite.Clear); + imgGraphics.fillRect(0,0, width, height); + + imgGraphics.setComposite(AlphaComposite.SrcOver); + /* scale image to smaller dimension and set background color + * to green with translucent alpha. + */ + imgGraphics. + drawImage(img, scaleX, scaleY, scaleWidth, scaleHeight, + backgroundColor, null); + //get BufferedImage out of VolatileImage + bufImg = img.getSnapshot(); + imgGraphics.dispose(); + } while (img.contentsLost()); + + /* get pixel information for background color with + * scaled coordinates. + */ + extractedColor = new Color(bufImg.getRGB(scaleX, scaleY), true); + verifyAlpha(extractedColor, alpha); + } + } + + private static VolatileImage createVolatileImage(int width, int height, + int transparency) { + GraphicsEnvironment ge = GraphicsEnvironment. + getLocalGraphicsEnvironment(); + GraphicsConfiguration gc = ge.getDefaultScreenDevice(). + getDefaultConfiguration(); + + VolatileImage image = gc.createCompatibleVolatileImage(width, height, + transparency); + return image; + } + + public static void main(String[] args) { + // test alpha channel with different types of BufferedImage + validateBufferedImageAlpha(); + // test alpha channel with VolatileImage + validateVolatileImageAlpha(); + } +} diff --git a/jdk/test/java/awt/image/SampleModelConstructorTest.java b/jdk/test/java/awt/image/SampleModelConstructorTest.java new file mode 100644 index 00000000000..b4bc1188b74 --- /dev/null +++ b/jdk/test/java/awt/image/SampleModelConstructorTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 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 + * @bug 6185114 + * @summary test SampleModel constructor for different combinations of + * width and height + */ + +import java.awt.image.DataBuffer; +import java.awt.image.Raster; +import java.awt.image.SampleModel; + + +public class SampleModelConstructorTest { + + public static void main(String[] a) throws RuntimeException { + + SampleModel model = Raster.createBandedRaster(DataBuffer.TYPE_INT, + 10, 5, 4, null).getSampleModel(); + + final int inputWidths[] + = {Integer.MIN_VALUE, -1000, -1, 0, 1, 1000, Integer.MAX_VALUE}; + + final int inputHeights[] + = {Integer.MIN_VALUE, -1000, -1, 0, 1, 1000, Integer.MAX_VALUE}; + + // There are 49 combinations of (width, height) possible using above two + // arrays + + // Only 6 valid combinations of (width, height) that do not throw + // exception are : + // (1, 1) + // (1, 1000) + // (1, Integer.MAX_VALUE) + // (1000, 1) + // (1000, 1000) + // (Integer.MAX_VALUE, 1) + final int expectedCount = 43; + int count = 0; + + for (int i : inputWidths) { + for (int j : inputHeights) { + try { + SampleModel model2 = model.createCompatibleSampleModel(i, j); + } catch (IllegalArgumentException e) { + count++; + } + } + } + + if (count != expectedCount) { + throw new RuntimeException( + "Test Failed. Expected IllegalArgumentException Count = " + + expectedCount + " Got Count = " + count); + } + } +} + diff --git a/jdk/test/java/awt/image/multiresolution/BaseMultiResolutionImageTest.java b/jdk/test/java/awt/image/multiresolution/BaseMultiResolutionImageTest.java index 1ce7b7faf82..02ba9d69e66 100644 --- a/jdk/test/java/awt/image/multiresolution/BaseMultiResolutionImageTest.java +++ b/jdk/test/java/awt/image/multiresolution/BaseMultiResolutionImageTest.java @@ -191,6 +191,17 @@ public class BaseMultiResolutionImageTest { if (!passed) { throw new RuntimeException("Resolution variants list is modifiable!"); } + + passed = false; + try { + mrImage.getGraphics(); + } catch (UnsupportedOperationException e) { + passed = true; + } + + if (!passed) { + throw new RuntimeException("getGraphics() method shouldn't be supported!"); + } } private static int getSize(int i) { diff --git a/jdk/test/java/awt/image/multiresolution/Corrupted2XImageTest.java b/jdk/test/java/awt/image/multiresolution/Corrupted2XImageTest.java new file mode 100644 index 00000000000..ba0f7b321d6 --- /dev/null +++ b/jdk/test/java/awt/image/multiresolution/Corrupted2XImageTest.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 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 + * @bug 8142406 + * @author a.stepanov + * @summary [HiDPI] [macosx] check that for a pair of images + * (image.ext, image@2x.ext) the 1st one is loaded + * in case if the 2nd is corrupted + * + * @requires (os.family == "mac") + * + * @library ../../../../lib/testlibrary/ + * @build ExtendedRobot + * @run main Corrupted2XImageTest + */ + +import java.awt.*; +import java.awt.image.*; +import java.io.*; + +import javax.imageio.ImageIO; + +public class Corrupted2XImageTest extends Frame { + + private static final int SZ = 200; + private static final Color C = Color.BLUE; + + private final String format, name1x, name2x; + + public Corrupted2XImageTest(String format) throws IOException { + + this.format = format; + name1x = "test." + format; + name2x = "test@2x." + format; + createFiles(); + } + + private void UI() { + + setTitle(format); + setSize(SZ, SZ); + setResizable(false); + setLocation(50, 50); + setVisible(true); + } + + @Override + public void paint(Graphics g) { + + Image img = Toolkit.getDefaultToolkit().getImage( + new File(name1x).getAbsolutePath()); + g.drawImage(img, 0, 0, this); + } + + private void createFiles() throws IOException { + + BufferedImage img = + new BufferedImage(SZ, SZ, BufferedImage.TYPE_INT_RGB); + Graphics g = img.getGraphics(); + g.setColor(C); + g.fillRect(0, 0, SZ, SZ); + ImageIO.write(img, format, new File(name1x)); + + // corrupted @2x "image" - just a text file + Writer writer = new BufferedWriter(new OutputStreamWriter( + new FileOutputStream(new File(name2x)), "utf-8")); + writer.write("corrupted \"image\""); + writer.close(); + } + + // need this for jpg + private static boolean cmpColors(Color c1, Color c2) { + + int tol = 10; + return ( + Math.abs(c2.getRed() - c1.getRed() ) < tol && + Math.abs(c2.getGreen() - c1.getGreen()) < tol && + Math.abs(c2.getBlue() - c1.getBlue() ) < tol); + } + + private void doTest() throws Exception { + + ExtendedRobot r = new ExtendedRobot(); + System.out.println("format: " + format); + r.waitForIdle(1000); + EventQueue.invokeAndWait(this::UI); + r.waitForIdle(1000); + Point loc = getLocationOnScreen(); + Color c = r.getPixelColor(loc.x + SZ / 2, loc.y + SZ / 2); + if (!cmpColors(c, C)) { + throw new RuntimeException("test failed, color = " + c); } + System.out.println("ok"); + dispose(); + } + + public static void main(String[] args) throws Exception { + + // formats supported by Toolkit.getImage() + for (String format : new String[]{"gif", "jpg", "png"}) { + (new Corrupted2XImageTest(format)).doTest(); + } + } +} diff --git a/jdk/test/java/awt/image/multiresolution/MenuMultiresolutionIconTest.java b/jdk/test/java/awt/image/multiresolution/MenuMultiresolutionIconTest.java index 332162be952..9a09f5c300f 100644 --- a/jdk/test/java/awt/image/multiresolution/MenuMultiresolutionIconTest.java +++ b/jdk/test/java/awt/image/multiresolution/MenuMultiresolutionIconTest.java @@ -115,13 +115,6 @@ public class MenuMultiresolutionIconTest extends JPanel { } } - private static boolean is2x() { - - return GraphicsEnvironment.getLocalGraphicsEnvironment(). - getDefaultScreenDevice().getDefaultConfiguration(). - getDefaultTransform().getScaleX() > 1.001; - } - private boolean eqColors(Color c1, Color c2) { int tol = 15; @@ -133,7 +126,8 @@ public class MenuMultiresolutionIconTest extends JPanel { private void checkIconColor(Point p, String what) { - Color expected = is2x() ? C2X : C1X; + String scale = System.getProperty(SCALE); + Color expected = "2".equals(scale) ? C2X : C1X; Color c = r.getPixelColor(p.x + SZ / 2, p.y + SZ / 2); if (!eqColors(c, expected)) { frame.dispose(); @@ -177,9 +171,6 @@ public class MenuMultiresolutionIconTest extends JPanel { public static void main(String s[]) throws Exception { - // TODO: remove is2x() after JDK-8150844 fix - if (is2x() == "2".equals(System.getProperty(SCALE))) { - (new MenuMultiresolutionIconTest()).doTest(); - } + (new MenuMultiresolutionIconTest()).doTest(); } } diff --git a/jdk/test/java/awt/image/multiresolution/MultiResolutionJOptionPaneIconTest.java b/jdk/test/java/awt/image/multiresolution/MultiResolutionJOptionPaneIconTest.java new file mode 100644 index 00000000000..ea3cee55515 --- /dev/null +++ b/jdk/test/java/awt/image/multiresolution/MultiResolutionJOptionPaneIconTest.java @@ -0,0 +1,181 @@ +/* + * Copyright (c) 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 + @bug 8150176 8150844 + @author a.stepanov + @summary Check if correct resolution variant is used + for JOptionPane dialog / internal frame icons. + @library ../../../../lib/testlibrary/ + @build ExtendedRobot + @run main/othervm/timeout=300 -Dsun.java2d.uiScale=1 MultiResolutionJOptionPaneIconTest + @run main/othervm/timeout=300 -Dsun.java2d.uiScale=2 MultiResolutionJOptionPaneIconTest +*/ + +import java.awt.*; +import java.awt.event.*; +import java.awt.image.*; +import javax.swing.*; + +public class MultiResolutionJOptionPaneIconTest implements ActionListener { + + private final static Color C1X = Color.ORANGE, C2X = Color.CYAN; + + private final boolean isInternal; + + private volatile JFrame test; + private volatile JDialog dialog; + private volatile JInternalFrame frame; + private final JDesktopPane parentPane = new JDesktopPane(); + private final JButton run = new JButton("run"); + + private final ExtendedRobot robot = new ExtendedRobot(); + + private static BufferedImage getSquare(int sz, Color c) { + + BufferedImage img = new BufferedImage(sz, sz, BufferedImage.TYPE_INT_RGB); + Graphics g = img.getGraphics(); + g.setColor(c); + g.fillRect(0, 0, sz, sz); + return img; + } + + private static Icon getIcon() { + + BaseMultiResolutionImage mri = new BaseMultiResolutionImage( + new BufferedImage[]{getSquare(16, C1X), getSquare(32, C2X)}); + return new ImageIcon(mri); + } + + public MultiResolutionJOptionPaneIconTest(boolean internal, + UIManager.LookAndFeelInfo lf) throws Exception { + + UIManager.setLookAndFeel(lf.getClassName()); + + isInternal = internal; + robot.setAutoDelay(50); + SwingUtilities.invokeAndWait(this::UI); + } + + private void UI() { + + test = new JFrame(); + test.setLayout(new BorderLayout()); + test.add(parentPane, BorderLayout.CENTER); + run.addActionListener(this); + test.add(run, BorderLayout.SOUTH); + test.setUndecorated(true); + test.setSize(400, 300); + test.setLocation(50, 50); + test.setVisible(true); + } + + private void disposeAll() { + + if (dialog != null) { dialog.dispose(); } + if (frame != null) { frame.dispose(); } + if (test != null) { test.dispose(); } + } + + public void doTest() throws Exception { + + robot.waitForIdle(1000); + clickButton(robot); + robot.waitForIdle(2000); + + Component c = isInternal ? + frame.getContentPane() : dialog.getContentPane(); + + System.out.println("\ncheck " + (isInternal ? "internal frame" : + "dialog") + " icon:"); + + Point pt = c.getLocationOnScreen(); + checkColors(pt.x, c.getWidth(), pt.y, c.getHeight()); + System.out.println("ok"); + robot.waitForIdle(); + SwingUtilities.invokeAndWait(this::disposeAll); + robot.waitForIdle(); + } + + private void checkColors(int x0, int w, int y0, int h) { + + boolean is2x = "2".equals(System.getProperty("sun.java2d.uiScale")); + Color + expected = is2x ? C2X : C1X, + unexpected = is2x ? C1X : C2X; + + for (int y = y0; y < y0 + h; y += 5) { + for (int x = x0; x < x0 + w; x += 5) { + + Color c = robot.getPixelColor(x, y); + if (c.equals(unexpected)) { + throw new RuntimeException( + "invalid color was found, test failed"); + } else if (c.equals(expected)) { return; } + } + } + + // no icon found at all + throw new RuntimeException("the icon wasn't found"); + } + + private void showDialogOrFrame() { + + JOptionPane pane = new JOptionPane("", + JOptionPane.DEFAULT_OPTION, + JOptionPane.INFORMATION_MESSAGE, + getIcon()); + pane.setOptions(new Object[]{}); // no buttons + + if (isInternal) { + frame = pane.createInternalFrame(parentPane, ""); + frame.setLocation(0, 0); + frame.setVisible(true); + } else { + dialog = pane.createDialog(parentPane, ""); + dialog.setVisible(true); + } + } + + public void clickButton(ExtendedRobot robot) { + + Point pt = run.getLocationOnScreen(); + robot.mouseMove(pt.x + run.getWidth() / 2, pt.y + run.getHeight() / 2); + robot.waitForIdle(); + robot.click(); + } + + @Override + public void actionPerformed(ActionEvent event) { showDialogOrFrame(); } + + + public static void main(String[] args) throws Exception { + + for (UIManager.LookAndFeelInfo LF: UIManager.getInstalledLookAndFeels()) { + System.out.println("\nL&F: " + LF.getName()); + (new MultiResolutionJOptionPaneIconTest(false, LF)).doTest(); + (new MultiResolutionJOptionPaneIconTest(true , LF)).doTest(); + } + } +} diff --git a/jdk/test/java/awt/image/multiresolution/MultiResolutionRenderingHintsTest.java b/jdk/test/java/awt/image/multiresolution/MultiResolutionRenderingHintsTest.java index 063088ca5c9..c6a6f845db4 100644 --- a/jdk/test/java/awt/image/multiresolution/MultiResolutionRenderingHintsTest.java +++ b/jdk/test/java/awt/image/multiresolution/MultiResolutionRenderingHintsTest.java @@ -47,6 +47,7 @@ import sun.java2d.loops.SurfaceType; * @author Alexander Scherbatiy * @summary Custom MultiResolution image support on HiDPI displays * @modules java.desktop/sun.java2d + * @modules java.desktop/sun.java2d.loops * @run main MultiResolutionRenderingHintsTest */ public class MultiResolutionRenderingHintsTest { diff --git a/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.java b/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.java index f6f069b0ed8..87a6de00917 100644 --- a/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.java +++ b/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.java @@ -90,8 +90,10 @@ public class MultiResolutionTrayIconTest extends Applet { BufferedImage nok = generateImage(w / 2 + 2, h / 2 + 2, Color.RED); BaseMultiResolutionImage mri = new BaseMultiResolutionImage(new BufferedImage[] {nok, img}); - icon = new TrayIcon(img); + icon = new TrayIcon(img); + icon.setImageAutoSize(true); // just in case iconMRI = new TrayIcon(mri); + iconMRI.setImageAutoSize(true); } private void doTest() { diff --git a/jdk/test/java/awt/image/multiresolution/MultiresolutionIconTest.java b/jdk/test/java/awt/image/multiresolution/MultiresolutionIconTest.java new file mode 100644 index 00000000000..e35a98a23d4 --- /dev/null +++ b/jdk/test/java/awt/image/multiresolution/MultiresolutionIconTest.java @@ -0,0 +1,223 @@ +/* + * Copyright (c) 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 + * @bug 8150724 8151303 + * @author a.stepanov + * @summary Check that correct resolution variants are chosen for icons + * when multiresolution image is used for their construction. + * + * @library ../../../../lib/testlibrary/ + * @build ExtendedRobot + * @run main/othervm/timeout=240 -Dsun.java2d.uiScale=1 MultiresolutionIconTest + * @run main/othervm/timeout=240 -Dsun.java2d.uiScale=2 MultiresolutionIconTest + */ + + +// TODO: please remove the "@requires" tag after 8151303 fix + + +import java.awt.*; +import java.awt.event.InputEvent; +import java.awt.image.BaseMultiResolutionImage; +import java.awt.image.BufferedImage; +import javax.swing.*; + +public class MultiresolutionIconTest extends JFrame { + + private final static int SZ = 100; + private final static int N = 5; // number of components + + private final static String SCALE = "sun.java2d.uiScale"; + private final static Color C1X = Color.RED; + private final static Color C2X = Color.BLUE; + + private JLabel lbl; + private JTabbedPane tabbedPane; + + private final ExtendedRobot r; + + private static BufferedImage generateImage(int sz, Color c) { + + BufferedImage img = new BufferedImage(sz, sz, BufferedImage.TYPE_INT_RGB); + Graphics g = img.getGraphics(); + g.setColor(c); + g.fillRect(0, 0, sz, sz); + return img; + } + + public MultiresolutionIconTest(UIManager.LookAndFeelInfo lf) throws Exception { + + UIManager.setLookAndFeel(lf.getClassName()); + r = new ExtendedRobot(); + SwingUtilities.invokeAndWait(this::UI); + } + + private void UI() { + + setUndecorated(true); + + BufferedImage img1x = generateImage(SZ / 2, C1X); + BufferedImage img2x = generateImage(SZ, C2X); + BaseMultiResolutionImage mri = new BaseMultiResolutionImage( + new BufferedImage[]{img1x, img2x}); + Icon icon = new ImageIcon(mri); + + // hardcoded icon size for OS X (Mac OS X L&F) - see JDK-8151060 + BufferedImage tab1x = generateImage(16, C1X); + BufferedImage tab2x = generateImage(32, C2X); + BaseMultiResolutionImage tabMRI = new BaseMultiResolutionImage( + new BufferedImage[]{tab1x, tab2x}); + Icon tabIcon = new ImageIcon(tabMRI); + + setSize((N + 1) * SZ, SZ); + setLocation(50, 50); + + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + getContentPane().setLayout(new GridLayout(1, 1)); + + JPanel p = new JPanel(); + p.setLayout(new GridLayout(1, N)); + + JButton btn = new JButton(icon); + p.add(btn); + + JToggleButton tbn = new JToggleButton(icon); + p.add(tbn); + + JRadioButton rbn = new JRadioButton(icon); + rbn.setHorizontalAlignment(SwingConstants.CENTER); + p.add(rbn); + + JCheckBox cbx = new JCheckBox(icon); + cbx.setHorizontalAlignment(SwingConstants.CENTER); + p.add(cbx); + + lbl = new JLabel(icon); + p.add(lbl); + + tabbedPane = new JTabbedPane(JTabbedPane.LEFT); + tabbedPane.addTab("", tabIcon, p); + getContentPane().add(tabbedPane); + + setResizable(false); + setVisible(true); + } + + private boolean checkPressedColor(int x, int y, Color ok) { + + r.mouseMove(x, y); + r.waitForIdle(); + r.mousePress(InputEvent.BUTTON1_DOWN_MASK); + r.waitForIdle(100); + Color c = r.getPixelColor(x, y); + r.waitForIdle(100); + r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + r.waitForIdle(100); + if (!c.equals(ok)) { return false; } + // check the icon's color hasn't changed + // after the mouse was released + c = r.getPixelColor(x, y); + return c.equals(ok); + } + + private boolean checkTabIcon( + int xStart, int xEnd, int yStart, int yEnd, Color ok, Color nok) { + + for (int y = yStart; y < yEnd; y += 2) { + for (int x = xStart; x < xEnd; x += 2) { + Color c = r.getPixelColor(x, y); + if (c.equals(nok)) { return false; } + else if (c.equals(ok)) { + // shift a bit to avoid the selection effects + return checkPressedColor(x + 5, y + 5, ok); + } + } + } + + return false; // didn't find the icon + } + + + private void doTest() { + + r.waitForIdle(2000); + String scale = System.getProperty(SCALE); + boolean is2x = "2".equals(scale); + Color expected = is2x ? C2X : C1X; + Color unexpected = is2x ? C1X : C2X; + + Point p = lbl.getLocationOnScreen(); + int x = p.x + lbl.getWidth() / 2; + int y = p.y + lbl.getHeight() / 2; + int w = lbl.getWidth(); + + boolean ok = true, curr; + Color c; + String components[] = new String[]{ + "JLabel", "JCheckBox", "JRadioButton", "JToggleButton", "JButton"}; + for (int i = 0; i < N; i++) { + + curr = true; + int t = x - i * w; + + // check icon color + c = r.getPixelColor(t, y); + System.out.print(components[i] + " icon: "); + if (!c.equals(expected)) { + curr = false; + } else { + // check icon color when mouse button pressed - see JDK-8151303 + curr = checkPressedColor(t, y, expected); + } + + System.out.println(curr ? "ok" : "nok"); + ok = ok && curr; + + r.waitForIdle(); + } + + int x0 = tabbedPane.getLocationOnScreen().x; + int x1 = x - ((N - 1) * w + w / 2); + int y0 = getLocationOnScreen().y; + int y1 = y0 + getHeight(); + curr = checkTabIcon(x0, x1, y0, y1, expected, unexpected); + + System.out.println("JTabbedPane icon: " + (curr ? "ok" : "nok")); + ok = ok && curr; + + if (!ok) { throw new RuntimeException("test failed"); } + + r.waitForIdle(); + dispose(); + } + + public static void main(String[] args) throws Exception { + + for (UIManager.LookAndFeelInfo LF: UIManager.getInstalledLookAndFeels()) { + System.out.println("\nL&F: " + LF.getName()); + (new MultiresolutionIconTest(LF)).doTest(); + } + } +} diff --git a/jdk/test/java/awt/image/multiresolution/MultiresolutionSourceTest.java b/jdk/test/java/awt/image/multiresolution/MultiresolutionSourceTest.java new file mode 100644 index 00000000000..e9aebf4052f --- /dev/null +++ b/jdk/test/java/awt/image/multiresolution/MultiresolutionSourceTest.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 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 + * @bug 8151269 + * @author a.stepanov + * @summary Multiresolution image: check that the base resolution variant + * source is passed to the corresponding ImageConsumer + * @run main MultiresolutionSourceTest + */ + +import java.awt.*; +import java.awt.image.*; + +public class MultiresolutionSourceTest { + + private static class Checker implements ImageConsumer { + + private final int refW, refH, refType; + private final boolean refHasAlpha; + private final Color refColor; + + public Checker(int w, + int h, + Color c, + boolean hasAlpha, + int transferType) { + refW = w; + refH = h; + refColor = c; + refHasAlpha = hasAlpha; + refType = transferType; + } + + @Override + public void imageComplete(int status) {} + + @Override + public void setColorModel(ColorModel model) { + + boolean a = model.hasAlpha(); + if (a != refHasAlpha) { + throw new RuntimeException("invalid hasAlpha: " + a); + } + + int tt = model.getTransferType(); + if (tt != refType) { + throw new RuntimeException("invalid transfer type: " + tt); + } + } + + @Override + public void setDimensions(int w, int h) { + + if (w != refW) { throw new RuntimeException("invalid width: " + w + + ", expected: " + refW); } + + if (h != refH) { throw new RuntimeException("invalid height: " + h + + ", expected: " + refH); } + } + + @Override + public void setHints(int flags) {} + + @Override + public void setPixels(int x, int y, int w, int h, ColorModel model, + byte pixels[], int offset, int scansize) { + + for (int i = 0; i < pixels.length; i++) { + int p = pixels[i]; + // just in case... + Color c = model.hasAlpha() ? + new Color(model.getRed (p), + model.getGreen(p), + model.getBlue (p), + model.getAlpha(p)) : + new Color(model.getRGB(p)); + + if (!c.equals(refColor)) { + throw new RuntimeException("invalid color: " + c + + ", expected: " + refColor); + } + } + } + + @Override + public void setPixels(int x, int y, int w, int h, ColorModel model, + int pixels[], int offset, int scansize) { + + for (int i = 0; i < pixels.length; i++) { + int p = pixels[i]; + Color c = model.hasAlpha() ? + new Color(model.getRed (p), + model.getGreen(p), + model.getBlue (p), + model.getAlpha(p)) : + new Color(model.getRGB(p)); + + if (!c.equals(refColor)) { + throw new RuntimeException("invalid color: " + c + + ", expected: " + refColor); + } + } + } + + @Override + public void setProperties(java.util.Hashtable props) {} + } + + private static BufferedImage generateImage(int w, int h, Color c, int type) { + + BufferedImage img = new BufferedImage(w, h, type); + Graphics g = img.getGraphics(); + g.setColor(c); + g.fillRect(0, 0, w, h); + return img; + } + + public static void main(String[] args) { + + final int w1 = 20, w2 = 100, h1 = 30, h2 = 50; + final Color + c1 = new Color(255, 0, 0, 100), c2 = Color.BLACK, gray = Color.GRAY; + + BufferedImage img1 = + generateImage(w1, h1, c1, BufferedImage.TYPE_INT_ARGB); + + BufferedImage dummy = + generateImage(w1 + 5, h1 + 5, gray, BufferedImage.TYPE_BYTE_GRAY); + + BufferedImage img2 = + generateImage(w2, h2, c2, BufferedImage.TYPE_BYTE_BINARY); + + BufferedImage vars[] = new BufferedImage[] {img1, dummy, img2}; + + // default base image index (zero) + BaseMultiResolutionImage mri1 = new BaseMultiResolutionImage(vars); + // base image index = 2 + BaseMultiResolutionImage mri2 = new BaseMultiResolutionImage(2, vars); + + // do checks + mri1.getSource().startProduction( + new Checker(w1, h1, c1, true, DataBuffer.TYPE_INT)); + + mri2.getSource().startProduction( + new Checker(w2, h2, c2, false, DataBuffer.TYPE_BYTE)); + } +} diff --git a/jdk/test/java/awt/keyboard/AllKeyCode/AllKeyCode.java b/jdk/test/java/awt/keyboard/AllKeyCode/AllKeyCode.java new file mode 100644 index 00000000000..2cb9c5cd3f2 --- /dev/null +++ b/jdk/test/java/awt/keyboard/AllKeyCode/AllKeyCode.java @@ -0,0 +1,227 @@ +/* + * Copyright (c) 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 + @bug 8149456 8147834 8150230 + @requires os.family == "mac" + @summary KeyEvents for all keys + @run main AllKeyCode +*/ + +import java.awt.AWTException; +import java.awt.GridBagLayout; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.Frame; +import java.awt.TextArea; + +public class AllKeyCode extends Frame { + + private static Frame frame; + private static TextArea textArea; + private static KeyListener keyListener; + private static int allKeyArr[]; + private static int keyPressedIndex; + + AllKeyCode() { + AllKeyCode.allKeyArr = new int[] { + KeyEvent.VK_BACK_SPACE, + KeyEvent.VK_TAB, + KeyEvent.VK_ENTER, + KeyEvent.VK_CLEAR, + KeyEvent.VK_SHIFT, + KeyEvent.VK_CONTROL, + KeyEvent.VK_ALT, + KeyEvent.VK_CAPS_LOCK, + KeyEvent.VK_ESCAPE, + KeyEvent.VK_SPACE, + KeyEvent.VK_PAGE_UP, + KeyEvent.VK_PAGE_DOWN, + KeyEvent.VK_END, + KeyEvent.VK_HOME, + KeyEvent.VK_LEFT, + KeyEvent.VK_UP, + KeyEvent.VK_RIGHT, + KeyEvent.VK_DOWN, + KeyEvent.VK_COMMA, + KeyEvent.VK_MINUS, + KeyEvent.VK_PERIOD, + KeyEvent.VK_SLASH, + KeyEvent.VK_0, + KeyEvent.VK_1, + KeyEvent.VK_2, + KeyEvent.VK_3, + KeyEvent.VK_4, + KeyEvent.VK_5, + KeyEvent.VK_6, + KeyEvent.VK_7, + KeyEvent.VK_8, + KeyEvent.VK_9, + KeyEvent.VK_SEMICOLON, + KeyEvent.VK_EQUALS, + KeyEvent.VK_A, + KeyEvent.VK_B, + KeyEvent.VK_C, + KeyEvent.VK_D, + KeyEvent.VK_E, + KeyEvent.VK_F, + KeyEvent.VK_G, + KeyEvent.VK_H, + KeyEvent.VK_I, + KeyEvent.VK_J, + KeyEvent.VK_K, + KeyEvent.VK_L, + KeyEvent.VK_M, + KeyEvent.VK_N, + KeyEvent.VK_O, + KeyEvent.VK_P, + KeyEvent.VK_Q, + KeyEvent.VK_R, + KeyEvent.VK_S, + KeyEvent.VK_T, + KeyEvent.VK_U, + KeyEvent.VK_V, + KeyEvent.VK_W, + KeyEvent.VK_X, + KeyEvent.VK_Y, + KeyEvent.VK_Z, + KeyEvent.VK_OPEN_BRACKET, + KeyEvent.VK_BACK_SLASH, + KeyEvent.VK_CLOSE_BRACKET, + KeyEvent.VK_NUMPAD0, + KeyEvent.VK_NUMPAD1, + KeyEvent.VK_NUMPAD2, + KeyEvent.VK_NUMPAD3, + KeyEvent.VK_NUMPAD4, + KeyEvent.VK_NUMPAD5, + KeyEvent.VK_NUMPAD6, + KeyEvent.VK_NUMPAD7, + KeyEvent.VK_NUMPAD8, + KeyEvent.VK_NUMPAD9, + KeyEvent.VK_MULTIPLY, + KeyEvent.VK_ADD, + KeyEvent.VK_SUBTRACT, + KeyEvent.VK_DECIMAL, + KeyEvent.VK_DIVIDE, + KeyEvent.VK_F1, + KeyEvent.VK_F2, + KeyEvent.VK_F3, + KeyEvent.VK_F4, + KeyEvent.VK_F5, + KeyEvent.VK_F6, + KeyEvent.VK_F7, + KeyEvent.VK_F8, + KeyEvent.VK_F9, + KeyEvent.VK_F10, + KeyEvent.VK_F11, + KeyEvent.VK_F12, + KeyEvent.VK_DELETE, + KeyEvent.VK_HELP, + KeyEvent.VK_META, + KeyEvent.VK_BACK_QUOTE, + KeyEvent.VK_QUOTE, + KeyEvent.VK_F13, + KeyEvent.VK_F14, + KeyEvent.VK_F15, + KeyEvent.VK_F16, + KeyEvent.VK_F17, + KeyEvent.VK_F18, + KeyEvent.VK_F19, + KeyEvent.VK_F20 + }; + + keyPressedIndex = -1; + } + + private void createAndShowGUI() { + frame = new Frame("Function Key Keycodes"); + textArea = new TextArea(); + textArea.setFocusable(true); + frame.add(textArea); + frame.pack(); + frame.setSize(200, 200); + + textArea.addKeyListener(keyListener = new KeyListener() { + + @Override + public void keyTyped(KeyEvent ke) { + } + + @Override + public void keyPressed(KeyEvent ke) { + if (allKeyArr[keyPressedIndex] != ke.getKeyCode()) { + throw new RuntimeException("Wrong keycode received"); + } + } + + @Override + public void keyReleased(KeyEvent ke) { + } + }); + frame.setVisible(true); + } + + private void removeListener() { + if (keyListener != null) { + textArea.removeKeyListener(keyListener); + keyListener = null; + } + } + + @Override + public void dispose() { + if (null != frame) { + frame.dispose(); + frame = null; + } + } + + public void generateFunctionKeyPress() { + try { + Robot robot = new Robot(); + robot.waitForIdle(); + + for (int i = 0; i < allKeyArr.length; i++) { + keyPressedIndex = i; + robot.keyPress(allKeyArr[i]); + robot.keyRelease(allKeyArr[i]); + robot.waitForIdle(); + } + removeListener(); + + } catch (AWTException e) { + throw new RuntimeException("Robot creation failed"); + } + } + + public static void main(String args[]) { + AllKeyCode allKeyObj = new AllKeyCode(); + allKeyObj.createAndShowGUI(); + allKeyObj.generateFunctionKeyPress(); + allKeyObj.dispose(); + + System.out.println("Test Passed"); + } +} diff --git a/jdk/test/java/awt/print/PageFormat/PageFormatFromAttributes.java b/jdk/test/java/awt/print/PageFormat/PageFormatFromAttributes.java index 082ab3f8ba2..e552db507de 100644 --- a/jdk/test/java/awt/print/PageFormat/PageFormatFromAttributes.java +++ b/jdk/test/java/awt/print/PageFormat/PageFormatFromAttributes.java @@ -84,12 +84,13 @@ public class PageFormatFromAttributes { throw new RuntimeException("expected a media size"); } double units = Size2DSyntax.INCH/72.0; - int w = (int)(mediaSize.getX(1)/units); - int h = (int)(mediaSize.getY(1)/units); + double w = mediaSize.getX(1) / units; + double h = mediaSize.getY(1) / units; Paper paper = pf.getPaper(); - int pw = (int)paper.getWidth(); - int ph = (int)paper.getHeight(); - if (pw != w || ph != h) { + double pw = paper.getWidth(); + double ph = paper.getHeight(); + if (Math.round(pw) != Math.round(w) || + Math.round(ph) != Math.round(h)) { throw new RuntimeException("size not as specified"); } } diff --git a/jdk/test/java/awt/print/PrinterJob/MultiMonPrintDlgTest.java b/jdk/test/java/awt/print/PrinterJob/MultiMonPrintDlgTest.java index 013de39b8a1..4086f663a5c 100644 --- a/jdk/test/java/awt/print/PrinterJob/MultiMonPrintDlgTest.java +++ b/jdk/test/java/awt/print/PrinterJob/MultiMonPrintDlgTest.java @@ -43,16 +43,18 @@ import javax.swing.SwingUtilities; */ public class MultiMonPrintDlgTest implements ActionListener { - Frame primaryFrame = null; - Frame secFrame = null; - GraphicsDevice gd[] = GraphicsEnvironment.getLocalGraphicsEnvironment(). + private static boolean testPassed; + private static Thread mainThread; + private static boolean testGeneratedInterrupt; + private static int sleepTime = 30000; + private static String message = "User has not executed the test"; + + static Frame primaryFrame = null; + static Frame secFrame = null; + static GraphicsDevice gd[] = GraphicsEnvironment.getLocalGraphicsEnvironment(). getScreenDevices(); - public MultiMonPrintDlgTest() throws Exception { - if (gd.length <= 1) { - System.out.println("This test should be run only on dual-monitor systems. Aborted!!"); - return; - } + private static void init() throws Exception { String[] instructions = { @@ -70,6 +72,10 @@ public class MultiMonPrintDlgTest implements ActionListener { instructions, "information", JOptionPane.INFORMATION_MESSAGE); }); + } + + private void executeTest() { + GraphicsDevice defDev = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); int x = 0; Frame f = null; @@ -95,31 +101,67 @@ public class MultiMonPrintDlgTest implements ActionListener { } public void actionPerformed (ActionEvent ae) { - try { - javax.print.attribute.PrintRequestAttributeSet prSet = - new javax.print.attribute.HashPrintRequestAttributeSet(); - java.awt.print.PrinterJob.getPrinterJob().pageDialog(prSet); - Window w = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); - int dialogButton = JOptionPane.showConfirmDialog (w, - "Did the pageDialog shown in non-default monitor?", - null, JOptionPane.YES_NO_OPTION); - if(dialogButton == JOptionPane.NO_OPTION) { - throw new RuntimeException("PageDialog is shown in wrong monitor"); - } + javax.print.attribute.PrintRequestAttributeSet prSet = + new javax.print.attribute.HashPrintRequestAttributeSet(); + java.awt.print.PrinterJob.getPrinterJob().pageDialog(prSet); + Window w = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); + int dialogButton = JOptionPane.showConfirmDialog (w, + "Did the pageDialog shown in non-default monitor?", + null, JOptionPane.YES_NO_OPTION); + if(dialogButton == JOptionPane.NO_OPTION) { + fail("PageDialog is shown in wrong monitor"); + } else { java.awt.print.PrinterJob.getPrinterJob().printDialog(prSet); dialogButton = JOptionPane.showConfirmDialog (w, - "Did the printDialog shown in non-default monitor?", - null, JOptionPane.YES_NO_OPTION); + "Did the printDialog shown in non-default monitor?", + null, JOptionPane.YES_NO_OPTION); if(dialogButton == JOptionPane.NO_OPTION) { - throw new RuntimeException("PrintDialog is shown in wrong monitor"); + fail("PrintDialog is shown in wrong monitor"); + } else { + pass(); } - } finally { - primaryFrame.dispose(); - secFrame.dispose(); } } + private static void dispose() { + primaryFrame.dispose(); + secFrame.dispose(); + } + + public static synchronized void pass() { + testPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + public static synchronized void fail(String msg) { + testPassed = false; + message = msg; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + public static void main (String args[]) throws Exception { + if (gd.length <= 1) { + System.out.println("This test should be run only on dual-monitor systems. Aborted!!"); + return; + } + init(); MultiMonPrintDlgTest test = new MultiMonPrintDlgTest(); + test.executeTest(); + mainThread = Thread.currentThread(); + + try { + mainThread.sleep(sleepTime); + } catch (InterruptedException ex) { + dispose(); + if (!testPassed && testGeneratedInterrupt) { + throw new RuntimeException(message); + } + } + if (!testGeneratedInterrupt) { + dispose(); + throw new RuntimeException(message); + } } } diff --git a/jdk/test/java/awt/print/PrinterJob/PrintTest.java b/jdk/test/java/awt/print/PrinterJob/PrintTest.java new file mode 100644 index 00000000000..3c3febe414c --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintTest.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 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 + * @bug 8151590 + * @summary All radio button should be selected when we call + * setDefaultSelection(JobAttributes.DefaultSelectionType.ALL); + * @run main/manual PrintTest + */ +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.JobAttributes; +import java.awt.PageAttributes; +import java.awt.PrintJob; +import java.awt.Toolkit; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; + +public class PrintTest { + + private static Thread mainThread; + private static boolean testPassed; + private static boolean testGeneratedInterrupt; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + doTest(PrintTest::printTest); + } + }); + mainThread = Thread.currentThread(); + try { + mainThread.sleep(30000); + } catch (InterruptedException e) { + if (!testPassed && testGeneratedInterrupt) { + throw new RuntimeException("All radio button is not selected"); + } + } + if (!testGeneratedInterrupt) { + throw new RuntimeException("user has not executed the test"); + } + } + + private static void printTest() { + JobAttributes job = new JobAttributes(); + PageAttributes page = new PageAttributes(); + job.setDialog(JobAttributes.DialogType.NATIVE); + job.setDefaultSelection(JobAttributes.DefaultSelectionType.ALL); + job.setFromPage(2); + job.setToPage(5); + Toolkit tk = Toolkit.getDefaultToolkit(); + // setting this dialog to native printdialog + if (tk != null) { + PrintJob pj = tk.getPrintJob(new JFrame(), + "testing the attribute setting ", job, page); + } + } + + public static synchronized void pass() { + testPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + public static synchronized void fail() { + testPassed = false; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + private static void doTest(Runnable action) { + String description + = " Visual inspection of print dialog is required.\n" + + " A print dialog will be shown.\n " + + " Please verify ALL radio button is selected.\n" + + " If ALL radio button is selected,press PASS else press FAIL"; + + final JDialog dialog = new JDialog(); + dialog.setTitle("printSelectionTest"); + JTextArea textArea = new JTextArea(description); + textArea.setEditable(false); + final JButton testButton = new JButton("Start Test"); + final JButton passButton = new JButton("PASS"); + passButton.setEnabled(false); + passButton.addActionListener((e) -> { + dialog.dispose(); + pass(); + }); + final JButton failButton = new JButton("FAIL"); + failButton.setEnabled(false); + failButton.addActionListener((e) -> { + dialog.dispose(); + fail(); + }); + testButton.addActionListener((e) -> { + testButton.setEnabled(false); + action.run(); + passButton.setEnabled(true); + failButton.setEnabled(true); + }); + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(textArea, BorderLayout.CENTER); + JPanel buttonPanel = new JPanel(new FlowLayout()); + buttonPanel.add(testButton); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + dialog.add(mainPanel); + dialog.pack(); + dialog.setVisible(true); + } +} diff --git a/jdk/test/java/awt/xembed/server/RunTestXEmbed.java b/jdk/test/java/awt/xembed/server/RunTestXEmbed.java index 04bb05dc04f..232e24c224c 100644 --- a/jdk/test/java/awt/xembed/server/RunTestXEmbed.java +++ b/jdk/test/java/awt/xembed/server/RunTestXEmbed.java @@ -28,8 +28,8 @@ * @author Denis Mikhalkin: area=awt.xembed * @requires (!(os.family=="mac") & !(os.family=="windows")) * @library /lib/testlibrary - * @build jdk.testlibrary.Platform * @modules java.desktop/sun.awt + * @build jdk.testlibrary.Platform * @compile JavaClient.java TesterClient.java TestXEmbedServer.java * @run main/timeout=6000 RunTestXEmbed */ @@ -39,6 +39,7 @@ import java.lang.reflect.Method; import java.util.logging.*; import java.util.*; import java.io.*; +import jdk.testlibrary.Platform; public class RunTestXEmbed extends TestXEmbedServer { private static final Logger log = Logger.getLogger("test.xembed"); @@ -72,7 +73,7 @@ public class RunTestXEmbed extends TestXEmbedServer { } } Process proc = Runtime.getRuntime().exec(java_home + - "/bin/java -Dawt.toolkit=sun.awt.X11.XToolkit TesterClient " + "/bin/java -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED -Dawt.toolkit=sun.awt.X11.XToolkit TesterClient " + test.getName() + " " + window + buf, enva); System.err.println("Test for " + test.getName() + " has started."); diff --git a/jdk/test/java/awt/xembed/server/TestXEmbedServerJava.java b/jdk/test/java/awt/xembed/server/TestXEmbedServerJava.java index 05e729e3caf..75898f4cbfe 100644 --- a/jdk/test/java/awt/xembed/server/TestXEmbedServerJava.java +++ b/jdk/test/java/awt/xembed/server/TestXEmbedServerJava.java @@ -26,6 +26,7 @@ * @bug 4931668 * @summary Tests XEmbed server/client functionality * @author denis mikhalkin: area=awt.xembed + * @requires (!(os.family=="mac") & !(os.family=="windows")) * @modules java.desktop/sun.awt * @compile JavaClient.java TesterClient.java TestXEmbedServer.java * @run main/manual TestXEmbedServerJava @@ -38,9 +39,6 @@ import java.io.*; public class TestXEmbedServerJava extends TestXEmbedServer { public static void main(String[] args) { - if (System.getProperty("os.name").toLowerCase().startsWith("win")) { - return; - } // Enabled XEmbed System.setProperty("sun.awt.xembedserver", "true"); @@ -78,7 +76,7 @@ public class TestXEmbedServerJava extends TestXEmbedServer { public Process startClient(Rectangle[] bounds, long window) { try { String java_home = System.getProperty("java.home"); - return Runtime.getRuntime().exec(java_home + "/bin/java JavaClient " + window); + return Runtime.getRuntime().exec(java_home + "/bin/java -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED JavaClient " + window); } catch (IOException ex1) { ex1.printStackTrace(); } diff --git a/jdk/test/java/awt/xembed/server/TesterClient.java b/jdk/test/java/awt/xembed/server/TesterClient.java index 535e65bb45d..699f57bd732 100644 --- a/jdk/test/java/awt/xembed/server/TesterClient.java +++ b/jdk/test/java/awt/xembed/server/TesterClient.java @@ -32,7 +32,6 @@ public class TesterClient { public static void main(String[] args) throws Throwable { // First parameter is the name of the test, second is the window, the rest are rectangles Class cl = Class.forName("sun.awt.X11.XEmbedServerTester"); - cl.getModule().addExports("sun.awt.X11",TesterClient.class.getModule()); test = cl.getMethod(args[0], new Class[0]); long window = Long.parseLong(args[1]); diff --git a/jdk/test/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java b/jdk/test/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java index 45a7b8e2259..393f9c7c4c6 100644 --- a/jdk/test/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java +++ b/jdk/test/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java @@ -61,8 +61,8 @@ import jdk.internal.module.Modules; * loads all the classes in the BCL, get their declared fields, * and call setAccessible(false) followed by setAccessible(true); * @modules java.base/jdk.internal.module - * @run main/othervm FieldSetAccessibleTest UNSECURE - * @run main/othervm FieldSetAccessibleTest SECURE + * @run main/othervm -Djdk.launcher.addmods=ALL-SYSTEM FieldSetAccessibleTest UNSECURE + * @run main/othervm -Djdk.launcher.addmods=ALL-SYSTEM FieldSetAccessibleTest SECURE * * @author danielfuchs */ diff --git a/jdk/test/java/lang/ProcessBuilder/Basic.java b/jdk/test/java/lang/ProcessBuilder/Basic.java index 7be2aa6ba71..9a1d97647f7 100644 --- a/jdk/test/java/lang/ProcessBuilder/Basic.java +++ b/jdk/test/java/lang/ProcessBuilder/Basic.java @@ -29,7 +29,6 @@ * 4947220 7018606 7034570 4244896 5049299 8003488 8054494 8058464 * 8067796 * @summary Basic tests for Process and Environment Variable code - * @modules java.base/sun.misc * @run main/othervm/timeout=300 Basic * @run main/othervm/timeout=300 -Djdk.lang.Process.launchMechanism=fork Basic * @author Martin Buchholz diff --git a/jdk/test/java/lang/ProcessBuilder/RedirectWithLongFilename.java b/jdk/test/java/lang/ProcessBuilder/RedirectWithLongFilename.java index 9f4c9fef0cb..0922153c511 100644 --- a/jdk/test/java/lang/ProcessBuilder/RedirectWithLongFilename.java +++ b/jdk/test/java/lang/ProcessBuilder/RedirectWithLongFilename.java @@ -25,7 +25,6 @@ * @test * @bug 8072611 * @summary ProcessBuilder Redirect to file appending on Windows should work with long file names - * @modules java.base/sun.misc * @author Thomas Stuefe */ diff --git a/jdk/test/java/lang/ProcessHandle/Basic.java b/jdk/test/java/lang/ProcessHandle/Basic.java index 2d7258f3ccc..b759e9c7c39 100644 --- a/jdk/test/java/lang/ProcessHandle/Basic.java +++ b/jdk/test/java/lang/ProcessHandle/Basic.java @@ -37,7 +37,8 @@ import org.testng.annotations.Test; /* * @test * @library /test/lib/share/classes - * @modules jdk.management + * @modules java.base/jdk.internal.misc + * jdk.management * @run testng Basic * @summary Basic tests for ProcessHandler * @author Roger Riggs diff --git a/jdk/test/java/lang/ProcessHandle/InfoTest.java b/jdk/test/java/lang/ProcessHandle/InfoTest.java index e269d3e33c8..7d8867d67da 100644 --- a/jdk/test/java/lang/ProcessHandle/InfoTest.java +++ b/jdk/test/java/lang/ProcessHandle/InfoTest.java @@ -49,7 +49,8 @@ import org.testng.annotations.Test; * @test * @bug 8077350 8081566 8081567 8098852 8136597 * @library /test/lib/share/classes - * @modules jdk.management + * @modules java.base/jdk.internal.misc + * jdk.management * @build jdk.test.lib.Platform jdk.test.lib.Utils * @run testng InfoTest * @summary Functions of ProcessHandle.Info diff --git a/jdk/test/java/lang/ProcessHandle/OnExitTest.java b/jdk/test/java/lang/ProcessHandle/OnExitTest.java index 77cc19d86dd..c797f4a705b 100644 --- a/jdk/test/java/lang/ProcessHandle/OnExitTest.java +++ b/jdk/test/java/lang/ProcessHandle/OnExitTest.java @@ -39,7 +39,8 @@ import org.testng.TestNG; /* * @test * @library /test/lib/share/classes - * @modules jdk.management + * @modules java.base/jdk.internal.misc + * jdk.management * @build jdk.test.lib.Platform jdk.test.lib.Utils * @run testng OnExitTest * @summary Functions of Process.onExit and ProcessHandle.onExit diff --git a/jdk/test/java/lang/ProcessHandle/TreeTest.java b/jdk/test/java/lang/ProcessHandle/TreeTest.java index 9840718d881..7ff580053e0 100644 --- a/jdk/test/java/lang/ProcessHandle/TreeTest.java +++ b/jdk/test/java/lang/ProcessHandle/TreeTest.java @@ -45,7 +45,8 @@ import org.testng.annotations.Test; /* * @test * @library /test/lib/share/classes - * @modules jdk.management + * @modules java.base/jdk.internal.misc + * jdk.management * @build jdk.test.lib.Utils * @run testng/othervm TreeTest * @summary Test counting and JavaChild.spawning and counting of Processes. diff --git a/jdk/test/java/lang/invoke/VMAnonymousClass.java b/jdk/test/java/lang/invoke/VMAnonymousClass.java index 5a2eebfffa8..8cd24d21c41 100644 --- a/jdk/test/java/lang/invoke/VMAnonymousClass.java +++ b/jdk/test/java/lang/invoke/VMAnonymousClass.java @@ -24,7 +24,7 @@ /* @test * @bug 8046903 * @summary VM anonymous class members can't be statically invocable - * @modules java.base/sun.misc java.base/jdk.internal.org.objectweb.asm + * @modules java.base/jdk.internal.misc java.base/jdk.internal.org.objectweb.asm * @run junit test.java.lang.invoke.VMAnonymousClass */ package test.java.lang.invoke; @@ -34,7 +34,7 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Field; import org.junit.Test; -import sun.misc.Unsafe; +import jdk.internal.misc.Unsafe; import jdk.internal.org.objectweb.asm.*; import static jdk.internal.org.objectweb.asm.Opcodes.*; @@ -43,17 +43,17 @@ public class VMAnonymousClass { VMAnonymousClass test = new VMAnonymousClass(); test.testJavaLang(); test.testJavaUtil(); - test.testSunMisc(); + test.testJdkInternalMisc(); test.testJavaLangInvoke(); System.out.println("TEST PASSED"); } // Test VM anonymous classes from different packages // (see j.l.i.InvokerBytecodeGenerator::isStaticallyInvocable). - @Test public void testJavaLang() throws Throwable { test("java/lang"); } - @Test public void testJavaUtil() throws Throwable { test("java/util"); } - @Test public void testSunMisc() throws Throwable { test("sun/misc"); } - @Test public void testJavaLangInvoke() throws Throwable { test("java/lang/invoke"); } + @Test public void testJavaLang() throws Throwable { test("java/lang"); } + @Test public void testJavaUtil() throws Throwable { test("java/util"); } + @Test public void testJdkInternalMisc() throws Throwable { test("jdk/internal/misc"); } + @Test public void testJavaLangInvoke() throws Throwable { test("java/lang/invoke"); } private static Unsafe unsafe = getUnsafe(); diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseByteArrayTest.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseByteArrayTest.java new file mode 100644 index 00000000000..6d90d77e0de --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseByteArrayTest.java @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2015, 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. + */ + +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; + +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 java.util.function.Function; + +public abstract class VarHandleBaseByteArrayTest extends VarHandleBaseTest { + + enum MemoryMode { + ALIGNED(0, false), UNALIGNED(0, true), + BIG_ENDIAN(1, false), LITTLE_ENDIAN(1, true), + READ_WRITE(2, false), READ_ONLY(2, true),; + + final int bit; + final int value; + + MemoryMode(int bit, boolean value) { + this.bit = bit; + this.value = value ? 1 << bit : 0; + } + + boolean isSet(int bitSet) { + return (bitSet & (1 << bit)) == value; + } + + static int bitSet(MemoryMode... modes) { + if (modes == null) return 0; + + int set = 0; + for (MemoryMode m : modes) { + set = (set & ~(1 << m.bit)) | m.value; + } + return set; + } + + static EnumSet enumSet(int bitSet) { + EnumSet es = EnumSet.noneOf(MemoryMode.class); + for (MemoryMode m : values()) { + if (m.isSet(bitSet)) { + es.add(m); + } + } + return es; + } + } + + static class Source { + final T s; + final int memoryModes; + + public Source(T s, MemoryMode... modes) { + this.s = s; + memoryModes = MemoryMode.bitSet(modes); + } + + @Override + public String toString() { + return s.getClass().getCanonicalName() + " " + MemoryMode.enumSet(memoryModes); + } + } + + static abstract class ByteArrayViewSource extends Source { + public ByteArrayViewSource(T t, MemoryMode... modes) { + super(t, modes); + } + + abstract void fill(byte value); + + abstract void fill(byte[] values); + } + + static class ByteArraySource extends ByteArrayViewSource { + public ByteArraySource(byte[] bytes, MemoryMode... modes) { + super(bytes, modes); + } + + void fill(byte value) { + Arrays.fill(s, value); + } + + void fill(byte[] values) { + for (int i = 0; i < s.length; i++) { + s[i] = values[i % values.length]; + } + } + } + + static class ByteBufferSource extends ByteArrayViewSource { + public ByteBufferSource(ByteBuffer buffer, MemoryMode... modes) { + super(buffer, modes); + } + + void fill(byte value) { + for (int i = 0; i < s.limit(); i++) { + s.put(i, value); + } + } + + void fill(byte[] values) { + for (int i = 0; i < s.limit(); i++) { + s.put(i, values[i % values.length]); + } + } + + @Override + public String toString() { + return s + " " + MemoryMode.enumSet(memoryModes); + } + } + + static class ByteBufferReadOnlySource extends ByteBufferSource { + final ByteBuffer rwSource; + + public ByteBufferReadOnlySource(ByteBuffer roBuffer, ByteBuffer rwSource, MemoryMode... modes) { + super(roBuffer, modes); + this.rwSource = rwSource; + } + + void fill(byte value) { + for (int i = 0; i < rwSource.limit(); i++) { + rwSource.put(i, value); + } + } + + void fill(byte[] values) { + for (int i = 0; i < rwSource.limit(); i++) { + rwSource.put(i, values[i % values.length]); + } + } + } + + static class VarHandleSource extends Source { + VarHandleSource(VarHandle vh, MemoryMode... modes) { + super(vh, modes); + } + + boolean matches(ByteArrayViewSource bav) { + return s.coordinateTypes().get(0).isAssignableFrom(bav.s.getClass()); + } + + @Override + public String toString() { + return " VarHandle " + MemoryMode.enumSet(memoryModes); + } + } + + static class VarHandleSourceAccessTestCase extends AccessTestCase { + final ByteArrayViewSource bs; + final VarHandleSource vhs; + + VarHandleSourceAccessTestCase(String desc, ByteArrayViewSource bs, VarHandleSource vhs, AccessTestAction ata) { + this(desc, bs, vhs, ata, true); + } + + VarHandleSourceAccessTestCase(String desc, ByteArrayViewSource bs, VarHandleSource vhs, AccessTestAction ata, boolean loop) { + super(vhs + " -> " + bs + " " + desc, ata, loop); + this.bs = bs; + this.vhs = vhs; + } + + @Override + VarHandleSource get() { + return vhs; + } + } + + + static double rotateLeft(double i, int distance) { + return Double.longBitsToDouble( + Long.rotateLeft(Double.doubleToRawLongBits(i), distance)); + } + + static double rotateRight(double i, int distance) { + return Double.longBitsToDouble( + Long.rotateRight(Double.doubleToRawLongBits(i), distance)); + } + + static float rotateLeft(float i, int distance) { + return Float.intBitsToFloat( + Integer.rotateLeft(Float.floatToRawIntBits(i), distance)); + } + + static float rotateRight(float i, int distance) { + return Float.intBitsToFloat( + Integer.rotateRight(Float.floatToRawIntBits(i), distance)); + } + + static long rotateLeft(long i, int distance) { + return Long.rotateLeft(i, distance); + } + + static long rotateRight(long i, int distance) { + return Long.rotateRight(i, distance); + } + + static int rotateLeft(int i, int distance) { + return Integer.rotateLeft(i, distance); + } + + static int rotateRight(int i, int distance) { + return Integer.rotateRight(i, distance); + } + + static short rotateLeft(short i, int distance) { + int v = (i << 16) | i; + v = Integer.rotateLeft(v, distance); + return (short) v; + } + + static short rotateRight(short i, int distance) { + int v = (i << 16) | i; + v = Integer.rotateRight(v, distance); + return (short) v; + } + + static char rotateLeft(char i, int distance) { + int v = (i << 16) | i; + v = Integer.rotateLeft(v, distance); + return (char) v; + } + + static char rotateRight(char i, int distance) { + int v = (i << 16) | i; + v = Integer.rotateRight(v, distance); + return (char) v; + } + + static final int LENGTH_BYTES = 32; + + byte[] array; + + List> bavss; + + List vhss; + + public void setupByteSources() { + array = new byte[LENGTH_BYTES]; + + // Native endianess + MemoryMode ne = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN + ? MemoryMode.BIG_ENDIAN : MemoryMode.LITTLE_ENDIAN; + + bavss = new ArrayList<>(); + + // byte[] source + ByteArraySource a = + new ByteArraySource(array, + ne, MemoryMode.READ_WRITE); + bavss.add(a); + + + // Combinations of ByteBuffer sources + ByteBufferSource hbb = + new ByteBufferSource(ByteBuffer.wrap(array), + MemoryMode.ALIGNED, ne, MemoryMode.READ_WRITE); + bavss.add(hbb); + ByteBufferReadOnlySource hbb_ro = + new ByteBufferReadOnlySource(hbb.s.asReadOnlyBuffer(), hbb.s, + MemoryMode.ALIGNED, ne, MemoryMode.READ_ONLY); + bavss.add(hbb_ro); + + ByteBufferSource hbb_offset_aligned = + new ByteBufferSource(ByteBuffer.wrap(array, array.length / 4, array.length / 2).slice(), + MemoryMode.ALIGNED, ne, MemoryMode.READ_WRITE); + bavss.add(hbb_offset_aligned); + ByteBufferReadOnlySource hbb_offset_aligned_ro = + new ByteBufferReadOnlySource(hbb_offset_aligned.s.asReadOnlyBuffer(), hbb_offset_aligned.s, + MemoryMode.ALIGNED, ne, MemoryMode.READ_ONLY); + bavss.add(hbb_offset_aligned_ro); + + ByteBufferSource hbb_offset_unaligned = + new ByteBufferSource(ByteBuffer.wrap(array, array.length / 4 - 1, array.length / 2).slice(), + MemoryMode.UNALIGNED, ne, MemoryMode.READ_WRITE); + bavss.add(hbb_offset_unaligned); + ByteBufferReadOnlySource hbb_offset_unaligned_ro = + new ByteBufferReadOnlySource(hbb_offset_unaligned.s.asReadOnlyBuffer(), hbb_offset_unaligned.s, + MemoryMode.UNALIGNED, ne, MemoryMode.READ_ONLY); + bavss.add(hbb_offset_unaligned_ro); + + + ByteBufferSource dbb = + new ByteBufferSource(ByteBuffer.allocateDirect(array.length), + MemoryMode.ALIGNED, ne, MemoryMode.READ_WRITE); + bavss.add(dbb); + ByteBufferReadOnlySource dbb_ro = + new ByteBufferReadOnlySource(dbb.s.asReadOnlyBuffer(), dbb.s, + MemoryMode.ALIGNED, ne, MemoryMode.READ_ONLY); + bavss.add(dbb_ro); + + ByteBufferSource dbb_offset_aligned = + new ByteBufferSource(dbb.s.slice().position(array.length / 4).limit(array.length / 4 + array.length / 2).slice(), + MemoryMode.ALIGNED, ne, MemoryMode.READ_WRITE); + bavss.add(dbb_offset_aligned); + ByteBufferReadOnlySource dbb_offset_aligned_ro = + new ByteBufferReadOnlySource(dbb_offset_aligned.s.asReadOnlyBuffer(), dbb_offset_aligned.s, + MemoryMode.ALIGNED, ne, MemoryMode.READ_ONLY); + bavss.add(dbb_offset_aligned_ro); + + ByteBufferSource dbb_offset_unaligned = + new ByteBufferSource(dbb.s.slice().position(array.length / 4 - 1).limit(array.length / 4 - 1 + array.length / 2).slice(), + MemoryMode.UNALIGNED, ne, MemoryMode.READ_WRITE); + bavss.add(dbb_offset_unaligned); + ByteBufferReadOnlySource dbb_offset_unaligned_ro = + new ByteBufferReadOnlySource(dbb_offset_unaligned.s.asReadOnlyBuffer(), dbb_offset_unaligned.s, + MemoryMode.UNALIGNED, ne, MemoryMode.READ_ONLY); + bavss.add(dbb_offset_unaligned_ro); + } + + @BeforeClass + public void setup() { + setupByteSources(); + setupVarHandleSources(); + } + + abstract void setupVarHandleSources(); + + + @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); + + Function>> vhToPts = vh -> + vh.coordinateTypes().get(0) == byte[].class ? aepts : bbpts; + + return vhss.stream().map(vh -> new Object[]{vh.s, vhToPts.apply(vh.s)}).toArray(Object[][]::new); + } +} diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseTest.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseTest.java new file mode 100644 index 00000000000..e41c2efc123 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseTest.java @@ -0,0 +1,476 @@ +/* + * Copyright (c) 2015, 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. + */ + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandleInfo; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.invoke.VarHandle; +import java.lang.invoke.WrongMethodTypeException; +import java.lang.reflect.Method; +import java.nio.ReadOnlyBufferException; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import static java.util.stream.Collectors.toList; +import static org.testng.Assert.*; + +abstract class VarHandleBaseTest { + static final int ITERS = Integer.getInteger("iters", 1); + + interface ThrowingRunnable { + void run() throws Throwable; + } + + static void checkUOE(ThrowingRunnable r) { + checkWithThrowable(UnsupportedOperationException.class, null, r); + } + + static void checkUOE(Object message, ThrowingRunnable r) { + checkWithThrowable(UnsupportedOperationException.class, message, r); + } + + static void checkROBE(ThrowingRunnable r) { + checkWithThrowable(ReadOnlyBufferException.class, null, r); + } + + static void checkROBE(Object message, ThrowingRunnable r) { + checkWithThrowable(ReadOnlyBufferException.class, message, r); + } + + static void checkIOOBE(ThrowingRunnable r) { + checkWithThrowable(IndexOutOfBoundsException.class, null, r); + } + + static void checkIOOBE(Object message, ThrowingRunnable r) { + checkWithThrowable(IndexOutOfBoundsException.class, message, r); + } + + static void checkISE(ThrowingRunnable r) { + checkWithThrowable(IllegalStateException.class, null, r); + } + + static void checkISE(Object message, ThrowingRunnable r) { + checkWithThrowable(IllegalStateException.class, message, r); + } + + static void checkIAE(ThrowingRunnable r) { + checkWithThrowable(IllegalAccessException.class, null, r); + } + + static void checkIAE(Object message, ThrowingRunnable r) { + checkWithThrowable(IllegalAccessException.class, message, r); + } + + static void checkWMTE(ThrowingRunnable r) { + checkWithThrowable(WrongMethodTypeException.class, null, r); + } + + static void checkWMTE(Object message, ThrowingRunnable r) { + checkWithThrowable(WrongMethodTypeException.class, message, r); + } + + static void checkCCE(ThrowingRunnable r) { + checkWithThrowable(ClassCastException.class, null, r); + } + + static void checkCCE(Object message, ThrowingRunnable r) { + checkWithThrowable(ClassCastException.class, message, r); + } + + static void checkNPE(ThrowingRunnable r) { + checkWithThrowable(NullPointerException.class, null, r); + } + + static void checkNPE(Object message, ThrowingRunnable r) { + checkWithThrowable(NullPointerException.class, message, r); + } + + 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)); + assertTrue(re.isInstance(_e), String.format("%sIncorrect throwable thrown, %s. Expected %s", message, _e, re)); + } + + + enum TestAccessType { + get, + set, + compareAndSet, + compareAndExchange, + getAndSet, + getAndAdd; + } + + enum TestAccessMode { + get(TestAccessType.get), + set(TestAccessType.set), + getVolatile(TestAccessType.get), + setVolatile(TestAccessType.set), + getAcquire(TestAccessType.get), + setRelease(TestAccessType.set), + getOpaque(TestAccessType.get), + setOpaque(TestAccessType.set), + compareAndSet(TestAccessType.compareAndSet), + compareAndExchangeVolatile(TestAccessType.compareAndExchange), + compareAndExchangeAcquire(TestAccessType.compareAndExchange), + compareAndExchangeRelease(TestAccessType.compareAndExchange), + weakCompareAndSet(TestAccessType.compareAndSet), + weakCompareAndSetAcquire(TestAccessType.compareAndSet), + weakCompareAndSetRelease(TestAccessType.compareAndSet), + getAndSet(TestAccessType.getAndSet), + getAndAdd(TestAccessType.getAndAdd), + addAndGet(TestAccessType.getAndAdd),; + + final TestAccessType at; + final boolean isPolyMorphicInReturnType; + final Class returnType; + + TestAccessMode(TestAccessType at) { + this.at = at; + + try { + Method m = VarHandle.class.getMethod(name(), Object[].class); + this.returnType = m.getReturnType(); + isPolyMorphicInReturnType = returnType != Object.class; + } + catch (Exception e) { + throw new Error(e); + } + } + + boolean isOfType(TestAccessType at) { + return this.at == at; + } + + VarHandle.AccessMode toAccessMode() { + return VarHandle.AccessMode.valueOf(name()); + } + } + + static List testAccessModes() { + return Stream.of(TestAccessMode.values()).collect(toList()); + } + + static List testAccessModesOfType(TestAccessType... ats) { + Stream s = Stream.of(TestAccessMode.values()); + for (TestAccessType at : ats) { + s = s.filter(e -> e.isOfType(at)); + } + return s.collect(toList()); + } + + static List accessModes() { + return Stream.of(VarHandle.AccessMode.values()).collect(toList()); + } + + static List accessModesOfType(TestAccessType... ats) { + Stream s = Stream.of(TestAccessMode.values()); + for (TestAccessType at : ats) { + s = s.filter(e -> e.isOfType(at)); + } + return s.map(TestAccessMode::toAccessMode).collect(toList()); + } + + static MethodHandle toMethodHandle(VarHandle vh, TestAccessMode tam, MethodType mt) { + return vh.toMethodHandle(tam.toAccessMode()); + } + + static MethodHandle findVirtual(VarHandle vh, TestAccessMode tam, MethodType mt) { + mt = vh.accessModeType(tam.toAccessMode()); + MethodHandle mh; + try { + mh = MethodHandles.publicLookup(). + findVirtual(VarHandle.class, + tam.name(), + mt); + } catch (Exception e) { + throw new RuntimeException(e); + } + return bind(vh, tam, mh, mt); + } + + static MethodHandle varHandleInvokerWithAccessModeType(VarHandle vh, TestAccessMode tam, MethodType mt) { + mt = vh.accessModeType(tam.toAccessMode()); + MethodHandle mh = MethodHandles.varHandleInvoker( + tam.toAccessMode(), + mt); + + return bind(vh, tam, mh, mt); + } + + static MethodHandle varHandleInvokerWithSymbolicTypeDescriptor(VarHandle vh, TestAccessMode tam, MethodType mt) { + MethodHandle mh = MethodHandles.varHandleInvoker( + tam.toAccessMode(), + mt); + + return bind(vh, tam, mh, mt); + } + + static MethodHandle varHandleExactInvokerWithAccessModeType(VarHandle vh, TestAccessMode tam, MethodType mt) { + mt = vh.accessModeType(tam.toAccessMode()); + MethodHandle mh = MethodHandles.varHandleExactInvoker( + tam.toAccessMode(), + mt); + + return bind(vh, tam, mh, mt); + } + + private static MethodHandle bind(VarHandle vh, TestAccessMode testAccessMode, MethodHandle mh, MethodType emt) { + assertEquals(mh.type(), emt.insertParameterTypes(0, VarHandle.class), + "MethodHandle type differs from access mode type"); + + MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh); + assertEquals(info.getMethodType(), emt, + "MethodHandleInfo method type differs from access mode type"); + + return mh.bindTo(vh); + } + + private interface TriFunction { + R apply(T t, U u, V v); + } + + enum VarHandleToMethodHandle { + VAR_HANDLE_TO_METHOD_HANDLE( + "VarHandle.toMethodHandle", + VarHandleBaseTest::toMethodHandle), + METHOD_HANDLES_LOOKUP_FIND_VIRTUAL( + "Lookup.findVirtual", + VarHandleBaseTest::findVirtual), + METHOD_HANDLES_VAR_HANDLE_INVOKER_WITH_ACCESS_MODE_TYPE( + "MethodHandles.varHandleInvoker(accessModeType)", + VarHandleBaseTest::varHandleInvokerWithAccessModeType), + METHOD_HANDLES_VAR_HANDLE_INVOKER_WITH_SYMBOLIC_TYPE_DESCRIPTOR( + "MethodHandles.varHandleInvoker(symbolicTypeDescriptor)", + VarHandleBaseTest::varHandleInvokerWithSymbolicTypeDescriptor), + METHOD_HANDLES_VAR_HANDLE_EXACT_INVOKER_WITH_ACCESS_MODE_TYPE( + "MethodHandles.varHandleExactInvoker(accessModeType)", + VarHandleBaseTest::varHandleExactInvokerWithAccessModeType); + + final String desc; + final TriFunction f; + final boolean exact; + + VarHandleToMethodHandle(String desc, TriFunction f) { + this(desc, f, false); + } + + VarHandleToMethodHandle(String desc, TriFunction f, + boolean exact) { + this.desc = desc; + this.f = f; + this.exact = exact; + } + + MethodHandle apply(VarHandle vh, TestAccessMode am, MethodType mt) { + return f.apply(vh, am, mt); + } + + @Override + public String toString() { + return desc; + } + } + + static class Handles { + static class AccessModeAndType { + final TestAccessMode tam; + final MethodType t; + + public AccessModeAndType(TestAccessMode tam, MethodType t) { + this.tam = tam; + this.t = t; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AccessModeAndType x = (AccessModeAndType) o; + + if (tam != x.tam) return false; + if (t != null ? !t.equals(x.t) : x.t != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = tam != null ? tam.hashCode() : 0; + result = 31 * result + (t != null ? t.hashCode() : 0); + return result; + } + } + + final VarHandle vh; + final VarHandleToMethodHandle f; + final EnumMap amToType; + final Map amToHandle; + + Handles(VarHandle vh, VarHandleToMethodHandle f) throws Exception { + this.vh = vh; + this.f = f; + this.amToHandle = new HashMap<>(); + + amToType = new EnumMap<>(TestAccessMode.class); + for (TestAccessMode am : testAccessModes()) { + amToType.put(am, vh.accessModeType(am.toAccessMode())); + } + } + + MethodHandle get(TestAccessMode am) { + return get(am, amToType.get(am)); + } + + MethodHandle get(TestAccessMode am, MethodType mt) { + AccessModeAndType amt = new AccessModeAndType(am, mt); + return amToHandle.computeIfAbsent( + amt, k -> f.apply(vh, am, mt)); + } + } + + interface AccessTestAction { + void action(T t) throws Throwable; + } + + static abstract class AccessTestCase { + final String desc; + final AccessTestAction ata; + final boolean loop; + + AccessTestCase(String desc, AccessTestAction ata, boolean loop) { + this.desc = desc; + this.ata = ata; + this.loop = loop; + } + + boolean requiresLoop() { + return loop; + } + + abstract T get() throws Exception; + + void testAccess(T t) throws Throwable { + ata.action(t); + } + + @Override + public String toString() { + return desc; + } + } + + static class VarHandleAccessTestCase extends AccessTestCase { + final VarHandle vh; + + VarHandleAccessTestCase(String desc, VarHandle vh, AccessTestAction ata) { + this(desc, vh, ata, true); + } + + VarHandleAccessTestCase(String desc, VarHandle vh, AccessTestAction ata, boolean loop) { + super("VarHandle -> " + desc, ata, loop); + this.vh = vh; + } + + @Override + VarHandle get() { + return vh; + } + } + + static class MethodHandleAccessTestCase extends AccessTestCase { + final VarHandle vh; + final VarHandleToMethodHandle f; + + MethodHandleAccessTestCase(String desc, VarHandle vh, VarHandleToMethodHandle f, AccessTestAction ata) { + this(desc, vh, f, ata, true); + } + + MethodHandleAccessTestCase(String desc, VarHandle vh, VarHandleToMethodHandle f, AccessTestAction ata, boolean loop) { + super("VarHandle -> " + f.toString() + " -> " + desc, ata, loop); + this.vh = vh; + this.f = f; + } + + @Override + Handles get() throws Exception { + return new Handles(vh, f); + } + } + + static void testTypes(VarHandle vh) { + List> pts = vh.coordinateTypes(); + + for (TestAccessMode accessMode : testAccessModes()) { + MethodType amt = vh.accessModeType(accessMode.toAccessMode()); + + assertEquals(amt.parameterList().subList(0, pts.size()), pts); + } + + for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.get)) { + MethodType mt = vh.accessModeType(testAccessMode.toAccessMode()); + assertEquals(mt.returnType(), vh.varType()); + assertEquals(mt.parameterList(), pts); + } + + 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()); + } + + for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.compareAndSet)) { + 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()); + } + + for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.compareAndExchange)) { + 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()); + } + + for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.getAndSet, TestAccessType.getAndAdd)) { + MethodType mt = vh.accessModeType(testAccessMode.toAccessMode()); + assertEquals(mt.returnType(), vh.varType()); + assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType()); + } + } +} \ No newline at end of file diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java new file mode 100644 index 00000000000..4a315a8a1c2 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java @@ -0,0 +1,647 @@ +/* + * Copyright (c) 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 + * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessBoolean + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessBoolean + * @run testng/othervm -Diters=20000 VarHandleTestAccessBoolean + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestAccessBoolean extends VarHandleBaseTest { + static final boolean static_final_v = true; + + static boolean static_v; + + final boolean final_v = true; + + boolean v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessBoolean.class, "final_v", boolean.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessBoolean.class, "v", boolean.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessBoolean.class, "static_final_v", boolean.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessBoolean.class, "static_v", boolean.class); + + vhArray = MethodHandles.arrayElementVarHandle(boolean[].class); + } + + + @DataProvider + public Object[][] varHandlesProvider() throws Exception { + List vhs = new ArrayList<>(); + vhs.add(vhField); + vhs.add(vhStaticField); + vhs.add(vhArray); + + return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandle vh) { + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); + } + + + @DataProvider + public Object[][] typesProvider() throws Exception { + List types = new ArrayList<>(); + types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessBoolean.class)}); + types.add(new Object[] {vhStaticField, Arrays.asList()}); + types.add(new Object[] {vhArray, Arrays.asList(boolean[].class, int.class)}); + + return types.stream().toArray(Object[][]::new); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), boolean.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @Test + public void testLookupInstanceToStatic() { + checkIAE("Lookup of static final field to instance final field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessBoolean.class, "final_v", boolean.class); + }); + + checkIAE("Lookup of static field to instance field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessBoolean.class, "v", boolean.class); + }); + } + + @Test + public void testLookupStaticToInstance() { + checkIAE("Lookup of instance final field to static final field", () -> { + MethodHandles.lookup().findVarHandle( + VarHandleTestAccessBoolean.class, "static_final_v", boolean.class); + }); + + checkIAE("Lookup of instance field to static field", () -> { + vhStaticField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessBoolean.class, "static_v", boolean.class); + }); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance final field", + vhFinalField, vh -> testInstanceFinalField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance final field unsupported", + vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static final field", + vhStaticFinalField, VarHandleTestAccessBoolean::testStaticFinalField)); + cases.add(new VarHandleAccessTestCase("Static final field unsupported", + vhStaticFinalField, VarHandleTestAccessBoolean::testStaticFinalFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Instance field", + vhField, vh -> testInstanceField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance field unsupported", + vhField, vh -> testInstanceFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field", + vhStaticField, VarHandleTestAccessBoolean::testStaticField)); + cases.add(new VarHandleAccessTestCase("Static field unsupported", + vhStaticField, VarHandleTestAccessBoolean::testStaticFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Array", + vhArray, VarHandleTestAccessBoolean::testArray)); + cases.add(new VarHandleAccessTestCase("Array unsupported", + vhArray, VarHandleTestAccessBoolean::testArrayUnsupported, + false)); + cases.add(new VarHandleAccessTestCase("Array index out of bounds", + vhArray, VarHandleTestAccessBoolean::testArrayIndexOutOfBounds, + false)); + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + + + static void testInstanceFinalField(VarHandleTestAccessBoolean recv, VarHandle vh) { + // Plain + { + boolean x = (boolean) vh.get(recv); + assertEquals(x, true, "get boolean value"); + } + + + // Volatile + { + boolean x = (boolean) vh.getVolatile(recv); + assertEquals(x, true, "getVolatile boolean value"); + } + + // Lazy + { + boolean x = (boolean) vh.getAcquire(recv); + assertEquals(x, true, "getRelease boolean value"); + } + + // Opaque + { + boolean x = (boolean) vh.getOpaque(recv); + assertEquals(x, true, "getOpaque boolean value"); + } + } + + static void testInstanceFinalFieldUnsupported(VarHandleTestAccessBoolean recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, false); + }); + + checkUOE(() -> { + vh.setVolatile(recv, false); + }); + + checkUOE(() -> { + vh.setRelease(recv, false); + }); + + checkUOE(() -> { + vh.setOpaque(recv, false); + }); + + checkUOE(() -> { + boolean r = vh.compareAndSet(recv, true, false); + }); + + checkUOE(() -> { + boolean r = (boolean) vh.compareAndExchangeVolatile(recv, true, false); + }); + + checkUOE(() -> { + boolean r = (boolean) vh.compareAndExchangeAcquire(recv, true, false); + }); + + checkUOE(() -> { + boolean r = (boolean) vh.compareAndExchangeRelease(recv, true, false); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(recv, true, false); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(recv, true, false); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(recv, true, false); + }); + + checkUOE(() -> { + boolean o = (boolean) vh.getAndAdd(recv, true); + }); + + checkUOE(() -> { + boolean o = (boolean) vh.addAndGet(recv, true); + }); + } + + + static void testStaticFinalField(VarHandle vh) { + // Plain + { + boolean x = (boolean) vh.get(); + assertEquals(x, true, "get boolean value"); + } + + + // Volatile + { + boolean x = (boolean) vh.getVolatile(); + assertEquals(x, true, "getVolatile boolean value"); + } + + // Lazy + { + boolean x = (boolean) vh.getAcquire(); + assertEquals(x, true, "getRelease boolean value"); + } + + // Opaque + { + boolean x = (boolean) vh.getOpaque(); + assertEquals(x, true, "getOpaque boolean value"); + } + } + + static void testStaticFinalFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + vh.set(false); + }); + + checkUOE(() -> { + vh.setVolatile(false); + }); + + checkUOE(() -> { + vh.setRelease(false); + }); + + checkUOE(() -> { + vh.setOpaque(false); + }); + + checkUOE(() -> { + boolean r = vh.compareAndSet(true, false); + }); + + checkUOE(() -> { + boolean r = (boolean) vh.compareAndExchangeVolatile(true, false); + }); + + checkUOE(() -> { + boolean r = (boolean) vh.compareAndExchangeAcquire(true, false); + }); + + checkUOE(() -> { + boolean r = (boolean) vh.compareAndExchangeRelease(true, false); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(true, false); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(true, false); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(true, false); + }); + + checkUOE(() -> { + boolean o = (boolean) vh.getAndAdd(true); + }); + + checkUOE(() -> { + boolean o = (boolean) vh.addAndGet(true); + }); + } + + + static void testInstanceField(VarHandleTestAccessBoolean recv, VarHandle vh) { + // Plain + { + vh.set(recv, true); + boolean x = (boolean) vh.get(recv); + assertEquals(x, true, "set boolean value"); + } + + + // Volatile + { + vh.setVolatile(recv, false); + boolean x = (boolean) vh.getVolatile(recv); + assertEquals(x, false, "setVolatile boolean value"); + } + + // Lazy + { + vh.setRelease(recv, true); + boolean x = (boolean) vh.getAcquire(recv); + assertEquals(x, true, "setRelease boolean value"); + } + + // Opaque + { + vh.setOpaque(recv, false); + boolean x = (boolean) vh.getOpaque(recv); + assertEquals(x, false, "setOpaque boolean value"); + } + + + } + + static void testInstanceFieldUnsupported(VarHandleTestAccessBoolean recv, VarHandle vh) { + checkUOE(() -> { + boolean r = vh.compareAndSet(recv, true, false); + }); + + checkUOE(() -> { + boolean r = (boolean) vh.compareAndExchangeVolatile(recv, true, false); + }); + + checkUOE(() -> { + boolean r = (boolean) vh.compareAndExchangeAcquire(recv, true, false); + }); + + checkUOE(() -> { + boolean r = (boolean) vh.compareAndExchangeRelease(recv, true, false); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(recv, true, false); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(recv, true, false); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(recv, true, false); + }); + + checkUOE(() -> { + boolean o = (boolean) vh.getAndAdd(recv, true); + }); + + checkUOE(() -> { + boolean o = (boolean) vh.addAndGet(recv, true); + }); + } + + + static void testStaticField(VarHandle vh) { + // Plain + { + vh.set(true); + boolean x = (boolean) vh.get(); + assertEquals(x, true, "set boolean value"); + } + + + // Volatile + { + vh.setVolatile(false); + boolean x = (boolean) vh.getVolatile(); + assertEquals(x, false, "setVolatile boolean value"); + } + + // Lazy + { + vh.setRelease(true); + boolean x = (boolean) vh.getAcquire(); + assertEquals(x, true, "setRelease boolean value"); + } + + // Opaque + { + vh.setOpaque(false); + boolean x = (boolean) vh.getOpaque(); + assertEquals(x, false, "setOpaque boolean value"); + } + + + } + + static void testStaticFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + boolean r = vh.compareAndSet(true, false); + }); + + checkUOE(() -> { + boolean r = (boolean) vh.compareAndExchangeVolatile(true, false); + }); + + checkUOE(() -> { + boolean r = (boolean) vh.compareAndExchangeAcquire(true, false); + }); + + checkUOE(() -> { + boolean r = (boolean) vh.compareAndExchangeRelease(true, false); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(true, false); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(true, false); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(true, false); + }); + + checkUOE(() -> { + boolean o = (boolean) vh.getAndAdd(true); + }); + + checkUOE(() -> { + boolean o = (boolean) vh.addAndGet(true); + }); + } + + + static void testArray(VarHandle vh) { + boolean[] array = new boolean[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + vh.set(array, i, true); + boolean x = (boolean) vh.get(array, i); + assertEquals(x, true, "get boolean value"); + } + + + // Volatile + { + vh.setVolatile(array, i, false); + boolean x = (boolean) vh.getVolatile(array, i); + assertEquals(x, false, "setVolatile boolean value"); + } + + // Lazy + { + vh.setRelease(array, i, true); + boolean x = (boolean) vh.getAcquire(array, i); + assertEquals(x, true, "setRelease boolean value"); + } + + // Opaque + { + vh.setOpaque(array, i, false); + boolean x = (boolean) vh.getOpaque(array, i); + assertEquals(x, false, "setOpaque boolean value"); + } + + + } + } + + static void testArrayUnsupported(VarHandle vh) { + boolean[] array = new boolean[10]; + + int i = 0; + checkUOE(() -> { + boolean r = vh.compareAndSet(array, i, true, false); + }); + + checkUOE(() -> { + boolean r = (boolean) vh.compareAndExchangeVolatile(array, i, true, false); + }); + + checkUOE(() -> { + boolean r = (boolean) vh.compareAndExchangeAcquire(array, i, true, false); + }); + + checkUOE(() -> { + boolean r = (boolean) vh.compareAndExchangeRelease(array, i, true, false); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, i, true, false); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, i, true, false); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, i, true, false); + }); + + checkUOE(() -> { + boolean o = (boolean) vh.getAndAdd(array, i, true); + }); + + checkUOE(() -> { + boolean o = (boolean) vh.addAndGet(array, i, true); + }); + } + + static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable { + boolean[] array = new boolean[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + boolean x = (boolean) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, true); + }); + + checkIOOBE(() -> { + boolean x = (boolean) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, true); + }); + + checkIOOBE(() -> { + boolean x = (boolean) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, true); + }); + + checkIOOBE(() -> { + boolean x = (boolean) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, true); + }); + + + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java new file mode 100644 index 00000000000..8fa89891ad5 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java @@ -0,0 +1,647 @@ +/* + * Copyright (c) 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 + * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessByte + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessByte + * @run testng/othervm -Diters=20000 VarHandleTestAccessByte + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestAccessByte extends VarHandleBaseTest { + static final byte static_final_v = (byte)1; + + static byte static_v; + + final byte final_v = (byte)1; + + byte v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessByte.class, "final_v", byte.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessByte.class, "v", byte.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessByte.class, "static_final_v", byte.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessByte.class, "static_v", byte.class); + + vhArray = MethodHandles.arrayElementVarHandle(byte[].class); + } + + + @DataProvider + public Object[][] varHandlesProvider() throws Exception { + List vhs = new ArrayList<>(); + vhs.add(vhField); + vhs.add(vhStaticField); + vhs.add(vhArray); + + return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandle vh) { + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); + } + + + @DataProvider + public Object[][] typesProvider() throws Exception { + List types = new ArrayList<>(); + types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessByte.class)}); + types.add(new Object[] {vhStaticField, Arrays.asList()}); + types.add(new Object[] {vhArray, Arrays.asList(byte[].class, int.class)}); + + return types.stream().toArray(Object[][]::new); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), byte.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @Test + public void testLookupInstanceToStatic() { + checkIAE("Lookup of static final field to instance final field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessByte.class, "final_v", byte.class); + }); + + checkIAE("Lookup of static field to instance field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessByte.class, "v", byte.class); + }); + } + + @Test + public void testLookupStaticToInstance() { + checkIAE("Lookup of instance final field to static final field", () -> { + MethodHandles.lookup().findVarHandle( + VarHandleTestAccessByte.class, "static_final_v", byte.class); + }); + + checkIAE("Lookup of instance field to static field", () -> { + vhStaticField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessByte.class, "static_v", byte.class); + }); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance final field", + vhFinalField, vh -> testInstanceFinalField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance final field unsupported", + vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static final field", + vhStaticFinalField, VarHandleTestAccessByte::testStaticFinalField)); + cases.add(new VarHandleAccessTestCase("Static final field unsupported", + vhStaticFinalField, VarHandleTestAccessByte::testStaticFinalFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Instance field", + vhField, vh -> testInstanceField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance field unsupported", + vhField, vh -> testInstanceFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field", + vhStaticField, VarHandleTestAccessByte::testStaticField)); + cases.add(new VarHandleAccessTestCase("Static field unsupported", + vhStaticField, VarHandleTestAccessByte::testStaticFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Array", + vhArray, VarHandleTestAccessByte::testArray)); + cases.add(new VarHandleAccessTestCase("Array unsupported", + vhArray, VarHandleTestAccessByte::testArrayUnsupported, + false)); + cases.add(new VarHandleAccessTestCase("Array index out of bounds", + vhArray, VarHandleTestAccessByte::testArrayIndexOutOfBounds, + false)); + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + + + static void testInstanceFinalField(VarHandleTestAccessByte recv, VarHandle vh) { + // Plain + { + byte x = (byte) vh.get(recv); + assertEquals(x, (byte)1, "get byte value"); + } + + + // Volatile + { + byte x = (byte) vh.getVolatile(recv); + assertEquals(x, (byte)1, "getVolatile byte value"); + } + + // Lazy + { + byte x = (byte) vh.getAcquire(recv); + assertEquals(x, (byte)1, "getRelease byte value"); + } + + // Opaque + { + byte x = (byte) vh.getOpaque(recv); + assertEquals(x, (byte)1, "getOpaque byte value"); + } + } + + static void testInstanceFinalFieldUnsupported(VarHandleTestAccessByte recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, (byte)2); + }); + + checkUOE(() -> { + vh.setVolatile(recv, (byte)2); + }); + + checkUOE(() -> { + vh.setRelease(recv, (byte)2); + }); + + checkUOE(() -> { + vh.setOpaque(recv, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.compareAndSet(recv, (byte)1, (byte)2); + }); + + checkUOE(() -> { + byte r = (byte) vh.compareAndExchangeVolatile(recv, (byte)1, (byte)2); + }); + + checkUOE(() -> { + byte r = (byte) vh.compareAndExchangeAcquire(recv, (byte)1, (byte)2); + }); + + checkUOE(() -> { + byte r = (byte) vh.compareAndExchangeRelease(recv, (byte)1, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(recv, (byte)1, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(recv, (byte)1, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(recv, (byte)1, (byte)2); + }); + + checkUOE(() -> { + byte o = (byte) vh.getAndAdd(recv, (byte)1); + }); + + checkUOE(() -> { + byte o = (byte) vh.addAndGet(recv, (byte)1); + }); + } + + + static void testStaticFinalField(VarHandle vh) { + // Plain + { + byte x = (byte) vh.get(); + assertEquals(x, (byte)1, "get byte value"); + } + + + // Volatile + { + byte x = (byte) vh.getVolatile(); + assertEquals(x, (byte)1, "getVolatile byte value"); + } + + // Lazy + { + byte x = (byte) vh.getAcquire(); + assertEquals(x, (byte)1, "getRelease byte value"); + } + + // Opaque + { + byte x = (byte) vh.getOpaque(); + assertEquals(x, (byte)1, "getOpaque byte value"); + } + } + + static void testStaticFinalFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + vh.set((byte)2); + }); + + checkUOE(() -> { + vh.setVolatile((byte)2); + }); + + checkUOE(() -> { + vh.setRelease((byte)2); + }); + + checkUOE(() -> { + vh.setOpaque((byte)2); + }); + + checkUOE(() -> { + boolean r = vh.compareAndSet((byte)1, (byte)2); + }); + + checkUOE(() -> { + byte r = (byte) vh.compareAndExchangeVolatile((byte)1, (byte)2); + }); + + checkUOE(() -> { + byte r = (byte) vh.compareAndExchangeAcquire((byte)1, (byte)2); + }); + + checkUOE(() -> { + byte r = (byte) vh.compareAndExchangeRelease((byte)1, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet((byte)1, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire((byte)1, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease((byte)1, (byte)2); + }); + + checkUOE(() -> { + byte o = (byte) vh.getAndAdd((byte)1); + }); + + checkUOE(() -> { + byte o = (byte) vh.addAndGet((byte)1); + }); + } + + + static void testInstanceField(VarHandleTestAccessByte recv, VarHandle vh) { + // Plain + { + vh.set(recv, (byte)1); + byte x = (byte) vh.get(recv); + assertEquals(x, (byte)1, "set byte value"); + } + + + // Volatile + { + vh.setVolatile(recv, (byte)2); + byte x = (byte) vh.getVolatile(recv); + assertEquals(x, (byte)2, "setVolatile byte value"); + } + + // Lazy + { + vh.setRelease(recv, (byte)1); + byte x = (byte) vh.getAcquire(recv); + assertEquals(x, (byte)1, "setRelease byte value"); + } + + // Opaque + { + vh.setOpaque(recv, (byte)2); + byte x = (byte) vh.getOpaque(recv); + assertEquals(x, (byte)2, "setOpaque byte value"); + } + + + } + + static void testInstanceFieldUnsupported(VarHandleTestAccessByte recv, VarHandle vh) { + checkUOE(() -> { + boolean r = vh.compareAndSet(recv, (byte)1, (byte)2); + }); + + checkUOE(() -> { + byte r = (byte) vh.compareAndExchangeVolatile(recv, (byte)1, (byte)2); + }); + + checkUOE(() -> { + byte r = (byte) vh.compareAndExchangeAcquire(recv, (byte)1, (byte)2); + }); + + checkUOE(() -> { + byte r = (byte) vh.compareAndExchangeRelease(recv, (byte)1, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(recv, (byte)1, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(recv, (byte)1, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(recv, (byte)1, (byte)2); + }); + + checkUOE(() -> { + byte o = (byte) vh.getAndAdd(recv, (byte)1); + }); + + checkUOE(() -> { + byte o = (byte) vh.addAndGet(recv, (byte)1); + }); + } + + + static void testStaticField(VarHandle vh) { + // Plain + { + vh.set((byte)1); + byte x = (byte) vh.get(); + assertEquals(x, (byte)1, "set byte value"); + } + + + // Volatile + { + vh.setVolatile((byte)2); + byte x = (byte) vh.getVolatile(); + assertEquals(x, (byte)2, "setVolatile byte value"); + } + + // Lazy + { + vh.setRelease((byte)1); + byte x = (byte) vh.getAcquire(); + assertEquals(x, (byte)1, "setRelease byte value"); + } + + // Opaque + { + vh.setOpaque((byte)2); + byte x = (byte) vh.getOpaque(); + assertEquals(x, (byte)2, "setOpaque byte value"); + } + + + } + + static void testStaticFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + boolean r = vh.compareAndSet((byte)1, (byte)2); + }); + + checkUOE(() -> { + byte r = (byte) vh.compareAndExchangeVolatile((byte)1, (byte)2); + }); + + checkUOE(() -> { + byte r = (byte) vh.compareAndExchangeAcquire((byte)1, (byte)2); + }); + + checkUOE(() -> { + byte r = (byte) vh.compareAndExchangeRelease((byte)1, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet((byte)1, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire((byte)1, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease((byte)1, (byte)2); + }); + + checkUOE(() -> { + byte o = (byte) vh.getAndAdd((byte)1); + }); + + checkUOE(() -> { + byte o = (byte) vh.addAndGet((byte)1); + }); + } + + + static void testArray(VarHandle vh) { + byte[] array = new byte[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + vh.set(array, i, (byte)1); + byte x = (byte) vh.get(array, i); + assertEquals(x, (byte)1, "get byte value"); + } + + + // Volatile + { + vh.setVolatile(array, i, (byte)2); + byte x = (byte) vh.getVolatile(array, i); + assertEquals(x, (byte)2, "setVolatile byte value"); + } + + // Lazy + { + vh.setRelease(array, i, (byte)1); + byte x = (byte) vh.getAcquire(array, i); + assertEquals(x, (byte)1, "setRelease byte value"); + } + + // Opaque + { + vh.setOpaque(array, i, (byte)2); + byte x = (byte) vh.getOpaque(array, i); + assertEquals(x, (byte)2, "setOpaque byte value"); + } + + + } + } + + static void testArrayUnsupported(VarHandle vh) { + byte[] array = new byte[10]; + + int i = 0; + checkUOE(() -> { + boolean r = vh.compareAndSet(array, i, (byte)1, (byte)2); + }); + + checkUOE(() -> { + byte r = (byte) vh.compareAndExchangeVolatile(array, i, (byte)1, (byte)2); + }); + + checkUOE(() -> { + byte r = (byte) vh.compareAndExchangeAcquire(array, i, (byte)1, (byte)2); + }); + + checkUOE(() -> { + byte r = (byte) vh.compareAndExchangeRelease(array, i, (byte)1, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, i, (byte)1, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, i, (byte)1, (byte)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, i, (byte)1, (byte)2); + }); + + checkUOE(() -> { + byte o = (byte) vh.getAndAdd(array, i, (byte)1); + }); + + checkUOE(() -> { + byte o = (byte) vh.addAndGet(array, i, (byte)1); + }); + } + + static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable { + byte[] array = new byte[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + byte x = (byte) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, (byte)1); + }); + + checkIOOBE(() -> { + byte x = (byte) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, (byte)1); + }); + + checkIOOBE(() -> { + byte x = (byte) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, (byte)1); + }); + + checkIOOBE(() -> { + byte x = (byte) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, (byte)1); + }); + + + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java new file mode 100644 index 00000000000..ab1a997ecad --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java @@ -0,0 +1,647 @@ +/* + * Copyright (c) 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 + * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessChar + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessChar + * @run testng/othervm -Diters=20000 VarHandleTestAccessChar + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestAccessChar extends VarHandleBaseTest { + static final char static_final_v = 'a'; + + static char static_v; + + final char final_v = 'a'; + + char v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessChar.class, "final_v", char.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessChar.class, "v", char.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessChar.class, "static_final_v", char.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessChar.class, "static_v", char.class); + + vhArray = MethodHandles.arrayElementVarHandle(char[].class); + } + + + @DataProvider + public Object[][] varHandlesProvider() throws Exception { + List vhs = new ArrayList<>(); + vhs.add(vhField); + vhs.add(vhStaticField); + vhs.add(vhArray); + + return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandle vh) { + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); + } + + + @DataProvider + public Object[][] typesProvider() throws Exception { + List types = new ArrayList<>(); + types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessChar.class)}); + types.add(new Object[] {vhStaticField, Arrays.asList()}); + types.add(new Object[] {vhArray, Arrays.asList(char[].class, int.class)}); + + return types.stream().toArray(Object[][]::new); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), char.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @Test + public void testLookupInstanceToStatic() { + checkIAE("Lookup of static final field to instance final field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessChar.class, "final_v", char.class); + }); + + checkIAE("Lookup of static field to instance field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessChar.class, "v", char.class); + }); + } + + @Test + public void testLookupStaticToInstance() { + checkIAE("Lookup of instance final field to static final field", () -> { + MethodHandles.lookup().findVarHandle( + VarHandleTestAccessChar.class, "static_final_v", char.class); + }); + + checkIAE("Lookup of instance field to static field", () -> { + vhStaticField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessChar.class, "static_v", char.class); + }); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance final field", + vhFinalField, vh -> testInstanceFinalField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance final field unsupported", + vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static final field", + vhStaticFinalField, VarHandleTestAccessChar::testStaticFinalField)); + cases.add(new VarHandleAccessTestCase("Static final field unsupported", + vhStaticFinalField, VarHandleTestAccessChar::testStaticFinalFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Instance field", + vhField, vh -> testInstanceField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance field unsupported", + vhField, vh -> testInstanceFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field", + vhStaticField, VarHandleTestAccessChar::testStaticField)); + cases.add(new VarHandleAccessTestCase("Static field unsupported", + vhStaticField, VarHandleTestAccessChar::testStaticFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Array", + vhArray, VarHandleTestAccessChar::testArray)); + cases.add(new VarHandleAccessTestCase("Array unsupported", + vhArray, VarHandleTestAccessChar::testArrayUnsupported, + false)); + cases.add(new VarHandleAccessTestCase("Array index out of bounds", + vhArray, VarHandleTestAccessChar::testArrayIndexOutOfBounds, + false)); + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + + + static void testInstanceFinalField(VarHandleTestAccessChar recv, VarHandle vh) { + // Plain + { + char x = (char) vh.get(recv); + assertEquals(x, 'a', "get char value"); + } + + + // Volatile + { + char x = (char) vh.getVolatile(recv); + assertEquals(x, 'a', "getVolatile char value"); + } + + // Lazy + { + char x = (char) vh.getAcquire(recv); + assertEquals(x, 'a', "getRelease char value"); + } + + // Opaque + { + char x = (char) vh.getOpaque(recv); + assertEquals(x, 'a', "getOpaque char value"); + } + } + + static void testInstanceFinalFieldUnsupported(VarHandleTestAccessChar recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, 'b'); + }); + + checkUOE(() -> { + vh.setVolatile(recv, 'b'); + }); + + checkUOE(() -> { + vh.setRelease(recv, 'b'); + }); + + checkUOE(() -> { + vh.setOpaque(recv, 'b'); + }); + + checkUOE(() -> { + boolean r = vh.compareAndSet(recv, 'a', 'b'); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeVolatile(recv, 'a', 'b'); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeAcquire(recv, 'a', 'b'); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeRelease(recv, 'a', 'b'); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(recv, 'a', 'b'); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(recv, 'a', 'b'); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(recv, 'a', 'b'); + }); + + checkUOE(() -> { + char o = (char) vh.getAndAdd(recv, 'a'); + }); + + checkUOE(() -> { + char o = (char) vh.addAndGet(recv, 'a'); + }); + } + + + static void testStaticFinalField(VarHandle vh) { + // Plain + { + char x = (char) vh.get(); + assertEquals(x, 'a', "get char value"); + } + + + // Volatile + { + char x = (char) vh.getVolatile(); + assertEquals(x, 'a', "getVolatile char value"); + } + + // Lazy + { + char x = (char) vh.getAcquire(); + assertEquals(x, 'a', "getRelease char value"); + } + + // Opaque + { + char x = (char) vh.getOpaque(); + assertEquals(x, 'a', "getOpaque char value"); + } + } + + static void testStaticFinalFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + vh.set('b'); + }); + + checkUOE(() -> { + vh.setVolatile('b'); + }); + + checkUOE(() -> { + vh.setRelease('b'); + }); + + checkUOE(() -> { + vh.setOpaque('b'); + }); + + checkUOE(() -> { + boolean r = vh.compareAndSet('a', 'b'); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeVolatile('a', 'b'); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeAcquire('a', 'b'); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeRelease('a', 'b'); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet('a', 'b'); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire('a', 'b'); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease('a', 'b'); + }); + + checkUOE(() -> { + char o = (char) vh.getAndAdd('a'); + }); + + checkUOE(() -> { + char o = (char) vh.addAndGet('a'); + }); + } + + + static void testInstanceField(VarHandleTestAccessChar recv, VarHandle vh) { + // Plain + { + vh.set(recv, 'a'); + char x = (char) vh.get(recv); + assertEquals(x, 'a', "set char value"); + } + + + // Volatile + { + vh.setVolatile(recv, 'b'); + char x = (char) vh.getVolatile(recv); + assertEquals(x, 'b', "setVolatile char value"); + } + + // Lazy + { + vh.setRelease(recv, 'a'); + char x = (char) vh.getAcquire(recv); + assertEquals(x, 'a', "setRelease char value"); + } + + // Opaque + { + vh.setOpaque(recv, 'b'); + char x = (char) vh.getOpaque(recv); + assertEquals(x, 'b', "setOpaque char value"); + } + + + } + + static void testInstanceFieldUnsupported(VarHandleTestAccessChar recv, VarHandle vh) { + checkUOE(() -> { + boolean r = vh.compareAndSet(recv, 'a', 'b'); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeVolatile(recv, 'a', 'b'); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeAcquire(recv, 'a', 'b'); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeRelease(recv, 'a', 'b'); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(recv, 'a', 'b'); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(recv, 'a', 'b'); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(recv, 'a', 'b'); + }); + + checkUOE(() -> { + char o = (char) vh.getAndAdd(recv, 'a'); + }); + + checkUOE(() -> { + char o = (char) vh.addAndGet(recv, 'a'); + }); + } + + + static void testStaticField(VarHandle vh) { + // Plain + { + vh.set('a'); + char x = (char) vh.get(); + assertEquals(x, 'a', "set char value"); + } + + + // Volatile + { + vh.setVolatile('b'); + char x = (char) vh.getVolatile(); + assertEquals(x, 'b', "setVolatile char value"); + } + + // Lazy + { + vh.setRelease('a'); + char x = (char) vh.getAcquire(); + assertEquals(x, 'a', "setRelease char value"); + } + + // Opaque + { + vh.setOpaque('b'); + char x = (char) vh.getOpaque(); + assertEquals(x, 'b', "setOpaque char value"); + } + + + } + + static void testStaticFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + boolean r = vh.compareAndSet('a', 'b'); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeVolatile('a', 'b'); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeAcquire('a', 'b'); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeRelease('a', 'b'); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet('a', 'b'); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire('a', 'b'); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease('a', 'b'); + }); + + checkUOE(() -> { + char o = (char) vh.getAndAdd('a'); + }); + + checkUOE(() -> { + char o = (char) vh.addAndGet('a'); + }); + } + + + static void testArray(VarHandle vh) { + char[] array = new char[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + vh.set(array, i, 'a'); + char x = (char) vh.get(array, i); + assertEquals(x, 'a', "get char value"); + } + + + // Volatile + { + vh.setVolatile(array, i, 'b'); + char x = (char) vh.getVolatile(array, i); + assertEquals(x, 'b', "setVolatile char value"); + } + + // Lazy + { + vh.setRelease(array, i, 'a'); + char x = (char) vh.getAcquire(array, i); + assertEquals(x, 'a', "setRelease char value"); + } + + // Opaque + { + vh.setOpaque(array, i, 'b'); + char x = (char) vh.getOpaque(array, i); + assertEquals(x, 'b', "setOpaque char value"); + } + + + } + } + + static void testArrayUnsupported(VarHandle vh) { + char[] array = new char[10]; + + int i = 0; + checkUOE(() -> { + boolean r = vh.compareAndSet(array, i, 'a', 'b'); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeVolatile(array, i, 'a', 'b'); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeAcquire(array, i, 'a', 'b'); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeRelease(array, i, 'a', 'b'); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, i, 'a', 'b'); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, i, 'a', 'b'); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, i, 'a', 'b'); + }); + + checkUOE(() -> { + char o = (char) vh.getAndAdd(array, i, 'a'); + }); + + checkUOE(() -> { + char o = (char) vh.addAndGet(array, i, 'a'); + }); + } + + static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable { + char[] array = new char[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + char x = (char) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, 'a'); + }); + + checkIOOBE(() -> { + char x = (char) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, 'a'); + }); + + checkIOOBE(() -> { + char x = (char) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, 'a'); + }); + + checkIOOBE(() -> { + char x = (char) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, 'a'); + }); + + + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java new file mode 100644 index 00000000000..d4c9ee27265 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java @@ -0,0 +1,647 @@ +/* + * Copyright (c) 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 + * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessDouble + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessDouble + * @run testng/othervm -Diters=20000 VarHandleTestAccessDouble + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestAccessDouble extends VarHandleBaseTest { + static final double static_final_v = 1.0d; + + static double static_v; + + final double final_v = 1.0d; + + double v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessDouble.class, "final_v", double.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessDouble.class, "v", double.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessDouble.class, "static_final_v", double.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessDouble.class, "static_v", double.class); + + vhArray = MethodHandles.arrayElementVarHandle(double[].class); + } + + + @DataProvider + public Object[][] varHandlesProvider() throws Exception { + List vhs = new ArrayList<>(); + vhs.add(vhField); + vhs.add(vhStaticField); + vhs.add(vhArray); + + return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandle vh) { + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); + } + + + @DataProvider + public Object[][] typesProvider() throws Exception { + List types = new ArrayList<>(); + types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessDouble.class)}); + types.add(new Object[] {vhStaticField, Arrays.asList()}); + types.add(new Object[] {vhArray, Arrays.asList(double[].class, int.class)}); + + return types.stream().toArray(Object[][]::new); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), double.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @Test + public void testLookupInstanceToStatic() { + checkIAE("Lookup of static final field to instance final field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessDouble.class, "final_v", double.class); + }); + + checkIAE("Lookup of static field to instance field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessDouble.class, "v", double.class); + }); + } + + @Test + public void testLookupStaticToInstance() { + checkIAE("Lookup of instance final field to static final field", () -> { + MethodHandles.lookup().findVarHandle( + VarHandleTestAccessDouble.class, "static_final_v", double.class); + }); + + checkIAE("Lookup of instance field to static field", () -> { + vhStaticField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessDouble.class, "static_v", double.class); + }); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance final field", + vhFinalField, vh -> testInstanceFinalField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance final field unsupported", + vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static final field", + vhStaticFinalField, VarHandleTestAccessDouble::testStaticFinalField)); + cases.add(new VarHandleAccessTestCase("Static final field unsupported", + vhStaticFinalField, VarHandleTestAccessDouble::testStaticFinalFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Instance field", + vhField, vh -> testInstanceField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance field unsupported", + vhField, vh -> testInstanceFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field", + vhStaticField, VarHandleTestAccessDouble::testStaticField)); + cases.add(new VarHandleAccessTestCase("Static field unsupported", + vhStaticField, VarHandleTestAccessDouble::testStaticFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Array", + vhArray, VarHandleTestAccessDouble::testArray)); + cases.add(new VarHandleAccessTestCase("Array unsupported", + vhArray, VarHandleTestAccessDouble::testArrayUnsupported, + false)); + cases.add(new VarHandleAccessTestCase("Array index out of bounds", + vhArray, VarHandleTestAccessDouble::testArrayIndexOutOfBounds, + false)); + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + + + static void testInstanceFinalField(VarHandleTestAccessDouble recv, VarHandle vh) { + // Plain + { + double x = (double) vh.get(recv); + assertEquals(x, 1.0d, "get double value"); + } + + + // Volatile + { + double x = (double) vh.getVolatile(recv); + assertEquals(x, 1.0d, "getVolatile double value"); + } + + // Lazy + { + double x = (double) vh.getAcquire(recv); + assertEquals(x, 1.0d, "getRelease double value"); + } + + // Opaque + { + double x = (double) vh.getOpaque(recv); + assertEquals(x, 1.0d, "getOpaque double value"); + } + } + + static void testInstanceFinalFieldUnsupported(VarHandleTestAccessDouble recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, 2.0d); + }); + + checkUOE(() -> { + vh.setVolatile(recv, 2.0d); + }); + + checkUOE(() -> { + vh.setRelease(recv, 2.0d); + }); + + checkUOE(() -> { + vh.setOpaque(recv, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.compareAndSet(recv, 1.0d, 2.0d); + }); + + checkUOE(() -> { + double r = (double) vh.compareAndExchangeVolatile(recv, 1.0d, 2.0d); + }); + + checkUOE(() -> { + double r = (double) vh.compareAndExchangeAcquire(recv, 1.0d, 2.0d); + }); + + checkUOE(() -> { + double r = (double) vh.compareAndExchangeRelease(recv, 1.0d, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(recv, 1.0d, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(recv, 1.0d, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(recv, 1.0d, 2.0d); + }); + + checkUOE(() -> { + double o = (double) vh.getAndAdd(recv, 1.0d); + }); + + checkUOE(() -> { + double o = (double) vh.addAndGet(recv, 1.0d); + }); + } + + + static void testStaticFinalField(VarHandle vh) { + // Plain + { + double x = (double) vh.get(); + assertEquals(x, 1.0d, "get double value"); + } + + + // Volatile + { + double x = (double) vh.getVolatile(); + assertEquals(x, 1.0d, "getVolatile double value"); + } + + // Lazy + { + double x = (double) vh.getAcquire(); + assertEquals(x, 1.0d, "getRelease double value"); + } + + // Opaque + { + double x = (double) vh.getOpaque(); + assertEquals(x, 1.0d, "getOpaque double value"); + } + } + + static void testStaticFinalFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + vh.set(2.0d); + }); + + checkUOE(() -> { + vh.setVolatile(2.0d); + }); + + checkUOE(() -> { + vh.setRelease(2.0d); + }); + + checkUOE(() -> { + vh.setOpaque(2.0d); + }); + + checkUOE(() -> { + boolean r = vh.compareAndSet(1.0d, 2.0d); + }); + + checkUOE(() -> { + double r = (double) vh.compareAndExchangeVolatile(1.0d, 2.0d); + }); + + checkUOE(() -> { + double r = (double) vh.compareAndExchangeAcquire(1.0d, 2.0d); + }); + + checkUOE(() -> { + double r = (double) vh.compareAndExchangeRelease(1.0d, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(1.0d, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(1.0d, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(1.0d, 2.0d); + }); + + checkUOE(() -> { + double o = (double) vh.getAndAdd(1.0d); + }); + + checkUOE(() -> { + double o = (double) vh.addAndGet(1.0d); + }); + } + + + static void testInstanceField(VarHandleTestAccessDouble recv, VarHandle vh) { + // Plain + { + vh.set(recv, 1.0d); + double x = (double) vh.get(recv); + assertEquals(x, 1.0d, "set double value"); + } + + + // Volatile + { + vh.setVolatile(recv, 2.0d); + double x = (double) vh.getVolatile(recv); + assertEquals(x, 2.0d, "setVolatile double value"); + } + + // Lazy + { + vh.setRelease(recv, 1.0d); + double x = (double) vh.getAcquire(recv); + assertEquals(x, 1.0d, "setRelease double value"); + } + + // Opaque + { + vh.setOpaque(recv, 2.0d); + double x = (double) vh.getOpaque(recv); + assertEquals(x, 2.0d, "setOpaque double value"); + } + + + } + + static void testInstanceFieldUnsupported(VarHandleTestAccessDouble recv, VarHandle vh) { + checkUOE(() -> { + boolean r = vh.compareAndSet(recv, 1.0d, 2.0d); + }); + + checkUOE(() -> { + double r = (double) vh.compareAndExchangeVolatile(recv, 1.0d, 2.0d); + }); + + checkUOE(() -> { + double r = (double) vh.compareAndExchangeAcquire(recv, 1.0d, 2.0d); + }); + + checkUOE(() -> { + double r = (double) vh.compareAndExchangeRelease(recv, 1.0d, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(recv, 1.0d, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(recv, 1.0d, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(recv, 1.0d, 2.0d); + }); + + checkUOE(() -> { + double o = (double) vh.getAndAdd(recv, 1.0d); + }); + + checkUOE(() -> { + double o = (double) vh.addAndGet(recv, 1.0d); + }); + } + + + static void testStaticField(VarHandle vh) { + // Plain + { + vh.set(1.0d); + double x = (double) vh.get(); + assertEquals(x, 1.0d, "set double value"); + } + + + // Volatile + { + vh.setVolatile(2.0d); + double x = (double) vh.getVolatile(); + assertEquals(x, 2.0d, "setVolatile double value"); + } + + // Lazy + { + vh.setRelease(1.0d); + double x = (double) vh.getAcquire(); + assertEquals(x, 1.0d, "setRelease double value"); + } + + // Opaque + { + vh.setOpaque(2.0d); + double x = (double) vh.getOpaque(); + assertEquals(x, 2.0d, "setOpaque double value"); + } + + + } + + static void testStaticFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + boolean r = vh.compareAndSet(1.0d, 2.0d); + }); + + checkUOE(() -> { + double r = (double) vh.compareAndExchangeVolatile(1.0d, 2.0d); + }); + + checkUOE(() -> { + double r = (double) vh.compareAndExchangeAcquire(1.0d, 2.0d); + }); + + checkUOE(() -> { + double r = (double) vh.compareAndExchangeRelease(1.0d, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(1.0d, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(1.0d, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(1.0d, 2.0d); + }); + + checkUOE(() -> { + double o = (double) vh.getAndAdd(1.0d); + }); + + checkUOE(() -> { + double o = (double) vh.addAndGet(1.0d); + }); + } + + + static void testArray(VarHandle vh) { + double[] array = new double[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + vh.set(array, i, 1.0d); + double x = (double) vh.get(array, i); + assertEquals(x, 1.0d, "get double value"); + } + + + // Volatile + { + vh.setVolatile(array, i, 2.0d); + double x = (double) vh.getVolatile(array, i); + assertEquals(x, 2.0d, "setVolatile double value"); + } + + // Lazy + { + vh.setRelease(array, i, 1.0d); + double x = (double) vh.getAcquire(array, i); + assertEquals(x, 1.0d, "setRelease double value"); + } + + // Opaque + { + vh.setOpaque(array, i, 2.0d); + double x = (double) vh.getOpaque(array, i); + assertEquals(x, 2.0d, "setOpaque double value"); + } + + + } + } + + static void testArrayUnsupported(VarHandle vh) { + double[] array = new double[10]; + + int i = 0; + checkUOE(() -> { + boolean r = vh.compareAndSet(array, i, 1.0d, 2.0d); + }); + + checkUOE(() -> { + double r = (double) vh.compareAndExchangeVolatile(array, i, 1.0d, 2.0d); + }); + + checkUOE(() -> { + double r = (double) vh.compareAndExchangeAcquire(array, i, 1.0d, 2.0d); + }); + + checkUOE(() -> { + double r = (double) vh.compareAndExchangeRelease(array, i, 1.0d, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, i, 1.0d, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, i, 1.0d, 2.0d); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, i, 1.0d, 2.0d); + }); + + checkUOE(() -> { + double o = (double) vh.getAndAdd(array, i, 1.0d); + }); + + checkUOE(() -> { + double o = (double) vh.addAndGet(array, i, 1.0d); + }); + } + + static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable { + double[] array = new double[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + double x = (double) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, 1.0d); + }); + + checkIOOBE(() -> { + double x = (double) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, 1.0d); + }); + + checkIOOBE(() -> { + double x = (double) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, 1.0d); + }); + + checkIOOBE(() -> { + double x = (double) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, 1.0d); + }); + + + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java new file mode 100644 index 00000000000..5970fe2de33 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java @@ -0,0 +1,647 @@ +/* + * Copyright (c) 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 + * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessFloat + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessFloat + * @run testng/othervm -Diters=20000 VarHandleTestAccessFloat + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestAccessFloat extends VarHandleBaseTest { + static final float static_final_v = 1.0f; + + static float static_v; + + final float final_v = 1.0f; + + float v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessFloat.class, "final_v", float.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessFloat.class, "v", float.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessFloat.class, "static_final_v", float.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessFloat.class, "static_v", float.class); + + vhArray = MethodHandles.arrayElementVarHandle(float[].class); + } + + + @DataProvider + public Object[][] varHandlesProvider() throws Exception { + List vhs = new ArrayList<>(); + vhs.add(vhField); + vhs.add(vhStaticField); + vhs.add(vhArray); + + return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandle vh) { + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); + } + + + @DataProvider + public Object[][] typesProvider() throws Exception { + List types = new ArrayList<>(); + types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessFloat.class)}); + types.add(new Object[] {vhStaticField, Arrays.asList()}); + types.add(new Object[] {vhArray, Arrays.asList(float[].class, int.class)}); + + return types.stream().toArray(Object[][]::new); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), float.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @Test + public void testLookupInstanceToStatic() { + checkIAE("Lookup of static final field to instance final field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessFloat.class, "final_v", float.class); + }); + + checkIAE("Lookup of static field to instance field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessFloat.class, "v", float.class); + }); + } + + @Test + public void testLookupStaticToInstance() { + checkIAE("Lookup of instance final field to static final field", () -> { + MethodHandles.lookup().findVarHandle( + VarHandleTestAccessFloat.class, "static_final_v", float.class); + }); + + checkIAE("Lookup of instance field to static field", () -> { + vhStaticField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessFloat.class, "static_v", float.class); + }); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance final field", + vhFinalField, vh -> testInstanceFinalField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance final field unsupported", + vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static final field", + vhStaticFinalField, VarHandleTestAccessFloat::testStaticFinalField)); + cases.add(new VarHandleAccessTestCase("Static final field unsupported", + vhStaticFinalField, VarHandleTestAccessFloat::testStaticFinalFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Instance field", + vhField, vh -> testInstanceField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance field unsupported", + vhField, vh -> testInstanceFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field", + vhStaticField, VarHandleTestAccessFloat::testStaticField)); + cases.add(new VarHandleAccessTestCase("Static field unsupported", + vhStaticField, VarHandleTestAccessFloat::testStaticFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Array", + vhArray, VarHandleTestAccessFloat::testArray)); + cases.add(new VarHandleAccessTestCase("Array unsupported", + vhArray, VarHandleTestAccessFloat::testArrayUnsupported, + false)); + cases.add(new VarHandleAccessTestCase("Array index out of bounds", + vhArray, VarHandleTestAccessFloat::testArrayIndexOutOfBounds, + false)); + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + + + static void testInstanceFinalField(VarHandleTestAccessFloat recv, VarHandle vh) { + // Plain + { + float x = (float) vh.get(recv); + assertEquals(x, 1.0f, "get float value"); + } + + + // Volatile + { + float x = (float) vh.getVolatile(recv); + assertEquals(x, 1.0f, "getVolatile float value"); + } + + // Lazy + { + float x = (float) vh.getAcquire(recv); + assertEquals(x, 1.0f, "getRelease float value"); + } + + // Opaque + { + float x = (float) vh.getOpaque(recv); + assertEquals(x, 1.0f, "getOpaque float value"); + } + } + + static void testInstanceFinalFieldUnsupported(VarHandleTestAccessFloat recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, 2.0f); + }); + + checkUOE(() -> { + vh.setVolatile(recv, 2.0f); + }); + + checkUOE(() -> { + vh.setRelease(recv, 2.0f); + }); + + checkUOE(() -> { + vh.setOpaque(recv, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.compareAndSet(recv, 1.0f, 2.0f); + }); + + checkUOE(() -> { + float r = (float) vh.compareAndExchangeVolatile(recv, 1.0f, 2.0f); + }); + + checkUOE(() -> { + float r = (float) vh.compareAndExchangeAcquire(recv, 1.0f, 2.0f); + }); + + checkUOE(() -> { + float r = (float) vh.compareAndExchangeRelease(recv, 1.0f, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(recv, 1.0f, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(recv, 1.0f, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(recv, 1.0f, 2.0f); + }); + + checkUOE(() -> { + float o = (float) vh.getAndAdd(recv, 1.0f); + }); + + checkUOE(() -> { + float o = (float) vh.addAndGet(recv, 1.0f); + }); + } + + + static void testStaticFinalField(VarHandle vh) { + // Plain + { + float x = (float) vh.get(); + assertEquals(x, 1.0f, "get float value"); + } + + + // Volatile + { + float x = (float) vh.getVolatile(); + assertEquals(x, 1.0f, "getVolatile float value"); + } + + // Lazy + { + float x = (float) vh.getAcquire(); + assertEquals(x, 1.0f, "getRelease float value"); + } + + // Opaque + { + float x = (float) vh.getOpaque(); + assertEquals(x, 1.0f, "getOpaque float value"); + } + } + + static void testStaticFinalFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + vh.set(2.0f); + }); + + checkUOE(() -> { + vh.setVolatile(2.0f); + }); + + checkUOE(() -> { + vh.setRelease(2.0f); + }); + + checkUOE(() -> { + vh.setOpaque(2.0f); + }); + + checkUOE(() -> { + boolean r = vh.compareAndSet(1.0f, 2.0f); + }); + + checkUOE(() -> { + float r = (float) vh.compareAndExchangeVolatile(1.0f, 2.0f); + }); + + checkUOE(() -> { + float r = (float) vh.compareAndExchangeAcquire(1.0f, 2.0f); + }); + + checkUOE(() -> { + float r = (float) vh.compareAndExchangeRelease(1.0f, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(1.0f, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(1.0f, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(1.0f, 2.0f); + }); + + checkUOE(() -> { + float o = (float) vh.getAndAdd(1.0f); + }); + + checkUOE(() -> { + float o = (float) vh.addAndGet(1.0f); + }); + } + + + static void testInstanceField(VarHandleTestAccessFloat recv, VarHandle vh) { + // Plain + { + vh.set(recv, 1.0f); + float x = (float) vh.get(recv); + assertEquals(x, 1.0f, "set float value"); + } + + + // Volatile + { + vh.setVolatile(recv, 2.0f); + float x = (float) vh.getVolatile(recv); + assertEquals(x, 2.0f, "setVolatile float value"); + } + + // Lazy + { + vh.setRelease(recv, 1.0f); + float x = (float) vh.getAcquire(recv); + assertEquals(x, 1.0f, "setRelease float value"); + } + + // Opaque + { + vh.setOpaque(recv, 2.0f); + float x = (float) vh.getOpaque(recv); + assertEquals(x, 2.0f, "setOpaque float value"); + } + + + } + + static void testInstanceFieldUnsupported(VarHandleTestAccessFloat recv, VarHandle vh) { + checkUOE(() -> { + boolean r = vh.compareAndSet(recv, 1.0f, 2.0f); + }); + + checkUOE(() -> { + float r = (float) vh.compareAndExchangeVolatile(recv, 1.0f, 2.0f); + }); + + checkUOE(() -> { + float r = (float) vh.compareAndExchangeAcquire(recv, 1.0f, 2.0f); + }); + + checkUOE(() -> { + float r = (float) vh.compareAndExchangeRelease(recv, 1.0f, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(recv, 1.0f, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(recv, 1.0f, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(recv, 1.0f, 2.0f); + }); + + checkUOE(() -> { + float o = (float) vh.getAndAdd(recv, 1.0f); + }); + + checkUOE(() -> { + float o = (float) vh.addAndGet(recv, 1.0f); + }); + } + + + static void testStaticField(VarHandle vh) { + // Plain + { + vh.set(1.0f); + float x = (float) vh.get(); + assertEquals(x, 1.0f, "set float value"); + } + + + // Volatile + { + vh.setVolatile(2.0f); + float x = (float) vh.getVolatile(); + assertEquals(x, 2.0f, "setVolatile float value"); + } + + // Lazy + { + vh.setRelease(1.0f); + float x = (float) vh.getAcquire(); + assertEquals(x, 1.0f, "setRelease float value"); + } + + // Opaque + { + vh.setOpaque(2.0f); + float x = (float) vh.getOpaque(); + assertEquals(x, 2.0f, "setOpaque float value"); + } + + + } + + static void testStaticFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + boolean r = vh.compareAndSet(1.0f, 2.0f); + }); + + checkUOE(() -> { + float r = (float) vh.compareAndExchangeVolatile(1.0f, 2.0f); + }); + + checkUOE(() -> { + float r = (float) vh.compareAndExchangeAcquire(1.0f, 2.0f); + }); + + checkUOE(() -> { + float r = (float) vh.compareAndExchangeRelease(1.0f, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(1.0f, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(1.0f, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(1.0f, 2.0f); + }); + + checkUOE(() -> { + float o = (float) vh.getAndAdd(1.0f); + }); + + checkUOE(() -> { + float o = (float) vh.addAndGet(1.0f); + }); + } + + + static void testArray(VarHandle vh) { + float[] array = new float[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + vh.set(array, i, 1.0f); + float x = (float) vh.get(array, i); + assertEquals(x, 1.0f, "get float value"); + } + + + // Volatile + { + vh.setVolatile(array, i, 2.0f); + float x = (float) vh.getVolatile(array, i); + assertEquals(x, 2.0f, "setVolatile float value"); + } + + // Lazy + { + vh.setRelease(array, i, 1.0f); + float x = (float) vh.getAcquire(array, i); + assertEquals(x, 1.0f, "setRelease float value"); + } + + // Opaque + { + vh.setOpaque(array, i, 2.0f); + float x = (float) vh.getOpaque(array, i); + assertEquals(x, 2.0f, "setOpaque float value"); + } + + + } + } + + static void testArrayUnsupported(VarHandle vh) { + float[] array = new float[10]; + + int i = 0; + checkUOE(() -> { + boolean r = vh.compareAndSet(array, i, 1.0f, 2.0f); + }); + + checkUOE(() -> { + float r = (float) vh.compareAndExchangeVolatile(array, i, 1.0f, 2.0f); + }); + + checkUOE(() -> { + float r = (float) vh.compareAndExchangeAcquire(array, i, 1.0f, 2.0f); + }); + + checkUOE(() -> { + float r = (float) vh.compareAndExchangeRelease(array, i, 1.0f, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, i, 1.0f, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, i, 1.0f, 2.0f); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, i, 1.0f, 2.0f); + }); + + checkUOE(() -> { + float o = (float) vh.getAndAdd(array, i, 1.0f); + }); + + checkUOE(() -> { + float o = (float) vh.addAndGet(array, i, 1.0f); + }); + } + + static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable { + float[] array = new float[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + float x = (float) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, 1.0f); + }); + + checkIOOBE(() -> { + float x = (float) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, 1.0f); + }); + + checkIOOBE(() -> { + float x = (float) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, 1.0f); + }); + + checkIOOBE(() -> { + float x = (float) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, 1.0f); + }); + + + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java new file mode 100644 index 00000000000..5ed6480d62a --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java @@ -0,0 +1,803 @@ +/* + * Copyright (c) 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 + * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessInt + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessInt + * @run testng/othervm -Diters=20000 VarHandleTestAccessInt + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestAccessInt extends VarHandleBaseTest { + static final int static_final_v = 1; + + static int static_v; + + final int final_v = 1; + + int v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessInt.class, "final_v", int.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessInt.class, "v", int.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessInt.class, "static_final_v", int.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessInt.class, "static_v", int.class); + + vhArray = MethodHandles.arrayElementVarHandle(int[].class); + } + + + @DataProvider + public Object[][] varHandlesProvider() throws Exception { + List vhs = new ArrayList<>(); + vhs.add(vhField); + vhs.add(vhStaticField); + vhs.add(vhArray); + + return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandle vh) { + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); + } + + + @DataProvider + public Object[][] typesProvider() throws Exception { + List types = new ArrayList<>(); + types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessInt.class)}); + types.add(new Object[] {vhStaticField, Arrays.asList()}); + types.add(new Object[] {vhArray, Arrays.asList(int[].class, int.class)}); + + return types.stream().toArray(Object[][]::new); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), int.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @Test + public void testLookupInstanceToStatic() { + checkIAE("Lookup of static final field to instance final field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessInt.class, "final_v", int.class); + }); + + checkIAE("Lookup of static field to instance field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessInt.class, "v", int.class); + }); + } + + @Test + public void testLookupStaticToInstance() { + checkIAE("Lookup of instance final field to static final field", () -> { + MethodHandles.lookup().findVarHandle( + VarHandleTestAccessInt.class, "static_final_v", int.class); + }); + + checkIAE("Lookup of instance field to static field", () -> { + vhStaticField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessInt.class, "static_v", int.class); + }); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance final field", + vhFinalField, vh -> testInstanceFinalField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance final field unsupported", + vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static final field", + vhStaticFinalField, VarHandleTestAccessInt::testStaticFinalField)); + cases.add(new VarHandleAccessTestCase("Static final field unsupported", + vhStaticFinalField, VarHandleTestAccessInt::testStaticFinalFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Instance field", + vhField, vh -> testInstanceField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance field unsupported", + vhField, vh -> testInstanceFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field", + vhStaticField, VarHandleTestAccessInt::testStaticField)); + cases.add(new VarHandleAccessTestCase("Static field unsupported", + vhStaticField, VarHandleTestAccessInt::testStaticFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Array", + vhArray, VarHandleTestAccessInt::testArray)); + cases.add(new VarHandleAccessTestCase("Array unsupported", + vhArray, VarHandleTestAccessInt::testArrayUnsupported, + false)); + cases.add(new VarHandleAccessTestCase("Array index out of bounds", + vhArray, VarHandleTestAccessInt::testArrayIndexOutOfBounds, + false)); + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + + + static void testInstanceFinalField(VarHandleTestAccessInt recv, VarHandle vh) { + // Plain + { + int x = (int) vh.get(recv); + assertEquals(x, 1, "get int value"); + } + + + // Volatile + { + int x = (int) vh.getVolatile(recv); + assertEquals(x, 1, "getVolatile int value"); + } + + // Lazy + { + int x = (int) vh.getAcquire(recv); + assertEquals(x, 1, "getRelease int value"); + } + + // Opaque + { + int x = (int) vh.getOpaque(recv); + assertEquals(x, 1, "getOpaque int value"); + } + } + + static void testInstanceFinalFieldUnsupported(VarHandleTestAccessInt recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, 2); + }); + + checkUOE(() -> { + vh.setVolatile(recv, 2); + }); + + checkUOE(() -> { + vh.setRelease(recv, 2); + }); + + checkUOE(() -> { + vh.setOpaque(recv, 2); + }); + + + } + + + static void testStaticFinalField(VarHandle vh) { + // Plain + { + int x = (int) vh.get(); + assertEquals(x, 1, "get int value"); + } + + + // Volatile + { + int x = (int) vh.getVolatile(); + assertEquals(x, 1, "getVolatile int value"); + } + + // Lazy + { + int x = (int) vh.getAcquire(); + assertEquals(x, 1, "getRelease int value"); + } + + // Opaque + { + int x = (int) vh.getOpaque(); + assertEquals(x, 1, "getOpaque int value"); + } + } + + static void testStaticFinalFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + vh.set(2); + }); + + checkUOE(() -> { + vh.setVolatile(2); + }); + + checkUOE(() -> { + vh.setRelease(2); + }); + + checkUOE(() -> { + vh.setOpaque(2); + }); + + + } + + + static void testInstanceField(VarHandleTestAccessInt recv, VarHandle vh) { + // Plain + { + vh.set(recv, 1); + int x = (int) vh.get(recv); + assertEquals(x, 1, "set int value"); + } + + + // Volatile + { + vh.setVolatile(recv, 2); + int x = (int) vh.getVolatile(recv); + assertEquals(x, 2, "setVolatile int value"); + } + + // Lazy + { + vh.setRelease(recv, 1); + int x = (int) vh.getAcquire(recv); + assertEquals(x, 1, "setRelease int value"); + } + + // Opaque + { + vh.setOpaque(recv, 2); + int x = (int) vh.getOpaque(recv); + assertEquals(x, 2, "setOpaque int value"); + } + + vh.set(recv, 1); + + // Compare + { + boolean r = vh.compareAndSet(recv, 1, 2); + assertEquals(r, true, "success compareAndSet int"); + int x = (int) vh.get(recv); + assertEquals(x, 2, "success compareAndSet int value"); + } + + { + boolean r = vh.compareAndSet(recv, 1, 3); + assertEquals(r, false, "failing compareAndSet int"); + int x = (int) vh.get(recv); + assertEquals(x, 2, "failing compareAndSet int value"); + } + + { + int r = (int) vh.compareAndExchangeVolatile(recv, 2, 1); + assertEquals(r, 2, "success compareAndExchangeVolatile int"); + int x = (int) vh.get(recv); + assertEquals(x, 1, "success compareAndExchangeVolatile int value"); + } + + { + int r = (int) vh.compareAndExchangeVolatile(recv, 2, 3); + assertEquals(r, 1, "failing compareAndExchangeVolatile int"); + int x = (int) vh.get(recv); + assertEquals(x, 1, "failing compareAndExchangeVolatile int value"); + } + + { + int r = (int) vh.compareAndExchangeAcquire(recv, 1, 2); + assertEquals(r, 1, "success compareAndExchangeAcquire int"); + int x = (int) vh.get(recv); + assertEquals(x, 2, "success compareAndExchangeAcquire int value"); + } + + { + int r = (int) vh.compareAndExchangeAcquire(recv, 1, 3); + assertEquals(r, 2, "failing compareAndExchangeAcquire int"); + int x = (int) vh.get(recv); + assertEquals(x, 2, "failing compareAndExchangeAcquire int value"); + } + + { + int r = (int) vh.compareAndExchangeRelease(recv, 2, 1); + assertEquals(r, 2, "success compareAndExchangeRelease int"); + int x = (int) vh.get(recv); + assertEquals(x, 1, "success compareAndExchangeRelease int value"); + } + + { + int r = (int) vh.compareAndExchangeRelease(recv, 2, 3); + assertEquals(r, 1, "failing compareAndExchangeRelease int"); + int x = (int) vh.get(recv); + assertEquals(x, 1, "failing compareAndExchangeRelease int value"); + } + + { + boolean r = vh.weakCompareAndSet(recv, 1, 2); + assertEquals(r, true, "weakCompareAndSet int"); + int x = (int) vh.get(recv); + assertEquals(x, 2, "weakCompareAndSet int value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(recv, 2, 1); + assertEquals(r, true, "weakCompareAndSetAcquire int"); + int x = (int) vh.get(recv); + assertEquals(x, 1, "weakCompareAndSetAcquire int"); + } + + { + boolean r = vh.weakCompareAndSetRelease(recv, 1, 2); + assertEquals(r, true, "weakCompareAndSetRelease int"); + int x = (int) vh.get(recv); + assertEquals(x, 2, "weakCompareAndSetRelease int"); + } + + // Compare set and get + { + int o = (int) vh.getAndSet(recv, 1); + assertEquals(o, 2, "getAndSet int"); + int x = (int) vh.get(recv); + assertEquals(x, 1, "getAndSet int value"); + } + + vh.set(recv, 1); + + // get and add, add and get + { + int o = (int) vh.getAndAdd(recv, 3); + assertEquals(o, 1, "getAndAdd int"); + int c = (int) vh.addAndGet(recv, 3); + assertEquals(c, 1 + 3 + 3, "getAndAdd int value"); + } + } + + static void testInstanceFieldUnsupported(VarHandleTestAccessInt recv, VarHandle vh) { + + } + + + static void testStaticField(VarHandle vh) { + // Plain + { + vh.set(1); + int x = (int) vh.get(); + assertEquals(x, 1, "set int value"); + } + + + // Volatile + { + vh.setVolatile(2); + int x = (int) vh.getVolatile(); + assertEquals(x, 2, "setVolatile int value"); + } + + // Lazy + { + vh.setRelease(1); + int x = (int) vh.getAcquire(); + assertEquals(x, 1, "setRelease int value"); + } + + // Opaque + { + vh.setOpaque(2); + int x = (int) vh.getOpaque(); + assertEquals(x, 2, "setOpaque int value"); + } + + vh.set(1); + + // Compare + { + boolean r = vh.compareAndSet(1, 2); + assertEquals(r, true, "success compareAndSet int"); + int x = (int) vh.get(); + assertEquals(x, 2, "success compareAndSet int value"); + } + + { + boolean r = vh.compareAndSet(1, 3); + assertEquals(r, false, "failing compareAndSet int"); + int x = (int) vh.get(); + assertEquals(x, 2, "failing compareAndSet int value"); + } + + { + int r = (int) vh.compareAndExchangeVolatile(2, 1); + assertEquals(r, 2, "success compareAndExchangeVolatile int"); + int x = (int) vh.get(); + assertEquals(x, 1, "success compareAndExchangeVolatile int value"); + } + + { + int r = (int) vh.compareAndExchangeVolatile(2, 3); + assertEquals(r, 1, "failing compareAndExchangeVolatile int"); + int x = (int) vh.get(); + assertEquals(x, 1, "failing compareAndExchangeVolatile int value"); + } + + { + int r = (int) vh.compareAndExchangeAcquire(1, 2); + assertEquals(r, 1, "success compareAndExchangeAcquire int"); + int x = (int) vh.get(); + assertEquals(x, 2, "success compareAndExchangeAcquire int value"); + } + + { + int r = (int) vh.compareAndExchangeAcquire(1, 3); + assertEquals(r, 2, "failing compareAndExchangeAcquire int"); + int x = (int) vh.get(); + assertEquals(x, 2, "failing compareAndExchangeAcquire int value"); + } + + { + int r = (int) vh.compareAndExchangeRelease(2, 1); + assertEquals(r, 2, "success compareAndExchangeRelease int"); + int x = (int) vh.get(); + assertEquals(x, 1, "success compareAndExchangeRelease int value"); + } + + { + int r = (int) vh.compareAndExchangeRelease(2, 3); + assertEquals(r, 1, "failing compareAndExchangeRelease int"); + int x = (int) vh.get(); + assertEquals(x, 1, "failing compareAndExchangeRelease int value"); + } + + { + boolean r = (boolean) vh.weakCompareAndSet(1, 2); + assertEquals(r, true, "weakCompareAndSet int"); + int x = (int) vh.get(); + assertEquals(x, 2, "weakCompareAndSet int value"); + } + + { + boolean r = (boolean) vh.weakCompareAndSetAcquire(2, 1); + assertEquals(r, true, "weakCompareAndSetAcquire int"); + int x = (int) vh.get(); + assertEquals(x, 1, "weakCompareAndSetAcquire int"); + } + + { + boolean r = (boolean) vh.weakCompareAndSetRelease( 1, 2); + assertEquals(r, true, "weakCompareAndSetRelease int"); + int x = (int) vh.get(); + assertEquals(x, 2, "weakCompareAndSetRelease int"); + } + + // Compare set and get + { + int o = (int) vh.getAndSet( 1); + assertEquals(o, 2, "getAndSet int"); + int x = (int) vh.get(); + assertEquals(x, 1, "getAndSet int value"); + } + + vh.set(1); + + // get and add, add and get + { + int o = (int) vh.getAndAdd( 3); + assertEquals(o, 1, "getAndAdd int"); + int c = (int) vh.addAndGet(3); + assertEquals(c, 1 + 3 + 3, "getAndAdd int value"); + } + } + + static void testStaticFieldUnsupported(VarHandle vh) { + + } + + + static void testArray(VarHandle vh) { + int[] array = new int[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + vh.set(array, i, 1); + int x = (int) vh.get(array, i); + assertEquals(x, 1, "get int value"); + } + + + // Volatile + { + vh.setVolatile(array, i, 2); + int x = (int) vh.getVolatile(array, i); + assertEquals(x, 2, "setVolatile int value"); + } + + // Lazy + { + vh.setRelease(array, i, 1); + int x = (int) vh.getAcquire(array, i); + assertEquals(x, 1, "setRelease int value"); + } + + // Opaque + { + vh.setOpaque(array, i, 2); + int x = (int) vh.getOpaque(array, i); + assertEquals(x, 2, "setOpaque int value"); + } + + vh.set(array, i, 1); + + // Compare + { + boolean r = vh.compareAndSet(array, i, 1, 2); + assertEquals(r, true, "success compareAndSet int"); + int x = (int) vh.get(array, i); + assertEquals(x, 2, "success compareAndSet int value"); + } + + { + boolean r = vh.compareAndSet(array, i, 1, 3); + assertEquals(r, false, "failing compareAndSet int"); + int x = (int) vh.get(array, i); + assertEquals(x, 2, "failing compareAndSet int value"); + } + + { + int r = (int) vh.compareAndExchangeVolatile(array, i, 2, 1); + assertEquals(r, 2, "success compareAndExchangeVolatile int"); + int x = (int) vh.get(array, i); + assertEquals(x, 1, "success compareAndExchangeVolatile int value"); + } + + { + int r = (int) vh.compareAndExchangeVolatile(array, i, 2, 3); + assertEquals(r, 1, "failing compareAndExchangeVolatile int"); + int x = (int) vh.get(array, i); + assertEquals(x, 1, "failing compareAndExchangeVolatile int value"); + } + + { + int r = (int) vh.compareAndExchangeAcquire(array, i, 1, 2); + assertEquals(r, 1, "success compareAndExchangeAcquire int"); + int x = (int) vh.get(array, i); + assertEquals(x, 2, "success compareAndExchangeAcquire int value"); + } + + { + int r = (int) vh.compareAndExchangeAcquire(array, i, 1, 3); + assertEquals(r, 2, "failing compareAndExchangeAcquire int"); + int x = (int) vh.get(array, i); + assertEquals(x, 2, "failing compareAndExchangeAcquire int value"); + } + + { + int r = (int) vh.compareAndExchangeRelease(array, i, 2, 1); + assertEquals(r, 2, "success compareAndExchangeRelease int"); + int x = (int) vh.get(array, i); + assertEquals(x, 1, "success compareAndExchangeRelease int value"); + } + + { + int r = (int) vh.compareAndExchangeRelease(array, i, 2, 3); + assertEquals(r, 1, "failing compareAndExchangeRelease int"); + int x = (int) vh.get(array, i); + assertEquals(x, 1, "failing compareAndExchangeRelease int value"); + } + + { + boolean r = vh.weakCompareAndSet(array, i, 1, 2); + assertEquals(r, true, "weakCompareAndSet int"); + int x = (int) vh.get(array, i); + assertEquals(x, 2, "weakCompareAndSet int value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(array, i, 2, 1); + assertEquals(r, true, "weakCompareAndSetAcquire int"); + int x = (int) vh.get(array, i); + assertEquals(x, 1, "weakCompareAndSetAcquire int"); + } + + { + boolean r = vh.weakCompareAndSetRelease(array, i, 1, 2); + assertEquals(r, true, "weakCompareAndSetRelease int"); + int x = (int) vh.get(array, i); + assertEquals(x, 2, "weakCompareAndSetRelease int"); + } + + // Compare set and get + { + int o = (int) vh.getAndSet(array, i, 1); + assertEquals(o, 2, "getAndSet int"); + int x = (int) vh.get(array, i); + assertEquals(x, 1, "getAndSet int value"); + } + + vh.set(array, i, 1); + + // get and add, add and get + { + int o = (int) vh.getAndAdd(array, i, 3); + assertEquals(o, 1, "getAndAdd int"); + int c = (int) vh.addAndGet(array, i, 3); + assertEquals(c, 1 + 3 + 3, "getAndAdd int value"); + } + } + } + + static void testArrayUnsupported(VarHandle vh) { + int[] array = new int[10]; + + int i = 0; + + } + + static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable { + int[] array = new int[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + int x = (int) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, 1); + }); + + checkIOOBE(() -> { + int x = (int) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, 1); + }); + + checkIOOBE(() -> { + int x = (int) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, 1); + }); + + checkIOOBE(() -> { + int x = (int) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, 1); + }); + + checkIOOBE(() -> { + boolean r = vh.compareAndSet(array, ci, 1, 2); + }); + + checkIOOBE(() -> { + int r = (int) vh.compareAndExchangeVolatile(array, ci, 2, 1); + }); + + checkIOOBE(() -> { + int r = (int) vh.compareAndExchangeAcquire(array, ci, 2, 1); + }); + + checkIOOBE(() -> { + int r = (int) vh.compareAndExchangeRelease(array, ci, 2, 1); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, 1, 2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, 1, 2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, 1, 2); + }); + + checkIOOBE(() -> { + int o = (int) vh.getAndSet(array, ci, 1); + }); + + checkIOOBE(() -> { + int o = (int) vh.getAndAdd(array, ci, 3); + }); + + checkIOOBE(() -> { + int o = (int) vh.addAndGet(array, ci, 3); + }); + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java new file mode 100644 index 00000000000..6d84211ea10 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java @@ -0,0 +1,803 @@ +/* + * Copyright (c) 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 + * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessLong + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessLong + * @run testng/othervm -Diters=20000 VarHandleTestAccessLong + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestAccessLong extends VarHandleBaseTest { + static final long static_final_v = 1L; + + static long static_v; + + final long final_v = 1L; + + long v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessLong.class, "final_v", long.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessLong.class, "v", long.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessLong.class, "static_final_v", long.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessLong.class, "static_v", long.class); + + vhArray = MethodHandles.arrayElementVarHandle(long[].class); + } + + + @DataProvider + public Object[][] varHandlesProvider() throws Exception { + List vhs = new ArrayList<>(); + vhs.add(vhField); + vhs.add(vhStaticField); + vhs.add(vhArray); + + return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandle vh) { + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); + } + + + @DataProvider + public Object[][] typesProvider() throws Exception { + List types = new ArrayList<>(); + types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessLong.class)}); + types.add(new Object[] {vhStaticField, Arrays.asList()}); + types.add(new Object[] {vhArray, Arrays.asList(long[].class, int.class)}); + + return types.stream().toArray(Object[][]::new); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), long.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @Test + public void testLookupInstanceToStatic() { + checkIAE("Lookup of static final field to instance final field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessLong.class, "final_v", long.class); + }); + + checkIAE("Lookup of static field to instance field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessLong.class, "v", long.class); + }); + } + + @Test + public void testLookupStaticToInstance() { + checkIAE("Lookup of instance final field to static final field", () -> { + MethodHandles.lookup().findVarHandle( + VarHandleTestAccessLong.class, "static_final_v", long.class); + }); + + checkIAE("Lookup of instance field to static field", () -> { + vhStaticField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessLong.class, "static_v", long.class); + }); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance final field", + vhFinalField, vh -> testInstanceFinalField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance final field unsupported", + vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static final field", + vhStaticFinalField, VarHandleTestAccessLong::testStaticFinalField)); + cases.add(new VarHandleAccessTestCase("Static final field unsupported", + vhStaticFinalField, VarHandleTestAccessLong::testStaticFinalFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Instance field", + vhField, vh -> testInstanceField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance field unsupported", + vhField, vh -> testInstanceFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field", + vhStaticField, VarHandleTestAccessLong::testStaticField)); + cases.add(new VarHandleAccessTestCase("Static field unsupported", + vhStaticField, VarHandleTestAccessLong::testStaticFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Array", + vhArray, VarHandleTestAccessLong::testArray)); + cases.add(new VarHandleAccessTestCase("Array unsupported", + vhArray, VarHandleTestAccessLong::testArrayUnsupported, + false)); + cases.add(new VarHandleAccessTestCase("Array index out of bounds", + vhArray, VarHandleTestAccessLong::testArrayIndexOutOfBounds, + false)); + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + + + static void testInstanceFinalField(VarHandleTestAccessLong recv, VarHandle vh) { + // Plain + { + long x = (long) vh.get(recv); + assertEquals(x, 1L, "get long value"); + } + + + // Volatile + { + long x = (long) vh.getVolatile(recv); + assertEquals(x, 1L, "getVolatile long value"); + } + + // Lazy + { + long x = (long) vh.getAcquire(recv); + assertEquals(x, 1L, "getRelease long value"); + } + + // Opaque + { + long x = (long) vh.getOpaque(recv); + assertEquals(x, 1L, "getOpaque long value"); + } + } + + static void testInstanceFinalFieldUnsupported(VarHandleTestAccessLong recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, 2L); + }); + + checkUOE(() -> { + vh.setVolatile(recv, 2L); + }); + + checkUOE(() -> { + vh.setRelease(recv, 2L); + }); + + checkUOE(() -> { + vh.setOpaque(recv, 2L); + }); + + + } + + + static void testStaticFinalField(VarHandle vh) { + // Plain + { + long x = (long) vh.get(); + assertEquals(x, 1L, "get long value"); + } + + + // Volatile + { + long x = (long) vh.getVolatile(); + assertEquals(x, 1L, "getVolatile long value"); + } + + // Lazy + { + long x = (long) vh.getAcquire(); + assertEquals(x, 1L, "getRelease long value"); + } + + // Opaque + { + long x = (long) vh.getOpaque(); + assertEquals(x, 1L, "getOpaque long value"); + } + } + + static void testStaticFinalFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + vh.set(2L); + }); + + checkUOE(() -> { + vh.setVolatile(2L); + }); + + checkUOE(() -> { + vh.setRelease(2L); + }); + + checkUOE(() -> { + vh.setOpaque(2L); + }); + + + } + + + static void testInstanceField(VarHandleTestAccessLong recv, VarHandle vh) { + // Plain + { + vh.set(recv, 1L); + long x = (long) vh.get(recv); + assertEquals(x, 1L, "set long value"); + } + + + // Volatile + { + vh.setVolatile(recv, 2L); + long x = (long) vh.getVolatile(recv); + assertEquals(x, 2L, "setVolatile long value"); + } + + // Lazy + { + vh.setRelease(recv, 1L); + long x = (long) vh.getAcquire(recv); + assertEquals(x, 1L, "setRelease long value"); + } + + // Opaque + { + vh.setOpaque(recv, 2L); + long x = (long) vh.getOpaque(recv); + assertEquals(x, 2L, "setOpaque long value"); + } + + vh.set(recv, 1L); + + // Compare + { + boolean r = vh.compareAndSet(recv, 1L, 2L); + assertEquals(r, true, "success compareAndSet long"); + long x = (long) vh.get(recv); + assertEquals(x, 2L, "success compareAndSet long value"); + } + + { + boolean r = vh.compareAndSet(recv, 1L, 3L); + assertEquals(r, false, "failing compareAndSet long"); + long x = (long) vh.get(recv); + assertEquals(x, 2L, "failing compareAndSet long value"); + } + + { + long r = (long) vh.compareAndExchangeVolatile(recv, 2L, 1L); + assertEquals(r, 2L, "success compareAndExchangeVolatile long"); + long x = (long) vh.get(recv); + assertEquals(x, 1L, "success compareAndExchangeVolatile long value"); + } + + { + long r = (long) vh.compareAndExchangeVolatile(recv, 2L, 3L); + assertEquals(r, 1L, "failing compareAndExchangeVolatile long"); + long x = (long) vh.get(recv); + assertEquals(x, 1L, "failing compareAndExchangeVolatile long value"); + } + + { + long r = (long) vh.compareAndExchangeAcquire(recv, 1L, 2L); + assertEquals(r, 1L, "success compareAndExchangeAcquire long"); + long x = (long) vh.get(recv); + assertEquals(x, 2L, "success compareAndExchangeAcquire long value"); + } + + { + long r = (long) vh.compareAndExchangeAcquire(recv, 1L, 3L); + assertEquals(r, 2L, "failing compareAndExchangeAcquire long"); + long x = (long) vh.get(recv); + assertEquals(x, 2L, "failing compareAndExchangeAcquire long value"); + } + + { + long r = (long) vh.compareAndExchangeRelease(recv, 2L, 1L); + assertEquals(r, 2L, "success compareAndExchangeRelease long"); + long x = (long) vh.get(recv); + assertEquals(x, 1L, "success compareAndExchangeRelease long value"); + } + + { + long r = (long) vh.compareAndExchangeRelease(recv, 2L, 3L); + assertEquals(r, 1L, "failing compareAndExchangeRelease long"); + long x = (long) vh.get(recv); + assertEquals(x, 1L, "failing compareAndExchangeRelease long value"); + } + + { + boolean r = vh.weakCompareAndSet(recv, 1L, 2L); + assertEquals(r, true, "weakCompareAndSet long"); + long x = (long) vh.get(recv); + assertEquals(x, 2L, "weakCompareAndSet long value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(recv, 2L, 1L); + assertEquals(r, true, "weakCompareAndSetAcquire long"); + long x = (long) vh.get(recv); + assertEquals(x, 1L, "weakCompareAndSetAcquire long"); + } + + { + boolean r = vh.weakCompareAndSetRelease(recv, 1L, 2L); + assertEquals(r, true, "weakCompareAndSetRelease long"); + long x = (long) vh.get(recv); + assertEquals(x, 2L, "weakCompareAndSetRelease long"); + } + + // Compare set and get + { + long o = (long) vh.getAndSet(recv, 1L); + assertEquals(o, 2L, "getAndSet long"); + long x = (long) vh.get(recv); + assertEquals(x, 1L, "getAndSet long value"); + } + + vh.set(recv, 1L); + + // get and add, add and get + { + long o = (long) vh.getAndAdd(recv, 3L); + assertEquals(o, 1L, "getAndAdd long"); + long c = (long) vh.addAndGet(recv, 3L); + assertEquals(c, 1L + 3L + 3L, "getAndAdd long value"); + } + } + + static void testInstanceFieldUnsupported(VarHandleTestAccessLong recv, VarHandle vh) { + + } + + + static void testStaticField(VarHandle vh) { + // Plain + { + vh.set(1L); + long x = (long) vh.get(); + assertEquals(x, 1L, "set long value"); + } + + + // Volatile + { + vh.setVolatile(2L); + long x = (long) vh.getVolatile(); + assertEquals(x, 2L, "setVolatile long value"); + } + + // Lazy + { + vh.setRelease(1L); + long x = (long) vh.getAcquire(); + assertEquals(x, 1L, "setRelease long value"); + } + + // Opaque + { + vh.setOpaque(2L); + long x = (long) vh.getOpaque(); + assertEquals(x, 2L, "setOpaque long value"); + } + + vh.set(1L); + + // Compare + { + boolean r = vh.compareAndSet(1L, 2L); + assertEquals(r, true, "success compareAndSet long"); + long x = (long) vh.get(); + assertEquals(x, 2L, "success compareAndSet long value"); + } + + { + boolean r = vh.compareAndSet(1L, 3L); + assertEquals(r, false, "failing compareAndSet long"); + long x = (long) vh.get(); + assertEquals(x, 2L, "failing compareAndSet long value"); + } + + { + long r = (long) vh.compareAndExchangeVolatile(2L, 1L); + assertEquals(r, 2L, "success compareAndExchangeVolatile long"); + long x = (long) vh.get(); + assertEquals(x, 1L, "success compareAndExchangeVolatile long value"); + } + + { + long r = (long) vh.compareAndExchangeVolatile(2L, 3L); + assertEquals(r, 1L, "failing compareAndExchangeVolatile long"); + long x = (long) vh.get(); + assertEquals(x, 1L, "failing compareAndExchangeVolatile long value"); + } + + { + long r = (long) vh.compareAndExchangeAcquire(1L, 2L); + assertEquals(r, 1L, "success compareAndExchangeAcquire long"); + long x = (long) vh.get(); + assertEquals(x, 2L, "success compareAndExchangeAcquire long value"); + } + + { + long r = (long) vh.compareAndExchangeAcquire(1L, 3L); + assertEquals(r, 2L, "failing compareAndExchangeAcquire long"); + long x = (long) vh.get(); + assertEquals(x, 2L, "failing compareAndExchangeAcquire long value"); + } + + { + long r = (long) vh.compareAndExchangeRelease(2L, 1L); + assertEquals(r, 2L, "success compareAndExchangeRelease long"); + long x = (long) vh.get(); + assertEquals(x, 1L, "success compareAndExchangeRelease long value"); + } + + { + long r = (long) vh.compareAndExchangeRelease(2L, 3L); + assertEquals(r, 1L, "failing compareAndExchangeRelease long"); + long x = (long) vh.get(); + assertEquals(x, 1L, "failing compareAndExchangeRelease long value"); + } + + { + boolean r = (boolean) vh.weakCompareAndSet(1L, 2L); + assertEquals(r, true, "weakCompareAndSet long"); + long x = (long) vh.get(); + assertEquals(x, 2L, "weakCompareAndSet long value"); + } + + { + boolean r = (boolean) vh.weakCompareAndSetAcquire(2L, 1L); + assertEquals(r, true, "weakCompareAndSetAcquire long"); + long x = (long) vh.get(); + assertEquals(x, 1L, "weakCompareAndSetAcquire long"); + } + + { + boolean r = (boolean) vh.weakCompareAndSetRelease( 1L, 2L); + assertEquals(r, true, "weakCompareAndSetRelease long"); + long x = (long) vh.get(); + assertEquals(x, 2L, "weakCompareAndSetRelease long"); + } + + // Compare set and get + { + long o = (long) vh.getAndSet( 1L); + assertEquals(o, 2L, "getAndSet long"); + long x = (long) vh.get(); + assertEquals(x, 1L, "getAndSet long value"); + } + + vh.set(1L); + + // get and add, add and get + { + long o = (long) vh.getAndAdd( 3L); + assertEquals(o, 1L, "getAndAdd long"); + long c = (long) vh.addAndGet(3L); + assertEquals(c, 1L + 3L + 3L, "getAndAdd long value"); + } + } + + static void testStaticFieldUnsupported(VarHandle vh) { + + } + + + static void testArray(VarHandle vh) { + long[] array = new long[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + vh.set(array, i, 1L); + long x = (long) vh.get(array, i); + assertEquals(x, 1L, "get long value"); + } + + + // Volatile + { + vh.setVolatile(array, i, 2L); + long x = (long) vh.getVolatile(array, i); + assertEquals(x, 2L, "setVolatile long value"); + } + + // Lazy + { + vh.setRelease(array, i, 1L); + long x = (long) vh.getAcquire(array, i); + assertEquals(x, 1L, "setRelease long value"); + } + + // Opaque + { + vh.setOpaque(array, i, 2L); + long x = (long) vh.getOpaque(array, i); + assertEquals(x, 2L, "setOpaque long value"); + } + + vh.set(array, i, 1L); + + // Compare + { + boolean r = vh.compareAndSet(array, i, 1L, 2L); + assertEquals(r, true, "success compareAndSet long"); + long x = (long) vh.get(array, i); + assertEquals(x, 2L, "success compareAndSet long value"); + } + + { + boolean r = vh.compareAndSet(array, i, 1L, 3L); + assertEquals(r, false, "failing compareAndSet long"); + long x = (long) vh.get(array, i); + assertEquals(x, 2L, "failing compareAndSet long value"); + } + + { + long r = (long) vh.compareAndExchangeVolatile(array, i, 2L, 1L); + assertEquals(r, 2L, "success compareAndExchangeVolatile long"); + long x = (long) vh.get(array, i); + assertEquals(x, 1L, "success compareAndExchangeVolatile long value"); + } + + { + long r = (long) vh.compareAndExchangeVolatile(array, i, 2L, 3L); + assertEquals(r, 1L, "failing compareAndExchangeVolatile long"); + long x = (long) vh.get(array, i); + assertEquals(x, 1L, "failing compareAndExchangeVolatile long value"); + } + + { + long r = (long) vh.compareAndExchangeAcquire(array, i, 1L, 2L); + assertEquals(r, 1L, "success compareAndExchangeAcquire long"); + long x = (long) vh.get(array, i); + assertEquals(x, 2L, "success compareAndExchangeAcquire long value"); + } + + { + long r = (long) vh.compareAndExchangeAcquire(array, i, 1L, 3L); + assertEquals(r, 2L, "failing compareAndExchangeAcquire long"); + long x = (long) vh.get(array, i); + assertEquals(x, 2L, "failing compareAndExchangeAcquire long value"); + } + + { + long r = (long) vh.compareAndExchangeRelease(array, i, 2L, 1L); + assertEquals(r, 2L, "success compareAndExchangeRelease long"); + long x = (long) vh.get(array, i); + assertEquals(x, 1L, "success compareAndExchangeRelease long value"); + } + + { + long r = (long) vh.compareAndExchangeRelease(array, i, 2L, 3L); + assertEquals(r, 1L, "failing compareAndExchangeRelease long"); + long x = (long) vh.get(array, i); + assertEquals(x, 1L, "failing compareAndExchangeRelease long value"); + } + + { + boolean r = vh.weakCompareAndSet(array, i, 1L, 2L); + assertEquals(r, true, "weakCompareAndSet long"); + long x = (long) vh.get(array, i); + assertEquals(x, 2L, "weakCompareAndSet long value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(array, i, 2L, 1L); + assertEquals(r, true, "weakCompareAndSetAcquire long"); + long x = (long) vh.get(array, i); + assertEquals(x, 1L, "weakCompareAndSetAcquire long"); + } + + { + boolean r = vh.weakCompareAndSetRelease(array, i, 1L, 2L); + assertEquals(r, true, "weakCompareAndSetRelease long"); + long x = (long) vh.get(array, i); + assertEquals(x, 2L, "weakCompareAndSetRelease long"); + } + + // Compare set and get + { + long o = (long) vh.getAndSet(array, i, 1L); + assertEquals(o, 2L, "getAndSet long"); + long x = (long) vh.get(array, i); + assertEquals(x, 1L, "getAndSet long value"); + } + + vh.set(array, i, 1L); + + // get and add, add and get + { + long o = (long) vh.getAndAdd(array, i, 3L); + assertEquals(o, 1L, "getAndAdd long"); + long c = (long) vh.addAndGet(array, i, 3L); + assertEquals(c, 1L + 3L + 3L, "getAndAdd long value"); + } + } + } + + static void testArrayUnsupported(VarHandle vh) { + long[] array = new long[10]; + + int i = 0; + + } + + static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable { + long[] array = new long[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + long x = (long) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, 1L); + }); + + checkIOOBE(() -> { + long x = (long) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, 1L); + }); + + checkIOOBE(() -> { + long x = (long) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, 1L); + }); + + checkIOOBE(() -> { + long x = (long) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, 1L); + }); + + checkIOOBE(() -> { + boolean r = vh.compareAndSet(array, ci, 1L, 2L); + }); + + checkIOOBE(() -> { + long r = (long) vh.compareAndExchangeVolatile(array, ci, 2L, 1L); + }); + + checkIOOBE(() -> { + long r = (long) vh.compareAndExchangeAcquire(array, ci, 2L, 1L); + }); + + checkIOOBE(() -> { + long r = (long) vh.compareAndExchangeRelease(array, ci, 2L, 1L); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, 1L, 2L); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, 1L, 2L); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, 1L, 2L); + }); + + checkIOOBE(() -> { + long o = (long) vh.getAndSet(array, ci, 1L); + }); + + checkIOOBE(() -> { + long o = (long) vh.getAndAdd(array, ci, 3L); + }); + + checkIOOBE(() -> { + long o = (long) vh.addAndGet(array, ci, 3L); + }); + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java new file mode 100644 index 00000000000..ac9dfd5587b --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java @@ -0,0 +1,647 @@ +/* + * Copyright (c) 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 + * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessShort + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessShort + * @run testng/othervm -Diters=20000 VarHandleTestAccessShort + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestAccessShort extends VarHandleBaseTest { + static final short static_final_v = (short)1; + + static short static_v; + + final short final_v = (short)1; + + short v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessShort.class, "final_v", short.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessShort.class, "v", short.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessShort.class, "static_final_v", short.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessShort.class, "static_v", short.class); + + vhArray = MethodHandles.arrayElementVarHandle(short[].class); + } + + + @DataProvider + public Object[][] varHandlesProvider() throws Exception { + List vhs = new ArrayList<>(); + vhs.add(vhField); + vhs.add(vhStaticField); + vhs.add(vhArray); + + return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandle vh) { + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); + } + + + @DataProvider + public Object[][] typesProvider() throws Exception { + List types = new ArrayList<>(); + types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessShort.class)}); + types.add(new Object[] {vhStaticField, Arrays.asList()}); + types.add(new Object[] {vhArray, Arrays.asList(short[].class, int.class)}); + + return types.stream().toArray(Object[][]::new); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), short.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @Test + public void testLookupInstanceToStatic() { + checkIAE("Lookup of static final field to instance final field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessShort.class, "final_v", short.class); + }); + + checkIAE("Lookup of static field to instance field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessShort.class, "v", short.class); + }); + } + + @Test + public void testLookupStaticToInstance() { + checkIAE("Lookup of instance final field to static final field", () -> { + MethodHandles.lookup().findVarHandle( + VarHandleTestAccessShort.class, "static_final_v", short.class); + }); + + checkIAE("Lookup of instance field to static field", () -> { + vhStaticField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessShort.class, "static_v", short.class); + }); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance final field", + vhFinalField, vh -> testInstanceFinalField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance final field unsupported", + vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static final field", + vhStaticFinalField, VarHandleTestAccessShort::testStaticFinalField)); + cases.add(new VarHandleAccessTestCase("Static final field unsupported", + vhStaticFinalField, VarHandleTestAccessShort::testStaticFinalFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Instance field", + vhField, vh -> testInstanceField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance field unsupported", + vhField, vh -> testInstanceFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field", + vhStaticField, VarHandleTestAccessShort::testStaticField)); + cases.add(new VarHandleAccessTestCase("Static field unsupported", + vhStaticField, VarHandleTestAccessShort::testStaticFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Array", + vhArray, VarHandleTestAccessShort::testArray)); + cases.add(new VarHandleAccessTestCase("Array unsupported", + vhArray, VarHandleTestAccessShort::testArrayUnsupported, + false)); + cases.add(new VarHandleAccessTestCase("Array index out of bounds", + vhArray, VarHandleTestAccessShort::testArrayIndexOutOfBounds, + false)); + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + + + static void testInstanceFinalField(VarHandleTestAccessShort recv, VarHandle vh) { + // Plain + { + short x = (short) vh.get(recv); + assertEquals(x, (short)1, "get short value"); + } + + + // Volatile + { + short x = (short) vh.getVolatile(recv); + assertEquals(x, (short)1, "getVolatile short value"); + } + + // Lazy + { + short x = (short) vh.getAcquire(recv); + assertEquals(x, (short)1, "getRelease short value"); + } + + // Opaque + { + short x = (short) vh.getOpaque(recv); + assertEquals(x, (short)1, "getOpaque short value"); + } + } + + static void testInstanceFinalFieldUnsupported(VarHandleTestAccessShort recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, (short)2); + }); + + checkUOE(() -> { + vh.setVolatile(recv, (short)2); + }); + + checkUOE(() -> { + vh.setRelease(recv, (short)2); + }); + + checkUOE(() -> { + vh.setOpaque(recv, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.compareAndSet(recv, (short)1, (short)2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeVolatile(recv, (short)1, (short)2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeAcquire(recv, (short)1, (short)2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeRelease(recv, (short)1, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(recv, (short)1, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(recv, (short)1, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(recv, (short)1, (short)2); + }); + + checkUOE(() -> { + short o = (short) vh.getAndAdd(recv, (short)1); + }); + + checkUOE(() -> { + short o = (short) vh.addAndGet(recv, (short)1); + }); + } + + + static void testStaticFinalField(VarHandle vh) { + // Plain + { + short x = (short) vh.get(); + assertEquals(x, (short)1, "get short value"); + } + + + // Volatile + { + short x = (short) vh.getVolatile(); + assertEquals(x, (short)1, "getVolatile short value"); + } + + // Lazy + { + short x = (short) vh.getAcquire(); + assertEquals(x, (short)1, "getRelease short value"); + } + + // Opaque + { + short x = (short) vh.getOpaque(); + assertEquals(x, (short)1, "getOpaque short value"); + } + } + + static void testStaticFinalFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + vh.set((short)2); + }); + + checkUOE(() -> { + vh.setVolatile((short)2); + }); + + checkUOE(() -> { + vh.setRelease((short)2); + }); + + checkUOE(() -> { + vh.setOpaque((short)2); + }); + + checkUOE(() -> { + boolean r = vh.compareAndSet((short)1, (short)2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeVolatile((short)1, (short)2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeAcquire((short)1, (short)2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeRelease((short)1, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet((short)1, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire((short)1, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease((short)1, (short)2); + }); + + checkUOE(() -> { + short o = (short) vh.getAndAdd((short)1); + }); + + checkUOE(() -> { + short o = (short) vh.addAndGet((short)1); + }); + } + + + static void testInstanceField(VarHandleTestAccessShort recv, VarHandle vh) { + // Plain + { + vh.set(recv, (short)1); + short x = (short) vh.get(recv); + assertEquals(x, (short)1, "set short value"); + } + + + // Volatile + { + vh.setVolatile(recv, (short)2); + short x = (short) vh.getVolatile(recv); + assertEquals(x, (short)2, "setVolatile short value"); + } + + // Lazy + { + vh.setRelease(recv, (short)1); + short x = (short) vh.getAcquire(recv); + assertEquals(x, (short)1, "setRelease short value"); + } + + // Opaque + { + vh.setOpaque(recv, (short)2); + short x = (short) vh.getOpaque(recv); + assertEquals(x, (short)2, "setOpaque short value"); + } + + + } + + static void testInstanceFieldUnsupported(VarHandleTestAccessShort recv, VarHandle vh) { + checkUOE(() -> { + boolean r = vh.compareAndSet(recv, (short)1, (short)2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeVolatile(recv, (short)1, (short)2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeAcquire(recv, (short)1, (short)2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeRelease(recv, (short)1, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(recv, (short)1, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(recv, (short)1, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(recv, (short)1, (short)2); + }); + + checkUOE(() -> { + short o = (short) vh.getAndAdd(recv, (short)1); + }); + + checkUOE(() -> { + short o = (short) vh.addAndGet(recv, (short)1); + }); + } + + + static void testStaticField(VarHandle vh) { + // Plain + { + vh.set((short)1); + short x = (short) vh.get(); + assertEquals(x, (short)1, "set short value"); + } + + + // Volatile + { + vh.setVolatile((short)2); + short x = (short) vh.getVolatile(); + assertEquals(x, (short)2, "setVolatile short value"); + } + + // Lazy + { + vh.setRelease((short)1); + short x = (short) vh.getAcquire(); + assertEquals(x, (short)1, "setRelease short value"); + } + + // Opaque + { + vh.setOpaque((short)2); + short x = (short) vh.getOpaque(); + assertEquals(x, (short)2, "setOpaque short value"); + } + + + } + + static void testStaticFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + boolean r = vh.compareAndSet((short)1, (short)2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeVolatile((short)1, (short)2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeAcquire((short)1, (short)2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeRelease((short)1, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet((short)1, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire((short)1, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease((short)1, (short)2); + }); + + checkUOE(() -> { + short o = (short) vh.getAndAdd((short)1); + }); + + checkUOE(() -> { + short o = (short) vh.addAndGet((short)1); + }); + } + + + static void testArray(VarHandle vh) { + short[] array = new short[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + vh.set(array, i, (short)1); + short x = (short) vh.get(array, i); + assertEquals(x, (short)1, "get short value"); + } + + + // Volatile + { + vh.setVolatile(array, i, (short)2); + short x = (short) vh.getVolatile(array, i); + assertEquals(x, (short)2, "setVolatile short value"); + } + + // Lazy + { + vh.setRelease(array, i, (short)1); + short x = (short) vh.getAcquire(array, i); + assertEquals(x, (short)1, "setRelease short value"); + } + + // Opaque + { + vh.setOpaque(array, i, (short)2); + short x = (short) vh.getOpaque(array, i); + assertEquals(x, (short)2, "setOpaque short value"); + } + + + } + } + + static void testArrayUnsupported(VarHandle vh) { + short[] array = new short[10]; + + int i = 0; + checkUOE(() -> { + boolean r = vh.compareAndSet(array, i, (short)1, (short)2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeVolatile(array, i, (short)1, (short)2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeAcquire(array, i, (short)1, (short)2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeRelease(array, i, (short)1, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, i, (short)1, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, i, (short)1, (short)2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, i, (short)1, (short)2); + }); + + checkUOE(() -> { + short o = (short) vh.getAndAdd(array, i, (short)1); + }); + + checkUOE(() -> { + short o = (short) vh.addAndGet(array, i, (short)1); + }); + } + + static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable { + short[] array = new short[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + short x = (short) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, (short)1); + }); + + checkIOOBE(() -> { + short x = (short) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, (short)1); + }); + + checkIOOBE(() -> { + short x = (short) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, (short)1); + }); + + checkIOOBE(() -> { + short x = (short) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, (short)1); + }); + + + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java new file mode 100644 index 00000000000..ac01cd467a7 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java @@ -0,0 +1,804 @@ +/* + * Copyright (c) 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 + * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessString + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessString + * @run testng/othervm -Diters=20000 VarHandleTestAccessString + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestAccessString extends VarHandleBaseTest { + static final String static_final_v = "foo"; + + static String static_v; + + final String final_v = "foo"; + + String v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessString.class, "final_v", String.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessString.class, "v", String.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessString.class, "static_final_v", String.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessString.class, "static_v", String.class); + + vhArray = MethodHandles.arrayElementVarHandle(String[].class); + } + + + @DataProvider + public Object[][] varHandlesProvider() throws Exception { + List vhs = new ArrayList<>(); + vhs.add(vhField); + vhs.add(vhStaticField); + vhs.add(vhArray); + + return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandle vh) { + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); + } + + + @DataProvider + public Object[][] typesProvider() throws Exception { + List types = new ArrayList<>(); + types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessString.class)}); + types.add(new Object[] {vhStaticField, Arrays.asList()}); + types.add(new Object[] {vhArray, Arrays.asList(String[].class, int.class)}); + + return types.stream().toArray(Object[][]::new); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), String.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @Test + public void testLookupInstanceToStatic() { + checkIAE("Lookup of static final field to instance final field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessString.class, "final_v", String.class); + }); + + checkIAE("Lookup of static field to instance field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccessString.class, "v", String.class); + }); + } + + @Test + public void testLookupStaticToInstance() { + checkIAE("Lookup of instance final field to static final field", () -> { + MethodHandles.lookup().findVarHandle( + VarHandleTestAccessString.class, "static_final_v", String.class); + }); + + checkIAE("Lookup of instance field to static field", () -> { + vhStaticField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccessString.class, "static_v", String.class); + }); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance final field", + vhFinalField, vh -> testInstanceFinalField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance final field unsupported", + vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static final field", + vhStaticFinalField, VarHandleTestAccessString::testStaticFinalField)); + cases.add(new VarHandleAccessTestCase("Static final field unsupported", + vhStaticFinalField, VarHandleTestAccessString::testStaticFinalFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Instance field", + vhField, vh -> testInstanceField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance field unsupported", + vhField, vh -> testInstanceFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field", + vhStaticField, VarHandleTestAccessString::testStaticField)); + cases.add(new VarHandleAccessTestCase("Static field unsupported", + vhStaticField, VarHandleTestAccessString::testStaticFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Array", + vhArray, VarHandleTestAccessString::testArray)); + cases.add(new VarHandleAccessTestCase("Array unsupported", + vhArray, VarHandleTestAccessString::testArrayUnsupported, + false)); + cases.add(new VarHandleAccessTestCase("Array index out of bounds", + vhArray, VarHandleTestAccessString::testArrayIndexOutOfBounds, + false)); + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + + + static void testInstanceFinalField(VarHandleTestAccessString recv, VarHandle vh) { + // Plain + { + String x = (String) vh.get(recv); + assertEquals(x, "foo", "get String value"); + } + + + // Volatile + { + String x = (String) vh.getVolatile(recv); + assertEquals(x, "foo", "getVolatile String value"); + } + + // Lazy + { + String x = (String) vh.getAcquire(recv); + assertEquals(x, "foo", "getRelease String value"); + } + + // Opaque + { + String x = (String) vh.getOpaque(recv); + assertEquals(x, "foo", "getOpaque String value"); + } + } + + static void testInstanceFinalFieldUnsupported(VarHandleTestAccessString recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, "bar"); + }); + + checkUOE(() -> { + vh.setVolatile(recv, "bar"); + }); + + checkUOE(() -> { + vh.setRelease(recv, "bar"); + }); + + checkUOE(() -> { + vh.setOpaque(recv, "bar"); + }); + + + checkUOE(() -> { + String o = (String) vh.getAndAdd(recv, "foo"); + }); + + checkUOE(() -> { + String o = (String) vh.addAndGet(recv, "foo"); + }); + } + + + static void testStaticFinalField(VarHandle vh) { + // Plain + { + String x = (String) vh.get(); + assertEquals(x, "foo", "get String value"); + } + + + // Volatile + { + String x = (String) vh.getVolatile(); + assertEquals(x, "foo", "getVolatile String value"); + } + + // Lazy + { + String x = (String) vh.getAcquire(); + assertEquals(x, "foo", "getRelease String value"); + } + + // Opaque + { + String x = (String) vh.getOpaque(); + assertEquals(x, "foo", "getOpaque String value"); + } + } + + static void testStaticFinalFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + vh.set("bar"); + }); + + checkUOE(() -> { + vh.setVolatile("bar"); + }); + + checkUOE(() -> { + vh.setRelease("bar"); + }); + + checkUOE(() -> { + vh.setOpaque("bar"); + }); + + + checkUOE(() -> { + String o = (String) vh.getAndAdd("foo"); + }); + + checkUOE(() -> { + String o = (String) vh.addAndGet("foo"); + }); + } + + + static void testInstanceField(VarHandleTestAccessString recv, VarHandle vh) { + // Plain + { + vh.set(recv, "foo"); + String x = (String) vh.get(recv); + assertEquals(x, "foo", "set String value"); + } + + + // Volatile + { + vh.setVolatile(recv, "bar"); + String x = (String) vh.getVolatile(recv); + assertEquals(x, "bar", "setVolatile String value"); + } + + // Lazy + { + vh.setRelease(recv, "foo"); + String x = (String) vh.getAcquire(recv); + assertEquals(x, "foo", "setRelease String value"); + } + + // Opaque + { + vh.setOpaque(recv, "bar"); + String x = (String) vh.getOpaque(recv); + assertEquals(x, "bar", "setOpaque String value"); + } + + vh.set(recv, "foo"); + + // Compare + { + 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"); + } + + { + 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"); + } + + { + String r = (String) vh.compareAndExchangeVolatile(recv, "bar", "foo"); + assertEquals(r, "bar", "success compareAndExchangeVolatile String"); + String x = (String) vh.get(recv); + assertEquals(x, "foo", "success compareAndExchangeVolatile String value"); + } + + { + String r = (String) vh.compareAndExchangeVolatile(recv, "bar", "baz"); + assertEquals(r, "foo", "failing compareAndExchangeVolatile String"); + String x = (String) vh.get(recv); + assertEquals(x, "foo", "failing compareAndExchangeVolatile 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + boolean r = vh.weakCompareAndSet(recv, "foo", "bar"); + assertEquals(r, true, "weakCompareAndSet String"); + String x = (String) vh.get(recv); + assertEquals(x, "bar", "weakCompareAndSet String value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(recv, "bar", "foo"); + assertEquals(r, true, "weakCompareAndSetAcquire String"); + String x = (String) vh.get(recv); + assertEquals(x, "foo", "weakCompareAndSetAcquire String"); + } + + { + boolean r = vh.weakCompareAndSetRelease(recv, "foo", "bar"); + assertEquals(r, true, "weakCompareAndSetRelease String"); + String x = (String) vh.get(recv); + assertEquals(x, "bar", "weakCompareAndSetRelease String"); + } + + // Compare set and get + { + String o = (String) vh.getAndSet(recv, "foo"); + assertEquals(o, "bar", "getAndSet String"); + String x = (String) vh.get(recv); + assertEquals(x, "foo", "getAndSet String value"); + } + + } + + static void testInstanceFieldUnsupported(VarHandleTestAccessString recv, VarHandle vh) { + + checkUOE(() -> { + String o = (String) vh.getAndAdd(recv, "foo"); + }); + + checkUOE(() -> { + String o = (String) vh.addAndGet(recv, "foo"); + }); + } + + + static void testStaticField(VarHandle vh) { + // Plain + { + vh.set("foo"); + String x = (String) vh.get(); + assertEquals(x, "foo", "set String value"); + } + + + // Volatile + { + vh.setVolatile("bar"); + String x = (String) vh.getVolatile(); + assertEquals(x, "bar", "setVolatile String value"); + } + + // Lazy + { + vh.setRelease("foo"); + String x = (String) vh.getAcquire(); + assertEquals(x, "foo", "setRelease String value"); + } + + // Opaque + { + vh.setOpaque("bar"); + String x = (String) vh.getOpaque(); + assertEquals(x, "bar", "setOpaque String value"); + } + + vh.set("foo"); + + // Compare + { + boolean r = vh.compareAndSet("foo", "bar"); + assertEquals(r, true, "success compareAndSet String"); + String x = (String) vh.get(); + assertEquals(x, "bar", "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"); + } + + { + String r = (String) vh.compareAndExchangeVolatile("bar", "foo"); + assertEquals(r, "bar", "success compareAndExchangeVolatile String"); + String x = (String) vh.get(); + assertEquals(x, "foo", "success compareAndExchangeVolatile String value"); + } + + { + String r = (String) vh.compareAndExchangeVolatile("bar", "baz"); + assertEquals(r, "foo", "failing compareAndExchangeVolatile String"); + String x = (String) vh.get(); + assertEquals(x, "foo", "failing compareAndExchangeVolatile 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + boolean r = (boolean) vh.weakCompareAndSet("foo", "bar"); + assertEquals(r, true, "weakCompareAndSet String"); + String x = (String) vh.get(); + assertEquals(x, "bar", "weakCompareAndSet String value"); + } + + { + boolean r = (boolean) vh.weakCompareAndSetAcquire("bar", "foo"); + assertEquals(r, true, "weakCompareAndSetAcquire String"); + String x = (String) vh.get(); + assertEquals(x, "foo", "weakCompareAndSetAcquire String"); + } + + { + boolean r = (boolean) vh.weakCompareAndSetRelease( "foo", "bar"); + assertEquals(r, true, "weakCompareAndSetRelease String"); + String x = (String) vh.get(); + assertEquals(x, "bar", "weakCompareAndSetRelease String"); + } + + // Compare set and get + { + String o = (String) vh.getAndSet( "foo"); + assertEquals(o, "bar", "getAndSet String"); + String x = (String) vh.get(); + assertEquals(x, "foo", "getAndSet String value"); + } + + } + + static void testStaticFieldUnsupported(VarHandle vh) { + + checkUOE(() -> { + String o = (String) vh.getAndAdd("foo"); + }); + + checkUOE(() -> { + String o = (String) vh.addAndGet("foo"); + }); + } + + + static void testArray(VarHandle vh) { + String[] array = new String[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + vh.set(array, i, "foo"); + String x = (String) vh.get(array, i); + assertEquals(x, "foo", "get String value"); + } + + + // Volatile + { + vh.setVolatile(array, i, "bar"); + String x = (String) vh.getVolatile(array, i); + assertEquals(x, "bar", "setVolatile String value"); + } + + // Lazy + { + vh.setRelease(array, i, "foo"); + String x = (String) vh.getAcquire(array, i); + assertEquals(x, "foo", "setRelease String value"); + } + + // Opaque + { + vh.setOpaque(array, i, "bar"); + String x = (String) vh.getOpaque(array, i); + assertEquals(x, "bar", "setOpaque String value"); + } + + vh.set(array, i, "foo"); + + // Compare + { + 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"); + } + + { + 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"); + } + + { + String r = (String) vh.compareAndExchangeVolatile(array, i, "bar", "foo"); + assertEquals(r, "bar", "success compareAndExchangeVolatile String"); + String x = (String) vh.get(array, i); + assertEquals(x, "foo", "success compareAndExchangeVolatile String value"); + } + + { + String r = (String) vh.compareAndExchangeVolatile(array, i, "bar", "baz"); + assertEquals(r, "foo", "failing compareAndExchangeVolatile String"); + String x = (String) vh.get(array, i); + assertEquals(x, "foo", "failing compareAndExchangeVolatile 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + boolean r = vh.weakCompareAndSet(array, i, "foo", "bar"); + assertEquals(r, true, "weakCompareAndSet String"); + String x = (String) vh.get(array, i); + assertEquals(x, "bar", "weakCompareAndSet String value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(array, i, "bar", "foo"); + assertEquals(r, true, "weakCompareAndSetAcquire String"); + String x = (String) vh.get(array, i); + assertEquals(x, "foo", "weakCompareAndSetAcquire String"); + } + + { + boolean r = vh.weakCompareAndSetRelease(array, i, "foo", "bar"); + assertEquals(r, true, "weakCompareAndSetRelease String"); + String x = (String) vh.get(array, i); + assertEquals(x, "bar", "weakCompareAndSetRelease String"); + } + + // Compare set and get + { + String o = (String) vh.getAndSet(array, i, "foo"); + assertEquals(o, "bar", "getAndSet String"); + String x = (String) vh.get(array, i); + assertEquals(x, "foo", "getAndSet String value"); + } + + } + } + + static void testArrayUnsupported(VarHandle vh) { + String[] array = new String[10]; + + int i = 0; + + checkUOE(() -> { + String o = (String) vh.getAndAdd(array, i, "foo"); + }); + + checkUOE(() -> { + String o = (String) vh.addAndGet(array, i, "foo"); + }); + } + + static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable { + String[] array = new String[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + String x = (String) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, "foo"); + }); + + checkIOOBE(() -> { + String x = (String) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, "foo"); + }); + + checkIOOBE(() -> { + String x = (String) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, "foo"); + }); + + checkIOOBE(() -> { + String x = (String) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, "foo"); + }); + + checkIOOBE(() -> { + boolean r = vh.compareAndSet(array, ci, "foo", "bar"); + }); + + checkIOOBE(() -> { + String r = (String) vh.compareAndExchangeVolatile(array, ci, "bar", "foo"); + }); + + checkIOOBE(() -> { + String r = (String) vh.compareAndExchangeAcquire(array, ci, "bar", "foo"); + }); + + checkIOOBE(() -> { + String r = (String) vh.compareAndExchangeRelease(array, ci, "bar", "foo"); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, "foo", "bar"); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, "foo", "bar"); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, "foo", "bar"); + }); + + checkIOOBE(() -> { + String o = (String) vh.getAndSet(array, ci, "foo"); + }); + + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java new file mode 100644 index 00000000000..ba099920ea6 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java @@ -0,0 +1,644 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsChar + * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsChar + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest { + static final int SIZE = Character.BYTES; + + static final char VALUE_1 = (char)0x0102; + + static final char VALUE_2 = (char)0x1112; + + static final char VALUE_3 = (char)0x2122; + + + @Override + public void setupVarHandleSources() { + // Combinations of VarHandle byte[] or ByteBuffer + vhss = new ArrayList<>(); + for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) { + VarHandleSource aeh = new VarHandleSource( + MethodHandles.byteArrayViewVarHandle(char[].class, + endianess == MemoryMode.BIG_ENDIAN), + endianess, MemoryMode.READ_WRITE); + vhss.add(aeh); + + VarHandleSource bbh = new VarHandleSource( + MethodHandles.byteBufferViewVarHandle(char[].class, + endianess == MemoryMode.BIG_ENDIAN), + endianess, MemoryMode.READ_WRITE); + vhss.add(bbh); + } + } + + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandleSource vhs) { + VarHandle vh = vhs.s; + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), char.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (ByteArrayViewSource bav : bavss) { + for (VarHandleSource vh : vhss) { + if (vh.matches(bav)) { + if (bav instanceof ByteArraySource) { + ByteArraySource bas = (ByteArraySource) bav; + + cases.add(new VarHandleSourceAccessTestCase( + "read write", bav, vh, h -> testArrayReadWrite(bas, h), + true)); + cases.add(new VarHandleSourceAccessTestCase( + "unsupported", bav, vh, h -> testArrayUnsupported(bas, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h), + false)); + } + else { + ByteBufferSource bbs = (ByteBufferSource) bav; + + if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) { + cases.add(new VarHandleSourceAccessTestCase( + "read write", bav, vh, h -> testArrayReadWrite(bbs, h), + true)); + } + else { + cases.add(new VarHandleSourceAccessTestCase( + "read only", bav, vh, h -> testArrayReadOnly(bbs, h), + true)); + } + + cases.add(new VarHandleSourceAccessTestCase( + "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h), + false)); + } + } + } + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + byte[] array = bs.s; + int ci = 1; + + checkUOE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + char o = (char) vh.getAndSet(array, ci, VALUE_1); + }); + + checkUOE(() -> { + char o = (char) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkUOE(() -> { + char o = (char) vh.addAndGet(array, ci, VALUE_1); + }); + } + + static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + int ci = 0; + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + + if (readOnly) { + checkROBE(() -> { + vh.set(array, ci, VALUE_1); + }); + } + + if (readOnly) { + checkROBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkROBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkROBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + checkUOE(() -> { + char r = (char) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + char o = (char) vh.getAndSet(array, ci, VALUE_1); + }); + + checkUOE(() -> { + char o = (char) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkUOE(() -> { + char o = (char) vh.addAndGet(array, ci, VALUE_1); + }); + } + else { + checkUOE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + char r = (char) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + char o = (char) vh.getAndSet(array, ci, VALUE_1); + }); + checkUOE(() -> { + char o = (char) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkUOE(() -> { + char o = (char) vh.addAndGet(array, ci, VALUE_1); + }); + } + } + + + static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int length = array.length - SIZE + 1; + for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + char x = (char) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + char x = (char) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + char x = (char) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + char x = (char) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + + } + } + + static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + + int length = array.limit() - SIZE + 1; + for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + char x = (char) vh.get(array, ci); + }); + + if (!readOnly) { + checkIOOBE(() -> { + vh.set(array, ci, VALUE_1); + }); + } + + checkIOOBE(() -> { + char x = (char) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + char x = (char) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + char x = (char) vh.getOpaque(array, ci); + }); + + if (!readOnly) { + checkIOOBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + + } + } + } + + static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); + + int length = array.length - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + final int ci = i; + + if (!iAligned) { + checkISE(() -> { + char x = (char) vh.getVolatile(array, ci); + }); + + checkISE(() -> { + char x = (char) vh.getAcquire(array, ci); + }); + + checkISE(() -> { + char x = (char) vh.getOpaque(array, ci); + }); + + checkISE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + + } + } + } + + static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + final int ci = i; + + if (!iAligned) { + checkISE(() -> { + char x = (char) vh.getVolatile(array, ci); + }); + + checkISE(() -> { + char x = (char) vh.getAcquire(array, ci); + }); + + checkISE(() -> { + char x = (char) vh.getOpaque(array, ci); + }); + + if (!readOnly) { + checkISE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + + } + } + } + } + + static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); + + bs.fill((byte) 0xff); + int length = array.length - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + // Plain + { + vh.set(array, i, VALUE_1); + char x = (char) vh.get(array, i); + assertEquals(x, VALUE_1, "get char value"); + } + + + if (iAligned) { + // Volatile + { + vh.setVolatile(array, i, VALUE_2); + char x = (char) vh.getVolatile(array, i); + assertEquals(x, VALUE_2, "setVolatile char value"); + } + + // Lazy + { + vh.setRelease(array, i, VALUE_1); + char x = (char) vh.getAcquire(array, i); + assertEquals(x, VALUE_1, "setRelease char value"); + } + + // Opaque + { + vh.setOpaque(array, i, VALUE_2); + char x = (char) vh.getOpaque(array, i); + assertEquals(x, VALUE_2, "setOpaque char value"); + } + + } + } + } + + + static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + bs.fill((byte) 0xff); + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + // Plain + { + vh.set(array, i, VALUE_1); + char x = (char) vh.get(array, i); + assertEquals(x, VALUE_1, "get char value"); + } + + if (iAligned) { + // Volatile + { + vh.setVolatile(array, i, VALUE_2); + char x = (char) vh.getVolatile(array, i); + assertEquals(x, VALUE_2, "setVolatile char value"); + } + + // Lazy + { + vh.setRelease(array, i, VALUE_1); + char x = (char) vh.getAcquire(array, i); + assertEquals(x, VALUE_1, "setRelease char value"); + } + + // Opaque + { + vh.setOpaque(array, i, VALUE_2); + char x = (char) vh.getOpaque(array, i); + assertEquals(x, VALUE_2, "setOpaque char value"); + } + + } + } + } + + static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + ByteBuffer bb = ByteBuffer.allocate(SIZE); + bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); + bs.fill(bb.putChar(0, VALUE_2).array()); + + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + char v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) + ? rotateLeft(VALUE_2, (i % SIZE) << 3) + : rotateRight(VALUE_2, (i % SIZE) << 3); + // Plain + { + char x = (char) vh.get(array, i); + assertEquals(x, v, "get char value"); + } + + if (iAligned) { + // Volatile + { + char x = (char) vh.getVolatile(array, i); + assertEquals(x, v, "getVolatile char value"); + } + + // Lazy + { + char x = (char) vh.getAcquire(array, i); + assertEquals(x, v, "getRelease char value"); + } + + // Opaque + { + char x = (char) vh.getOpaque(array, i); + assertEquals(x, v, "getOpaque char value"); + } + } + } + } + +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java new file mode 100644 index 00000000000..794e82226d6 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java @@ -0,0 +1,892 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsDouble + * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsDouble + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { + static final int SIZE = Double.BYTES; + + static final double VALUE_1 = 0x0102030405060708L; + + static final double VALUE_2 = 0x1112131415161718L; + + static final double VALUE_3 = 0x2122232425262728L; + + + @Override + public void setupVarHandleSources() { + // Combinations of VarHandle byte[] or ByteBuffer + vhss = new ArrayList<>(); + for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) { + VarHandleSource aeh = new VarHandleSource( + MethodHandles.byteArrayViewVarHandle(double[].class, + endianess == MemoryMode.BIG_ENDIAN), + endianess, MemoryMode.READ_WRITE); + vhss.add(aeh); + + VarHandleSource bbh = new VarHandleSource( + MethodHandles.byteBufferViewVarHandle(double[].class, + endianess == MemoryMode.BIG_ENDIAN), + endianess, MemoryMode.READ_WRITE); + vhss.add(bbh); + } + } + + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandleSource vhs) { + VarHandle vh = vhs.s; + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), double.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (ByteArrayViewSource bav : bavss) { + for (VarHandleSource vh : vhss) { + if (vh.matches(bav)) { + if (bav instanceof ByteArraySource) { + ByteArraySource bas = (ByteArraySource) bav; + + cases.add(new VarHandleSourceAccessTestCase( + "read write", bav, vh, h -> testArrayReadWrite(bas, h), + true)); + cases.add(new VarHandleSourceAccessTestCase( + "unsupported", bav, vh, h -> testArrayUnsupported(bas, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h), + false)); + } + else { + ByteBufferSource bbs = (ByteBufferSource) bav; + + if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) { + cases.add(new VarHandleSourceAccessTestCase( + "read write", bav, vh, h -> testArrayReadWrite(bbs, h), + true)); + } + else { + cases.add(new VarHandleSourceAccessTestCase( + "read only", bav, vh, h -> testArrayReadOnly(bbs, h), + true)); + } + + cases.add(new VarHandleSourceAccessTestCase( + "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h), + false)); + } + } + } + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + byte[] array = bs.s; + int ci = 1; + + + checkUOE(() -> { + double o = (double) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkUOE(() -> { + double o = (double) vh.addAndGet(array, ci, VALUE_1); + }); + } + + static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + int ci = 0; + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + + if (readOnly) { + checkROBE(() -> { + vh.set(array, ci, VALUE_1); + }); + } + + if (readOnly) { + checkROBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkROBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkROBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkROBE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + double r = (double) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkROBE(() -> { + double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkROBE(() -> { + double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkROBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + double o = (double) vh.getAndSet(array, ci, VALUE_1); + }); + checkUOE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + double o = (double) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkUOE(() -> { + double o = (double) vh.addAndGet(array, ci, VALUE_1); + }); + } + else { + checkUOE(() -> { + double o = (double) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkUOE(() -> { + double o = (double) vh.addAndGet(array, ci, VALUE_1); + }); + } + } + + + static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int length = array.length - SIZE + 1; + for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + double x = (double) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + double x = (double) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + double x = (double) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + double x = (double) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + double r = (double) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + double o = (double) vh.getAndSet(array, ci, VALUE_1); + }); + + + } + } + + static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + + int length = array.limit() - SIZE + 1; + for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + double x = (double) vh.get(array, ci); + }); + + if (!readOnly) { + checkIOOBE(() -> { + vh.set(array, ci, VALUE_1); + }); + } + + checkIOOBE(() -> { + double x = (double) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + double x = (double) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + double x = (double) vh.getOpaque(array, ci); + }); + + if (!readOnly) { + checkIOOBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + double r = (double) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + double o = (double) vh.getAndSet(array, ci, VALUE_1); + }); + + } + } + } + + static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); + + int length = array.length - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + final int ci = i; + + if (!iAligned) { + checkISE(() -> { + double x = (double) vh.getVolatile(array, ci); + }); + + checkISE(() -> { + double x = (double) vh.getAcquire(array, ci); + }); + + checkISE(() -> { + double x = (double) vh.getOpaque(array, ci); + }); + + checkISE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + double r = (double) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + double o = (double) vh.getAndSet(array, ci, VALUE_1); + }); + + + } + } + } + + static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + final int ci = i; + + if (!iAligned) { + checkISE(() -> { + double x = (double) vh.getVolatile(array, ci); + }); + + checkISE(() -> { + double x = (double) vh.getAcquire(array, ci); + }); + + checkISE(() -> { + double x = (double) vh.getOpaque(array, ci); + }); + + if (!readOnly) { + checkISE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + double r = (double) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + double o = (double) vh.getAndSet(array, ci, VALUE_1); + }); + + } + } + } + } + + static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); + + bs.fill((byte) 0xff); + int length = array.length - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + // Plain + { + vh.set(array, i, VALUE_1); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_1, "get double value"); + } + + + if (iAligned) { + // Volatile + { + vh.setVolatile(array, i, VALUE_2); + double x = (double) vh.getVolatile(array, i); + assertEquals(x, VALUE_2, "setVolatile double value"); + } + + // Lazy + { + vh.setRelease(array, i, VALUE_1); + double x = (double) vh.getAcquire(array, i); + assertEquals(x, VALUE_1, "setRelease double value"); + } + + // Opaque + { + vh.setOpaque(array, i, VALUE_2); + double x = (double) vh.getOpaque(array, i); + assertEquals(x, VALUE_2, "setOpaque double value"); + } + + vh.set(array, i, VALUE_1); + + // Compare + { + 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"); + } + + { + 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"); + } + + { + double r = (double) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); + assertEquals(r, VALUE_2, "success compareAndExchangeVolatile double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_1, "success compareAndExchangeVolatile double value"); + } + + { + double r = (double) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); + assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSet double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSet double value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + assertEquals(r, true, "weakCompareAndSetAcquire double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_1, "weakCompareAndSetAcquire double"); + } + + { + boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSetRelease double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSetRelease double"); + } + + // Compare set and get + { + double o = (double) vh.getAndSet(array, i, VALUE_1); + assertEquals(o, VALUE_2, "getAndSet double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_1, "getAndSet double value"); + } + + } + } + } + + + static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + bs.fill((byte) 0xff); + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + // Plain + { + vh.set(array, i, VALUE_1); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_1, "get double value"); + } + + if (iAligned) { + // Volatile + { + vh.setVolatile(array, i, VALUE_2); + double x = (double) vh.getVolatile(array, i); + assertEquals(x, VALUE_2, "setVolatile double value"); + } + + // Lazy + { + vh.setRelease(array, i, VALUE_1); + double x = (double) vh.getAcquire(array, i); + assertEquals(x, VALUE_1, "setRelease double value"); + } + + // Opaque + { + vh.setOpaque(array, i, VALUE_2); + double x = (double) vh.getOpaque(array, i); + assertEquals(x, VALUE_2, "setOpaque double value"); + } + + vh.set(array, i, VALUE_1); + + // Compare + { + 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"); + } + + { + 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"); + } + + { + double r = (double) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); + assertEquals(r, VALUE_2, "success compareAndExchangeVolatile double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_1, "success compareAndExchangeVolatile double value"); + } + + { + double r = (double) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); + assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSet double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSet double value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + assertEquals(r, true, "weakCompareAndSetAcquire double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_1, "weakCompareAndSetAcquire double"); + } + + { + boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSetRelease double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSetRelease double"); + } + + // Compare set and get + { + double o = (double) vh.getAndSet(array, i, VALUE_1); + assertEquals(o, VALUE_2, "getAndSet double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_1, "getAndSet double value"); + } + + } + } + } + + static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + ByteBuffer bb = ByteBuffer.allocate(SIZE); + bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); + bs.fill(bb.putDouble(0, VALUE_2).array()); + + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + double v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) + ? rotateLeft(VALUE_2, (i % SIZE) << 3) + : rotateRight(VALUE_2, (i % SIZE) << 3); + // Plain + { + double x = (double) vh.get(array, i); + assertEquals(x, v, "get double value"); + } + + if (iAligned) { + // Volatile + { + double x = (double) vh.getVolatile(array, i); + assertEquals(x, v, "getVolatile double value"); + } + + // Lazy + { + double x = (double) vh.getAcquire(array, i); + assertEquals(x, v, "getRelease double value"); + } + + // Opaque + { + double x = (double) vh.getOpaque(array, i); + assertEquals(x, v, "getOpaque double value"); + } + } + } + } + +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java new file mode 100644 index 00000000000..090796f77e8 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java @@ -0,0 +1,892 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsFloat + * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsFloat + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { + static final int SIZE = Float.BYTES; + + static final float VALUE_1 = 0x01020304; + + static final float VALUE_2 = 0x11121314; + + static final float VALUE_3 = 0x21222324; + + + @Override + public void setupVarHandleSources() { + // Combinations of VarHandle byte[] or ByteBuffer + vhss = new ArrayList<>(); + for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) { + VarHandleSource aeh = new VarHandleSource( + MethodHandles.byteArrayViewVarHandle(float[].class, + endianess == MemoryMode.BIG_ENDIAN), + endianess, MemoryMode.READ_WRITE); + vhss.add(aeh); + + VarHandleSource bbh = new VarHandleSource( + MethodHandles.byteBufferViewVarHandle(float[].class, + endianess == MemoryMode.BIG_ENDIAN), + endianess, MemoryMode.READ_WRITE); + vhss.add(bbh); + } + } + + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandleSource vhs) { + VarHandle vh = vhs.s; + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), float.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (ByteArrayViewSource bav : bavss) { + for (VarHandleSource vh : vhss) { + if (vh.matches(bav)) { + if (bav instanceof ByteArraySource) { + ByteArraySource bas = (ByteArraySource) bav; + + cases.add(new VarHandleSourceAccessTestCase( + "read write", bav, vh, h -> testArrayReadWrite(bas, h), + true)); + cases.add(new VarHandleSourceAccessTestCase( + "unsupported", bav, vh, h -> testArrayUnsupported(bas, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h), + false)); + } + else { + ByteBufferSource bbs = (ByteBufferSource) bav; + + if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) { + cases.add(new VarHandleSourceAccessTestCase( + "read write", bav, vh, h -> testArrayReadWrite(bbs, h), + true)); + } + else { + cases.add(new VarHandleSourceAccessTestCase( + "read only", bav, vh, h -> testArrayReadOnly(bbs, h), + true)); + } + + cases.add(new VarHandleSourceAccessTestCase( + "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h), + false)); + } + } + } + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + byte[] array = bs.s; + int ci = 1; + + + checkUOE(() -> { + float o = (float) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkUOE(() -> { + float o = (float) vh.addAndGet(array, ci, VALUE_1); + }); + } + + static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + int ci = 0; + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + + if (readOnly) { + checkROBE(() -> { + vh.set(array, ci, VALUE_1); + }); + } + + if (readOnly) { + checkROBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkROBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkROBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkROBE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkROBE(() -> { + float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkROBE(() -> { + float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkROBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + float o = (float) vh.getAndSet(array, ci, VALUE_1); + }); + checkUOE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + float o = (float) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkUOE(() -> { + float o = (float) vh.addAndGet(array, ci, VALUE_1); + }); + } + else { + checkUOE(() -> { + float o = (float) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkUOE(() -> { + float o = (float) vh.addAndGet(array, ci, VALUE_1); + }); + } + } + + + static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int length = array.length - SIZE + 1; + for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + float x = (float) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + float x = (float) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + float x = (float) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + float x = (float) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + float o = (float) vh.getAndSet(array, ci, VALUE_1); + }); + + + } + } + + static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + + int length = array.limit() - SIZE + 1; + for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + float x = (float) vh.get(array, ci); + }); + + if (!readOnly) { + checkIOOBE(() -> { + vh.set(array, ci, VALUE_1); + }); + } + + checkIOOBE(() -> { + float x = (float) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + float x = (float) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + float x = (float) vh.getOpaque(array, ci); + }); + + if (!readOnly) { + checkIOOBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + float o = (float) vh.getAndSet(array, ci, VALUE_1); + }); + + } + } + } + + static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); + + int length = array.length - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + final int ci = i; + + if (!iAligned) { + checkISE(() -> { + float x = (float) vh.getVolatile(array, ci); + }); + + checkISE(() -> { + float x = (float) vh.getAcquire(array, ci); + }); + + checkISE(() -> { + float x = (float) vh.getOpaque(array, ci); + }); + + checkISE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + float o = (float) vh.getAndSet(array, ci, VALUE_1); + }); + + + } + } + } + + static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + final int ci = i; + + if (!iAligned) { + checkISE(() -> { + float x = (float) vh.getVolatile(array, ci); + }); + + checkISE(() -> { + float x = (float) vh.getAcquire(array, ci); + }); + + checkISE(() -> { + float x = (float) vh.getOpaque(array, ci); + }); + + if (!readOnly) { + checkISE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + float o = (float) vh.getAndSet(array, ci, VALUE_1); + }); + + } + } + } + } + + static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); + + bs.fill((byte) 0xff); + int length = array.length - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + // Plain + { + vh.set(array, i, VALUE_1); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_1, "get float value"); + } + + + if (iAligned) { + // Volatile + { + vh.setVolatile(array, i, VALUE_2); + float x = (float) vh.getVolatile(array, i); + assertEquals(x, VALUE_2, "setVolatile float value"); + } + + // Lazy + { + vh.setRelease(array, i, VALUE_1); + float x = (float) vh.getAcquire(array, i); + assertEquals(x, VALUE_1, "setRelease float value"); + } + + // Opaque + { + vh.setOpaque(array, i, VALUE_2); + float x = (float) vh.getOpaque(array, i); + assertEquals(x, VALUE_2, "setOpaque float value"); + } + + vh.set(array, i, VALUE_1); + + // Compare + { + 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"); + } + + { + 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"); + } + + { + float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); + assertEquals(r, VALUE_2, "success compareAndExchangeVolatile float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_1, "success compareAndExchangeVolatile float value"); + } + + { + float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); + assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSet float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSet float value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + assertEquals(r, true, "weakCompareAndSetAcquire float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_1, "weakCompareAndSetAcquire float"); + } + + { + boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSetRelease float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSetRelease float"); + } + + // Compare set and get + { + float o = (float) vh.getAndSet(array, i, VALUE_1); + assertEquals(o, VALUE_2, "getAndSet float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_1, "getAndSet float value"); + } + + } + } + } + + + static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + bs.fill((byte) 0xff); + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + // Plain + { + vh.set(array, i, VALUE_1); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_1, "get float value"); + } + + if (iAligned) { + // Volatile + { + vh.setVolatile(array, i, VALUE_2); + float x = (float) vh.getVolatile(array, i); + assertEquals(x, VALUE_2, "setVolatile float value"); + } + + // Lazy + { + vh.setRelease(array, i, VALUE_1); + float x = (float) vh.getAcquire(array, i); + assertEquals(x, VALUE_1, "setRelease float value"); + } + + // Opaque + { + vh.setOpaque(array, i, VALUE_2); + float x = (float) vh.getOpaque(array, i); + assertEquals(x, VALUE_2, "setOpaque float value"); + } + + vh.set(array, i, VALUE_1); + + // Compare + { + 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"); + } + + { + 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"); + } + + { + float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); + assertEquals(r, VALUE_2, "success compareAndExchangeVolatile float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_1, "success compareAndExchangeVolatile float value"); + } + + { + float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); + assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSet float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSet float value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + assertEquals(r, true, "weakCompareAndSetAcquire float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_1, "weakCompareAndSetAcquire float"); + } + + { + boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSetRelease float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSetRelease float"); + } + + // Compare set and get + { + float o = (float) vh.getAndSet(array, i, VALUE_1); + assertEquals(o, VALUE_2, "getAndSet float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_1, "getAndSet float value"); + } + + } + } + } + + static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + ByteBuffer bb = ByteBuffer.allocate(SIZE); + bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); + bs.fill(bb.putFloat(0, VALUE_2).array()); + + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + float v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) + ? rotateLeft(VALUE_2, (i % SIZE) << 3) + : rotateRight(VALUE_2, (i % SIZE) << 3); + // Plain + { + float x = (float) vh.get(array, i); + assertEquals(x, v, "get float value"); + } + + if (iAligned) { + // Volatile + { + float x = (float) vh.getVolatile(array, i); + assertEquals(x, v, "getVolatile float value"); + } + + // Lazy + { + float x = (float) vh.getAcquire(array, i); + assertEquals(x, v, "getRelease float value"); + } + + // Opaque + { + float x = (float) vh.getOpaque(array, i); + assertEquals(x, v, "getOpaque float value"); + } + } + } + } + +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java new file mode 100644 index 00000000000..c9764200d41 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java @@ -0,0 +1,924 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsInt + * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsInt + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { + static final int SIZE = Integer.BYTES; + + static final int VALUE_1 = 0x01020304; + + static final int VALUE_2 = 0x11121314; + + static final int VALUE_3 = 0x21222324; + + + @Override + public void setupVarHandleSources() { + // Combinations of VarHandle byte[] or ByteBuffer + vhss = new ArrayList<>(); + for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) { + VarHandleSource aeh = new VarHandleSource( + MethodHandles.byteArrayViewVarHandle(int[].class, + endianess == MemoryMode.BIG_ENDIAN), + endianess, MemoryMode.READ_WRITE); + vhss.add(aeh); + + VarHandleSource bbh = new VarHandleSource( + MethodHandles.byteBufferViewVarHandle(int[].class, + endianess == MemoryMode.BIG_ENDIAN), + endianess, MemoryMode.READ_WRITE); + vhss.add(bbh); + } + } + + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandleSource vhs) { + VarHandle vh = vhs.s; + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), int.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (ByteArrayViewSource bav : bavss) { + for (VarHandleSource vh : vhss) { + if (vh.matches(bav)) { + if (bav instanceof ByteArraySource) { + ByteArraySource bas = (ByteArraySource) bav; + + cases.add(new VarHandleSourceAccessTestCase( + "read write", bav, vh, h -> testArrayReadWrite(bas, h), + true)); + cases.add(new VarHandleSourceAccessTestCase( + "unsupported", bav, vh, h -> testArrayUnsupported(bas, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h), + false)); + } + else { + ByteBufferSource bbs = (ByteBufferSource) bav; + + if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) { + cases.add(new VarHandleSourceAccessTestCase( + "read write", bav, vh, h -> testArrayReadWrite(bbs, h), + true)); + } + else { + cases.add(new VarHandleSourceAccessTestCase( + "read only", bav, vh, h -> testArrayReadOnly(bbs, h), + true)); + } + + cases.add(new VarHandleSourceAccessTestCase( + "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h), + false)); + } + } + } + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + byte[] array = bs.s; + int ci = 1; + + + } + + static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + int ci = 0; + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + + if (readOnly) { + checkROBE(() -> { + vh.set(array, ci, VALUE_1); + }); + } + + if (readOnly) { + checkROBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkROBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkROBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkROBE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + int r = (int) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkROBE(() -> { + int r = (int) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkROBE(() -> { + int r = (int) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkROBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + int o = (int) vh.getAndSet(array, ci, VALUE_1); + }); + checkUOE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + int o = (int) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkROBE(() -> { + int o = (int) vh.addAndGet(array, ci, VALUE_1); + }); + } + else { + } + } + + + static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int length = array.length - SIZE + 1; + for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + int x = (int) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + int x = (int) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + int x = (int) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + int x = (int) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + int r = (int) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + int r = (int) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + int r = (int) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + int o = (int) vh.getAndSet(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + int o = (int) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + int o = (int) vh.addAndGet(array, ci, VALUE_1); + }); + + } + } + + static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + + int length = array.limit() - SIZE + 1; + for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + int x = (int) vh.get(array, ci); + }); + + if (!readOnly) { + checkIOOBE(() -> { + vh.set(array, ci, VALUE_1); + }); + } + + checkIOOBE(() -> { + int x = (int) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + int x = (int) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + int x = (int) vh.getOpaque(array, ci); + }); + + if (!readOnly) { + checkIOOBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + int r = (int) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + int r = (int) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + int r = (int) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + int o = (int) vh.getAndSet(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + int o = (int) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + int o = (int) vh.addAndGet(array, ci, VALUE_1); + }); + } + } + } + + static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); + + int length = array.length - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + final int ci = i; + + if (!iAligned) { + checkISE(() -> { + int x = (int) vh.getVolatile(array, ci); + }); + + checkISE(() -> { + int x = (int) vh.getAcquire(array, ci); + }); + + checkISE(() -> { + int x = (int) vh.getOpaque(array, ci); + }); + + checkISE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + int r = (int) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + int r = (int) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + int r = (int) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + int o = (int) vh.getAndSet(array, ci, VALUE_1); + }); + + checkISE(() -> { + int o = (int) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkISE(() -> { + int o = (int) vh.addAndGet(array, ci, VALUE_1); + }); + + } + } + } + + static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + final int ci = i; + + if (!iAligned) { + checkISE(() -> { + int x = (int) vh.getVolatile(array, ci); + }); + + checkISE(() -> { + int x = (int) vh.getAcquire(array, ci); + }); + + checkISE(() -> { + int x = (int) vh.getOpaque(array, ci); + }); + + if (!readOnly) { + checkISE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + int r = (int) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + int r = (int) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + int r = (int) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + int o = (int) vh.getAndSet(array, ci, VALUE_1); + }); + + checkISE(() -> { + int o = (int) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkISE(() -> { + int o = (int) vh.addAndGet(array, ci, VALUE_1); + }); + } + } + } + } + + static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); + + bs.fill((byte) 0xff); + int length = array.length - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + // Plain + { + vh.set(array, i, VALUE_1); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_1, "get int value"); + } + + + if (iAligned) { + // Volatile + { + vh.setVolatile(array, i, VALUE_2); + int x = (int) vh.getVolatile(array, i); + assertEquals(x, VALUE_2, "setVolatile int value"); + } + + // Lazy + { + vh.setRelease(array, i, VALUE_1); + int x = (int) vh.getAcquire(array, i); + assertEquals(x, VALUE_1, "setRelease int value"); + } + + // Opaque + { + vh.setOpaque(array, i, VALUE_2); + int x = (int) vh.getOpaque(array, i); + assertEquals(x, VALUE_2, "setOpaque int value"); + } + + vh.set(array, i, VALUE_1); + + // Compare + { + 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"); + } + + { + 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"); + } + + { + int r = (int) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); + assertEquals(r, VALUE_2, "success compareAndExchangeVolatile int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_1, "success compareAndExchangeVolatile int value"); + } + + { + int r = (int) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); + assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSet int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSet int value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + assertEquals(r, true, "weakCompareAndSetAcquire int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_1, "weakCompareAndSetAcquire int"); + } + + { + boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSetRelease int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSetRelease int"); + } + + // Compare set and get + { + int o = (int) vh.getAndSet(array, i, VALUE_1); + assertEquals(o, VALUE_2, "getAndSet int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_1, "getAndSet int value"); + } + + vh.set(array, i, VALUE_1); + + // get and add, add and get + { + int o = (int) vh.getAndAdd(array, i, VALUE_3); + assertEquals(o, VALUE_1, "getAndAdd int"); + int c = (int) vh.addAndGet(array, i, VALUE_3); + assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd int value"); + } + } + } + } + + + static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + bs.fill((byte) 0xff); + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + // Plain + { + vh.set(array, i, VALUE_1); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_1, "get int value"); + } + + if (iAligned) { + // Volatile + { + vh.setVolatile(array, i, VALUE_2); + int x = (int) vh.getVolatile(array, i); + assertEquals(x, VALUE_2, "setVolatile int value"); + } + + // Lazy + { + vh.setRelease(array, i, VALUE_1); + int x = (int) vh.getAcquire(array, i); + assertEquals(x, VALUE_1, "setRelease int value"); + } + + // Opaque + { + vh.setOpaque(array, i, VALUE_2); + int x = (int) vh.getOpaque(array, i); + assertEquals(x, VALUE_2, "setOpaque int value"); + } + + vh.set(array, i, VALUE_1); + + // Compare + { + 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"); + } + + { + 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"); + } + + { + int r = (int) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); + assertEquals(r, VALUE_2, "success compareAndExchangeVolatile int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_1, "success compareAndExchangeVolatile int value"); + } + + { + int r = (int) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); + assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSet int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSet int value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + assertEquals(r, true, "weakCompareAndSetAcquire int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_1, "weakCompareAndSetAcquire int"); + } + + { + boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSetRelease int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSetRelease int"); + } + + // Compare set and get + { + int o = (int) vh.getAndSet(array, i, VALUE_1); + assertEquals(o, VALUE_2, "getAndSet int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_1, "getAndSet int value"); + } + + vh.set(array, i, VALUE_1); + + // get and add, add and get + { + int o = (int) vh.getAndAdd(array, i, VALUE_3); + assertEquals(o, VALUE_1, "getAndAdd int"); + int c = (int) vh.addAndGet(array, i, VALUE_3); + assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd int value"); + } + } + } + } + + static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + ByteBuffer bb = ByteBuffer.allocate(SIZE); + bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); + bs.fill(bb.putInt(0, VALUE_2).array()); + + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + int v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) + ? rotateLeft(VALUE_2, (i % SIZE) << 3) + : rotateRight(VALUE_2, (i % SIZE) << 3); + // Plain + { + int x = (int) vh.get(array, i); + assertEquals(x, v, "get int value"); + } + + if (iAligned) { + // Volatile + { + int x = (int) vh.getVolatile(array, i); + assertEquals(x, v, "getVolatile int value"); + } + + // Lazy + { + int x = (int) vh.getAcquire(array, i); + assertEquals(x, v, "getRelease int value"); + } + + // Opaque + { + int x = (int) vh.getOpaque(array, i); + assertEquals(x, v, "getOpaque int value"); + } + } + } + } + +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java new file mode 100644 index 00000000000..3f97979737a --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java @@ -0,0 +1,924 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsLong + * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsLong + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { + static final int SIZE = Long.BYTES; + + static final long VALUE_1 = 0x0102030405060708L; + + static final long VALUE_2 = 0x1112131415161718L; + + static final long VALUE_3 = 0x2122232425262728L; + + + @Override + public void setupVarHandleSources() { + // Combinations of VarHandle byte[] or ByteBuffer + vhss = new ArrayList<>(); + for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) { + VarHandleSource aeh = new VarHandleSource( + MethodHandles.byteArrayViewVarHandle(long[].class, + endianess == MemoryMode.BIG_ENDIAN), + endianess, MemoryMode.READ_WRITE); + vhss.add(aeh); + + VarHandleSource bbh = new VarHandleSource( + MethodHandles.byteBufferViewVarHandle(long[].class, + endianess == MemoryMode.BIG_ENDIAN), + endianess, MemoryMode.READ_WRITE); + vhss.add(bbh); + } + } + + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandleSource vhs) { + VarHandle vh = vhs.s; + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), long.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (ByteArrayViewSource bav : bavss) { + for (VarHandleSource vh : vhss) { + if (vh.matches(bav)) { + if (bav instanceof ByteArraySource) { + ByteArraySource bas = (ByteArraySource) bav; + + cases.add(new VarHandleSourceAccessTestCase( + "read write", bav, vh, h -> testArrayReadWrite(bas, h), + true)); + cases.add(new VarHandleSourceAccessTestCase( + "unsupported", bav, vh, h -> testArrayUnsupported(bas, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h), + false)); + } + else { + ByteBufferSource bbs = (ByteBufferSource) bav; + + if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) { + cases.add(new VarHandleSourceAccessTestCase( + "read write", bav, vh, h -> testArrayReadWrite(bbs, h), + true)); + } + else { + cases.add(new VarHandleSourceAccessTestCase( + "read only", bav, vh, h -> testArrayReadOnly(bbs, h), + true)); + } + + cases.add(new VarHandleSourceAccessTestCase( + "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h), + false)); + } + } + } + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + byte[] array = bs.s; + int ci = 1; + + + } + + static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + int ci = 0; + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + + if (readOnly) { + checkROBE(() -> { + vh.set(array, ci, VALUE_1); + }); + } + + if (readOnly) { + checkROBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkROBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkROBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkROBE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkROBE(() -> { + long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkROBE(() -> { + long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkROBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + long o = (long) vh.getAndSet(array, ci, VALUE_1); + }); + checkUOE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + long o = (long) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkROBE(() -> { + long o = (long) vh.addAndGet(array, ci, VALUE_1); + }); + } + else { + } + } + + + static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int length = array.length - SIZE + 1; + for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + long x = (long) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + long x = (long) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + long x = (long) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + long x = (long) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + long o = (long) vh.getAndSet(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + long o = (long) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + long o = (long) vh.addAndGet(array, ci, VALUE_1); + }); + + } + } + + static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + + int length = array.limit() - SIZE + 1; + for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + long x = (long) vh.get(array, ci); + }); + + if (!readOnly) { + checkIOOBE(() -> { + vh.set(array, ci, VALUE_1); + }); + } + + checkIOOBE(() -> { + long x = (long) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + long x = (long) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + long x = (long) vh.getOpaque(array, ci); + }); + + if (!readOnly) { + checkIOOBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + long o = (long) vh.getAndSet(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + long o = (long) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + long o = (long) vh.addAndGet(array, ci, VALUE_1); + }); + } + } + } + + static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); + + int length = array.length - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + final int ci = i; + + if (!iAligned) { + checkISE(() -> { + long x = (long) vh.getVolatile(array, ci); + }); + + checkISE(() -> { + long x = (long) vh.getAcquire(array, ci); + }); + + checkISE(() -> { + long x = (long) vh.getOpaque(array, ci); + }); + + checkISE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + long o = (long) vh.getAndSet(array, ci, VALUE_1); + }); + + checkISE(() -> { + long o = (long) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkISE(() -> { + long o = (long) vh.addAndGet(array, ci, VALUE_1); + }); + + } + } + } + + static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + final int ci = i; + + if (!iAligned) { + checkISE(() -> { + long x = (long) vh.getVolatile(array, ci); + }); + + checkISE(() -> { + long x = (long) vh.getAcquire(array, ci); + }); + + checkISE(() -> { + long x = (long) vh.getOpaque(array, ci); + }); + + if (!readOnly) { + checkISE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + long o = (long) vh.getAndSet(array, ci, VALUE_1); + }); + + checkISE(() -> { + long o = (long) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkISE(() -> { + long o = (long) vh.addAndGet(array, ci, VALUE_1); + }); + } + } + } + } + + static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); + + bs.fill((byte) 0xff); + int length = array.length - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + // Plain + { + vh.set(array, i, VALUE_1); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_1, "get long value"); + } + + + if (iAligned) { + // Volatile + { + vh.setVolatile(array, i, VALUE_2); + long x = (long) vh.getVolatile(array, i); + assertEquals(x, VALUE_2, "setVolatile long value"); + } + + // Lazy + { + vh.setRelease(array, i, VALUE_1); + long x = (long) vh.getAcquire(array, i); + assertEquals(x, VALUE_1, "setRelease long value"); + } + + // Opaque + { + vh.setOpaque(array, i, VALUE_2); + long x = (long) vh.getOpaque(array, i); + assertEquals(x, VALUE_2, "setOpaque long value"); + } + + vh.set(array, i, VALUE_1); + + // Compare + { + 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"); + } + + { + 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"); + } + + { + long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); + assertEquals(r, VALUE_2, "success compareAndExchangeVolatile long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_1, "success compareAndExchangeVolatile long value"); + } + + { + long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); + assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSet long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSet long value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + assertEquals(r, true, "weakCompareAndSetAcquire long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_1, "weakCompareAndSetAcquire long"); + } + + { + boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSetRelease long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSetRelease long"); + } + + // Compare set and get + { + long o = (long) vh.getAndSet(array, i, VALUE_1); + assertEquals(o, VALUE_2, "getAndSet long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_1, "getAndSet long value"); + } + + vh.set(array, i, VALUE_1); + + // get and add, add and get + { + long o = (long) vh.getAndAdd(array, i, VALUE_3); + assertEquals(o, VALUE_1, "getAndAdd long"); + long c = (long) vh.addAndGet(array, i, VALUE_3); + assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd long value"); + } + } + } + } + + + static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + bs.fill((byte) 0xff); + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + // Plain + { + vh.set(array, i, VALUE_1); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_1, "get long value"); + } + + if (iAligned) { + // Volatile + { + vh.setVolatile(array, i, VALUE_2); + long x = (long) vh.getVolatile(array, i); + assertEquals(x, VALUE_2, "setVolatile long value"); + } + + // Lazy + { + vh.setRelease(array, i, VALUE_1); + long x = (long) vh.getAcquire(array, i); + assertEquals(x, VALUE_1, "setRelease long value"); + } + + // Opaque + { + vh.setOpaque(array, i, VALUE_2); + long x = (long) vh.getOpaque(array, i); + assertEquals(x, VALUE_2, "setOpaque long value"); + } + + vh.set(array, i, VALUE_1); + + // Compare + { + 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"); + } + + { + 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"); + } + + { + long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); + assertEquals(r, VALUE_2, "success compareAndExchangeVolatile long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_1, "success compareAndExchangeVolatile long value"); + } + + { + long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); + assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + 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"); + } + + { + boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSet long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSet long value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + assertEquals(r, true, "weakCompareAndSetAcquire long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_1, "weakCompareAndSetAcquire long"); + } + + { + boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSetRelease long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSetRelease long"); + } + + // Compare set and get + { + long o = (long) vh.getAndSet(array, i, VALUE_1); + assertEquals(o, VALUE_2, "getAndSet long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_1, "getAndSet long value"); + } + + vh.set(array, i, VALUE_1); + + // get and add, add and get + { + long o = (long) vh.getAndAdd(array, i, VALUE_3); + assertEquals(o, VALUE_1, "getAndAdd long"); + long c = (long) vh.addAndGet(array, i, VALUE_3); + assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd long value"); + } + } + } + } + + static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + ByteBuffer bb = ByteBuffer.allocate(SIZE); + bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); + bs.fill(bb.putLong(0, VALUE_2).array()); + + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + long v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) + ? rotateLeft(VALUE_2, (i % SIZE) << 3) + : rotateRight(VALUE_2, (i % SIZE) << 3); + // Plain + { + long x = (long) vh.get(array, i); + assertEquals(x, v, "get long value"); + } + + if (iAligned) { + // Volatile + { + long x = (long) vh.getVolatile(array, i); + assertEquals(x, v, "getVolatile long value"); + } + + // Lazy + { + long x = (long) vh.getAcquire(array, i); + assertEquals(x, v, "getRelease long value"); + } + + // Opaque + { + long x = (long) vh.getOpaque(array, i); + assertEquals(x, v, "getOpaque long value"); + } + } + } + } + +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java new file mode 100644 index 00000000000..d7ea851b8c8 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java @@ -0,0 +1,644 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsShort + * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsShort + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest { + static final int SIZE = Short.BYTES; + + static final short VALUE_1 = (short)0x0102; + + static final short VALUE_2 = (short)0x1112; + + static final short VALUE_3 = (short)0x2122; + + + @Override + public void setupVarHandleSources() { + // Combinations of VarHandle byte[] or ByteBuffer + vhss = new ArrayList<>(); + for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) { + VarHandleSource aeh = new VarHandleSource( + MethodHandles.byteArrayViewVarHandle(short[].class, + endianess == MemoryMode.BIG_ENDIAN), + endianess, MemoryMode.READ_WRITE); + vhss.add(aeh); + + VarHandleSource bbh = new VarHandleSource( + MethodHandles.byteBufferViewVarHandle(short[].class, + endianess == MemoryMode.BIG_ENDIAN), + endianess, MemoryMode.READ_WRITE); + vhss.add(bbh); + } + } + + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandleSource vhs) { + VarHandle vh = vhs.s; + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); + + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), short.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (ByteArrayViewSource bav : bavss) { + for (VarHandleSource vh : vhss) { + if (vh.matches(bav)) { + if (bav instanceof ByteArraySource) { + ByteArraySource bas = (ByteArraySource) bav; + + cases.add(new VarHandleSourceAccessTestCase( + "read write", bav, vh, h -> testArrayReadWrite(bas, h), + true)); + cases.add(new VarHandleSourceAccessTestCase( + "unsupported", bav, vh, h -> testArrayUnsupported(bas, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h), + false)); + } + else { + ByteBufferSource bbs = (ByteBufferSource) bav; + + if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) { + cases.add(new VarHandleSourceAccessTestCase( + "read write", bav, vh, h -> testArrayReadWrite(bbs, h), + true)); + } + else { + cases.add(new VarHandleSourceAccessTestCase( + "read only", bav, vh, h -> testArrayReadOnly(bbs, h), + true)); + } + + cases.add(new VarHandleSourceAccessTestCase( + "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h), + false)); + } + } + } + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + byte[] array = bs.s; + int ci = 1; + + checkUOE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + short o = (short) vh.getAndSet(array, ci, VALUE_1); + }); + + checkUOE(() -> { + short o = (short) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkUOE(() -> { + short o = (short) vh.addAndGet(array, ci, VALUE_1); + }); + } + + static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + int ci = 0; + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + + if (readOnly) { + checkROBE(() -> { + vh.set(array, ci, VALUE_1); + }); + } + + if (readOnly) { + checkROBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkROBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkROBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + checkUOE(() -> { + short r = (short) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + short o = (short) vh.getAndSet(array, ci, VALUE_1); + }); + + checkUOE(() -> { + short o = (short) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkUOE(() -> { + short o = (short) vh.addAndGet(array, ci, VALUE_1); + }); + } + else { + checkUOE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + short r = (short) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + short o = (short) vh.getAndSet(array, ci, VALUE_1); + }); + checkUOE(() -> { + short o = (short) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkUOE(() -> { + short o = (short) vh.addAndGet(array, ci, VALUE_1); + }); + } + } + + + static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int length = array.length - SIZE + 1; + for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + short x = (short) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + short x = (short) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + short x = (short) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + short x = (short) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + + } + } + + static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + + int length = array.limit() - SIZE + 1; + for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + short x = (short) vh.get(array, ci); + }); + + if (!readOnly) { + checkIOOBE(() -> { + vh.set(array, ci, VALUE_1); + }); + } + + checkIOOBE(() -> { + short x = (short) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + short x = (short) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + short x = (short) vh.getOpaque(array, ci); + }); + + if (!readOnly) { + checkIOOBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + + } + } + } + + static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); + + int length = array.length - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + final int ci = i; + + if (!iAligned) { + checkISE(() -> { + short x = (short) vh.getVolatile(array, ci); + }); + + checkISE(() -> { + short x = (short) vh.getAcquire(array, ci); + }); + + checkISE(() -> { + short x = (short) vh.getOpaque(array, ci); + }); + + checkISE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + + } + } + } + + static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + final int ci = i; + + if (!iAligned) { + checkISE(() -> { + short x = (short) vh.getVolatile(array, ci); + }); + + checkISE(() -> { + short x = (short) vh.getAcquire(array, ci); + }); + + checkISE(() -> { + short x = (short) vh.getOpaque(array, ci); + }); + + if (!readOnly) { + checkISE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + + + } + } + } + } + + static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); + + bs.fill((byte) 0xff); + int length = array.length - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + // Plain + { + vh.set(array, i, VALUE_1); + short x = (short) vh.get(array, i); + assertEquals(x, VALUE_1, "get short value"); + } + + + if (iAligned) { + // Volatile + { + vh.setVolatile(array, i, VALUE_2); + short x = (short) vh.getVolatile(array, i); + assertEquals(x, VALUE_2, "setVolatile short value"); + } + + // Lazy + { + vh.setRelease(array, i, VALUE_1); + short x = (short) vh.getAcquire(array, i); + assertEquals(x, VALUE_1, "setRelease short value"); + } + + // Opaque + { + vh.setOpaque(array, i, VALUE_2); + short x = (short) vh.getOpaque(array, i); + assertEquals(x, VALUE_2, "setOpaque short value"); + } + + } + } + } + + + static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + bs.fill((byte) 0xff); + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + // Plain + { + vh.set(array, i, VALUE_1); + short x = (short) vh.get(array, i); + assertEquals(x, VALUE_1, "get short value"); + } + + if (iAligned) { + // Volatile + { + vh.setVolatile(array, i, VALUE_2); + short x = (short) vh.getVolatile(array, i); + assertEquals(x, VALUE_2, "setVolatile short value"); + } + + // Lazy + { + vh.setRelease(array, i, VALUE_1); + short x = (short) vh.getAcquire(array, i); + assertEquals(x, VALUE_1, "setRelease short value"); + } + + // Opaque + { + vh.setOpaque(array, i, VALUE_2); + short x = (short) vh.getOpaque(array, i); + assertEquals(x, VALUE_2, "setOpaque short value"); + } + + } + } + } + + static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + ByteBuffer bb = ByteBuffer.allocate(SIZE); + bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); + bs.fill(bb.putShort(0, VALUE_2).array()); + + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + short v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) + ? rotateLeft(VALUE_2, (i % SIZE) << 3) + : rotateRight(VALUE_2, (i % SIZE) << 3); + // Plain + { + short x = (short) vh.get(array, i); + assertEquals(x, v, "get short value"); + } + + if (iAligned) { + // Volatile + { + short x = (short) vh.getVolatile(array, i); + assertEquals(x, v, "getVolatile short value"); + } + + // Lazy + { + short x = (short) vh.getAcquire(array, i); + assertEquals(x, v, "getRelease short value"); + } + + // Opaque + { + short x = (short) vh.getOpaque(array, i); + assertEquals(x, v, "getOpaque short value"); + } + } + } + } + +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java new file mode 100644 index 00000000000..2bde4da9a70 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessBoolean + */ + +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.*; + +public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { + static final boolean static_final_v = true; + + static boolean static_v; + + final boolean final_v = true; + + boolean v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessBoolean.class, "final_v", boolean.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessBoolean.class, "v", boolean.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessBoolean.class, "static_final_v", boolean.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessBoolean.class, "static_v", boolean.class); + + vhArray = MethodHandles.arrayElementVarHandle(boolean[].class); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field", + vhField, f, hs -> testInstanceField(this, hs))); + cases.add(new MethodHandleAccessTestCase("Instance field unsupported", + vhField, f, hs -> testInstanceFieldUnsupported(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field", + vhStaticField, f, VarHandleTestMethodHandleAccessBoolean::testStaticField)); + cases.add(new MethodHandleAccessTestCase("Static field unsupported", + vhStaticField, f, VarHandleTestMethodHandleAccessBoolean::testStaticFieldUnsupported, + false)); + + cases.add(new MethodHandleAccessTestCase("Array", + vhArray, f, VarHandleTestMethodHandleAccessBoolean::testArray)); + cases.add(new MethodHandleAccessTestCase("Array unsupported", + vhArray, f, VarHandleTestMethodHandleAccessBoolean::testArrayUnsupported, + false)); + cases.add(new MethodHandleAccessTestCase("Array index out of bounds", + vhArray, f, VarHandleTestMethodHandleAccessBoolean::testArrayIndexOutOfBounds, + false)); + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + 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"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(recv, false); + boolean x = (boolean) hs.get(TestAccessMode.getVolatile).invokeExact(recv); + assertEquals(x, false, "setVolatile boolean value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(recv, true); + boolean x = (boolean) hs.get(TestAccessMode.getAcquire).invokeExact(recv); + assertEquals(x, true, "setRelease boolean value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(recv, false); + boolean x = (boolean) hs.get(TestAccessMode.getOpaque).invokeExact(recv); + assertEquals(x, false, "setOpaque boolean value"); + } + + + } + + static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessBoolean recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(recv, true, false); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(recv, true, false); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(recv, true); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(recv, true); + }); + } + } + + + static void testStaticField(Handles hs) throws Throwable { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(true); + boolean x = (boolean) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, true, "set boolean value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(false); + boolean x = (boolean) hs.get(TestAccessMode.getVolatile).invokeExact(); + assertEquals(x, false, "setVolatile boolean value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(true); + boolean x = (boolean) hs.get(TestAccessMode.getAcquire).invokeExact(); + assertEquals(x, true, "setRelease boolean value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(false); + boolean x = (boolean) hs.get(TestAccessMode.getOpaque).invokeExact(); + assertEquals(x, false, "setOpaque boolean value"); + } + + + } + + static void testStaticFieldUnsupported(Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(true, false); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(true, false); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(true); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(true); + }); + } + } + + + static void testArray(Handles hs) throws Throwable { + boolean[] array = new boolean[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(array, i, true); + boolean x = (boolean) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, true, "get boolean value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(array, i, false); + boolean x = (boolean) hs.get(TestAccessMode.getVolatile).invokeExact(array, i); + assertEquals(x, false, "setVolatile boolean value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(array, i, true); + boolean x = (boolean) hs.get(TestAccessMode.getAcquire).invokeExact(array, i); + assertEquals(x, true, "setRelease boolean value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(array, i, false); + boolean x = (boolean) hs.get(TestAccessMode.getOpaque).invokeExact(array, i); + assertEquals(x, false, "setOpaque boolean value"); + } + + + } + } + + static void testArrayUnsupported(Handles hs) throws Throwable { + boolean[] array = new boolean[10]; + + final int i = 0; + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(array, i, true, false); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(array, i, true, false); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(array, i, true); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + boolean o = (boolean) hs.get(am).invokeExact(array, i, true); + }); + } + } + + static void testArrayIndexOutOfBounds(Handles hs) throws Throwable { + boolean[] array = new boolean[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + checkIOOBE(am, () -> { + boolean x = (boolean) hs.get(am).invokeExact(array, ci); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkIOOBE(am, () -> { + hs.get(am).invokeExact(array, ci, true); + }); + } + + + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java new file mode 100644 index 00000000000..a994faff5b2 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessByte + */ + +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.*; + +public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { + static final byte static_final_v = (byte)1; + + static byte static_v; + + final byte final_v = (byte)1; + + byte v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessByte.class, "final_v", byte.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessByte.class, "v", byte.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessByte.class, "static_final_v", byte.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessByte.class, "static_v", byte.class); + + vhArray = MethodHandles.arrayElementVarHandle(byte[].class); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field", + vhField, f, hs -> testInstanceField(this, hs))); + cases.add(new MethodHandleAccessTestCase("Instance field unsupported", + vhField, f, hs -> testInstanceFieldUnsupported(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field", + vhStaticField, f, VarHandleTestMethodHandleAccessByte::testStaticField)); + cases.add(new MethodHandleAccessTestCase("Static field unsupported", + vhStaticField, f, VarHandleTestMethodHandleAccessByte::testStaticFieldUnsupported, + false)); + + cases.add(new MethodHandleAccessTestCase("Array", + vhArray, f, VarHandleTestMethodHandleAccessByte::testArray)); + cases.add(new MethodHandleAccessTestCase("Array unsupported", + vhArray, f, VarHandleTestMethodHandleAccessByte::testArrayUnsupported, + false)); + cases.add(new MethodHandleAccessTestCase("Array index out of bounds", + vhArray, f, VarHandleTestMethodHandleAccessByte::testArrayIndexOutOfBounds, + false)); + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testInstanceField(VarHandleTestMethodHandleAccessByte recv, Handles hs) throws Throwable { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(recv, (byte)1); + byte x = (byte) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, (byte)1, "set byte value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(recv, (byte)2); + byte x = (byte) hs.get(TestAccessMode.getVolatile).invokeExact(recv); + assertEquals(x, (byte)2, "setVolatile byte value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(recv, (byte)1); + byte x = (byte) hs.get(TestAccessMode.getAcquire).invokeExact(recv); + assertEquals(x, (byte)1, "setRelease byte value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(recv, (byte)2); + byte x = (byte) hs.get(TestAccessMode.getOpaque).invokeExact(recv); + assertEquals(x, (byte)2, "setOpaque byte value"); + } + + + } + + static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessByte recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(recv, (byte)1, (byte)2); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + byte r = (byte) hs.get(am).invokeExact(recv, (byte)1, (byte)2); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + byte r = (byte) hs.get(am).invokeExact(recv, (byte)1); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + byte r = (byte) hs.get(am).invokeExact(recv, (byte)1); + }); + } + } + + + static void testStaticField(Handles hs) throws Throwable { + // Plain + { + hs.get(TestAccessMode.set).invokeExact((byte)1); + byte x = (byte) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, (byte)1, "set byte value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact((byte)2); + byte x = (byte) hs.get(TestAccessMode.getVolatile).invokeExact(); + assertEquals(x, (byte)2, "setVolatile byte value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact((byte)1); + byte x = (byte) hs.get(TestAccessMode.getAcquire).invokeExact(); + assertEquals(x, (byte)1, "setRelease byte value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact((byte)2); + byte x = (byte) hs.get(TestAccessMode.getOpaque).invokeExact(); + assertEquals(x, (byte)2, "setOpaque byte value"); + } + + + } + + static void testStaticFieldUnsupported(Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact((byte)1, (byte)2); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + byte r = (byte) hs.get(am).invokeExact((byte)1, (byte)2); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + byte r = (byte) hs.get(am).invokeExact((byte)1); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + byte r = (byte) hs.get(am).invokeExact((byte)1); + }); + } + } + + + static void testArray(Handles hs) throws Throwable { + byte[] array = new byte[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(array, i, (byte)1); + byte x = (byte) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, (byte)1, "get byte value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(array, i, (byte)2); + byte x = (byte) hs.get(TestAccessMode.getVolatile).invokeExact(array, i); + assertEquals(x, (byte)2, "setVolatile byte value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(array, i, (byte)1); + byte x = (byte) hs.get(TestAccessMode.getAcquire).invokeExact(array, i); + assertEquals(x, (byte)1, "setRelease byte value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(array, i, (byte)2); + byte x = (byte) hs.get(TestAccessMode.getOpaque).invokeExact(array, i); + assertEquals(x, (byte)2, "setOpaque byte value"); + } + + + } + } + + static void testArrayUnsupported(Handles hs) throws Throwable { + byte[] array = new byte[10]; + + final int i = 0; + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(array, i, (byte)1, (byte)2); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + byte r = (byte) hs.get(am).invokeExact(array, i, (byte)1, (byte)2); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + byte r = (byte) hs.get(am).invokeExact(array, i, (byte)1); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + byte o = (byte) hs.get(am).invokeExact(array, i, (byte)1); + }); + } + } + + static void testArrayIndexOutOfBounds(Handles hs) throws Throwable { + byte[] array = new byte[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + checkIOOBE(am, () -> { + byte x = (byte) hs.get(am).invokeExact(array, ci); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkIOOBE(am, () -> { + hs.get(am).invokeExact(array, ci, (byte)1); + }); + } + + + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java new file mode 100644 index 00000000000..7e40ed00c65 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessChar + */ + +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.*; + +public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { + static final char static_final_v = 'a'; + + static char static_v; + + final char final_v = 'a'; + + char v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessChar.class, "final_v", char.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessChar.class, "v", char.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessChar.class, "static_final_v", char.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessChar.class, "static_v", char.class); + + vhArray = MethodHandles.arrayElementVarHandle(char[].class); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field", + vhField, f, hs -> testInstanceField(this, hs))); + cases.add(new MethodHandleAccessTestCase("Instance field unsupported", + vhField, f, hs -> testInstanceFieldUnsupported(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field", + vhStaticField, f, VarHandleTestMethodHandleAccessChar::testStaticField)); + cases.add(new MethodHandleAccessTestCase("Static field unsupported", + vhStaticField, f, VarHandleTestMethodHandleAccessChar::testStaticFieldUnsupported, + false)); + + cases.add(new MethodHandleAccessTestCase("Array", + vhArray, f, VarHandleTestMethodHandleAccessChar::testArray)); + cases.add(new MethodHandleAccessTestCase("Array unsupported", + vhArray, f, VarHandleTestMethodHandleAccessChar::testArrayUnsupported, + false)); + cases.add(new MethodHandleAccessTestCase("Array index out of bounds", + vhArray, f, VarHandleTestMethodHandleAccessChar::testArrayIndexOutOfBounds, + false)); + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testInstanceField(VarHandleTestMethodHandleAccessChar recv, Handles hs) throws Throwable { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(recv, 'a'); + char x = (char) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 'a', "set char value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(recv, 'b'); + char x = (char) hs.get(TestAccessMode.getVolatile).invokeExact(recv); + assertEquals(x, 'b', "setVolatile char value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(recv, 'a'); + char x = (char) hs.get(TestAccessMode.getAcquire).invokeExact(recv); + assertEquals(x, 'a', "setRelease char value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(recv, 'b'); + char x = (char) hs.get(TestAccessMode.getOpaque).invokeExact(recv); + assertEquals(x, 'b', "setOpaque char value"); + } + + + } + + static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessChar recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(recv, 'a', 'b'); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + char r = (char) hs.get(am).invokeExact(recv, 'a', 'b'); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + char r = (char) hs.get(am).invokeExact(recv, 'a'); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + char r = (char) hs.get(am).invokeExact(recv, 'a'); + }); + } + } + + + static void testStaticField(Handles hs) throws Throwable { + // Plain + { + hs.get(TestAccessMode.set).invokeExact('a'); + char x = (char) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 'a', "set char value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact('b'); + char x = (char) hs.get(TestAccessMode.getVolatile).invokeExact(); + assertEquals(x, 'b', "setVolatile char value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact('a'); + char x = (char) hs.get(TestAccessMode.getAcquire).invokeExact(); + assertEquals(x, 'a', "setRelease char value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact('b'); + char x = (char) hs.get(TestAccessMode.getOpaque).invokeExact(); + assertEquals(x, 'b', "setOpaque char value"); + } + + + } + + static void testStaticFieldUnsupported(Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact('a', 'b'); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + char r = (char) hs.get(am).invokeExact('a', 'b'); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + char r = (char) hs.get(am).invokeExact('a'); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + char r = (char) hs.get(am).invokeExact('a'); + }); + } + } + + + static void testArray(Handles hs) throws Throwable { + char[] array = new char[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(array, i, 'a'); + char x = (char) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 'a', "get char value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 'b'); + char x = (char) hs.get(TestAccessMode.getVolatile).invokeExact(array, i); + assertEquals(x, 'b', "setVolatile char value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(array, i, 'a'); + char x = (char) hs.get(TestAccessMode.getAcquire).invokeExact(array, i); + assertEquals(x, 'a', "setRelease char value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 'b'); + char x = (char) hs.get(TestAccessMode.getOpaque).invokeExact(array, i); + assertEquals(x, 'b', "setOpaque char value"); + } + + + } + } + + static void testArrayUnsupported(Handles hs) throws Throwable { + char[] array = new char[10]; + + final int i = 0; + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(array, i, 'a', 'b'); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + char r = (char) hs.get(am).invokeExact(array, i, 'a', 'b'); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + char r = (char) hs.get(am).invokeExact(array, i, 'a'); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + char o = (char) hs.get(am).invokeExact(array, i, 'a'); + }); + } + } + + static void testArrayIndexOutOfBounds(Handles hs) throws Throwable { + char[] array = new char[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + checkIOOBE(am, () -> { + char x = (char) hs.get(am).invokeExact(array, ci); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkIOOBE(am, () -> { + hs.get(am).invokeExact(array, ci, 'a'); + }); + } + + + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java new file mode 100644 index 00000000000..20927000f1e --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessDouble + */ + +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.*; + +public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { + static final double static_final_v = 1.0d; + + static double static_v; + + final double final_v = 1.0d; + + double v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessDouble.class, "final_v", double.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessDouble.class, "v", double.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessDouble.class, "static_final_v", double.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessDouble.class, "static_v", double.class); + + vhArray = MethodHandles.arrayElementVarHandle(double[].class); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field", + vhField, f, hs -> testInstanceField(this, hs))); + cases.add(new MethodHandleAccessTestCase("Instance field unsupported", + vhField, f, hs -> testInstanceFieldUnsupported(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field", + vhStaticField, f, VarHandleTestMethodHandleAccessDouble::testStaticField)); + cases.add(new MethodHandleAccessTestCase("Static field unsupported", + vhStaticField, f, VarHandleTestMethodHandleAccessDouble::testStaticFieldUnsupported, + false)); + + cases.add(new MethodHandleAccessTestCase("Array", + vhArray, f, VarHandleTestMethodHandleAccessDouble::testArray)); + cases.add(new MethodHandleAccessTestCase("Array unsupported", + vhArray, f, VarHandleTestMethodHandleAccessDouble::testArrayUnsupported, + false)); + cases.add(new MethodHandleAccessTestCase("Array index out of bounds", + vhArray, f, VarHandleTestMethodHandleAccessDouble::testArrayIndexOutOfBounds, + false)); + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + 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"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(recv, 2.0d); + double x = (double) hs.get(TestAccessMode.getVolatile).invokeExact(recv); + assertEquals(x, 2.0d, "setVolatile double value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(recv, 1.0d); + double x = (double) hs.get(TestAccessMode.getAcquire).invokeExact(recv); + assertEquals(x, 1.0d, "setRelease double value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(recv, 2.0d); + double x = (double) hs.get(TestAccessMode.getOpaque).invokeExact(recv); + assertEquals(x, 2.0d, "setOpaque double value"); + } + + + } + + static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessDouble recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(recv, 1.0d, 2.0d); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + double r = (double) hs.get(am).invokeExact(recv, 1.0d, 2.0d); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + double r = (double) hs.get(am).invokeExact(recv, 1.0d); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + double r = (double) hs.get(am).invokeExact(recv, 1.0d); + }); + } + } + + + static void testStaticField(Handles hs) throws Throwable { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(1.0d); + double x = (double) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1.0d, "set double value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(2.0d); + double x = (double) hs.get(TestAccessMode.getVolatile).invokeExact(); + assertEquals(x, 2.0d, "setVolatile double value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(1.0d); + double x = (double) hs.get(TestAccessMode.getAcquire).invokeExact(); + assertEquals(x, 1.0d, "setRelease double value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(2.0d); + double x = (double) hs.get(TestAccessMode.getOpaque).invokeExact(); + assertEquals(x, 2.0d, "setOpaque double value"); + } + + + } + + static void testStaticFieldUnsupported(Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(1.0d, 2.0d); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + double r = (double) hs.get(am).invokeExact(1.0d, 2.0d); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + double r = (double) hs.get(am).invokeExact(1.0d); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + double r = (double) hs.get(am).invokeExact(1.0d); + }); + } + } + + + static void testArray(Handles hs) throws Throwable { + double[] array = new double[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + 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"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 2.0d); + double x = (double) hs.get(TestAccessMode.getVolatile).invokeExact(array, i); + assertEquals(x, 2.0d, "setVolatile double value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(array, i, 1.0d); + double x = (double) hs.get(TestAccessMode.getAcquire).invokeExact(array, i); + assertEquals(x, 1.0d, "setRelease double value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 2.0d); + double x = (double) hs.get(TestAccessMode.getOpaque).invokeExact(array, i); + assertEquals(x, 2.0d, "setOpaque double value"); + } + + + } + } + + static void testArrayUnsupported(Handles hs) throws Throwable { + double[] array = new double[10]; + + final int i = 0; + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(array, i, 1.0d, 2.0d); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + double r = (double) hs.get(am).invokeExact(array, i, 1.0d, 2.0d); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + double r = (double) hs.get(am).invokeExact(array, i, 1.0d); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + double o = (double) hs.get(am).invokeExact(array, i, 1.0d); + }); + } + } + + static void testArrayIndexOutOfBounds(Handles hs) throws Throwable { + double[] array = new double[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + checkIOOBE(am, () -> { + double x = (double) hs.get(am).invokeExact(array, ci); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkIOOBE(am, () -> { + hs.get(am).invokeExact(array, ci, 1.0d); + }); + } + + + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java new file mode 100644 index 00000000000..7ca74923cef --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessFloat + */ + +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.*; + +public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { + static final float static_final_v = 1.0f; + + static float static_v; + + final float final_v = 1.0f; + + float v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessFloat.class, "final_v", float.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessFloat.class, "v", float.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessFloat.class, "static_final_v", float.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessFloat.class, "static_v", float.class); + + vhArray = MethodHandles.arrayElementVarHandle(float[].class); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field", + vhField, f, hs -> testInstanceField(this, hs))); + cases.add(new MethodHandleAccessTestCase("Instance field unsupported", + vhField, f, hs -> testInstanceFieldUnsupported(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field", + vhStaticField, f, VarHandleTestMethodHandleAccessFloat::testStaticField)); + cases.add(new MethodHandleAccessTestCase("Static field unsupported", + vhStaticField, f, VarHandleTestMethodHandleAccessFloat::testStaticFieldUnsupported, + false)); + + cases.add(new MethodHandleAccessTestCase("Array", + vhArray, f, VarHandleTestMethodHandleAccessFloat::testArray)); + cases.add(new MethodHandleAccessTestCase("Array unsupported", + vhArray, f, VarHandleTestMethodHandleAccessFloat::testArrayUnsupported, + false)); + cases.add(new MethodHandleAccessTestCase("Array index out of bounds", + vhArray, f, VarHandleTestMethodHandleAccessFloat::testArrayIndexOutOfBounds, + false)); + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + 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"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(recv, 2.0f); + float x = (float) hs.get(TestAccessMode.getVolatile).invokeExact(recv); + assertEquals(x, 2.0f, "setVolatile float value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(recv, 1.0f); + float x = (float) hs.get(TestAccessMode.getAcquire).invokeExact(recv); + assertEquals(x, 1.0f, "setRelease float value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(recv, 2.0f); + float x = (float) hs.get(TestAccessMode.getOpaque).invokeExact(recv); + assertEquals(x, 2.0f, "setOpaque float value"); + } + + + } + + static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessFloat recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(recv, 1.0f, 2.0f); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + float r = (float) hs.get(am).invokeExact(recv, 1.0f, 2.0f); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + float r = (float) hs.get(am).invokeExact(recv, 1.0f); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + float r = (float) hs.get(am).invokeExact(recv, 1.0f); + }); + } + } + + + static void testStaticField(Handles hs) throws Throwable { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(1.0f); + float x = (float) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1.0f, "set float value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(2.0f); + float x = (float) hs.get(TestAccessMode.getVolatile).invokeExact(); + assertEquals(x, 2.0f, "setVolatile float value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(1.0f); + float x = (float) hs.get(TestAccessMode.getAcquire).invokeExact(); + assertEquals(x, 1.0f, "setRelease float value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(2.0f); + float x = (float) hs.get(TestAccessMode.getOpaque).invokeExact(); + assertEquals(x, 2.0f, "setOpaque float value"); + } + + + } + + static void testStaticFieldUnsupported(Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(1.0f, 2.0f); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + float r = (float) hs.get(am).invokeExact(1.0f, 2.0f); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + float r = (float) hs.get(am).invokeExact(1.0f); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + float r = (float) hs.get(am).invokeExact(1.0f); + }); + } + } + + + static void testArray(Handles hs) throws Throwable { + float[] array = new float[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + 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"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 2.0f); + float x = (float) hs.get(TestAccessMode.getVolatile).invokeExact(array, i); + assertEquals(x, 2.0f, "setVolatile float value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(array, i, 1.0f); + float x = (float) hs.get(TestAccessMode.getAcquire).invokeExact(array, i); + assertEquals(x, 1.0f, "setRelease float value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 2.0f); + float x = (float) hs.get(TestAccessMode.getOpaque).invokeExact(array, i); + assertEquals(x, 2.0f, "setOpaque float value"); + } + + + } + } + + static void testArrayUnsupported(Handles hs) throws Throwable { + float[] array = new float[10]; + + final int i = 0; + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(array, i, 1.0f, 2.0f); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + float r = (float) hs.get(am).invokeExact(array, i, 1.0f, 2.0f); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + float r = (float) hs.get(am).invokeExact(array, i, 1.0f); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + float o = (float) hs.get(am).invokeExact(array, i, 1.0f); + }); + } + } + + static void testArrayIndexOutOfBounds(Handles hs) throws Throwable { + float[] array = new float[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + checkIOOBE(am, () -> { + float x = (float) hs.get(am).invokeExact(array, ci); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkIOOBE(am, () -> { + hs.get(am).invokeExact(array, ci, 1.0f); + }); + } + + + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java new file mode 100644 index 00000000000..66711948767 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java @@ -0,0 +1,573 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessInt + */ + +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.*; + +public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { + static final int static_final_v = 1; + + static int static_v; + + final int final_v = 1; + + int v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessInt.class, "final_v", int.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessInt.class, "v", int.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessInt.class, "static_final_v", int.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessInt.class, "static_v", int.class); + + vhArray = MethodHandles.arrayElementVarHandle(int[].class); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field", + vhField, f, hs -> testInstanceField(this, hs))); + cases.add(new MethodHandleAccessTestCase("Instance field unsupported", + vhField, f, hs -> testInstanceFieldUnsupported(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field", + vhStaticField, f, VarHandleTestMethodHandleAccessInt::testStaticField)); + cases.add(new MethodHandleAccessTestCase("Static field unsupported", + vhStaticField, f, VarHandleTestMethodHandleAccessInt::testStaticFieldUnsupported, + false)); + + cases.add(new MethodHandleAccessTestCase("Array", + vhArray, f, VarHandleTestMethodHandleAccessInt::testArray)); + cases.add(new MethodHandleAccessTestCase("Array unsupported", + vhArray, f, VarHandleTestMethodHandleAccessInt::testArrayUnsupported, + false)); + cases.add(new MethodHandleAccessTestCase("Array index out of bounds", + vhArray, f, VarHandleTestMethodHandleAccessInt::testArrayIndexOutOfBounds, + false)); + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testInstanceField(VarHandleTestMethodHandleAccessInt recv, Handles hs) throws Throwable { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(recv, 1); + int x = (int) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 1, "set int value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(recv, 2); + int x = (int) hs.get(TestAccessMode.getVolatile).invokeExact(recv); + assertEquals(x, 2, "setVolatile int value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(recv, 1); + int x = (int) hs.get(TestAccessMode.getAcquire).invokeExact(recv); + assertEquals(x, 1, "setRelease int value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(recv, 2); + int x = (int) hs.get(TestAccessMode.getOpaque).invokeExact(recv); + assertEquals(x, 2, "setOpaque int value"); + } + + hs.get(TestAccessMode.set).invokeExact(recv, 1); + + // Compare + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, 1, 2); + assertEquals(r, true, "success compareAndSet int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 2, "success compareAndSet int value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, 1, 3); + assertEquals(r, false, "failing compareAndSet int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 2, "failing compareAndSet int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, 2, 1); + assertEquals(r, 2, "success compareAndExchangeVolatile int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 1, "success compareAndExchangeVolatile int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, 2, 3); + assertEquals(r, 1, "failing compareAndExchangeVolatile int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 1, "failing compareAndExchangeVolatile int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, 1, 2); + assertEquals(r, 1, "success compareAndExchangeAcquire int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 2, "success compareAndExchangeAcquire int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, 1, 3); + assertEquals(r, 2, "failing compareAndExchangeAcquire int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 2, "failing compareAndExchangeAcquire int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, 2, 1); + assertEquals(r, 2, "success compareAndExchangeRelease int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 1, "success compareAndExchangeRelease int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, 2, 3); + assertEquals(r, 1, "failing compareAndExchangeRelease int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 1, "failing compareAndExchangeRelease int value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(recv, 1, 2); + assertEquals(r, true, "weakCompareAndSet int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 2, "weakCompareAndSet int value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(recv, 2, 1); + assertEquals(r, true, "weakCompareAndSetAcquire int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 1, "weakCompareAndSetAcquire int"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(recv, 1, 2); + assertEquals(r, true, "weakCompareAndSetRelease int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 2, "weakCompareAndSetRelease int"); + } + + // Compare set and get + { + int o = (int) hs.get(TestAccessMode.getAndSet).invokeExact(recv, 1); + assertEquals(o, 2, "getAndSet int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 1, "getAndSet int value"); + } + + hs.get(TestAccessMode.set).invokeExact(recv, 1); + + // get and add, add and get + { + int o = (int) hs.get(TestAccessMode.getAndAdd).invokeExact(recv, 3); + assertEquals(o, 1, "getAndAdd int"); + int c = (int) hs.get(TestAccessMode.addAndGet).invokeExact(recv, 3); + assertEquals(c, 1 + 3 + 3, "getAndAdd int value"); + } + } + + static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessInt recv, Handles hs) throws Throwable { + + } + + + static void testStaticField(Handles hs) throws Throwable { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(1); + int x = (int) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1, "set int value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(2); + int x = (int) hs.get(TestAccessMode.getVolatile).invokeExact(); + assertEquals(x, 2, "setVolatile int value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(1); + int x = (int) hs.get(TestAccessMode.getAcquire).invokeExact(); + assertEquals(x, 1, "setRelease int value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(2); + int x = (int) hs.get(TestAccessMode.getOpaque).invokeExact(); + assertEquals(x, 2, "setOpaque int value"); + } + + hs.get(TestAccessMode.set).invokeExact(1); + + // Compare + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(1, 2); + assertEquals(r, true, "success compareAndSet int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 2, "success compareAndSet int value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(1, 3); + assertEquals(r, false, "failing compareAndSet int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 2, "failing compareAndSet int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(2, 1); + assertEquals(r, 2, "success compareAndExchangeVolatile int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1, "success compareAndExchangeVolatile int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(2, 3); + assertEquals(r, 1, "failing compareAndExchangeVolatile int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1, "failing compareAndExchangeVolatile int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(1, 2); + assertEquals(r, 1, "success compareAndExchangeAcquire int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 2, "success compareAndExchangeAcquire int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(1, 3); + assertEquals(r, 2, "failing compareAndExchangeAcquire int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 2, "failing compareAndExchangeAcquire int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(2, 1); + assertEquals(r, 2, "success compareAndExchangeRelease int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1, "success compareAndExchangeRelease int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(2, 3); + assertEquals(r, 1, "failing compareAndExchangeRelease int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1, "failing compareAndExchangeRelease int value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(1, 2); + assertEquals(r, true, "weakCompareAndSet int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 2, "weakCompareAndSet int value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(2, 1); + assertEquals(r, true, "weakCompareAndSetAcquire int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1, "weakCompareAndSetAcquire int"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact( 1, 2); + assertEquals(r, true, "weakCompareAndSetRelease int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 2, "weakCompareAndSetRelease int"); + } + + // Compare set and get + { + int o = (int) hs.get(TestAccessMode.getAndSet).invokeExact( 1); + assertEquals(o, 2, "getAndSet int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1, "getAndSet int value"); + } + + hs.get(TestAccessMode.set).invokeExact(1); + + // get and add, add and get + { + int o = (int) hs.get(TestAccessMode.getAndAdd).invokeExact( 3); + assertEquals(o, 1, "getAndAdd int"); + int c = (int) hs.get(TestAccessMode.addAndGet).invokeExact(3); + assertEquals(c, 1 + 3 + 3, "getAndAdd int value"); + } + } + + static void testStaticFieldUnsupported(Handles hs) throws Throwable { + + } + + + static void testArray(Handles hs) throws Throwable { + int[] array = new int[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(array, i, 1); + int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 1, "get int value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 2); + int x = (int) hs.get(TestAccessMode.getVolatile).invokeExact(array, i); + assertEquals(x, 2, "setVolatile int value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(array, i, 1); + int x = (int) hs.get(TestAccessMode.getAcquire).invokeExact(array, i); + assertEquals(x, 1, "setRelease int value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 2); + int x = (int) hs.get(TestAccessMode.getOpaque).invokeExact(array, i); + assertEquals(x, 2, "setOpaque int value"); + } + + hs.get(TestAccessMode.set).invokeExact(array, i, 1); + + // Compare + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, 1, 2); + assertEquals(r, true, "success compareAndSet int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 2, "success compareAndSet int value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, 1, 3); + assertEquals(r, false, "failing compareAndSet int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 2, "failing compareAndSet int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, 2, 1); + assertEquals(r, 2, "success compareAndExchangeVolatile int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 1, "success compareAndExchangeVolatile int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, 2, 3); + assertEquals(r, 1, "failing compareAndExchangeVolatile int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 1, "failing compareAndExchangeVolatile int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, 1, 2); + assertEquals(r, 1, "success compareAndExchangeAcquire int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 2, "success compareAndExchangeAcquire int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, 1, 3); + assertEquals(r, 2, "failing compareAndExchangeAcquire int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 2, "failing compareAndExchangeAcquire int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, 2, 1); + assertEquals(r, 2, "success compareAndExchangeRelease int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 1, "success compareAndExchangeRelease int value"); + } + + { + int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, 2, 3); + assertEquals(r, 1, "failing compareAndExchangeRelease int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 1, "failing compareAndExchangeRelease int value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(array, i, 1, 2); + assertEquals(r, true, "weakCompareAndSet int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 2, "weakCompareAndSet int value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(array, i, 2, 1); + assertEquals(r, true, "weakCompareAndSetAcquire int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 1, "weakCompareAndSetAcquire int"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(array, i, 1, 2); + assertEquals(r, true, "weakCompareAndSetRelease int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 2, "weakCompareAndSetRelease int"); + } + + // Compare set and get + { + int o = (int) hs.get(TestAccessMode.getAndSet).invokeExact(array, i, 1); + assertEquals(o, 2, "getAndSet int"); + int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 1, "getAndSet int value"); + } + + hs.get(TestAccessMode.set).invokeExact(array, i, 1); + + // get and add, add and get + { + int o = (int) hs.get(TestAccessMode.getAndAdd).invokeExact(array, i, 3); + assertEquals(o, 1, "getAndAdd int"); + int c = (int) hs.get(TestAccessMode.addAndGet).invokeExact(array, i, 3); + assertEquals(c, 1 + 3 + 3, "getAndAdd int value"); + } + } + } + + static void testArrayUnsupported(Handles hs) throws Throwable { + int[] array = new int[10]; + + final int i = 0; + + } + + static void testArrayIndexOutOfBounds(Handles hs) throws Throwable { + int[] array = new int[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + checkIOOBE(am, () -> { + int x = (int) hs.get(am).invokeExact(array, ci); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkIOOBE(am, () -> { + hs.get(am).invokeExact(array, ci, 1); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkIOOBE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(array, ci, 1, 2); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkIOOBE(am, () -> { + int r = (int) hs.get(am).invokeExact(array, ci, 2, 1); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkIOOBE(am, () -> { + int o = (int) hs.get(am).invokeExact(array, ci, 1); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkIOOBE(am, () -> { + int o = (int) hs.get(am).invokeExact(array, ci, 3); + }); + } + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java new file mode 100644 index 00000000000..c3a38c7c425 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java @@ -0,0 +1,573 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessLong + */ + +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.*; + +public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { + static final long static_final_v = 1L; + + static long static_v; + + final long final_v = 1L; + + long v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessLong.class, "final_v", long.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessLong.class, "v", long.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessLong.class, "static_final_v", long.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessLong.class, "static_v", long.class); + + vhArray = MethodHandles.arrayElementVarHandle(long[].class); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field", + vhField, f, hs -> testInstanceField(this, hs))); + cases.add(new MethodHandleAccessTestCase("Instance field unsupported", + vhField, f, hs -> testInstanceFieldUnsupported(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field", + vhStaticField, f, VarHandleTestMethodHandleAccessLong::testStaticField)); + cases.add(new MethodHandleAccessTestCase("Static field unsupported", + vhStaticField, f, VarHandleTestMethodHandleAccessLong::testStaticFieldUnsupported, + false)); + + cases.add(new MethodHandleAccessTestCase("Array", + vhArray, f, VarHandleTestMethodHandleAccessLong::testArray)); + cases.add(new MethodHandleAccessTestCase("Array unsupported", + vhArray, f, VarHandleTestMethodHandleAccessLong::testArrayUnsupported, + false)); + cases.add(new MethodHandleAccessTestCase("Array index out of bounds", + vhArray, f, VarHandleTestMethodHandleAccessLong::testArrayIndexOutOfBounds, + false)); + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testInstanceField(VarHandleTestMethodHandleAccessLong recv, Handles hs) throws Throwable { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(recv, 1L); + long x = (long) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 1L, "set long value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(recv, 2L); + long x = (long) hs.get(TestAccessMode.getVolatile).invokeExact(recv); + assertEquals(x, 2L, "setVolatile long value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(recv, 1L); + long x = (long) hs.get(TestAccessMode.getAcquire).invokeExact(recv); + assertEquals(x, 1L, "setRelease long value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(recv, 2L); + long x = (long) hs.get(TestAccessMode.getOpaque).invokeExact(recv); + assertEquals(x, 2L, "setOpaque long value"); + } + + hs.get(TestAccessMode.set).invokeExact(recv, 1L); + + // Compare + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, 1L, 2L); + assertEquals(r, true, "success compareAndSet long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 2L, "success compareAndSet long value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, 1L, 3L); + assertEquals(r, false, "failing compareAndSet long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 2L, "failing compareAndSet long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, 2L, 1L); + assertEquals(r, 2L, "success compareAndExchangeVolatile long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 1L, "success compareAndExchangeVolatile long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, 2L, 3L); + assertEquals(r, 1L, "failing compareAndExchangeVolatile long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 1L, "failing compareAndExchangeVolatile long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, 1L, 2L); + assertEquals(r, 1L, "success compareAndExchangeAcquire long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 2L, "success compareAndExchangeAcquire long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, 1L, 3L); + assertEquals(r, 2L, "failing compareAndExchangeAcquire long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 2L, "failing compareAndExchangeAcquire long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, 2L, 1L); + assertEquals(r, 2L, "success compareAndExchangeRelease long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 1L, "success compareAndExchangeRelease long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, 2L, 3L); + assertEquals(r, 1L, "failing compareAndExchangeRelease long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 1L, "failing compareAndExchangeRelease long value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(recv, 1L, 2L); + assertEquals(r, true, "weakCompareAndSet long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 2L, "weakCompareAndSet long value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(recv, 2L, 1L); + assertEquals(r, true, "weakCompareAndSetAcquire long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 1L, "weakCompareAndSetAcquire long"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(recv, 1L, 2L); + assertEquals(r, true, "weakCompareAndSetRelease long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 2L, "weakCompareAndSetRelease long"); + } + + // Compare set and get + { + long o = (long) hs.get(TestAccessMode.getAndSet).invokeExact(recv, 1L); + assertEquals(o, 2L, "getAndSet long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, 1L, "getAndSet long value"); + } + + hs.get(TestAccessMode.set).invokeExact(recv, 1L); + + // get and add, add and get + { + long o = (long) hs.get(TestAccessMode.getAndAdd).invokeExact(recv, 3L); + assertEquals(o, 1L, "getAndAdd long"); + long c = (long) hs.get(TestAccessMode.addAndGet).invokeExact(recv, 3L); + assertEquals(c, 1L + 3L + 3L, "getAndAdd long value"); + } + } + + static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessLong recv, Handles hs) throws Throwable { + + } + + + static void testStaticField(Handles hs) throws Throwable { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(1L); + long x = (long) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1L, "set long value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(2L); + long x = (long) hs.get(TestAccessMode.getVolatile).invokeExact(); + assertEquals(x, 2L, "setVolatile long value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(1L); + long x = (long) hs.get(TestAccessMode.getAcquire).invokeExact(); + assertEquals(x, 1L, "setRelease long value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(2L); + long x = (long) hs.get(TestAccessMode.getOpaque).invokeExact(); + assertEquals(x, 2L, "setOpaque long value"); + } + + hs.get(TestAccessMode.set).invokeExact(1L); + + // Compare + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(1L, 2L); + assertEquals(r, true, "success compareAndSet long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 2L, "success compareAndSet long value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(1L, 3L); + assertEquals(r, false, "failing compareAndSet long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 2L, "failing compareAndSet long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(2L, 1L); + assertEquals(r, 2L, "success compareAndExchangeVolatile long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1L, "success compareAndExchangeVolatile long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(2L, 3L); + assertEquals(r, 1L, "failing compareAndExchangeVolatile long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1L, "failing compareAndExchangeVolatile long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(1L, 2L); + assertEquals(r, 1L, "success compareAndExchangeAcquire long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 2L, "success compareAndExchangeAcquire long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(1L, 3L); + assertEquals(r, 2L, "failing compareAndExchangeAcquire long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 2L, "failing compareAndExchangeAcquire long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(2L, 1L); + assertEquals(r, 2L, "success compareAndExchangeRelease long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1L, "success compareAndExchangeRelease long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(2L, 3L); + assertEquals(r, 1L, "failing compareAndExchangeRelease long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1L, "failing compareAndExchangeRelease long value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(1L, 2L); + assertEquals(r, true, "weakCompareAndSet long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 2L, "weakCompareAndSet long value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(2L, 1L); + assertEquals(r, true, "weakCompareAndSetAcquire long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1L, "weakCompareAndSetAcquire long"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact( 1L, 2L); + assertEquals(r, true, "weakCompareAndSetRelease long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 2L, "weakCompareAndSetRelease long"); + } + + // Compare set and get + { + long o = (long) hs.get(TestAccessMode.getAndSet).invokeExact( 1L); + assertEquals(o, 2L, "getAndSet long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, 1L, "getAndSet long value"); + } + + hs.get(TestAccessMode.set).invokeExact(1L); + + // get and add, add and get + { + long o = (long) hs.get(TestAccessMode.getAndAdd).invokeExact( 3L); + assertEquals(o, 1L, "getAndAdd long"); + long c = (long) hs.get(TestAccessMode.addAndGet).invokeExact(3L); + assertEquals(c, 1L + 3L + 3L, "getAndAdd long value"); + } + } + + static void testStaticFieldUnsupported(Handles hs) throws Throwable { + + } + + + static void testArray(Handles hs) throws Throwable { + long[] array = new long[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(array, i, 1L); + long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 1L, "get long value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 2L); + long x = (long) hs.get(TestAccessMode.getVolatile).invokeExact(array, i); + assertEquals(x, 2L, "setVolatile long value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(array, i, 1L); + long x = (long) hs.get(TestAccessMode.getAcquire).invokeExact(array, i); + assertEquals(x, 1L, "setRelease long value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 2L); + long x = (long) hs.get(TestAccessMode.getOpaque).invokeExact(array, i); + assertEquals(x, 2L, "setOpaque long value"); + } + + hs.get(TestAccessMode.set).invokeExact(array, i, 1L); + + // Compare + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, 1L, 2L); + assertEquals(r, true, "success compareAndSet long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 2L, "success compareAndSet long value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, 1L, 3L); + assertEquals(r, false, "failing compareAndSet long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 2L, "failing compareAndSet long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, 2L, 1L); + assertEquals(r, 2L, "success compareAndExchangeVolatile long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 1L, "success compareAndExchangeVolatile long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, 2L, 3L); + assertEquals(r, 1L, "failing compareAndExchangeVolatile long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 1L, "failing compareAndExchangeVolatile long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, 1L, 2L); + assertEquals(r, 1L, "success compareAndExchangeAcquire long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 2L, "success compareAndExchangeAcquire long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, 1L, 3L); + assertEquals(r, 2L, "failing compareAndExchangeAcquire long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 2L, "failing compareAndExchangeAcquire long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, 2L, 1L); + assertEquals(r, 2L, "success compareAndExchangeRelease long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 1L, "success compareAndExchangeRelease long value"); + } + + { + long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, 2L, 3L); + assertEquals(r, 1L, "failing compareAndExchangeRelease long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 1L, "failing compareAndExchangeRelease long value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(array, i, 1L, 2L); + assertEquals(r, true, "weakCompareAndSet long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 2L, "weakCompareAndSet long value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(array, i, 2L, 1L); + assertEquals(r, true, "weakCompareAndSetAcquire long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 1L, "weakCompareAndSetAcquire long"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(array, i, 1L, 2L); + assertEquals(r, true, "weakCompareAndSetRelease long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 2L, "weakCompareAndSetRelease long"); + } + + // Compare set and get + { + long o = (long) hs.get(TestAccessMode.getAndSet).invokeExact(array, i, 1L); + assertEquals(o, 2L, "getAndSet long"); + long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, 1L, "getAndSet long value"); + } + + hs.get(TestAccessMode.set).invokeExact(array, i, 1L); + + // get and add, add and get + { + long o = (long) hs.get(TestAccessMode.getAndAdd).invokeExact(array, i, 3L); + assertEquals(o, 1L, "getAndAdd long"); + long c = (long) hs.get(TestAccessMode.addAndGet).invokeExact(array, i, 3L); + assertEquals(c, 1L + 3L + 3L, "getAndAdd long value"); + } + } + } + + static void testArrayUnsupported(Handles hs) throws Throwable { + long[] array = new long[10]; + + final int i = 0; + + } + + static void testArrayIndexOutOfBounds(Handles hs) throws Throwable { + long[] array = new long[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + checkIOOBE(am, () -> { + long x = (long) hs.get(am).invokeExact(array, ci); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkIOOBE(am, () -> { + hs.get(am).invokeExact(array, ci, 1L); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkIOOBE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(array, ci, 1L, 2L); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkIOOBE(am, () -> { + long r = (long) hs.get(am).invokeExact(array, ci, 2L, 1L); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkIOOBE(am, () -> { + long o = (long) hs.get(am).invokeExact(array, ci, 1L); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkIOOBE(am, () -> { + long o = (long) hs.get(am).invokeExact(array, ci, 3L); + }); + } + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java new file mode 100644 index 00000000000..da7a12b3692 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessShort + */ + +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.*; + +public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { + static final short static_final_v = (short)1; + + static short static_v; + + final short final_v = (short)1; + + short v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessShort.class, "final_v", short.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessShort.class, "v", short.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessShort.class, "static_final_v", short.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessShort.class, "static_v", short.class); + + vhArray = MethodHandles.arrayElementVarHandle(short[].class); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field", + vhField, f, hs -> testInstanceField(this, hs))); + cases.add(new MethodHandleAccessTestCase("Instance field unsupported", + vhField, f, hs -> testInstanceFieldUnsupported(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field", + vhStaticField, f, VarHandleTestMethodHandleAccessShort::testStaticField)); + cases.add(new MethodHandleAccessTestCase("Static field unsupported", + vhStaticField, f, VarHandleTestMethodHandleAccessShort::testStaticFieldUnsupported, + false)); + + cases.add(new MethodHandleAccessTestCase("Array", + vhArray, f, VarHandleTestMethodHandleAccessShort::testArray)); + cases.add(new MethodHandleAccessTestCase("Array unsupported", + vhArray, f, VarHandleTestMethodHandleAccessShort::testArrayUnsupported, + false)); + cases.add(new MethodHandleAccessTestCase("Array index out of bounds", + vhArray, f, VarHandleTestMethodHandleAccessShort::testArrayIndexOutOfBounds, + false)); + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testInstanceField(VarHandleTestMethodHandleAccessShort recv, Handles hs) throws Throwable { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(recv, (short)1); + short x = (short) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, (short)1, "set short value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(recv, (short)2); + short x = (short) hs.get(TestAccessMode.getVolatile).invokeExact(recv); + assertEquals(x, (short)2, "setVolatile short value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(recv, (short)1); + short x = (short) hs.get(TestAccessMode.getAcquire).invokeExact(recv); + assertEquals(x, (short)1, "setRelease short value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(recv, (short)2); + short x = (short) hs.get(TestAccessMode.getOpaque).invokeExact(recv); + assertEquals(x, (short)2, "setOpaque short value"); + } + + + } + + static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessShort recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(recv, (short)1, (short)2); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + short r = (short) hs.get(am).invokeExact(recv, (short)1, (short)2); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + short r = (short) hs.get(am).invokeExact(recv, (short)1); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + short r = (short) hs.get(am).invokeExact(recv, (short)1); + }); + } + } + + + static void testStaticField(Handles hs) throws Throwable { + // Plain + { + hs.get(TestAccessMode.set).invokeExact((short)1); + short x = (short) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, (short)1, "set short value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact((short)2); + short x = (short) hs.get(TestAccessMode.getVolatile).invokeExact(); + assertEquals(x, (short)2, "setVolatile short value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact((short)1); + short x = (short) hs.get(TestAccessMode.getAcquire).invokeExact(); + assertEquals(x, (short)1, "setRelease short value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact((short)2); + short x = (short) hs.get(TestAccessMode.getOpaque).invokeExact(); + assertEquals(x, (short)2, "setOpaque short value"); + } + + + } + + static void testStaticFieldUnsupported(Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact((short)1, (short)2); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + short r = (short) hs.get(am).invokeExact((short)1, (short)2); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + short r = (short) hs.get(am).invokeExact((short)1); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + short r = (short) hs.get(am).invokeExact((short)1); + }); + } + } + + + static void testArray(Handles hs) throws Throwable { + short[] array = new short[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(array, i, (short)1); + short x = (short) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, (short)1, "get short value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(array, i, (short)2); + short x = (short) hs.get(TestAccessMode.getVolatile).invokeExact(array, i); + assertEquals(x, (short)2, "setVolatile short value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(array, i, (short)1); + short x = (short) hs.get(TestAccessMode.getAcquire).invokeExact(array, i); + assertEquals(x, (short)1, "setRelease short value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(array, i, (short)2); + short x = (short) hs.get(TestAccessMode.getOpaque).invokeExact(array, i); + assertEquals(x, (short)2, "setOpaque short value"); + } + + + } + } + + static void testArrayUnsupported(Handles hs) throws Throwable { + short[] array = new short[10]; + + final int i = 0; + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(array, i, (short)1, (short)2); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + short r = (short) hs.get(am).invokeExact(array, i, (short)1, (short)2); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + short r = (short) hs.get(am).invokeExact(array, i, (short)1); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + short o = (short) hs.get(am).invokeExact(array, i, (short)1); + }); + } + } + + static void testArrayIndexOutOfBounds(Handles hs) throws Throwable { + short[] array = new short[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + checkIOOBE(am, () -> { + short x = (short) hs.get(am).invokeExact(array, ci); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkIOOBE(am, () -> { + hs.get(am).invokeExact(array, ci, (short)1); + }); + } + + + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java new file mode 100644 index 00000000000..6034dd268d9 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java @@ -0,0 +1,556 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessString + */ + +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.*; + +public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { + static final String static_final_v = "foo"; + + static String static_v; + + final String final_v = "foo"; + + String v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessString.class, "final_v", String.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccessString.class, "v", String.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessString.class, "static_final_v", String.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccessString.class, "static_v", String.class); + + vhArray = MethodHandles.arrayElementVarHandle(String[].class); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field", + vhField, f, hs -> testInstanceField(this, hs))); + cases.add(new MethodHandleAccessTestCase("Instance field unsupported", + vhField, f, hs -> testInstanceFieldUnsupported(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field", + vhStaticField, f, VarHandleTestMethodHandleAccessString::testStaticField)); + cases.add(new MethodHandleAccessTestCase("Static field unsupported", + vhStaticField, f, VarHandleTestMethodHandleAccessString::testStaticFieldUnsupported, + false)); + + cases.add(new MethodHandleAccessTestCase("Array", + vhArray, f, VarHandleTestMethodHandleAccessString::testArray)); + cases.add(new MethodHandleAccessTestCase("Array unsupported", + vhArray, f, VarHandleTestMethodHandleAccessString::testArrayUnsupported, + false)); + cases.add(new MethodHandleAccessTestCase("Array index out of bounds", + vhArray, f, VarHandleTestMethodHandleAccessString::testArrayIndexOutOfBounds, + false)); + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + 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"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(recv, "bar"); + String x = (String) hs.get(TestAccessMode.getVolatile).invokeExact(recv); + assertEquals(x, "bar", "setVolatile String value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(recv, "foo"); + String x = (String) hs.get(TestAccessMode.getAcquire).invokeExact(recv); + assertEquals(x, "foo", "setRelease String value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(recv, "bar"); + String x = (String) hs.get(TestAccessMode.getOpaque).invokeExact(recv); + assertEquals(x, "bar", "setOpaque String value"); + } + + hs.get(TestAccessMode.set).invokeExact(recv, "foo"); + + // Compare + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).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"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).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"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, "bar", "foo"); + assertEquals(r, "bar", "success compareAndExchangeVolatile String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, "foo", "success compareAndExchangeVolatile String value"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, "bar", "baz"); + assertEquals(r, "foo", "failing compareAndExchangeVolatile String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, "foo", "failing compareAndExchangeVolatile String value"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).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"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).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"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).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"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).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"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(recv, "foo", "bar"); + assertEquals(r, true, "weakCompareAndSet String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, "bar", "weakCompareAndSet String value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(recv, "bar", "foo"); + assertEquals(r, true, "weakCompareAndSetAcquire String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, "foo", "weakCompareAndSetAcquire String"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(recv, "foo", "bar"); + assertEquals(r, true, "weakCompareAndSetRelease String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, "bar", "weakCompareAndSetRelease String"); + } + + // Compare set and get + { + String o = (String) hs.get(TestAccessMode.getAndSet).invokeExact(recv, "foo"); + assertEquals(o, "bar", "getAndSet String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, "foo", "getAndSet String value"); + } + + } + + static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessString recv, Handles hs) throws Throwable { + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + String r = (String) hs.get(am).invokeExact(recv, "foo"); + }); + } + } + + + static void testStaticField(Handles hs) throws Throwable { + // Plain + { + hs.get(TestAccessMode.set).invokeExact("foo"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, "foo", "set String value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact("bar"); + String x = (String) hs.get(TestAccessMode.getVolatile).invokeExact(); + assertEquals(x, "bar", "setVolatile String value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact("foo"); + String x = (String) hs.get(TestAccessMode.getAcquire).invokeExact(); + assertEquals(x, "foo", "setRelease String value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact("bar"); + String x = (String) hs.get(TestAccessMode.getOpaque).invokeExact(); + assertEquals(x, "bar", "setOpaque String value"); + } + + hs.get(TestAccessMode.set).invokeExact("foo"); + + // Compare + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact("foo", "bar"); + assertEquals(r, true, "success compareAndSet String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, "bar", "success compareAndSet String value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact("foo", "baz"); + assertEquals(r, false, "failing compareAndSet String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, "bar", "failing compareAndSet String value"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact("bar", "foo"); + assertEquals(r, "bar", "success compareAndExchangeVolatile String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, "foo", "success compareAndExchangeVolatile String value"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact("bar", "baz"); + assertEquals(r, "foo", "failing compareAndExchangeVolatile String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, "foo", "failing compareAndExchangeVolatile String value"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact("foo", "bar"); + assertEquals(r, "foo", "success compareAndExchangeAcquire String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, "bar", "success compareAndExchangeAcquire String value"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact("foo", "baz"); + assertEquals(r, "bar", "failing compareAndExchangeAcquire String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, "bar", "failing compareAndExchangeAcquire String value"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact("bar", "foo"); + assertEquals(r, "bar", "success compareAndExchangeRelease String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, "foo", "success compareAndExchangeRelease String value"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact("bar", "baz"); + assertEquals(r, "foo", "failing compareAndExchangeRelease String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, "foo", "failing compareAndExchangeRelease String value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact("foo", "bar"); + assertEquals(r, true, "weakCompareAndSet String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, "bar", "weakCompareAndSet String value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact("bar", "foo"); + assertEquals(r, true, "weakCompareAndSetAcquire String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, "foo", "weakCompareAndSetAcquire String"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact( "foo", "bar"); + assertEquals(r, true, "weakCompareAndSetRelease String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, "bar", "weakCompareAndSetRelease String"); + } + + // Compare set and get + { + String o = (String) hs.get(TestAccessMode.getAndSet).invokeExact( "foo"); + assertEquals(o, "bar", "getAndSet String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, "foo", "getAndSet String value"); + } + + } + + static void testStaticFieldUnsupported(Handles hs) throws Throwable { + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + String r = (String) hs.get(am).invokeExact("foo"); + }); + } + } + + + static void testArray(Handles hs) throws Throwable { + String[] array = new String[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(array, i, "foo"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, "foo", "get String value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(array, i, "bar"); + String x = (String) hs.get(TestAccessMode.getVolatile).invokeExact(array, i); + assertEquals(x, "bar", "setVolatile String value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(array, i, "foo"); + String x = (String) hs.get(TestAccessMode.getAcquire).invokeExact(array, i); + assertEquals(x, "foo", "setRelease String value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(array, i, "bar"); + String x = (String) hs.get(TestAccessMode.getOpaque).invokeExact(array, i); + assertEquals(x, "bar", "setOpaque String value"); + } + + hs.get(TestAccessMode.set).invokeExact(array, i, "foo"); + + // Compare + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).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"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).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"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, "bar", "foo"); + assertEquals(r, "bar", "success compareAndExchangeVolatile String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, "foo", "success compareAndExchangeVolatile String value"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, "bar", "baz"); + assertEquals(r, "foo", "failing compareAndExchangeVolatile String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, "foo", "failing compareAndExchangeVolatile String value"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).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"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).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"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).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"); + } + + { + String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).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"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(array, i, "foo", "bar"); + assertEquals(r, true, "weakCompareAndSet String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, "bar", "weakCompareAndSet String value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(array, i, "bar", "foo"); + assertEquals(r, true, "weakCompareAndSetAcquire String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, "foo", "weakCompareAndSetAcquire String"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(array, i, "foo", "bar"); + assertEquals(r, true, "weakCompareAndSetRelease String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, "bar", "weakCompareAndSetRelease String"); + } + + // Compare set and get + { + String o = (String) hs.get(TestAccessMode.getAndSet).invokeExact(array, i, "foo"); + assertEquals(o, "bar", "getAndSet String"); + String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, "foo", "getAndSet String value"); + } + + } + } + + static void testArrayUnsupported(Handles hs) throws Throwable { + String[] array = new String[10]; + + final int i = 0; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + String o = (String) hs.get(am).invokeExact(array, i, "foo"); + }); + } + } + + static void testArrayIndexOutOfBounds(Handles hs) throws Throwable { + String[] array = new String[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + checkIOOBE(am, () -> { + String x = (String) hs.get(am).invokeExact(array, ci); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkIOOBE(am, () -> { + hs.get(am).invokeExact(array, ci, "foo"); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkIOOBE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(array, ci, "foo", "bar"); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkIOOBE(am, () -> { + String r = (String) hs.get(am).invokeExact(array, ci, "bar", "foo"); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkIOOBE(am, () -> { + String o = (String) hs.get(am).invokeExact(array, ci, "foo"); + }); + } + + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeBoolean.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeBoolean.java new file mode 100644 index 00000000000..f0c79ea9f60 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeBoolean.java @@ -0,0 +1,856 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm VarHandleTestMethodTypeBoolean + * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false 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.*; + +public class VarHandleTestMethodTypeBoolean extends VarHandleBaseTest { + static final boolean static_final_v = true; + + static boolean static_v = true; + + final boolean final_v = true; + + boolean v = true; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeBoolean.class, "final_v", boolean.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeBoolean.class, "v", boolean.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeBoolean.class, "static_final_v", boolean.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeBoolean.class, "static_v", boolean.class); + + vhArray = MethodHandles.arrayElementVarHandle(boolean[].class); + } + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + vhField, vh -> testInstanceFieldWrongMethodType(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field wrong method type", + vhStaticField, VarHandleTestMethodTypeBoolean::testStaticFieldWrongMethodType, + false)); + + cases.add(new VarHandleAccessTestCase("Array wrong method type", + vhArray, VarHandleTestMethodTypeBoolean::testArrayWrongMethodType, + false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + vhStaticField, f, VarHandleTestMethodTypeBoolean::testStaticFieldWrongMethodType, + false)); + + cases.add(new MethodHandleAccessTestCase("Array wrong method type", + vhArray, f, VarHandleTestMethodTypeBoolean::testArrayWrongMethodType, + false)); + } + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeBoolean recv, VarHandle vh) throws Throwable { + // Get + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean x = (boolean) vh.get(null); + }); + checkCCE(() -> { // receiver reference class + boolean x = (boolean) vh.get(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean x = (boolean) vh.get(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(recv); + }); + checkWMTE(() -> { // primitive class + int x = (int) vh.get(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean x = (boolean) vh.get(); + }); + checkWMTE(() -> { // > + boolean x = (boolean) vh.get(recv, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.set(null, true); + }); + checkCCE(() -> { // receiver reference class + vh.set(Void.class, true); + }); + checkWMTE(() -> { // value reference class + vh.set(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, true); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(recv, true, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean x = (boolean) vh.getVolatile(null); + }); + checkCCE(() -> { // receiver reference class + boolean x = (boolean) vh.getVolatile(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean x = (boolean) vh.getVolatile(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(recv); + }); + checkWMTE(() -> { // primitive class + int x = (int) vh.getVolatile(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean x = (boolean) vh.getVolatile(); + }); + checkWMTE(() -> { // > + boolean x = (boolean) vh.getVolatile(recv, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setVolatile(null, true); + }); + checkCCE(() -> { // receiver reference class + vh.setVolatile(Void.class, true); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, true); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(recv, true, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean x = (boolean) vh.getOpaque(null); + }); + checkCCE(() -> { // receiver reference class + boolean x = (boolean) vh.getOpaque(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean x = (boolean) vh.getOpaque(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(recv); + }); + checkWMTE(() -> { // primitive class + int x = (int) vh.getOpaque(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean x = (boolean) vh.getOpaque(); + }); + checkWMTE(() -> { // > + boolean x = (boolean) vh.getOpaque(recv, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setOpaque(null, true); + }); + checkCCE(() -> { // receiver reference class + vh.setOpaque(Void.class, true); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, true); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(recv, true, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean x = (boolean) vh.getAcquire(null); + }); + checkCCE(() -> { // receiver reference class + boolean x = (boolean) vh.getAcquire(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean x = (boolean) vh.getAcquire(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(recv); + }); + checkWMTE(() -> { // primitive class + int x = (int) vh.getAcquire(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean x = (boolean) vh.getAcquire(); + }); + checkWMTE(() -> { // > + boolean x = (boolean) vh.getAcquire(recv, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setRelease(null, true); + }); + checkCCE(() -> { // receiver reference class + vh.setRelease(Void.class, true); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, true); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(recv, true, Void.class); + }); + + + + } + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeBoolean recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean x = (boolean) hs.get(am, methodType(boolean.class, Void.class)). + invoke(null); + }); + checkCCE(() -> { // receiver reference class + boolean x = (boolean) hs.get(am, methodType(boolean.class, Class.class)). + invoke(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class)). + invoke(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeBoolean.class)). + invoke(recv); + }); + checkWMTE(() -> { // primitive class + int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeBoolean.class)). + invoke(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean x = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + checkWMTE(() -> { // > + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeBoolean.class, Class.class)). + invoke(recv, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + hs.get(am, methodType(void.class, Void.class, boolean.class)). + invoke(null, true); + }); + checkCCE(() -> { // receiver reference class + hs.get(am, methodType(void.class, Class.class, boolean.class)). + invoke(Void.class, true); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, VarHandleTestMethodTypeBoolean.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, boolean.class)). + invoke(0, true); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, VarHandleTestMethodTypeBoolean.class, boolean.class, Class.class)). + invoke(recv, true, Void.class); + }); + } + + + } + + + static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable { + // Get + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(); + }); + checkWMTE(() -> { // primitive class + int x = (int) vh.get(); + }); + // Incorrect arity + checkWMTE(() -> { // > + boolean x = (boolean) vh.get(Void.class); + }); + + + // Set + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.set(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(true, Void.class); + }); + + + // GetVolatile + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(); + }); + checkWMTE(() -> { // primitive class + int x = (int) vh.getVolatile(); + }); + checkWMTE(() -> { // > + boolean x = (boolean) vh.getVolatile(Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setVolatile(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(true, Void.class); + }); + + + // GetOpaque + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(); + }); + checkWMTE(() -> { // primitive class + int x = (int) vh.getOpaque(); + }); + checkWMTE(() -> { // > + boolean x = (boolean) vh.getOpaque(Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setOpaque(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(true, Void.class); + }); + + + // GetAcquire + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(); + }); + checkWMTE(() -> { // primitive class + int x = (int) vh.getAcquire(); + }); + checkWMTE(() -> { // > + boolean x = (boolean) vh.getAcquire(Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setRelease(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(true, Void.class); + }); + + + + } + + static void testStaticFieldWrongMethodType(Handles hs) throws Throwable { + int i = 0; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class)). + invoke(); + }); + checkWMTE(() -> { // primitive class + int x = (int) hs.get(am, methodType(int.class)). + invoke(); + }); + // Incorrect arity + checkWMTE(() -> { // > + boolean x = (boolean) hs.get(am, methodType(Class.class)). + invoke(Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, Class.class)). + invoke(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, boolean.class, Class.class)). + invoke(true, Void.class); + }); + } + + } + + + static void testArrayWrongMethodType(VarHandle vh) throws Throwable { + boolean[] array = new boolean[10]; + Arrays.fill(array, true); + + // Get + // Incorrect argument types + checkNPE(() -> { // null array + boolean x = (boolean) vh.get(null, 0); + }); + checkCCE(() -> { // array reference class + boolean x = (boolean) vh.get(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + boolean x = (boolean) vh.get(0, 0); + }); + checkWMTE(() -> { // index reference class + boolean x = (boolean) vh.get(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(array, 0); + }); + checkWMTE(() -> { // primitive class + int x = (int) vh.get(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean x = (boolean) vh.get(); + }); + checkWMTE(() -> { // > + boolean x = (boolean) vh.get(array, 0, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null array + vh.set(null, 0, true); + }); + checkCCE(() -> { // array reference class + vh.set(Void.class, 0, true); + }); + checkWMTE(() -> { // value reference class + vh.set(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, 0, true); + }); + checkWMTE(() -> { // index reference class + vh.set(array, Void.class, true); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(array, 0, true, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + boolean x = (boolean) vh.getVolatile(null, 0); + }); + checkCCE(() -> { // array reference class + boolean x = (boolean) vh.getVolatile(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + boolean x = (boolean) vh.getVolatile(0, 0); + }); + checkWMTE(() -> { // index reference class + boolean x = (boolean) vh.getVolatile(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(array, 0); + }); + checkWMTE(() -> { // primitive class + int x = (int) vh.getVolatile(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean x = (boolean) vh.getVolatile(); + }); + checkWMTE(() -> { // > + boolean x = (boolean) vh.getVolatile(array, 0, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + vh.setVolatile(null, 0, true); + }); + checkCCE(() -> { // array reference class + vh.setVolatile(Void.class, 0, true); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, 0, true); + }); + checkWMTE(() -> { // index reference class + vh.setVolatile(array, Void.class, true); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(array, 0, true, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + boolean x = (boolean) vh.getOpaque(null, 0); + }); + checkCCE(() -> { // array reference class + boolean x = (boolean) vh.getOpaque(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + boolean x = (boolean) vh.getOpaque(0, 0); + }); + checkWMTE(() -> { // index reference class + boolean x = (boolean) vh.getOpaque(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(array, 0); + }); + checkWMTE(() -> { // primitive class + int x = (int) vh.getOpaque(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean x = (boolean) vh.getOpaque(); + }); + checkWMTE(() -> { // > + boolean x = (boolean) vh.getOpaque(array, 0, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + vh.setOpaque(null, 0, true); + }); + checkCCE(() -> { // array reference class + vh.setOpaque(Void.class, 0, true); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, 0, true); + }); + checkWMTE(() -> { // index reference class + vh.setOpaque(array, Void.class, true); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(array, 0, true, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null array + boolean x = (boolean) vh.getAcquire(null, 0); + }); + checkCCE(() -> { // array reference class + boolean x = (boolean) vh.getAcquire(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + boolean x = (boolean) vh.getAcquire(0, 0); + }); + checkWMTE(() -> { // index reference class + boolean x = (boolean) vh.getAcquire(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(array, 0); + }); + checkWMTE(() -> { // primitive class + int x = (int) vh.getAcquire(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean x = (boolean) vh.getAcquire(); + }); + checkWMTE(() -> { // > + boolean x = (boolean) vh.getAcquire(array, 0, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null array + vh.setRelease(null, 0, true); + }); + checkCCE(() -> { // array reference class + vh.setRelease(Void.class, 0, true); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, 0, true); + }); + checkWMTE(() -> { // index reference class + vh.setRelease(array, Void.class, true); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(array, 0, true, Void.class); + }); + + + + } + + static void testArrayWrongMethodType(Handles hs) throws Throwable { + boolean[] array = new boolean[10]; + Arrays.fill(array, true); + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null array + boolean x = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class)). + invoke(null, 0); + }); + checkCCE(() -> { // array reference class + boolean x = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class)). + invoke(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class)). + invoke(0, 0); + }); + checkWMTE(() -> { // index reference class + boolean x = (boolean) hs.get(am, methodType(boolean.class, boolean[].class, Class.class)). + invoke(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class, boolean[].class, int.class)). + invoke(array, 0); + }); + checkWMTE(() -> { // primitive class + int x = (int) hs.get(am, methodType(int.class, boolean[].class, int.class)). + invoke(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean x = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + checkWMTE(() -> { // > + boolean x = (boolean) hs.get(am, methodType(boolean.class, boolean[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null array + hs.get(am, methodType(void.class, Void.class, int.class, boolean.class)). + invoke(null, 0, true); + }); + checkCCE(() -> { // array reference class + hs.get(am, methodType(void.class, Class.class, int.class, boolean.class)). + invoke(Void.class, 0, true); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, boolean[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, int.class, boolean.class)). + invoke(0, 0, true); + }); + checkWMTE(() -> { // index reference class + hs.get(am, methodType(void.class, boolean[].class, Class.class, boolean.class)). + invoke(array, Void.class, true); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, boolean[].class, int.class, Class.class)). + invoke(array, 0, true, Void.class); + }); + } + + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeByte.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeByte.java new file mode 100644 index 00000000000..1969c464348 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeByte.java @@ -0,0 +1,856 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm VarHandleTestMethodTypeByte + * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false 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.*; + +public class VarHandleTestMethodTypeByte extends VarHandleBaseTest { + static final byte static_final_v = (byte)1; + + static byte static_v = (byte)1; + + final byte final_v = (byte)1; + + byte v = (byte)1; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeByte.class, "final_v", byte.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeByte.class, "v", byte.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeByte.class, "static_final_v", byte.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeByte.class, "static_v", byte.class); + + vhArray = MethodHandles.arrayElementVarHandle(byte[].class); + } + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + vhField, vh -> testInstanceFieldWrongMethodType(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field wrong method type", + vhStaticField, VarHandleTestMethodTypeByte::testStaticFieldWrongMethodType, + false)); + + cases.add(new VarHandleAccessTestCase("Array wrong method type", + vhArray, VarHandleTestMethodTypeByte::testArrayWrongMethodType, + false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + vhStaticField, f, VarHandleTestMethodTypeByte::testStaticFieldWrongMethodType, + false)); + + cases.add(new MethodHandleAccessTestCase("Array wrong method type", + vhArray, f, VarHandleTestMethodTypeByte::testArrayWrongMethodType, + false)); + } + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeByte recv, VarHandle vh) throws Throwable { + // Get + // Incorrect argument types + checkNPE(() -> { // null receiver + byte x = (byte) vh.get(null); + }); + checkCCE(() -> { // receiver reference class + byte x = (byte) vh.get(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + byte x = (byte) vh.get(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + byte x = (byte) vh.get(); + }); + checkWMTE(() -> { // > + byte x = (byte) vh.get(recv, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.set(null, (byte)1); + }); + checkCCE(() -> { // receiver reference class + vh.set(Void.class, (byte)1); + }); + checkWMTE(() -> { // value reference class + vh.set(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, (byte)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(recv, (byte)1, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + byte x = (byte) vh.getVolatile(null); + }); + checkCCE(() -> { // receiver reference class + byte x = (byte) vh.getVolatile(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + byte x = (byte) vh.getVolatile(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + byte x = (byte) vh.getVolatile(); + }); + checkWMTE(() -> { // > + byte x = (byte) vh.getVolatile(recv, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setVolatile(null, (byte)1); + }); + checkCCE(() -> { // receiver reference class + vh.setVolatile(Void.class, (byte)1); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, (byte)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(recv, (byte)1, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + byte x = (byte) vh.getOpaque(null); + }); + checkCCE(() -> { // receiver reference class + byte x = (byte) vh.getOpaque(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + byte x = (byte) vh.getOpaque(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + byte x = (byte) vh.getOpaque(); + }); + checkWMTE(() -> { // > + byte x = (byte) vh.getOpaque(recv, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setOpaque(null, (byte)1); + }); + checkCCE(() -> { // receiver reference class + vh.setOpaque(Void.class, (byte)1); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, (byte)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(recv, (byte)1, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + byte x = (byte) vh.getAcquire(null); + }); + checkCCE(() -> { // receiver reference class + byte x = (byte) vh.getAcquire(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + byte x = (byte) vh.getAcquire(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + byte x = (byte) vh.getAcquire(); + }); + checkWMTE(() -> { // > + byte x = (byte) vh.getAcquire(recv, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setRelease(null, (byte)1); + }); + checkCCE(() -> { // receiver reference class + vh.setRelease(Void.class, (byte)1); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, (byte)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(recv, (byte)1, Void.class); + }); + + + + } + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeByte recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + byte x = (byte) hs.get(am, methodType(byte.class, Void.class)). + invoke(null); + }); + checkCCE(() -> { // receiver reference class + byte x = (byte) hs.get(am, methodType(byte.class, Class.class)). + invoke(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + byte x = (byte) hs.get(am, methodType(byte.class, int.class)). + invoke(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(byte.class, VarHandleTestMethodTypeByte.class)). + invoke(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeByte.class)). + invoke(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + byte x = (byte) hs.get(am, methodType(byte.class)). + invoke(); + }); + checkWMTE(() -> { // > + byte x = (byte) hs.get(am, methodType(byte.class, VarHandleTestMethodTypeByte.class, Class.class)). + invoke(recv, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + hs.get(am, methodType(void.class, Void.class, byte.class)). + invoke(null, (byte)1); + }); + checkCCE(() -> { // receiver reference class + hs.get(am, methodType(void.class, Class.class, byte.class)). + invoke(Void.class, (byte)1); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, VarHandleTestMethodTypeByte.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, byte.class)). + invoke(0, (byte)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, VarHandleTestMethodTypeByte.class, byte.class, Class.class)). + invoke(recv, (byte)1, Void.class); + }); + } + + + } + + + static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable { + // Get + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(); + }); + // Incorrect arity + checkWMTE(() -> { // > + byte x = (byte) vh.get(Void.class); + }); + + + // Set + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.set(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set((byte)1, Void.class); + }); + + + // GetVolatile + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(); + }); + checkWMTE(() -> { // > + byte x = (byte) vh.getVolatile(Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setVolatile(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile((byte)1, Void.class); + }); + + + // GetOpaque + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(); + }); + checkWMTE(() -> { // > + byte x = (byte) vh.getOpaque(Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setOpaque(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque((byte)1, Void.class); + }); + + + // GetAcquire + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(); + }); + checkWMTE(() -> { // > + byte x = (byte) vh.getAcquire(Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setRelease(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease((byte)1, Void.class); + }); + + + + } + + static void testStaticFieldWrongMethodType(Handles hs) throws Throwable { + int i = 0; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class)). + invoke(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + // Incorrect arity + checkWMTE(() -> { // > + byte x = (byte) hs.get(am, methodType(Class.class)). + invoke(Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, Class.class)). + invoke(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, byte.class, Class.class)). + invoke((byte)1, Void.class); + }); + } + + } + + + static void testArrayWrongMethodType(VarHandle vh) throws Throwable { + byte[] array = new byte[10]; + Arrays.fill(array, (byte)1); + + // Get + // Incorrect argument types + checkNPE(() -> { // null array + byte x = (byte) vh.get(null, 0); + }); + checkCCE(() -> { // array reference class + byte x = (byte) vh.get(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + byte x = (byte) vh.get(0, 0); + }); + checkWMTE(() -> { // index reference class + byte x = (byte) vh.get(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + byte x = (byte) vh.get(); + }); + checkWMTE(() -> { // > + byte x = (byte) vh.get(array, 0, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null array + vh.set(null, 0, (byte)1); + }); + checkCCE(() -> { // array reference class + vh.set(Void.class, 0, (byte)1); + }); + checkWMTE(() -> { // value reference class + vh.set(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, 0, (byte)1); + }); + checkWMTE(() -> { // index reference class + vh.set(array, Void.class, (byte)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(array, 0, (byte)1, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + byte x = (byte) vh.getVolatile(null, 0); + }); + checkCCE(() -> { // array reference class + byte x = (byte) vh.getVolatile(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + byte x = (byte) vh.getVolatile(0, 0); + }); + checkWMTE(() -> { // index reference class + byte x = (byte) vh.getVolatile(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + byte x = (byte) vh.getVolatile(); + }); + checkWMTE(() -> { // > + byte x = (byte) vh.getVolatile(array, 0, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + vh.setVolatile(null, 0, (byte)1); + }); + checkCCE(() -> { // array reference class + vh.setVolatile(Void.class, 0, (byte)1); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, 0, (byte)1); + }); + checkWMTE(() -> { // index reference class + vh.setVolatile(array, Void.class, (byte)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(array, 0, (byte)1, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + byte x = (byte) vh.getOpaque(null, 0); + }); + checkCCE(() -> { // array reference class + byte x = (byte) vh.getOpaque(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + byte x = (byte) vh.getOpaque(0, 0); + }); + checkWMTE(() -> { // index reference class + byte x = (byte) vh.getOpaque(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + byte x = (byte) vh.getOpaque(); + }); + checkWMTE(() -> { // > + byte x = (byte) vh.getOpaque(array, 0, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + vh.setOpaque(null, 0, (byte)1); + }); + checkCCE(() -> { // array reference class + vh.setOpaque(Void.class, 0, (byte)1); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, 0, (byte)1); + }); + checkWMTE(() -> { // index reference class + vh.setOpaque(array, Void.class, (byte)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(array, 0, (byte)1, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null array + byte x = (byte) vh.getAcquire(null, 0); + }); + checkCCE(() -> { // array reference class + byte x = (byte) vh.getAcquire(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + byte x = (byte) vh.getAcquire(0, 0); + }); + checkWMTE(() -> { // index reference class + byte x = (byte) vh.getAcquire(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + byte x = (byte) vh.getAcquire(); + }); + checkWMTE(() -> { // > + byte x = (byte) vh.getAcquire(array, 0, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null array + vh.setRelease(null, 0, (byte)1); + }); + checkCCE(() -> { // array reference class + vh.setRelease(Void.class, 0, (byte)1); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, 0, (byte)1); + }); + checkWMTE(() -> { // index reference class + vh.setRelease(array, Void.class, (byte)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(array, 0, (byte)1, Void.class); + }); + + + + } + + static void testArrayWrongMethodType(Handles hs) throws Throwable { + byte[] array = new byte[10]; + Arrays.fill(array, (byte)1); + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null array + byte x = (byte) hs.get(am, methodType(byte.class, Void.class, int.class)). + invoke(null, 0); + }); + checkCCE(() -> { // array reference class + byte x = (byte) hs.get(am, methodType(byte.class, Class.class, int.class)). + invoke(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + byte x = (byte) hs.get(am, methodType(byte.class, int.class, int.class)). + invoke(0, 0); + }); + checkWMTE(() -> { // index reference class + byte x = (byte) hs.get(am, methodType(byte.class, byte[].class, Class.class)). + invoke(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class, byte[].class, int.class)). + invoke(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, byte[].class, int.class)). + invoke(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + byte x = (byte) hs.get(am, methodType(byte.class)). + invoke(); + }); + checkWMTE(() -> { // > + byte x = (byte) hs.get(am, methodType(byte.class, byte[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null array + hs.get(am, methodType(void.class, Void.class, int.class, byte.class)). + invoke(null, 0, (byte)1); + }); + checkCCE(() -> { // array reference class + hs.get(am, methodType(void.class, Class.class, int.class, byte.class)). + invoke(Void.class, 0, (byte)1); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, byte[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, int.class, byte.class)). + invoke(0, 0, (byte)1); + }); + checkWMTE(() -> { // index reference class + hs.get(am, methodType(void.class, byte[].class, Class.class, byte.class)). + invoke(array, Void.class, (byte)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, byte[].class, int.class, Class.class)). + invoke(array, 0, (byte)1, Void.class); + }); + } + + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeChar.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeChar.java new file mode 100644 index 00000000000..296806255c3 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeChar.java @@ -0,0 +1,856 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm VarHandleTestMethodTypeChar + * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false 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.*; + +public class VarHandleTestMethodTypeChar extends VarHandleBaseTest { + static final char static_final_v = 'a'; + + static char static_v = 'a'; + + final char final_v = 'a'; + + char v = 'a'; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeChar.class, "final_v", char.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeChar.class, "v", char.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeChar.class, "static_final_v", char.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeChar.class, "static_v", char.class); + + vhArray = MethodHandles.arrayElementVarHandle(char[].class); + } + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + vhField, vh -> testInstanceFieldWrongMethodType(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field wrong method type", + vhStaticField, VarHandleTestMethodTypeChar::testStaticFieldWrongMethodType, + false)); + + cases.add(new VarHandleAccessTestCase("Array wrong method type", + vhArray, VarHandleTestMethodTypeChar::testArrayWrongMethodType, + false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + vhStaticField, f, VarHandleTestMethodTypeChar::testStaticFieldWrongMethodType, + false)); + + cases.add(new MethodHandleAccessTestCase("Array wrong method type", + vhArray, f, VarHandleTestMethodTypeChar::testArrayWrongMethodType, + false)); + } + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeChar recv, VarHandle vh) throws Throwable { + // Get + // Incorrect argument types + checkNPE(() -> { // null receiver + char x = (char) vh.get(null); + }); + checkCCE(() -> { // receiver reference class + char x = (char) vh.get(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + char x = (char) vh.get(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + char x = (char) vh.get(); + }); + checkWMTE(() -> { // > + char x = (char) vh.get(recv, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.set(null, 'a'); + }); + checkCCE(() -> { // receiver reference class + vh.set(Void.class, 'a'); + }); + checkWMTE(() -> { // value reference class + vh.set(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, 'a'); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(recv, 'a', Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + char x = (char) vh.getVolatile(null); + }); + checkCCE(() -> { // receiver reference class + char x = (char) vh.getVolatile(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + char x = (char) vh.getVolatile(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + char x = (char) vh.getVolatile(); + }); + checkWMTE(() -> { // > + char x = (char) vh.getVolatile(recv, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setVolatile(null, 'a'); + }); + checkCCE(() -> { // receiver reference class + vh.setVolatile(Void.class, 'a'); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, 'a'); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(recv, 'a', Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + char x = (char) vh.getOpaque(null); + }); + checkCCE(() -> { // receiver reference class + char x = (char) vh.getOpaque(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + char x = (char) vh.getOpaque(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + char x = (char) vh.getOpaque(); + }); + checkWMTE(() -> { // > + char x = (char) vh.getOpaque(recv, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setOpaque(null, 'a'); + }); + checkCCE(() -> { // receiver reference class + vh.setOpaque(Void.class, 'a'); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, 'a'); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(recv, 'a', Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + char x = (char) vh.getAcquire(null); + }); + checkCCE(() -> { // receiver reference class + char x = (char) vh.getAcquire(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + char x = (char) vh.getAcquire(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + char x = (char) vh.getAcquire(); + }); + checkWMTE(() -> { // > + char x = (char) vh.getAcquire(recv, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setRelease(null, 'a'); + }); + checkCCE(() -> { // receiver reference class + vh.setRelease(Void.class, 'a'); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, 'a'); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(recv, 'a', Void.class); + }); + + + + } + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeChar recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + char x = (char) hs.get(am, methodType(char.class, Void.class)). + invoke(null); + }); + checkCCE(() -> { // receiver reference class + char x = (char) hs.get(am, methodType(char.class, Class.class)). + invoke(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + char x = (char) hs.get(am, methodType(char.class, int.class)). + invoke(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(char.class, VarHandleTestMethodTypeChar.class)). + invoke(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeChar.class)). + invoke(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + char x = (char) hs.get(am, methodType(char.class)). + invoke(); + }); + checkWMTE(() -> { // > + char x = (char) hs.get(am, methodType(char.class, VarHandleTestMethodTypeChar.class, Class.class)). + invoke(recv, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + hs.get(am, methodType(void.class, Void.class, char.class)). + invoke(null, 'a'); + }); + checkCCE(() -> { // receiver reference class + hs.get(am, methodType(void.class, Class.class, char.class)). + invoke(Void.class, 'a'); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, VarHandleTestMethodTypeChar.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, char.class)). + invoke(0, 'a'); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, VarHandleTestMethodTypeChar.class, char.class, Class.class)). + invoke(recv, 'a', Void.class); + }); + } + + + } + + + static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable { + // Get + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(); + }); + // Incorrect arity + checkWMTE(() -> { // > + char x = (char) vh.get(Void.class); + }); + + + // Set + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.set(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set('a', Void.class); + }); + + + // GetVolatile + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(); + }); + checkWMTE(() -> { // > + char x = (char) vh.getVolatile(Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setVolatile(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile('a', Void.class); + }); + + + // GetOpaque + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(); + }); + checkWMTE(() -> { // > + char x = (char) vh.getOpaque(Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setOpaque(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque('a', Void.class); + }); + + + // GetAcquire + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(); + }); + checkWMTE(() -> { // > + char x = (char) vh.getAcquire(Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setRelease(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease('a', Void.class); + }); + + + + } + + static void testStaticFieldWrongMethodType(Handles hs) throws Throwable { + int i = 0; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class)). + invoke(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + // Incorrect arity + checkWMTE(() -> { // > + char x = (char) hs.get(am, methodType(Class.class)). + invoke(Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, Class.class)). + invoke(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, char.class, Class.class)). + invoke('a', Void.class); + }); + } + + } + + + static void testArrayWrongMethodType(VarHandle vh) throws Throwable { + char[] array = new char[10]; + Arrays.fill(array, 'a'); + + // Get + // Incorrect argument types + checkNPE(() -> { // null array + char x = (char) vh.get(null, 0); + }); + checkCCE(() -> { // array reference class + char x = (char) vh.get(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + char x = (char) vh.get(0, 0); + }); + checkWMTE(() -> { // index reference class + char x = (char) vh.get(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + char x = (char) vh.get(); + }); + checkWMTE(() -> { // > + char x = (char) vh.get(array, 0, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null array + vh.set(null, 0, 'a'); + }); + checkCCE(() -> { // array reference class + vh.set(Void.class, 0, 'a'); + }); + checkWMTE(() -> { // value reference class + vh.set(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, 0, 'a'); + }); + checkWMTE(() -> { // index reference class + vh.set(array, Void.class, 'a'); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(array, 0, 'a', Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + char x = (char) vh.getVolatile(null, 0); + }); + checkCCE(() -> { // array reference class + char x = (char) vh.getVolatile(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + char x = (char) vh.getVolatile(0, 0); + }); + checkWMTE(() -> { // index reference class + char x = (char) vh.getVolatile(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + char x = (char) vh.getVolatile(); + }); + checkWMTE(() -> { // > + char x = (char) vh.getVolatile(array, 0, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + vh.setVolatile(null, 0, 'a'); + }); + checkCCE(() -> { // array reference class + vh.setVolatile(Void.class, 0, 'a'); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, 0, 'a'); + }); + checkWMTE(() -> { // index reference class + vh.setVolatile(array, Void.class, 'a'); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(array, 0, 'a', Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + char x = (char) vh.getOpaque(null, 0); + }); + checkCCE(() -> { // array reference class + char x = (char) vh.getOpaque(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + char x = (char) vh.getOpaque(0, 0); + }); + checkWMTE(() -> { // index reference class + char x = (char) vh.getOpaque(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + char x = (char) vh.getOpaque(); + }); + checkWMTE(() -> { // > + char x = (char) vh.getOpaque(array, 0, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + vh.setOpaque(null, 0, 'a'); + }); + checkCCE(() -> { // array reference class + vh.setOpaque(Void.class, 0, 'a'); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, 0, 'a'); + }); + checkWMTE(() -> { // index reference class + vh.setOpaque(array, Void.class, 'a'); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(array, 0, 'a', Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null array + char x = (char) vh.getAcquire(null, 0); + }); + checkCCE(() -> { // array reference class + char x = (char) vh.getAcquire(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + char x = (char) vh.getAcquire(0, 0); + }); + checkWMTE(() -> { // index reference class + char x = (char) vh.getAcquire(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + char x = (char) vh.getAcquire(); + }); + checkWMTE(() -> { // > + char x = (char) vh.getAcquire(array, 0, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null array + vh.setRelease(null, 0, 'a'); + }); + checkCCE(() -> { // array reference class + vh.setRelease(Void.class, 0, 'a'); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, 0, 'a'); + }); + checkWMTE(() -> { // index reference class + vh.setRelease(array, Void.class, 'a'); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(array, 0, 'a', Void.class); + }); + + + + } + + static void testArrayWrongMethodType(Handles hs) throws Throwable { + char[] array = new char[10]; + Arrays.fill(array, 'a'); + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null array + char x = (char) hs.get(am, methodType(char.class, Void.class, int.class)). + invoke(null, 0); + }); + checkCCE(() -> { // array reference class + char x = (char) hs.get(am, methodType(char.class, Class.class, int.class)). + invoke(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + char x = (char) hs.get(am, methodType(char.class, int.class, int.class)). + invoke(0, 0); + }); + checkWMTE(() -> { // index reference class + char x = (char) hs.get(am, methodType(char.class, char[].class, Class.class)). + invoke(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class, char[].class, int.class)). + invoke(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, char[].class, int.class)). + invoke(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + char x = (char) hs.get(am, methodType(char.class)). + invoke(); + }); + checkWMTE(() -> { // > + char x = (char) hs.get(am, methodType(char.class, char[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null array + hs.get(am, methodType(void.class, Void.class, int.class, char.class)). + invoke(null, 0, 'a'); + }); + checkCCE(() -> { // array reference class + hs.get(am, methodType(void.class, Class.class, int.class, char.class)). + invoke(Void.class, 0, 'a'); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, char[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, int.class, char.class)). + invoke(0, 0, 'a'); + }); + checkWMTE(() -> { // index reference class + hs.get(am, methodType(void.class, char[].class, Class.class, char.class)). + invoke(array, Void.class, 'a'); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, char[].class, int.class, Class.class)). + invoke(array, 0, 'a', Void.class); + }); + } + + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java new file mode 100644 index 00000000000..c09a73c6ddb --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java @@ -0,0 +1,856 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm VarHandleTestMethodTypeDouble + * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false 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.*; + +public class VarHandleTestMethodTypeDouble extends VarHandleBaseTest { + static final double static_final_v = 1.0d; + + static double static_v = 1.0d; + + final double final_v = 1.0d; + + double v = 1.0d; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeDouble.class, "final_v", double.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeDouble.class, "v", double.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeDouble.class, "static_final_v", double.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeDouble.class, "static_v", double.class); + + vhArray = MethodHandles.arrayElementVarHandle(double[].class); + } + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + vhField, vh -> testInstanceFieldWrongMethodType(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field wrong method type", + vhStaticField, VarHandleTestMethodTypeDouble::testStaticFieldWrongMethodType, + false)); + + cases.add(new VarHandleAccessTestCase("Array wrong method type", + vhArray, VarHandleTestMethodTypeDouble::testArrayWrongMethodType, + false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + vhStaticField, f, VarHandleTestMethodTypeDouble::testStaticFieldWrongMethodType, + false)); + + cases.add(new MethodHandleAccessTestCase("Array wrong method type", + vhArray, f, VarHandleTestMethodTypeDouble::testArrayWrongMethodType, + false)); + } + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeDouble recv, VarHandle vh) throws Throwable { + // Get + // Incorrect argument types + checkNPE(() -> { // null receiver + double x = (double) vh.get(null); + }); + checkCCE(() -> { // receiver reference class + double x = (double) vh.get(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + double x = (double) vh.get(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + double x = (double) vh.get(); + }); + checkWMTE(() -> { // > + double x = (double) vh.get(recv, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.set(null, 1.0d); + }); + checkCCE(() -> { // receiver reference class + vh.set(Void.class, 1.0d); + }); + checkWMTE(() -> { // value reference class + vh.set(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, 1.0d); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(recv, 1.0d, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + double x = (double) vh.getVolatile(null); + }); + checkCCE(() -> { // receiver reference class + double x = (double) vh.getVolatile(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + double x = (double) vh.getVolatile(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + double x = (double) vh.getVolatile(); + }); + checkWMTE(() -> { // > + double x = (double) vh.getVolatile(recv, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setVolatile(null, 1.0d); + }); + checkCCE(() -> { // receiver reference class + vh.setVolatile(Void.class, 1.0d); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, 1.0d); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(recv, 1.0d, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + double x = (double) vh.getOpaque(null); + }); + checkCCE(() -> { // receiver reference class + double x = (double) vh.getOpaque(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + double x = (double) vh.getOpaque(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + double x = (double) vh.getOpaque(); + }); + checkWMTE(() -> { // > + double x = (double) vh.getOpaque(recv, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setOpaque(null, 1.0d); + }); + checkCCE(() -> { // receiver reference class + vh.setOpaque(Void.class, 1.0d); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, 1.0d); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(recv, 1.0d, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + double x = (double) vh.getAcquire(null); + }); + checkCCE(() -> { // receiver reference class + double x = (double) vh.getAcquire(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + double x = (double) vh.getAcquire(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + double x = (double) vh.getAcquire(); + }); + checkWMTE(() -> { // > + double x = (double) vh.getAcquire(recv, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setRelease(null, 1.0d); + }); + checkCCE(() -> { // receiver reference class + vh.setRelease(Void.class, 1.0d); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, 1.0d); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(recv, 1.0d, Void.class); + }); + + + + } + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeDouble recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + double x = (double) hs.get(am, methodType(double.class, Void.class)). + invoke(null); + }); + checkCCE(() -> { // receiver reference class + double x = (double) hs.get(am, methodType(double.class, Class.class)). + invoke(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + double x = (double) hs.get(am, methodType(double.class, int.class)). + invoke(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class)). + invoke(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeDouble.class)). + invoke(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + double x = (double) hs.get(am, methodType(double.class)). + invoke(); + }); + checkWMTE(() -> { // > + double x = (double) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class, Class.class)). + invoke(recv, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + hs.get(am, methodType(void.class, Void.class, double.class)). + invoke(null, 1.0d); + }); + checkCCE(() -> { // receiver reference class + hs.get(am, methodType(void.class, Class.class, double.class)). + invoke(Void.class, 1.0d); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, VarHandleTestMethodTypeDouble.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, double.class)). + invoke(0, 1.0d); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, VarHandleTestMethodTypeDouble.class, double.class, Class.class)). + invoke(recv, 1.0d, Void.class); + }); + } + + + } + + + static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable { + // Get + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(); + }); + // Incorrect arity + checkWMTE(() -> { // > + double x = (double) vh.get(Void.class); + }); + + + // Set + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.set(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(1.0d, Void.class); + }); + + + // GetVolatile + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(); + }); + checkWMTE(() -> { // > + double x = (double) vh.getVolatile(Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setVolatile(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(1.0d, Void.class); + }); + + + // GetOpaque + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(); + }); + checkWMTE(() -> { // > + double x = (double) vh.getOpaque(Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setOpaque(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(1.0d, Void.class); + }); + + + // GetAcquire + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(); + }); + checkWMTE(() -> { // > + double x = (double) vh.getAcquire(Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setRelease(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(1.0d, Void.class); + }); + + + + } + + static void testStaticFieldWrongMethodType(Handles hs) throws Throwable { + int i = 0; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class)). + invoke(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + // Incorrect arity + checkWMTE(() -> { // > + double x = (double) hs.get(am, methodType(Class.class)). + invoke(Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, Class.class)). + invoke(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, double.class, Class.class)). + invoke(1.0d, Void.class); + }); + } + + } + + + static void testArrayWrongMethodType(VarHandle vh) throws Throwable { + double[] array = new double[10]; + Arrays.fill(array, 1.0d); + + // Get + // Incorrect argument types + checkNPE(() -> { // null array + double x = (double) vh.get(null, 0); + }); + checkCCE(() -> { // array reference class + double x = (double) vh.get(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + double x = (double) vh.get(0, 0); + }); + checkWMTE(() -> { // index reference class + double x = (double) vh.get(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + double x = (double) vh.get(); + }); + checkWMTE(() -> { // > + double x = (double) vh.get(array, 0, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null array + vh.set(null, 0, 1.0d); + }); + checkCCE(() -> { // array reference class + vh.set(Void.class, 0, 1.0d); + }); + checkWMTE(() -> { // value reference class + vh.set(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, 0, 1.0d); + }); + checkWMTE(() -> { // index reference class + vh.set(array, Void.class, 1.0d); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(array, 0, 1.0d, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + double x = (double) vh.getVolatile(null, 0); + }); + checkCCE(() -> { // array reference class + double x = (double) vh.getVolatile(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + double x = (double) vh.getVolatile(0, 0); + }); + checkWMTE(() -> { // index reference class + double x = (double) vh.getVolatile(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + double x = (double) vh.getVolatile(); + }); + checkWMTE(() -> { // > + double x = (double) vh.getVolatile(array, 0, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + vh.setVolatile(null, 0, 1.0d); + }); + checkCCE(() -> { // array reference class + vh.setVolatile(Void.class, 0, 1.0d); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, 0, 1.0d); + }); + checkWMTE(() -> { // index reference class + vh.setVolatile(array, Void.class, 1.0d); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(array, 0, 1.0d, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + double x = (double) vh.getOpaque(null, 0); + }); + checkCCE(() -> { // array reference class + double x = (double) vh.getOpaque(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + double x = (double) vh.getOpaque(0, 0); + }); + checkWMTE(() -> { // index reference class + double x = (double) vh.getOpaque(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + double x = (double) vh.getOpaque(); + }); + checkWMTE(() -> { // > + double x = (double) vh.getOpaque(array, 0, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + vh.setOpaque(null, 0, 1.0d); + }); + checkCCE(() -> { // array reference class + vh.setOpaque(Void.class, 0, 1.0d); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, 0, 1.0d); + }); + checkWMTE(() -> { // index reference class + vh.setOpaque(array, Void.class, 1.0d); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(array, 0, 1.0d, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null array + double x = (double) vh.getAcquire(null, 0); + }); + checkCCE(() -> { // array reference class + double x = (double) vh.getAcquire(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + double x = (double) vh.getAcquire(0, 0); + }); + checkWMTE(() -> { // index reference class + double x = (double) vh.getAcquire(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + double x = (double) vh.getAcquire(); + }); + checkWMTE(() -> { // > + double x = (double) vh.getAcquire(array, 0, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null array + vh.setRelease(null, 0, 1.0d); + }); + checkCCE(() -> { // array reference class + vh.setRelease(Void.class, 0, 1.0d); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, 0, 1.0d); + }); + checkWMTE(() -> { // index reference class + vh.setRelease(array, Void.class, 1.0d); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(array, 0, 1.0d, Void.class); + }); + + + + } + + static void testArrayWrongMethodType(Handles hs) throws Throwable { + double[] array = new double[10]; + Arrays.fill(array, 1.0d); + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null array + double x = (double) hs.get(am, methodType(double.class, Void.class, int.class)). + invoke(null, 0); + }); + checkCCE(() -> { // array reference class + double x = (double) hs.get(am, methodType(double.class, Class.class, int.class)). + invoke(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + double x = (double) hs.get(am, methodType(double.class, int.class, int.class)). + invoke(0, 0); + }); + checkWMTE(() -> { // index reference class + double x = (double) hs.get(am, methodType(double.class, double[].class, Class.class)). + invoke(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class, double[].class, int.class)). + invoke(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, double[].class, int.class)). + invoke(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + double x = (double) hs.get(am, methodType(double.class)). + invoke(); + }); + checkWMTE(() -> { // > + double x = (double) hs.get(am, methodType(double.class, double[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null array + hs.get(am, methodType(void.class, Void.class, int.class, double.class)). + invoke(null, 0, 1.0d); + }); + checkCCE(() -> { // array reference class + hs.get(am, methodType(void.class, Class.class, int.class, double.class)). + invoke(Void.class, 0, 1.0d); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, double[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, int.class, double.class)). + invoke(0, 0, 1.0d); + }); + checkWMTE(() -> { // index reference class + hs.get(am, methodType(void.class, double[].class, Class.class, double.class)). + invoke(array, Void.class, 1.0d); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, double[].class, int.class, Class.class)). + invoke(array, 0, 1.0d, Void.class); + }); + } + + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java new file mode 100644 index 00000000000..0ea65921dd4 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java @@ -0,0 +1,856 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm VarHandleTestMethodTypeFloat + * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false 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.*; + +public class VarHandleTestMethodTypeFloat extends VarHandleBaseTest { + static final float static_final_v = 1.0f; + + static float static_v = 1.0f; + + final float final_v = 1.0f; + + float v = 1.0f; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeFloat.class, "final_v", float.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeFloat.class, "v", float.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeFloat.class, "static_final_v", float.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeFloat.class, "static_v", float.class); + + vhArray = MethodHandles.arrayElementVarHandle(float[].class); + } + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + vhField, vh -> testInstanceFieldWrongMethodType(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field wrong method type", + vhStaticField, VarHandleTestMethodTypeFloat::testStaticFieldWrongMethodType, + false)); + + cases.add(new VarHandleAccessTestCase("Array wrong method type", + vhArray, VarHandleTestMethodTypeFloat::testArrayWrongMethodType, + false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + vhStaticField, f, VarHandleTestMethodTypeFloat::testStaticFieldWrongMethodType, + false)); + + cases.add(new MethodHandleAccessTestCase("Array wrong method type", + vhArray, f, VarHandleTestMethodTypeFloat::testArrayWrongMethodType, + false)); + } + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeFloat recv, VarHandle vh) throws Throwable { + // Get + // Incorrect argument types + checkNPE(() -> { // null receiver + float x = (float) vh.get(null); + }); + checkCCE(() -> { // receiver reference class + float x = (float) vh.get(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + float x = (float) vh.get(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + float x = (float) vh.get(); + }); + checkWMTE(() -> { // > + float x = (float) vh.get(recv, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.set(null, 1.0f); + }); + checkCCE(() -> { // receiver reference class + vh.set(Void.class, 1.0f); + }); + checkWMTE(() -> { // value reference class + vh.set(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, 1.0f); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(recv, 1.0f, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + float x = (float) vh.getVolatile(null); + }); + checkCCE(() -> { // receiver reference class + float x = (float) vh.getVolatile(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + float x = (float) vh.getVolatile(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + float x = (float) vh.getVolatile(); + }); + checkWMTE(() -> { // > + float x = (float) vh.getVolatile(recv, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setVolatile(null, 1.0f); + }); + checkCCE(() -> { // receiver reference class + vh.setVolatile(Void.class, 1.0f); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, 1.0f); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(recv, 1.0f, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + float x = (float) vh.getOpaque(null); + }); + checkCCE(() -> { // receiver reference class + float x = (float) vh.getOpaque(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + float x = (float) vh.getOpaque(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + float x = (float) vh.getOpaque(); + }); + checkWMTE(() -> { // > + float x = (float) vh.getOpaque(recv, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setOpaque(null, 1.0f); + }); + checkCCE(() -> { // receiver reference class + vh.setOpaque(Void.class, 1.0f); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, 1.0f); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(recv, 1.0f, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + float x = (float) vh.getAcquire(null); + }); + checkCCE(() -> { // receiver reference class + float x = (float) vh.getAcquire(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + float x = (float) vh.getAcquire(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + float x = (float) vh.getAcquire(); + }); + checkWMTE(() -> { // > + float x = (float) vh.getAcquire(recv, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setRelease(null, 1.0f); + }); + checkCCE(() -> { // receiver reference class + vh.setRelease(Void.class, 1.0f); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, 1.0f); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(recv, 1.0f, Void.class); + }); + + + + } + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeFloat recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + float x = (float) hs.get(am, methodType(float.class, Void.class)). + invoke(null); + }); + checkCCE(() -> { // receiver reference class + float x = (float) hs.get(am, methodType(float.class, Class.class)). + invoke(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + float x = (float) hs.get(am, methodType(float.class, int.class)). + invoke(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class)). + invoke(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeFloat.class)). + invoke(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + float x = (float) hs.get(am, methodType(float.class)). + invoke(); + }); + checkWMTE(() -> { // > + float x = (float) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class, Class.class)). + invoke(recv, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + hs.get(am, methodType(void.class, Void.class, float.class)). + invoke(null, 1.0f); + }); + checkCCE(() -> { // receiver reference class + hs.get(am, methodType(void.class, Class.class, float.class)). + invoke(Void.class, 1.0f); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, VarHandleTestMethodTypeFloat.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, float.class)). + invoke(0, 1.0f); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, VarHandleTestMethodTypeFloat.class, float.class, Class.class)). + invoke(recv, 1.0f, Void.class); + }); + } + + + } + + + static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable { + // Get + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(); + }); + // Incorrect arity + checkWMTE(() -> { // > + float x = (float) vh.get(Void.class); + }); + + + // Set + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.set(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(1.0f, Void.class); + }); + + + // GetVolatile + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(); + }); + checkWMTE(() -> { // > + float x = (float) vh.getVolatile(Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setVolatile(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(1.0f, Void.class); + }); + + + // GetOpaque + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(); + }); + checkWMTE(() -> { // > + float x = (float) vh.getOpaque(Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setOpaque(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(1.0f, Void.class); + }); + + + // GetAcquire + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(); + }); + checkWMTE(() -> { // > + float x = (float) vh.getAcquire(Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setRelease(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(1.0f, Void.class); + }); + + + + } + + static void testStaticFieldWrongMethodType(Handles hs) throws Throwable { + int i = 0; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class)). + invoke(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + // Incorrect arity + checkWMTE(() -> { // > + float x = (float) hs.get(am, methodType(Class.class)). + invoke(Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, Class.class)). + invoke(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, float.class, Class.class)). + invoke(1.0f, Void.class); + }); + } + + } + + + static void testArrayWrongMethodType(VarHandle vh) throws Throwable { + float[] array = new float[10]; + Arrays.fill(array, 1.0f); + + // Get + // Incorrect argument types + checkNPE(() -> { // null array + float x = (float) vh.get(null, 0); + }); + checkCCE(() -> { // array reference class + float x = (float) vh.get(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + float x = (float) vh.get(0, 0); + }); + checkWMTE(() -> { // index reference class + float x = (float) vh.get(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + float x = (float) vh.get(); + }); + checkWMTE(() -> { // > + float x = (float) vh.get(array, 0, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null array + vh.set(null, 0, 1.0f); + }); + checkCCE(() -> { // array reference class + vh.set(Void.class, 0, 1.0f); + }); + checkWMTE(() -> { // value reference class + vh.set(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, 0, 1.0f); + }); + checkWMTE(() -> { // index reference class + vh.set(array, Void.class, 1.0f); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(array, 0, 1.0f, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + float x = (float) vh.getVolatile(null, 0); + }); + checkCCE(() -> { // array reference class + float x = (float) vh.getVolatile(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + float x = (float) vh.getVolatile(0, 0); + }); + checkWMTE(() -> { // index reference class + float x = (float) vh.getVolatile(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + float x = (float) vh.getVolatile(); + }); + checkWMTE(() -> { // > + float x = (float) vh.getVolatile(array, 0, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + vh.setVolatile(null, 0, 1.0f); + }); + checkCCE(() -> { // array reference class + vh.setVolatile(Void.class, 0, 1.0f); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, 0, 1.0f); + }); + checkWMTE(() -> { // index reference class + vh.setVolatile(array, Void.class, 1.0f); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(array, 0, 1.0f, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + float x = (float) vh.getOpaque(null, 0); + }); + checkCCE(() -> { // array reference class + float x = (float) vh.getOpaque(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + float x = (float) vh.getOpaque(0, 0); + }); + checkWMTE(() -> { // index reference class + float x = (float) vh.getOpaque(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + float x = (float) vh.getOpaque(); + }); + checkWMTE(() -> { // > + float x = (float) vh.getOpaque(array, 0, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + vh.setOpaque(null, 0, 1.0f); + }); + checkCCE(() -> { // array reference class + vh.setOpaque(Void.class, 0, 1.0f); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, 0, 1.0f); + }); + checkWMTE(() -> { // index reference class + vh.setOpaque(array, Void.class, 1.0f); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(array, 0, 1.0f, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null array + float x = (float) vh.getAcquire(null, 0); + }); + checkCCE(() -> { // array reference class + float x = (float) vh.getAcquire(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + float x = (float) vh.getAcquire(0, 0); + }); + checkWMTE(() -> { // index reference class + float x = (float) vh.getAcquire(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + float x = (float) vh.getAcquire(); + }); + checkWMTE(() -> { // > + float x = (float) vh.getAcquire(array, 0, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null array + vh.setRelease(null, 0, 1.0f); + }); + checkCCE(() -> { // array reference class + vh.setRelease(Void.class, 0, 1.0f); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, 0, 1.0f); + }); + checkWMTE(() -> { // index reference class + vh.setRelease(array, Void.class, 1.0f); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(array, 0, 1.0f, Void.class); + }); + + + + } + + static void testArrayWrongMethodType(Handles hs) throws Throwable { + float[] array = new float[10]; + Arrays.fill(array, 1.0f); + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null array + float x = (float) hs.get(am, methodType(float.class, Void.class, int.class)). + invoke(null, 0); + }); + checkCCE(() -> { // array reference class + float x = (float) hs.get(am, methodType(float.class, Class.class, int.class)). + invoke(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + float x = (float) hs.get(am, methodType(float.class, int.class, int.class)). + invoke(0, 0); + }); + checkWMTE(() -> { // index reference class + float x = (float) hs.get(am, methodType(float.class, float[].class, Class.class)). + invoke(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class, float[].class, int.class)). + invoke(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, float[].class, int.class)). + invoke(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + float x = (float) hs.get(am, methodType(float.class)). + invoke(); + }); + checkWMTE(() -> { // > + float x = (float) hs.get(am, methodType(float.class, float[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null array + hs.get(am, methodType(void.class, Void.class, int.class, float.class)). + invoke(null, 0, 1.0f); + }); + checkCCE(() -> { // array reference class + hs.get(am, methodType(void.class, Class.class, int.class, float.class)). + invoke(Void.class, 0, 1.0f); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, float[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, int.class, float.class)). + invoke(0, 0, 1.0f); + }); + checkWMTE(() -> { // index reference class + hs.get(am, methodType(void.class, float[].class, Class.class, float.class)). + invoke(array, Void.class, 1.0f); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, float[].class, int.class, Class.class)). + invoke(array, 0, 1.0f, Void.class); + }); + } + + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java new file mode 100644 index 00000000000..fd8e57d597e --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java @@ -0,0 +1,2075 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm VarHandleTestMethodTypeInt + * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false 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.*; + +public class VarHandleTestMethodTypeInt extends VarHandleBaseTest { + static final int static_final_v = 1; + + static int static_v = 1; + + final int final_v = 1; + + int v = 1; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeInt.class, "final_v", int.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeInt.class, "v", int.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeInt.class, "static_final_v", int.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeInt.class, "static_v", int.class); + + vhArray = MethodHandles.arrayElementVarHandle(int[].class); + } + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + vhField, vh -> testInstanceFieldWrongMethodType(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field wrong method type", + vhStaticField, VarHandleTestMethodTypeInt::testStaticFieldWrongMethodType, + false)); + + cases.add(new VarHandleAccessTestCase("Array wrong method type", + vhArray, VarHandleTestMethodTypeInt::testArrayWrongMethodType, + false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + vhStaticField, f, VarHandleTestMethodTypeInt::testStaticFieldWrongMethodType, + false)); + + cases.add(new MethodHandleAccessTestCase("Array wrong method type", + vhArray, f, VarHandleTestMethodTypeInt::testArrayWrongMethodType, + false)); + } + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeInt recv, VarHandle vh) throws Throwable { + // Get + // Incorrect argument types + checkNPE(() -> { // null receiver + int x = (int) vh.get(null); + }); + checkCCE(() -> { // receiver reference class + int x = (int) vh.get(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + int x = (int) vh.get(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.get(); + }); + checkWMTE(() -> { // > + int x = (int) vh.get(recv, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.set(null, 1); + }); + checkCCE(() -> { // receiver reference class + vh.set(Void.class, 1); + }); + checkWMTE(() -> { // value reference class + vh.set(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(recv, 1, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + int x = (int) vh.getVolatile(null); + }); + checkCCE(() -> { // receiver reference class + int x = (int) vh.getVolatile(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + int x = (int) vh.getVolatile(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.getVolatile(); + }); + checkWMTE(() -> { // > + int x = (int) vh.getVolatile(recv, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setVolatile(null, 1); + }); + checkCCE(() -> { // receiver reference class + vh.setVolatile(Void.class, 1); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(recv, 1, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + int x = (int) vh.getOpaque(null); + }); + checkCCE(() -> { // receiver reference class + int x = (int) vh.getOpaque(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + int x = (int) vh.getOpaque(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.getOpaque(); + }); + checkWMTE(() -> { // > + int x = (int) vh.getOpaque(recv, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setOpaque(null, 1); + }); + checkCCE(() -> { // receiver reference class + vh.setOpaque(Void.class, 1); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(recv, 1, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + int x = (int) vh.getAcquire(null); + }); + checkCCE(() -> { // receiver reference class + int x = (int) vh.getAcquire(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + int x = (int) vh.getAcquire(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.getAcquire(); + }); + checkWMTE(() -> { // > + int x = (int) vh.getAcquire(recv, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setRelease(null, 1); + }); + checkCCE(() -> { // receiver reference class + vh.setRelease(Void.class, 1); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(recv, 1, Void.class); + }); + + + // CompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.compareAndSet(null, 1, 1); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.compareAndSet(Void.class, 1, 1); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.compareAndSet(recv, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.compareAndSet(recv, 1, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.compareAndSet(0, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.compareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.compareAndSet(recv, 1, 1, Void.class); + }); + + + // WeakCompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSet(null, 1, 1); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSet(Void.class, 1, 1); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSet(recv, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSet(recv, 1, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSet(0, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSet(recv, 1, 1, Void.class); + }); + + + // WeakCompareAndSetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetAcquire(null, 1, 1); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetAcquire(Void.class, 1, 1); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetAcquire(recv, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetAcquire(recv, 1, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetAcquire(0, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetAcquire(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetAcquire(recv, 1, 1, Void.class); + }); + + + // WeakCompareAndSetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetRelease(null, 1, 1); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetRelease(Void.class, 1, 1); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetRelease(recv, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetRelease(recv, 1, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetRelease(0, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetRelease(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetRelease(recv, 1, 1, Void.class); + }); + + + // CompareAndExchangeVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + int x = (int) vh.compareAndExchangeVolatile(null, 1, 1); + }); + checkCCE(() -> { // receiver reference class + int x = (int) vh.compareAndExchangeVolatile(Void.class, 1, 1); + }); + checkWMTE(() -> { // expected reference class + int x = (int) vh.compareAndExchangeVolatile(recv, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + int x = (int) vh.compareAndExchangeVolatile(recv, 1, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + int x = (int) vh.compareAndExchangeVolatile(0, 1, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeVolatile(recv, 1, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeVolatile(recv, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.compareAndExchangeVolatile(); + }); + checkWMTE(() -> { // > + int x = (int) vh.compareAndExchangeVolatile(recv, 1, 1, Void.class); + }); + + + // CompareAndExchangeVolatileAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + int x = (int) vh.compareAndExchangeAcquire(null, 1, 1); + }); + checkCCE(() -> { // receiver reference class + int x = (int) vh.compareAndExchangeAcquire(Void.class, 1, 1); + }); + checkWMTE(() -> { // expected reference class + int x = (int) vh.compareAndExchangeAcquire(recv, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + int x = (int) vh.compareAndExchangeAcquire(recv, 1, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + int x = (int) vh.compareAndExchangeAcquire(0, 1, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeAcquire(recv, 1, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeAcquire(recv, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.compareAndExchangeAcquire(); + }); + checkWMTE(() -> { // > + int x = (int) vh.compareAndExchangeAcquire(recv, 1, 1, Void.class); + }); + + + // CompareAndExchangeRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + int x = (int) vh.compareAndExchangeRelease(null, 1, 1); + }); + checkCCE(() -> { // receiver reference class + int x = (int) vh.compareAndExchangeRelease(Void.class, 1, 1); + }); + checkWMTE(() -> { // expected reference class + int x = (int) vh.compareAndExchangeRelease(recv, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + int x = (int) vh.compareAndExchangeRelease(recv, 1, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + int x = (int) vh.compareAndExchangeRelease(0, 1, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeRelease(recv, 1, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeRelease(recv, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.compareAndExchangeRelease(); + }); + checkWMTE(() -> { // > + int x = (int) vh.compareAndExchangeRelease(recv, 1, 1, Void.class); + }); + + + // GetAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + int x = (int) vh.getAndSet(null, 1); + }); + checkCCE(() -> { // receiver reference class + int x = (int) vh.getAndSet(Void.class, 1); + }); + checkWMTE(() -> { // value reference class + int x = (int) vh.getAndSet(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + int x = (int) vh.getAndSet(0, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.getAndSet(recv, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAndSet(recv, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.getAndSet(); + }); + checkWMTE(() -> { // > + int x = (int) vh.getAndSet(recv, 1, Void.class); + }); + + // GetAndAdd + // Incorrect argument types + checkNPE(() -> { // null receiver + int x = (int) vh.getAndAdd(null, 1); + }); + checkCCE(() -> { // receiver reference class + int x = (int) vh.getAndAdd(Void.class, 1); + }); + checkWMTE(() -> { // value reference class + int x = (int) vh.getAndAdd(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + int x = (int) vh.getAndAdd(0, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.getAndAdd(recv, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAndAdd(recv, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.getAndAdd(); + }); + checkWMTE(() -> { // > + int x = (int) vh.getAndAdd(recv, 1, Void.class); + }); + + + // AddAndGet + // Incorrect argument types + checkNPE(() -> { // null receiver + int x = (int) vh.addAndGet(null, 1); + }); + checkCCE(() -> { // receiver reference class + int x = (int) vh.addAndGet(Void.class, 1); + }); + checkWMTE(() -> { // value reference class + int x = (int) vh.addAndGet(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + int x = (int) vh.addAndGet(0, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.addAndGet(recv, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.addAndGet(recv, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.addAndGet(); + }); + checkWMTE(() -> { // > + int x = (int) vh.addAndGet(recv, 1, Void.class); + }); + } + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeInt recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + int x = (int) hs.get(am, methodType(int.class, Void.class)). + invoke(null); + }); + checkCCE(() -> { // receiver reference class + int x = (int) hs.get(am, methodType(int.class, Class.class)). + invoke(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + int x = (int) hs.get(am, methodType(int.class, int.class)). + invoke(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class)). + invoke(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class)). + invoke(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) hs.get(am, methodType(int.class)). + invoke(); + }); + checkWMTE(() -> { // > + int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class)). + invoke(recv, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + hs.get(am, methodType(void.class, Void.class, int.class)). + invoke(null, 1); + }); + checkCCE(() -> { // receiver reference class + hs.get(am, methodType(void.class, Class.class, int.class)). + invoke(Void.class, 1); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, VarHandleTestMethodTypeInt.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, int.class)). + invoke(0, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, VarHandleTestMethodTypeInt.class, int.class, Class.class)). + invoke(recv, 1, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, int.class)). + invoke(null, 1, 1); + }); + checkCCE(() -> { // receiver reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, int.class)). + invoke(Void.class, 1, 1); + }); + checkWMTE(() -> { // expected reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, Class.class, int.class)). + invoke(recv, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class, Class.class)). + invoke(recv, 1, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , int.class, int.class)). + invoke(0, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + checkWMTE(() -> { // > + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class, int.class, Class.class)). + invoke(recv, 1, 1, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkNPE(() -> { // null receiver + int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class)). + invoke(null, 1, 1); + }); + checkCCE(() -> { // receiver reference class + int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class)). + invoke(Void.class, 1, 1); + }); + checkWMTE(() -> { // expected reference class + int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class, int.class)). + invoke(recv, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class, Class.class)). + invoke(recv, 1, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + int x = (int) hs.get(am, methodType(int.class, int.class , int.class, int.class)). + invoke(0, 1, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeInt.class , int.class, int.class)). + invoke(recv, 1, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class , int.class, int.class)). + invoke(recv, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) hs.get(am, methodType(int.class)). + invoke(); + }); + checkWMTE(() -> { // > + int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class, int.class, Class.class)). + invoke(recv, 1, 1, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkNPE(() -> { // null receiver + int x = (int) hs.get(am, methodType(int.class, Void.class, int.class)). + invoke(null, 1); + }); + checkCCE(() -> { // receiver reference class + int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)). + invoke(Void.class, 1); + }); + checkWMTE(() -> { // value reference class + int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + int x = (int) hs.get(am, methodType(int.class, int.class, int.class)). + invoke(0, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeInt.class, int.class)). + invoke(recv, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class)). + invoke(recv, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) hs.get(am, methodType(int.class)). + invoke(); + }); + checkWMTE(() -> { // > + int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class)). + invoke(recv, 1, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkNPE(() -> { // null receiver + int x = (int) hs.get(am, methodType(int.class, Void.class, int.class)). + invoke(null, 1); + }); + checkCCE(() -> { // receiver reference class + int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)). + invoke(Void.class, 1); + }); + checkWMTE(() -> { // value reference class + int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + int x = (int) hs.get(am, methodType(int.class, int.class, int.class)). + invoke(0, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeInt.class, int.class)). + invoke(recv, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class)). + invoke(recv, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) hs.get(am, methodType(int.class)). + invoke(); + }); + checkWMTE(() -> { // > + int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class)). + invoke(recv, 1, Void.class); + }); + } + } + + + static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable { + // Get + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(); + }); + // Incorrect arity + checkWMTE(() -> { // > + int x = (int) vh.get(Void.class); + }); + + + // Set + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.set(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(1, Void.class); + }); + + + // GetVolatile + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(); + }); + checkWMTE(() -> { // > + int x = (int) vh.getVolatile(Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setVolatile(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(1, Void.class); + }); + + + // GetOpaque + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(); + }); + checkWMTE(() -> { // > + int x = (int) vh.getOpaque(Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setOpaque(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(1, Void.class); + }); + + + // GetAcquire + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(); + }); + checkWMTE(() -> { // > + int x = (int) vh.getAcquire(Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setRelease(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(1, Void.class); + }); + + + // CompareAndSet + // Incorrect argument types + checkWMTE(() -> { // expected reference class + boolean r = vh.compareAndSet(Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.compareAndSet(1, Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.compareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.compareAndSet(1, 1, Void.class); + }); + + + // WeakCompareAndSet + // Incorrect argument types + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSet(Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSet(1, Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSet(1, 1, Void.class); + }); + + + // WeakCompareAndSetAcquire + // Incorrect argument types + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetAcquire(Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetAcquire(1, Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetAcquire(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetAcquire(1, 1, Void.class); + }); + + + // WeakCompareAndSetRelease + // Incorrect argument types + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetRelease(Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetRelease(1, Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetRelease(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetRelease(1, 1, Void.class); + }); + + + // CompareAndExchangeVolatile + // Incorrect argument types + checkWMTE(() -> { // expected reference class + int x = (int) vh.compareAndExchangeVolatile(Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + int x = (int) vh.compareAndExchangeVolatile(1, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeVolatile(1, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeVolatile(1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.compareAndExchangeVolatile(); + }); + checkWMTE(() -> { // > + int x = (int) vh.compareAndExchangeVolatile(1, 1, Void.class); + }); + + + // CompareAndExchangeAcquire + // Incorrect argument types + checkWMTE(() -> { // expected reference class + int x = (int) vh.compareAndExchangeAcquire(Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + int x = (int) vh.compareAndExchangeAcquire(1, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeAcquire(1, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeAcquire(1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.compareAndExchangeAcquire(); + }); + checkWMTE(() -> { // > + int x = (int) vh.compareAndExchangeAcquire(1, 1, Void.class); + }); + + + // CompareAndExchangeRelease + // Incorrect argument types + checkWMTE(() -> { // expected reference class + int x = (int) vh.compareAndExchangeRelease(Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + int x = (int) vh.compareAndExchangeRelease(1, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeRelease(1, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeRelease(1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.compareAndExchangeRelease(); + }); + checkWMTE(() -> { // > + int x = (int) vh.compareAndExchangeRelease(1, 1, Void.class); + }); + + + // GetAndSet + // Incorrect argument types + checkWMTE(() -> { // value reference class + int x = (int) vh.getAndSet(Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.getAndSet(1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAndSet(1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.getAndSet(); + }); + checkWMTE(() -> { // > + int x = (int) vh.getAndSet(1, Void.class); + }); + + // GetAndAdd + // Incorrect argument types + checkWMTE(() -> { // value reference class + int x = (int) vh.getAndAdd(Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.getAndAdd(1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAndAdd(1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.getAndAdd(); + }); + checkWMTE(() -> { // > + int x = (int) vh.getAndAdd(1, Void.class); + }); + + + // AddAndGet + // Incorrect argument types + checkWMTE(() -> { // value reference class + int x = (int) vh.addAndGet(Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.addAndGet(1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.addAndGet(1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.addAndGet(); + }); + checkWMTE(() -> { // > + int x = (int) vh.addAndGet(1, Void.class); + }); + } + + static void testStaticFieldWrongMethodType(Handles hs) throws Throwable { + int i = 0; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class)). + invoke(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + // Incorrect arity + checkWMTE(() -> { // > + int x = (int) hs.get(am, methodType(Class.class)). + invoke(Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, Class.class)). + invoke(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, int.class, Class.class)). + invoke(1, Void.class); + }); + } + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + // Incorrect argument types + checkWMTE(() -> { // expected reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class)). + invoke(Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, Class.class)). + invoke(1, Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + checkWMTE(() -> { // > + boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, Class.class)). + invoke(1, 1, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + // Incorrect argument types + checkWMTE(() -> { // expected reference class + int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)). + invoke(Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + int x = (int) hs.get(am, methodType(int.class, int.class, Class.class)). + invoke(1, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, int.class, int.class)). + invoke(1, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class)). + invoke(1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) hs.get(am, methodType(int.class)). + invoke(); + }); + checkWMTE(() -> { // > + int x = (int) hs.get(am, methodType(int.class, int.class, int.class, Class.class)). + invoke(1, 1, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + // Incorrect argument types + checkWMTE(() -> { // value reference class + int x = (int) hs.get(am, methodType(int.class, Class.class)). + invoke(Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, int.class)). + invoke(1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class)). + invoke(1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) hs.get(am, methodType(int.class)). + invoke(); + }); + checkWMTE(() -> { // > + int x = (int) hs.get(am, methodType(int.class, int.class, Class.class)). + invoke(1, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + // Incorrect argument types + checkWMTE(() -> { // value reference class + int x = (int) hs.get(am, methodType(int.class, Class.class)). + invoke(Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, int.class)). + invoke(1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class)). + invoke(1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) hs.get(am, methodType(int.class)). + invoke(); + }); + checkWMTE(() -> { // > + int x = (int) hs.get(am, methodType(int.class, int.class, Class.class)). + invoke(1, Void.class); + }); + } + } + + + static void testArrayWrongMethodType(VarHandle vh) throws Throwable { + int[] array = new int[10]; + Arrays.fill(array, 1); + + // Get + // Incorrect argument types + checkNPE(() -> { // null array + int x = (int) vh.get(null, 0); + }); + checkCCE(() -> { // array reference class + int x = (int) vh.get(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + int x = (int) vh.get(0, 0); + }); + checkWMTE(() -> { // index reference class + int x = (int) vh.get(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.get(); + }); + checkWMTE(() -> { // > + int x = (int) vh.get(array, 0, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null array + vh.set(null, 0, 1); + }); + checkCCE(() -> { // array reference class + vh.set(Void.class, 0, 1); + }); + checkWMTE(() -> { // value reference class + vh.set(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, 0, 1); + }); + checkWMTE(() -> { // index reference class + vh.set(array, Void.class, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(array, 0, 1, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + int x = (int) vh.getVolatile(null, 0); + }); + checkCCE(() -> { // array reference class + int x = (int) vh.getVolatile(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + int x = (int) vh.getVolatile(0, 0); + }); + checkWMTE(() -> { // index reference class + int x = (int) vh.getVolatile(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.getVolatile(); + }); + checkWMTE(() -> { // > + int x = (int) vh.getVolatile(array, 0, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + vh.setVolatile(null, 0, 1); + }); + checkCCE(() -> { // array reference class + vh.setVolatile(Void.class, 0, 1); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, 0, 1); + }); + checkWMTE(() -> { // index reference class + vh.setVolatile(array, Void.class, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(array, 0, 1, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + int x = (int) vh.getOpaque(null, 0); + }); + checkCCE(() -> { // array reference class + int x = (int) vh.getOpaque(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + int x = (int) vh.getOpaque(0, 0); + }); + checkWMTE(() -> { // index reference class + int x = (int) vh.getOpaque(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.getOpaque(); + }); + checkWMTE(() -> { // > + int x = (int) vh.getOpaque(array, 0, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + vh.setOpaque(null, 0, 1); + }); + checkCCE(() -> { // array reference class + vh.setOpaque(Void.class, 0, 1); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, 0, 1); + }); + checkWMTE(() -> { // index reference class + vh.setOpaque(array, Void.class, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(array, 0, 1, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null array + int x = (int) vh.getAcquire(null, 0); + }); + checkCCE(() -> { // array reference class + int x = (int) vh.getAcquire(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + int x = (int) vh.getAcquire(0, 0); + }); + checkWMTE(() -> { // index reference class + int x = (int) vh.getAcquire(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.getAcquire(); + }); + checkWMTE(() -> { // > + int x = (int) vh.getAcquire(array, 0, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null array + vh.setRelease(null, 0, 1); + }); + checkCCE(() -> { // array reference class + vh.setRelease(Void.class, 0, 1); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, 0, 1); + }); + checkWMTE(() -> { // index reference class + vh.setRelease(array, Void.class, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(array, 0, 1, Void.class); + }); + + + // CompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.compareAndSet(null, 0, 1, 1); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.compareAndSet(Void.class, 0, 1, 1); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.compareAndSet(array, 0, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.compareAndSet(array, 0, 1, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.compareAndSet(0, 0, 1, 1); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.compareAndSet(array, Void.class, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.compareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.compareAndSet(array, 0, 1, 1, Void.class); + }); + + + // WeakCompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSet(null, 0, 1, 1); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSet(Void.class, 0, 1, 1); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSet(array, 0, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSet(array, 0, 1, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSet(0, 0, 1, 1); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.weakCompareAndSet(array, Void.class, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSet(array, 0, 1, 1, Void.class); + }); + + + // WeakCompareAndSetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetAcquire(null, 0, 1, 1); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, 1, 1); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetAcquire(array, 0, 1, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetAcquire(0, 0, 1, 1); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.weakCompareAndSetAcquire(array, Void.class, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetAcquire(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetAcquire(array, 0, 1, 1, Void.class); + }); + + + // WeakCompareAndSetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetRelease(null, 0, 1, 1); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetRelease(Void.class, 0, 1, 1); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetRelease(array, 0, 1, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetRelease(0, 0, 1, 1); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.weakCompareAndSetRelease(array, Void.class, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetRelease(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetRelease(array, 0, 1, 1, Void.class); + }); + + + // CompareAndExchangeVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + int x = (int) vh.compareAndExchangeVolatile(null, 0, 1, 1); + }); + checkCCE(() -> { // array reference class + int x = (int) vh.compareAndExchangeVolatile(Void.class, 0, 1, 1); + }); + checkWMTE(() -> { // expected reference class + int x = (int) vh.compareAndExchangeVolatile(array, 0, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + int x = (int) vh.compareAndExchangeVolatile(array, 0, 1, Void.class); + }); + checkWMTE(() -> { // array primitive class + int x = (int) vh.compareAndExchangeVolatile(0, 0, 1, 1); + }); + checkWMTE(() -> { // index reference class + int x = (int) vh.compareAndExchangeVolatile(array, Void.class, 1, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeVolatile(array, 0, 1, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeVolatile(array, 0, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.compareAndExchangeVolatile(); + }); + checkWMTE(() -> { // > + int x = (int) vh.compareAndExchangeVolatile(array, 0, 1, 1, Void.class); + }); + + + // CompareAndExchangeAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + int x = (int) vh.compareAndExchangeAcquire(null, 0, 1, 1); + }); + checkCCE(() -> { // array reference class + int x = (int) vh.compareAndExchangeAcquire(Void.class, 0, 1, 1); + }); + checkWMTE(() -> { // expected reference class + int x = (int) vh.compareAndExchangeAcquire(array, 0, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + int x = (int) vh.compareAndExchangeAcquire(array, 0, 1, Void.class); + }); + checkWMTE(() -> { // array primitive class + int x = (int) vh.compareAndExchangeAcquire(0, 0, 1, 1); + }); + checkWMTE(() -> { // index reference class + int x = (int) vh.compareAndExchangeAcquire(array, Void.class, 1, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeAcquire(array, 0, 1, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeAcquire(array, 0, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.compareAndExchangeAcquire(); + }); + checkWMTE(() -> { // > + int x = (int) vh.compareAndExchangeAcquire(array, 0, 1, 1, Void.class); + }); + + + // CompareAndExchangeRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + int x = (int) vh.compareAndExchangeRelease(null, 0, 1, 1); + }); + checkCCE(() -> { // array reference class + int x = (int) vh.compareAndExchangeRelease(Void.class, 0, 1, 1); + }); + checkWMTE(() -> { // expected reference class + int x = (int) vh.compareAndExchangeRelease(array, 0, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + int x = (int) vh.compareAndExchangeRelease(array, 0, 1, Void.class); + }); + checkWMTE(() -> { // array primitive class + int x = (int) vh.compareAndExchangeRelease(0, 0, 1, 1); + }); + checkWMTE(() -> { // index reference class + int x = (int) vh.compareAndExchangeRelease(array, Void.class, 1, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeRelease(array, 0, 1, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeRelease(array, 0, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.compareAndExchangeRelease(); + }); + checkWMTE(() -> { // > + int x = (int) vh.compareAndExchangeRelease(array, 0, 1, 1, Void.class); + }); + + + // GetAndSet + // Incorrect argument types + checkNPE(() -> { // null array + int x = (int) vh.getAndSet(null, 0, 1); + }); + checkCCE(() -> { // array reference class + int x = (int) vh.getAndSet(Void.class, 0, 1); + }); + checkWMTE(() -> { // value reference class + int x = (int) vh.getAndSet(array, 0, Void.class); + }); + checkWMTE(() -> { // reciarrayever primitive class + int x = (int) vh.getAndSet(0, 0, 1); + }); + checkWMTE(() -> { // index reference class + int x = (int) vh.getAndSet(array, Void.class, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.getAndSet(array, 0, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAndSet(array, 0, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.getAndSet(); + }); + checkWMTE(() -> { // > + int x = (int) vh.getAndSet(array, 0, 1, Void.class); + }); + + // GetAndAdd + // Incorrect argument types + checkNPE(() -> { // null array + int x = (int) vh.getAndAdd(null, 0, 1); + }); + checkCCE(() -> { // array reference class + int x = (int) vh.getAndAdd(Void.class, 0, 1); + }); + checkWMTE(() -> { // value reference class + int x = (int) vh.getAndAdd(array, 0, Void.class); + }); + checkWMTE(() -> { // array primitive class + int x = (int) vh.getAndAdd(0, 0, 1); + }); + checkWMTE(() -> { // index reference class + int x = (int) vh.getAndAdd(array, Void.class, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.getAndAdd(array, 0, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAndAdd(array, 0, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.getAndAdd(); + }); + checkWMTE(() -> { // > + int x = (int) vh.getAndAdd(array, 0, 1, Void.class); + }); + + + // AddAndGet + // Incorrect argument types + checkNPE(() -> { // null array + int x = (int) vh.addAndGet(null, 0, 1); + }); + checkCCE(() -> { // array reference class + int x = (int) vh.addAndGet(Void.class, 0, 1); + }); + checkWMTE(() -> { // value reference class + int x = (int) vh.addAndGet(array, 0, Void.class); + }); + checkWMTE(() -> { // array primitive class + int x = (int) vh.addAndGet(0, 0, 1); + }); + checkWMTE(() -> { // index reference class + int x = (int) vh.addAndGet(array, Void.class, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.addAndGet(array, 0, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.addAndGet(array, 0, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) vh.addAndGet(); + }); + checkWMTE(() -> { // > + int x = (int) vh.addAndGet(array, 0, 1, Void.class); + }); + } + + static void testArrayWrongMethodType(Handles hs) throws Throwable { + int[] array = new int[10]; + Arrays.fill(array, 1); + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null array + int x = (int) hs.get(am, methodType(int.class, Void.class, int.class)). + invoke(null, 0); + }); + checkCCE(() -> { // array reference class + int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)). + invoke(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + int x = (int) hs.get(am, methodType(int.class, int.class, int.class)). + invoke(0, 0); + }); + checkWMTE(() -> { // index reference class + int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class)). + invoke(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class, int[].class, int.class)). + invoke(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class)). + invoke(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) hs.get(am, methodType(int.class)). + invoke(); + }); + checkWMTE(() -> { // > + int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null array + hs.get(am, methodType(void.class, Void.class, int.class, int.class)). + invoke(null, 0, 1); + }); + checkCCE(() -> { // array reference class + hs.get(am, methodType(void.class, Class.class, int.class, int.class)). + invoke(Void.class, 0, 1); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, int[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, int.class, int.class)). + invoke(0, 0, 1); + }); + checkWMTE(() -> { // index reference class + hs.get(am, methodType(void.class, int[].class, Class.class, int.class)). + invoke(array, Void.class, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, int[].class, int.class, Class.class)). + invoke(array, 0, 1, Void.class); + }); + } + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, int.class, int.class)). + invoke(null, 0, 1, 1); + }); + checkCCE(() -> { // receiver reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, int.class, int.class)). + invoke(Void.class, 0, 1, 1); + }); + checkWMTE(() -> { // expected reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, Class.class, int.class)). + invoke(array, 0, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class, Class.class)). + invoke(array, 0, 1, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, int.class, int.class)). + invoke(0, 0, 1, 1); + }); + checkWMTE(() -> { // index reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, Class.class, int.class, int.class)). + invoke(array, Void.class, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + checkWMTE(() -> { // > + boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class, int.class, Class.class)). + invoke(array, 0, 1, 1, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class, int.class)). + invoke(null, 0, 1, 1); + }); + checkCCE(() -> { // array reference class + int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class, int.class)). + invoke(Void.class, 0, 1, 1); + }); + checkWMTE(() -> { // expected reference class + int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class, int.class)). + invoke(array, 0, Void.class, 1); + }); + checkWMTE(() -> { // actual reference class + int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, Class.class)). + invoke(array, 0, 1, Void.class); + }); + checkWMTE(() -> { // array primitive class + int x = (int) hs.get(am, methodType(int.class, int.class, int.class, int.class, int.class)). + invoke(0, 0, 1, 1); + }); + checkWMTE(() -> { // index reference class + int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class, int.class, int.class)). + invoke(array, Void.class, 1, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, int[].class, int.class, int.class, int.class)). + invoke(array, 0, 1, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class, int.class)). + invoke(array, 0, 1, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) hs.get(am, methodType(int.class)). + invoke(); + }); + checkWMTE(() -> { // > + int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, int.class, Class.class)). + invoke(array, 0, 1, 1, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + // Incorrect argument types + checkNPE(() -> { // null array + int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class)). + invoke(null, 0, 1); + }); + checkCCE(() -> { // array reference class + int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class)). + invoke(Void.class, 0, 1); + }); + checkWMTE(() -> { // value reference class + int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // array primitive class + int x = (int) hs.get(am, methodType(int.class, int.class, int.class, int.class)). + invoke(0, 0, 1); + }); + checkWMTE(() -> { // index reference class + int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class, int.class)). + invoke(array, Void.class, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, int[].class, int.class, int.class)). + invoke(array, 0, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class)). + invoke(array, 0, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) hs.get(am, methodType(int.class)). + invoke(); + }); + checkWMTE(() -> { // > + int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, Class.class)). + invoke(array, 0, 1, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + // Incorrect argument types + checkNPE(() -> { // null array + int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class)). + invoke(null, 0, 1); + }); + checkCCE(() -> { // array reference class + int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class)). + invoke(Void.class, 0, 1); + }); + checkWMTE(() -> { // value reference class + int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // array primitive class + int x = (int) hs.get(am, methodType(int.class, int.class, int.class, int.class)). + invoke(0, 0, 1); + }); + checkWMTE(() -> { // index reference class + int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class, int.class)). + invoke(array, Void.class, 1); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, int[].class, int.class, int.class)). + invoke(array, 0, 1); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class)). + invoke(array, 0, 1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + int x = (int) hs.get(am, methodType(int.class)). + invoke(); + }); + checkWMTE(() -> { // > + int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, Class.class)). + invoke(array, 0, 1, Void.class); + }); + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java new file mode 100644 index 00000000000..91cbcf5f3be --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java @@ -0,0 +1,2075 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm VarHandleTestMethodTypeLong + * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false 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.*; + +public class VarHandleTestMethodTypeLong extends VarHandleBaseTest { + static final long static_final_v = 1L; + + static long static_v = 1L; + + final long final_v = 1L; + + long v = 1L; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeLong.class, "final_v", long.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeLong.class, "v", long.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeLong.class, "static_final_v", long.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeLong.class, "static_v", long.class); + + vhArray = MethodHandles.arrayElementVarHandle(long[].class); + } + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + vhField, vh -> testInstanceFieldWrongMethodType(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field wrong method type", + vhStaticField, VarHandleTestMethodTypeLong::testStaticFieldWrongMethodType, + false)); + + cases.add(new VarHandleAccessTestCase("Array wrong method type", + vhArray, VarHandleTestMethodTypeLong::testArrayWrongMethodType, + false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + vhStaticField, f, VarHandleTestMethodTypeLong::testStaticFieldWrongMethodType, + false)); + + cases.add(new MethodHandleAccessTestCase("Array wrong method type", + vhArray, f, VarHandleTestMethodTypeLong::testArrayWrongMethodType, + false)); + } + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeLong recv, VarHandle vh) throws Throwable { + // Get + // Incorrect argument types + checkNPE(() -> { // null receiver + long x = (long) vh.get(null); + }); + checkCCE(() -> { // receiver reference class + long x = (long) vh.get(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + long x = (long) vh.get(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.get(); + }); + checkWMTE(() -> { // > + long x = (long) vh.get(recv, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.set(null, 1L); + }); + checkCCE(() -> { // receiver reference class + vh.set(Void.class, 1L); + }); + checkWMTE(() -> { // value reference class + vh.set(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(recv, 1L, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + long x = (long) vh.getVolatile(null); + }); + checkCCE(() -> { // receiver reference class + long x = (long) vh.getVolatile(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + long x = (long) vh.getVolatile(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.getVolatile(); + }); + checkWMTE(() -> { // > + long x = (long) vh.getVolatile(recv, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setVolatile(null, 1L); + }); + checkCCE(() -> { // receiver reference class + vh.setVolatile(Void.class, 1L); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(recv, 1L, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + long x = (long) vh.getOpaque(null); + }); + checkCCE(() -> { // receiver reference class + long x = (long) vh.getOpaque(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + long x = (long) vh.getOpaque(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.getOpaque(); + }); + checkWMTE(() -> { // > + long x = (long) vh.getOpaque(recv, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setOpaque(null, 1L); + }); + checkCCE(() -> { // receiver reference class + vh.setOpaque(Void.class, 1L); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(recv, 1L, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + long x = (long) vh.getAcquire(null); + }); + checkCCE(() -> { // receiver reference class + long x = (long) vh.getAcquire(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + long x = (long) vh.getAcquire(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.getAcquire(); + }); + checkWMTE(() -> { // > + long x = (long) vh.getAcquire(recv, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setRelease(null, 1L); + }); + checkCCE(() -> { // receiver reference class + vh.setRelease(Void.class, 1L); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(recv, 1L, Void.class); + }); + + + // CompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.compareAndSet(null, 1L, 1L); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.compareAndSet(Void.class, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.compareAndSet(recv, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.compareAndSet(recv, 1L, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.compareAndSet(0, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.compareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.compareAndSet(recv, 1L, 1L, Void.class); + }); + + + // WeakCompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSet(null, 1L, 1L); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSet(Void.class, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSet(recv, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSet(recv, 1L, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSet(0, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSet(recv, 1L, 1L, Void.class); + }); + + + // WeakCompareAndSetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetAcquire(null, 1L, 1L); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetAcquire(Void.class, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetAcquire(recv, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetAcquire(recv, 1L, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetAcquire(0, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetAcquire(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetAcquire(recv, 1L, 1L, Void.class); + }); + + + // WeakCompareAndSetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetRelease(null, 1L, 1L); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetRelease(Void.class, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetRelease(recv, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetRelease(recv, 1L, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetRelease(0, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetRelease(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetRelease(recv, 1L, 1L, Void.class); + }); + + + // CompareAndExchangeVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + long x = (long) vh.compareAndExchangeVolatile(null, 1L, 1L); + }); + checkCCE(() -> { // receiver reference class + long x = (long) vh.compareAndExchangeVolatile(Void.class, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + long x = (long) vh.compareAndExchangeVolatile(recv, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + long x = (long) vh.compareAndExchangeVolatile(recv, 1L, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + long x = (long) vh.compareAndExchangeVolatile(0, 1L, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeVolatile(recv, 1L, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeVolatile(recv, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.compareAndExchangeVolatile(); + }); + checkWMTE(() -> { // > + long x = (long) vh.compareAndExchangeVolatile(recv, 1L, 1L, Void.class); + }); + + + // CompareAndExchangeVolatileAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + long x = (long) vh.compareAndExchangeAcquire(null, 1L, 1L); + }); + checkCCE(() -> { // receiver reference class + long x = (long) vh.compareAndExchangeAcquire(Void.class, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + long x = (long) vh.compareAndExchangeAcquire(recv, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + long x = (long) vh.compareAndExchangeAcquire(recv, 1L, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + long x = (long) vh.compareAndExchangeAcquire(0, 1L, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeAcquire(recv, 1L, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeAcquire(recv, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.compareAndExchangeAcquire(); + }); + checkWMTE(() -> { // > + long x = (long) vh.compareAndExchangeAcquire(recv, 1L, 1L, Void.class); + }); + + + // CompareAndExchangeRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + long x = (long) vh.compareAndExchangeRelease(null, 1L, 1L); + }); + checkCCE(() -> { // receiver reference class + long x = (long) vh.compareAndExchangeRelease(Void.class, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + long x = (long) vh.compareAndExchangeRelease(recv, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + long x = (long) vh.compareAndExchangeRelease(recv, 1L, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + long x = (long) vh.compareAndExchangeRelease(0, 1L, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeRelease(recv, 1L, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeRelease(recv, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.compareAndExchangeRelease(); + }); + checkWMTE(() -> { // > + long x = (long) vh.compareAndExchangeRelease(recv, 1L, 1L, Void.class); + }); + + + // GetAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + long x = (long) vh.getAndSet(null, 1L); + }); + checkCCE(() -> { // receiver reference class + long x = (long) vh.getAndSet(Void.class, 1L); + }); + checkWMTE(() -> { // value reference class + long x = (long) vh.getAndSet(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + long x = (long) vh.getAndSet(0, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.getAndSet(recv, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAndSet(recv, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.getAndSet(); + }); + checkWMTE(() -> { // > + long x = (long) vh.getAndSet(recv, 1L, Void.class); + }); + + // GetAndAdd + // Incorrect argument types + checkNPE(() -> { // null receiver + long x = (long) vh.getAndAdd(null, 1L); + }); + checkCCE(() -> { // receiver reference class + long x = (long) vh.getAndAdd(Void.class, 1L); + }); + checkWMTE(() -> { // value reference class + long x = (long) vh.getAndAdd(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + long x = (long) vh.getAndAdd(0, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.getAndAdd(recv, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAndAdd(recv, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.getAndAdd(); + }); + checkWMTE(() -> { // > + long x = (long) vh.getAndAdd(recv, 1L, Void.class); + }); + + + // AddAndGet + // Incorrect argument types + checkNPE(() -> { // null receiver + long x = (long) vh.addAndGet(null, 1L); + }); + checkCCE(() -> { // receiver reference class + long x = (long) vh.addAndGet(Void.class, 1L); + }); + checkWMTE(() -> { // value reference class + long x = (long) vh.addAndGet(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + long x = (long) vh.addAndGet(0, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.addAndGet(recv, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.addAndGet(recv, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.addAndGet(); + }); + checkWMTE(() -> { // > + long x = (long) vh.addAndGet(recv, 1L, Void.class); + }); + } + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeLong recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + long x = (long) hs.get(am, methodType(long.class, Void.class)). + invoke(null); + }); + checkCCE(() -> { // receiver reference class + long x = (long) hs.get(am, methodType(long.class, Class.class)). + invoke(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + long x = (long) hs.get(am, methodType(long.class, int.class)). + invoke(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class)). + invoke(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class)). + invoke(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) hs.get(am, methodType(long.class)). + invoke(); + }); + checkWMTE(() -> { // > + long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class)). + invoke(recv, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + hs.get(am, methodType(void.class, Void.class, long.class)). + invoke(null, 1L); + }); + checkCCE(() -> { // receiver reference class + hs.get(am, methodType(void.class, Class.class, long.class)). + invoke(Void.class, 1L); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, VarHandleTestMethodTypeLong.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, long.class)). + invoke(0, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, VarHandleTestMethodTypeLong.class, long.class, Class.class)). + invoke(recv, 1L, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, long.class, long.class)). + invoke(null, 1L, 1L); + }); + checkCCE(() -> { // receiver reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, long.class, long.class)). + invoke(Void.class, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, Class.class, long.class)). + invoke(recv, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class, Class.class)). + invoke(recv, 1L, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , long.class, long.class)). + invoke(0, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + checkWMTE(() -> { // > + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class, long.class, Class.class)). + invoke(recv, 1L, 1L, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkNPE(() -> { // null receiver + long x = (long) hs.get(am, methodType(long.class, Void.class, long.class, long.class)). + invoke(null, 1L, 1L); + }); + checkCCE(() -> { // receiver reference class + long x = (long) hs.get(am, methodType(long.class, Class.class, long.class, long.class)). + invoke(Void.class, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class, long.class)). + invoke(recv, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class, Class.class)). + invoke(recv, 1L, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + long x = (long) hs.get(am, methodType(long.class, int.class , long.class, long.class)). + invoke(0, 1L, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeLong.class , long.class, long.class)). + invoke(recv, 1L, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class , long.class, long.class)). + invoke(recv, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) hs.get(am, methodType(long.class)). + invoke(); + }); + checkWMTE(() -> { // > + long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class, long.class, Class.class)). + invoke(recv, 1L, 1L, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkNPE(() -> { // null receiver + long x = (long) hs.get(am, methodType(long.class, Void.class, long.class)). + invoke(null, 1L); + }); + checkCCE(() -> { // receiver reference class + long x = (long) hs.get(am, methodType(long.class, Class.class, long.class)). + invoke(Void.class, 1L); + }); + checkWMTE(() -> { // value reference class + long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + long x = (long) hs.get(am, methodType(long.class, int.class, long.class)). + invoke(0, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeLong.class, long.class)). + invoke(recv, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class)). + invoke(recv, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) hs.get(am, methodType(long.class)). + invoke(); + }); + checkWMTE(() -> { // > + long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class)). + invoke(recv, 1L, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkNPE(() -> { // null receiver + long x = (long) hs.get(am, methodType(long.class, Void.class, long.class)). + invoke(null, 1L); + }); + checkCCE(() -> { // receiver reference class + long x = (long) hs.get(am, methodType(long.class, Class.class, long.class)). + invoke(Void.class, 1L); + }); + checkWMTE(() -> { // value reference class + long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + long x = (long) hs.get(am, methodType(long.class, int.class, long.class)). + invoke(0, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeLong.class, long.class)). + invoke(recv, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class)). + invoke(recv, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) hs.get(am, methodType(long.class)). + invoke(); + }); + checkWMTE(() -> { // > + long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class)). + invoke(recv, 1L, Void.class); + }); + } + } + + + static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable { + // Get + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(); + }); + // Incorrect arity + checkWMTE(() -> { // > + long x = (long) vh.get(Void.class); + }); + + + // Set + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.set(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(1L, Void.class); + }); + + + // GetVolatile + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(); + }); + checkWMTE(() -> { // > + long x = (long) vh.getVolatile(Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setVolatile(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(1L, Void.class); + }); + + + // GetOpaque + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(); + }); + checkWMTE(() -> { // > + long x = (long) vh.getOpaque(Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setOpaque(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(1L, Void.class); + }); + + + // GetAcquire + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(); + }); + checkWMTE(() -> { // > + long x = (long) vh.getAcquire(Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setRelease(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(1L, Void.class); + }); + + + // CompareAndSet + // Incorrect argument types + checkWMTE(() -> { // expected reference class + boolean r = vh.compareAndSet(Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.compareAndSet(1L, Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.compareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.compareAndSet(1L, 1L, Void.class); + }); + + + // WeakCompareAndSet + // Incorrect argument types + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSet(Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSet(1L, Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSet(1L, 1L, Void.class); + }); + + + // WeakCompareAndSetAcquire + // Incorrect argument types + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetAcquire(Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetAcquire(1L, Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetAcquire(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetAcquire(1L, 1L, Void.class); + }); + + + // WeakCompareAndSetRelease + // Incorrect argument types + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetRelease(Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetRelease(1L, Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetRelease(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetRelease(1L, 1L, Void.class); + }); + + + // CompareAndExchangeVolatile + // Incorrect argument types + checkWMTE(() -> { // expected reference class + long x = (long) vh.compareAndExchangeVolatile(Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + long x = (long) vh.compareAndExchangeVolatile(1L, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeVolatile(1L, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeVolatile(1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.compareAndExchangeVolatile(); + }); + checkWMTE(() -> { // > + long x = (long) vh.compareAndExchangeVolatile(1L, 1L, Void.class); + }); + + + // CompareAndExchangeAcquire + // Incorrect argument types + checkWMTE(() -> { // expected reference class + long x = (long) vh.compareAndExchangeAcquire(Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + long x = (long) vh.compareAndExchangeAcquire(1L, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeAcquire(1L, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeAcquire(1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.compareAndExchangeAcquire(); + }); + checkWMTE(() -> { // > + long x = (long) vh.compareAndExchangeAcquire(1L, 1L, Void.class); + }); + + + // CompareAndExchangeRelease + // Incorrect argument types + checkWMTE(() -> { // expected reference class + long x = (long) vh.compareAndExchangeRelease(Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + long x = (long) vh.compareAndExchangeRelease(1L, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeRelease(1L, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeRelease(1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.compareAndExchangeRelease(); + }); + checkWMTE(() -> { // > + long x = (long) vh.compareAndExchangeRelease(1L, 1L, Void.class); + }); + + + // GetAndSet + // Incorrect argument types + checkWMTE(() -> { // value reference class + long x = (long) vh.getAndSet(Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.getAndSet(1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAndSet(1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.getAndSet(); + }); + checkWMTE(() -> { // > + long x = (long) vh.getAndSet(1L, Void.class); + }); + + // GetAndAdd + // Incorrect argument types + checkWMTE(() -> { // value reference class + long x = (long) vh.getAndAdd(Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.getAndAdd(1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAndAdd(1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.getAndAdd(); + }); + checkWMTE(() -> { // > + long x = (long) vh.getAndAdd(1L, Void.class); + }); + + + // AddAndGet + // Incorrect argument types + checkWMTE(() -> { // value reference class + long x = (long) vh.addAndGet(Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.addAndGet(1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.addAndGet(1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.addAndGet(); + }); + checkWMTE(() -> { // > + long x = (long) vh.addAndGet(1L, Void.class); + }); + } + + static void testStaticFieldWrongMethodType(Handles hs) throws Throwable { + int i = 0; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class)). + invoke(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + // Incorrect arity + checkWMTE(() -> { // > + long x = (long) hs.get(am, methodType(Class.class)). + invoke(Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, Class.class)). + invoke(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, long.class, Class.class)). + invoke(1L, Void.class); + }); + } + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + // Incorrect argument types + checkWMTE(() -> { // expected reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, long.class)). + invoke(Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, long.class, Class.class)). + invoke(1L, Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + checkWMTE(() -> { // > + boolean r = (boolean) hs.get(am, methodType(boolean.class, long.class, long.class, Class.class)). + invoke(1L, 1L, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + // Incorrect argument types + checkWMTE(() -> { // expected reference class + long x = (long) hs.get(am, methodType(long.class, Class.class, long.class)). + invoke(Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + long x = (long) hs.get(am, methodType(long.class, long.class, Class.class)). + invoke(1L, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, long.class, long.class)). + invoke(1L, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, long.class, long.class)). + invoke(1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) hs.get(am, methodType(long.class)). + invoke(); + }); + checkWMTE(() -> { // > + long x = (long) hs.get(am, methodType(long.class, long.class, long.class, Class.class)). + invoke(1L, 1L, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + // Incorrect argument types + checkWMTE(() -> { // value reference class + long x = (long) hs.get(am, methodType(long.class, Class.class)). + invoke(Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, long.class)). + invoke(1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, long.class)). + invoke(1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) hs.get(am, methodType(long.class)). + invoke(); + }); + checkWMTE(() -> { // > + long x = (long) hs.get(am, methodType(long.class, long.class, Class.class)). + invoke(1L, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + // Incorrect argument types + checkWMTE(() -> { // value reference class + long x = (long) hs.get(am, methodType(long.class, Class.class)). + invoke(Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, long.class)). + invoke(1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, long.class)). + invoke(1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) hs.get(am, methodType(long.class)). + invoke(); + }); + checkWMTE(() -> { // > + long x = (long) hs.get(am, methodType(long.class, long.class, Class.class)). + invoke(1L, Void.class); + }); + } + } + + + static void testArrayWrongMethodType(VarHandle vh) throws Throwable { + long[] array = new long[10]; + Arrays.fill(array, 1L); + + // Get + // Incorrect argument types + checkNPE(() -> { // null array + long x = (long) vh.get(null, 0); + }); + checkCCE(() -> { // array reference class + long x = (long) vh.get(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + long x = (long) vh.get(0, 0); + }); + checkWMTE(() -> { // index reference class + long x = (long) vh.get(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.get(); + }); + checkWMTE(() -> { // > + long x = (long) vh.get(array, 0, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null array + vh.set(null, 0, 1L); + }); + checkCCE(() -> { // array reference class + vh.set(Void.class, 0, 1L); + }); + checkWMTE(() -> { // value reference class + vh.set(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, 0, 1L); + }); + checkWMTE(() -> { // index reference class + vh.set(array, Void.class, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(array, 0, 1L, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + long x = (long) vh.getVolatile(null, 0); + }); + checkCCE(() -> { // array reference class + long x = (long) vh.getVolatile(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + long x = (long) vh.getVolatile(0, 0); + }); + checkWMTE(() -> { // index reference class + long x = (long) vh.getVolatile(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.getVolatile(); + }); + checkWMTE(() -> { // > + long x = (long) vh.getVolatile(array, 0, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + vh.setVolatile(null, 0, 1L); + }); + checkCCE(() -> { // array reference class + vh.setVolatile(Void.class, 0, 1L); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, 0, 1L); + }); + checkWMTE(() -> { // index reference class + vh.setVolatile(array, Void.class, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(array, 0, 1L, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + long x = (long) vh.getOpaque(null, 0); + }); + checkCCE(() -> { // array reference class + long x = (long) vh.getOpaque(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + long x = (long) vh.getOpaque(0, 0); + }); + checkWMTE(() -> { // index reference class + long x = (long) vh.getOpaque(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.getOpaque(); + }); + checkWMTE(() -> { // > + long x = (long) vh.getOpaque(array, 0, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + vh.setOpaque(null, 0, 1L); + }); + checkCCE(() -> { // array reference class + vh.setOpaque(Void.class, 0, 1L); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, 0, 1L); + }); + checkWMTE(() -> { // index reference class + vh.setOpaque(array, Void.class, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(array, 0, 1L, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null array + long x = (long) vh.getAcquire(null, 0); + }); + checkCCE(() -> { // array reference class + long x = (long) vh.getAcquire(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + long x = (long) vh.getAcquire(0, 0); + }); + checkWMTE(() -> { // index reference class + long x = (long) vh.getAcquire(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.getAcquire(); + }); + checkWMTE(() -> { // > + long x = (long) vh.getAcquire(array, 0, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null array + vh.setRelease(null, 0, 1L); + }); + checkCCE(() -> { // array reference class + vh.setRelease(Void.class, 0, 1L); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, 0, 1L); + }); + checkWMTE(() -> { // index reference class + vh.setRelease(array, Void.class, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(array, 0, 1L, Void.class); + }); + + + // CompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.compareAndSet(null, 0, 1L, 1L); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.compareAndSet(Void.class, 0, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.compareAndSet(array, 0, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.compareAndSet(array, 0, 1L, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.compareAndSet(0, 0, 1L, 1L); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.compareAndSet(array, Void.class, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.compareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.compareAndSet(array, 0, 1L, 1L, Void.class); + }); + + + // WeakCompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSet(null, 0, 1L, 1L); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSet(Void.class, 0, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSet(array, 0, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSet(array, 0, 1L, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSet(0, 0, 1L, 1L); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.weakCompareAndSet(array, Void.class, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSet(array, 0, 1L, 1L, Void.class); + }); + + + // WeakCompareAndSetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetAcquire(null, 0, 1L, 1L); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetAcquire(array, 0, 1L, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetAcquire(0, 0, 1L, 1L); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.weakCompareAndSetAcquire(array, Void.class, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetAcquire(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetAcquire(array, 0, 1L, 1L, Void.class); + }); + + + // WeakCompareAndSetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetRelease(null, 0, 1L, 1L); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetRelease(Void.class, 0, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetRelease(array, 0, 1L, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetRelease(0, 0, 1L, 1L); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.weakCompareAndSetRelease(array, Void.class, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetRelease(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetRelease(array, 0, 1L, 1L, Void.class); + }); + + + // CompareAndExchangeVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + long x = (long) vh.compareAndExchangeVolatile(null, 0, 1L, 1L); + }); + checkCCE(() -> { // array reference class + long x = (long) vh.compareAndExchangeVolatile(Void.class, 0, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + long x = (long) vh.compareAndExchangeVolatile(array, 0, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + long x = (long) vh.compareAndExchangeVolatile(array, 0, 1L, Void.class); + }); + checkWMTE(() -> { // array primitive class + long x = (long) vh.compareAndExchangeVolatile(0, 0, 1L, 1L); + }); + checkWMTE(() -> { // index reference class + long x = (long) vh.compareAndExchangeVolatile(array, Void.class, 1L, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeVolatile(array, 0, 1L, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeVolatile(array, 0, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.compareAndExchangeVolatile(); + }); + checkWMTE(() -> { // > + long x = (long) vh.compareAndExchangeVolatile(array, 0, 1L, 1L, Void.class); + }); + + + // CompareAndExchangeAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + long x = (long) vh.compareAndExchangeAcquire(null, 0, 1L, 1L); + }); + checkCCE(() -> { // array reference class + long x = (long) vh.compareAndExchangeAcquire(Void.class, 0, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + long x = (long) vh.compareAndExchangeAcquire(array, 0, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + long x = (long) vh.compareAndExchangeAcquire(array, 0, 1L, Void.class); + }); + checkWMTE(() -> { // array primitive class + long x = (long) vh.compareAndExchangeAcquire(0, 0, 1L, 1L); + }); + checkWMTE(() -> { // index reference class + long x = (long) vh.compareAndExchangeAcquire(array, Void.class, 1L, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeAcquire(array, 0, 1L, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeAcquire(array, 0, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.compareAndExchangeAcquire(); + }); + checkWMTE(() -> { // > + long x = (long) vh.compareAndExchangeAcquire(array, 0, 1L, 1L, Void.class); + }); + + + // CompareAndExchangeRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + long x = (long) vh.compareAndExchangeRelease(null, 0, 1L, 1L); + }); + checkCCE(() -> { // array reference class + long x = (long) vh.compareAndExchangeRelease(Void.class, 0, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + long x = (long) vh.compareAndExchangeRelease(array, 0, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + long x = (long) vh.compareAndExchangeRelease(array, 0, 1L, Void.class); + }); + checkWMTE(() -> { // array primitive class + long x = (long) vh.compareAndExchangeRelease(0, 0, 1L, 1L); + }); + checkWMTE(() -> { // index reference class + long x = (long) vh.compareAndExchangeRelease(array, Void.class, 1L, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeRelease(array, 0, 1L, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeRelease(array, 0, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.compareAndExchangeRelease(); + }); + checkWMTE(() -> { // > + long x = (long) vh.compareAndExchangeRelease(array, 0, 1L, 1L, Void.class); + }); + + + // GetAndSet + // Incorrect argument types + checkNPE(() -> { // null array + long x = (long) vh.getAndSet(null, 0, 1L); + }); + checkCCE(() -> { // array reference class + long x = (long) vh.getAndSet(Void.class, 0, 1L); + }); + checkWMTE(() -> { // value reference class + long x = (long) vh.getAndSet(array, 0, Void.class); + }); + checkWMTE(() -> { // reciarrayever primitive class + long x = (long) vh.getAndSet(0, 0, 1L); + }); + checkWMTE(() -> { // index reference class + long x = (long) vh.getAndSet(array, Void.class, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.getAndSet(array, 0, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAndSet(array, 0, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.getAndSet(); + }); + checkWMTE(() -> { // > + long x = (long) vh.getAndSet(array, 0, 1L, Void.class); + }); + + // GetAndAdd + // Incorrect argument types + checkNPE(() -> { // null array + long x = (long) vh.getAndAdd(null, 0, 1L); + }); + checkCCE(() -> { // array reference class + long x = (long) vh.getAndAdd(Void.class, 0, 1L); + }); + checkWMTE(() -> { // value reference class + long x = (long) vh.getAndAdd(array, 0, Void.class); + }); + checkWMTE(() -> { // array primitive class + long x = (long) vh.getAndAdd(0, 0, 1L); + }); + checkWMTE(() -> { // index reference class + long x = (long) vh.getAndAdd(array, Void.class, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.getAndAdd(array, 0, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAndAdd(array, 0, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.getAndAdd(); + }); + checkWMTE(() -> { // > + long x = (long) vh.getAndAdd(array, 0, 1L, Void.class); + }); + + + // AddAndGet + // Incorrect argument types + checkNPE(() -> { // null array + long x = (long) vh.addAndGet(null, 0, 1L); + }); + checkCCE(() -> { // array reference class + long x = (long) vh.addAndGet(Void.class, 0, 1L); + }); + checkWMTE(() -> { // value reference class + long x = (long) vh.addAndGet(array, 0, Void.class); + }); + checkWMTE(() -> { // array primitive class + long x = (long) vh.addAndGet(0, 0, 1L); + }); + checkWMTE(() -> { // index reference class + long x = (long) vh.addAndGet(array, Void.class, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) vh.addAndGet(array, 0, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.addAndGet(array, 0, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) vh.addAndGet(); + }); + checkWMTE(() -> { // > + long x = (long) vh.addAndGet(array, 0, 1L, Void.class); + }); + } + + static void testArrayWrongMethodType(Handles hs) throws Throwable { + long[] array = new long[10]; + Arrays.fill(array, 1L); + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null array + long x = (long) hs.get(am, methodType(long.class, Void.class, int.class)). + invoke(null, 0); + }); + checkCCE(() -> { // array reference class + long x = (long) hs.get(am, methodType(long.class, Class.class, int.class)). + invoke(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + long x = (long) hs.get(am, methodType(long.class, int.class, int.class)). + invoke(0, 0); + }); + checkWMTE(() -> { // index reference class + long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class)). + invoke(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class, long[].class, int.class)). + invoke(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class)). + invoke(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) hs.get(am, methodType(long.class)). + invoke(); + }); + checkWMTE(() -> { // > + long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null array + hs.get(am, methodType(void.class, Void.class, int.class, long.class)). + invoke(null, 0, 1L); + }); + checkCCE(() -> { // array reference class + hs.get(am, methodType(void.class, Class.class, int.class, long.class)). + invoke(Void.class, 0, 1L); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, long[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, int.class, long.class)). + invoke(0, 0, 1L); + }); + checkWMTE(() -> { // index reference class + hs.get(am, methodType(void.class, long[].class, Class.class, long.class)). + invoke(array, Void.class, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, long[].class, int.class, Class.class)). + invoke(array, 0, 1L, Void.class); + }); + } + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, long.class, long.class)). + invoke(null, 0, 1L, 1L); + }); + checkCCE(() -> { // receiver reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, long.class, long.class)). + invoke(Void.class, 0, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, Class.class, long.class)). + invoke(array, 0, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class, Class.class)). + invoke(array, 0, 1L, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, long.class, long.class)). + invoke(0, 0, 1L, 1L); + }); + checkWMTE(() -> { // index reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, Class.class, long.class, long.class)). + invoke(array, Void.class, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + checkWMTE(() -> { // > + boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class, long.class, Class.class)). + invoke(array, 0, 1L, 1L, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + long x = (long) hs.get(am, methodType(long.class, Void.class, int.class, long.class, long.class)). + invoke(null, 0, 1L, 1L); + }); + checkCCE(() -> { // array reference class + long x = (long) hs.get(am, methodType(long.class, Class.class, int.class, long.class, long.class)). + invoke(Void.class, 0, 1L, 1L); + }); + checkWMTE(() -> { // expected reference class + long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class, long.class)). + invoke(array, 0, Void.class, 1L); + }); + checkWMTE(() -> { // actual reference class + long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, Class.class)). + invoke(array, 0, 1L, Void.class); + }); + checkWMTE(() -> { // array primitive class + long x = (long) hs.get(am, methodType(long.class, int.class, int.class, long.class, long.class)). + invoke(0, 0, 1L, 1L); + }); + checkWMTE(() -> { // index reference class + long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class, long.class, long.class)). + invoke(array, Void.class, 1L, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, long[].class, int.class, long.class, long.class)). + invoke(array, 0, 1L, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class, long.class)). + invoke(array, 0, 1L, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) hs.get(am, methodType(long.class)). + invoke(); + }); + checkWMTE(() -> { // > + long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, long.class, Class.class)). + invoke(array, 0, 1L, 1L, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + // Incorrect argument types + checkNPE(() -> { // null array + long x = (long) hs.get(am, methodType(long.class, Void.class, int.class, long.class)). + invoke(null, 0, 1L); + }); + checkCCE(() -> { // array reference class + long x = (long) hs.get(am, methodType(long.class, Class.class, int.class, long.class)). + invoke(Void.class, 0, 1L); + }); + checkWMTE(() -> { // value reference class + long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // array primitive class + long x = (long) hs.get(am, methodType(long.class, int.class, int.class, long.class)). + invoke(0, 0, 1L); + }); + checkWMTE(() -> { // index reference class + long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class, long.class)). + invoke(array, Void.class, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, long[].class, int.class, long.class)). + invoke(array, 0, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class)). + invoke(array, 0, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) hs.get(am, methodType(long.class)). + invoke(); + }); + checkWMTE(() -> { // > + long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, Class.class)). + invoke(array, 0, 1L, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + // Incorrect argument types + checkNPE(() -> { // null array + long x = (long) hs.get(am, methodType(long.class, Void.class, int.class, long.class)). + invoke(null, 0, 1L); + }); + checkCCE(() -> { // array reference class + long x = (long) hs.get(am, methodType(long.class, Class.class, int.class, long.class)). + invoke(Void.class, 0, 1L); + }); + checkWMTE(() -> { // value reference class + long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // array primitive class + long x = (long) hs.get(am, methodType(long.class, int.class, int.class, long.class)). + invoke(0, 0, 1L); + }); + checkWMTE(() -> { // index reference class + long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class, long.class)). + invoke(array, Void.class, 1L); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, long[].class, int.class, long.class)). + invoke(array, 0, 1L); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class)). + invoke(array, 0, 1L); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + long x = (long) hs.get(am, methodType(long.class)). + invoke(); + }); + checkWMTE(() -> { // > + long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, Class.class)). + invoke(array, 0, 1L, Void.class); + }); + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeShort.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeShort.java new file mode 100644 index 00000000000..a8059959630 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeShort.java @@ -0,0 +1,856 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm VarHandleTestMethodTypeShort + * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false 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.*; + +public class VarHandleTestMethodTypeShort extends VarHandleBaseTest { + static final short static_final_v = (short)1; + + static short static_v = (short)1; + + final short final_v = (short)1; + + short v = (short)1; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeShort.class, "final_v", short.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeShort.class, "v", short.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeShort.class, "static_final_v", short.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeShort.class, "static_v", short.class); + + vhArray = MethodHandles.arrayElementVarHandle(short[].class); + } + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + vhField, vh -> testInstanceFieldWrongMethodType(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field wrong method type", + vhStaticField, VarHandleTestMethodTypeShort::testStaticFieldWrongMethodType, + false)); + + cases.add(new VarHandleAccessTestCase("Array wrong method type", + vhArray, VarHandleTestMethodTypeShort::testArrayWrongMethodType, + false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + vhStaticField, f, VarHandleTestMethodTypeShort::testStaticFieldWrongMethodType, + false)); + + cases.add(new MethodHandleAccessTestCase("Array wrong method type", + vhArray, f, VarHandleTestMethodTypeShort::testArrayWrongMethodType, + false)); + } + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeShort recv, VarHandle vh) throws Throwable { + // Get + // Incorrect argument types + checkNPE(() -> { // null receiver + short x = (short) vh.get(null); + }); + checkCCE(() -> { // receiver reference class + short x = (short) vh.get(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + short x = (short) vh.get(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + short x = (short) vh.get(); + }); + checkWMTE(() -> { // > + short x = (short) vh.get(recv, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.set(null, (short)1); + }); + checkCCE(() -> { // receiver reference class + vh.set(Void.class, (short)1); + }); + checkWMTE(() -> { // value reference class + vh.set(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, (short)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(recv, (short)1, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + short x = (short) vh.getVolatile(null); + }); + checkCCE(() -> { // receiver reference class + short x = (short) vh.getVolatile(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + short x = (short) vh.getVolatile(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + short x = (short) vh.getVolatile(); + }); + checkWMTE(() -> { // > + short x = (short) vh.getVolatile(recv, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setVolatile(null, (short)1); + }); + checkCCE(() -> { // receiver reference class + vh.setVolatile(Void.class, (short)1); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, (short)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(recv, (short)1, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + short x = (short) vh.getOpaque(null); + }); + checkCCE(() -> { // receiver reference class + short x = (short) vh.getOpaque(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + short x = (short) vh.getOpaque(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + short x = (short) vh.getOpaque(); + }); + checkWMTE(() -> { // > + short x = (short) vh.getOpaque(recv, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setOpaque(null, (short)1); + }); + checkCCE(() -> { // receiver reference class + vh.setOpaque(Void.class, (short)1); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, (short)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(recv, (short)1, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + short x = (short) vh.getAcquire(null); + }); + checkCCE(() -> { // receiver reference class + short x = (short) vh.getAcquire(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + short x = (short) vh.getAcquire(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + short x = (short) vh.getAcquire(); + }); + checkWMTE(() -> { // > + short x = (short) vh.getAcquire(recv, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setRelease(null, (short)1); + }); + checkCCE(() -> { // receiver reference class + vh.setRelease(Void.class, (short)1); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, (short)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(recv, (short)1, Void.class); + }); + + + + } + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeShort recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + short x = (short) hs.get(am, methodType(short.class, Void.class)). + invoke(null); + }); + checkCCE(() -> { // receiver reference class + short x = (short) hs.get(am, methodType(short.class, Class.class)). + invoke(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + short x = (short) hs.get(am, methodType(short.class, int.class)). + invoke(0); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(short.class, VarHandleTestMethodTypeShort.class)). + invoke(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeShort.class)). + invoke(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + short x = (short) hs.get(am, methodType(short.class)). + invoke(); + }); + checkWMTE(() -> { // > + short x = (short) hs.get(am, methodType(short.class, VarHandleTestMethodTypeShort.class, Class.class)). + invoke(recv, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + hs.get(am, methodType(void.class, Void.class, short.class)). + invoke(null, (short)1); + }); + checkCCE(() -> { // receiver reference class + hs.get(am, methodType(void.class, Class.class, short.class)). + invoke(Void.class, (short)1); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, VarHandleTestMethodTypeShort.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, short.class)). + invoke(0, (short)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, VarHandleTestMethodTypeShort.class, short.class, Class.class)). + invoke(recv, (short)1, Void.class); + }); + } + + + } + + + static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable { + // Get + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(); + }); + // Incorrect arity + checkWMTE(() -> { // > + short x = (short) vh.get(Void.class); + }); + + + // Set + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.set(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set((short)1, Void.class); + }); + + + // GetVolatile + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(); + }); + checkWMTE(() -> { // > + short x = (short) vh.getVolatile(Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setVolatile(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile((short)1, Void.class); + }); + + + // GetOpaque + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(); + }); + checkWMTE(() -> { // > + short x = (short) vh.getOpaque(Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setOpaque(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque((short)1, Void.class); + }); + + + // GetAcquire + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(); + }); + checkWMTE(() -> { // > + short x = (short) vh.getAcquire(Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkWMTE(() -> { // value reference class + vh.setRelease(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease((short)1, Void.class); + }); + + + + } + + static void testStaticFieldWrongMethodType(Handles hs) throws Throwable { + int i = 0; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class)). + invoke(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + // Incorrect arity + checkWMTE(() -> { // > + short x = (short) hs.get(am, methodType(Class.class)). + invoke(Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, Class.class)). + invoke(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, short.class, Class.class)). + invoke((short)1, Void.class); + }); + } + + } + + + static void testArrayWrongMethodType(VarHandle vh) throws Throwable { + short[] array = new short[10]; + Arrays.fill(array, (short)1); + + // Get + // Incorrect argument types + checkNPE(() -> { // null array + short x = (short) vh.get(null, 0); + }); + checkCCE(() -> { // array reference class + short x = (short) vh.get(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + short x = (short) vh.get(0, 0); + }); + checkWMTE(() -> { // index reference class + short x = (short) vh.get(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.get(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + short x = (short) vh.get(); + }); + checkWMTE(() -> { // > + short x = (short) vh.get(array, 0, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null array + vh.set(null, 0, (short)1); + }); + checkCCE(() -> { // array reference class + vh.set(Void.class, 0, (short)1); + }); + checkWMTE(() -> { // value reference class + vh.set(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, 0, (short)1); + }); + checkWMTE(() -> { // index reference class + vh.set(array, Void.class, (short)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(array, 0, (short)1, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + short x = (short) vh.getVolatile(null, 0); + }); + checkCCE(() -> { // array reference class + short x = (short) vh.getVolatile(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + short x = (short) vh.getVolatile(0, 0); + }); + checkWMTE(() -> { // index reference class + short x = (short) vh.getVolatile(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getVolatile(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + short x = (short) vh.getVolatile(); + }); + checkWMTE(() -> { // > + short x = (short) vh.getVolatile(array, 0, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + vh.setVolatile(null, 0, (short)1); + }); + checkCCE(() -> { // array reference class + vh.setVolatile(Void.class, 0, (short)1); + }); + checkWMTE(() -> { // value reference class + vh.setVolatile(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, 0, (short)1); + }); + checkWMTE(() -> { // index reference class + vh.setVolatile(array, Void.class, (short)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(array, 0, (short)1, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + short x = (short) vh.getOpaque(null, 0); + }); + checkCCE(() -> { // array reference class + short x = (short) vh.getOpaque(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + short x = (short) vh.getOpaque(0, 0); + }); + checkWMTE(() -> { // index reference class + short x = (short) vh.getOpaque(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getOpaque(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + short x = (short) vh.getOpaque(); + }); + checkWMTE(() -> { // > + short x = (short) vh.getOpaque(array, 0, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + vh.setOpaque(null, 0, (short)1); + }); + checkCCE(() -> { // array reference class + vh.setOpaque(Void.class, 0, (short)1); + }); + checkWMTE(() -> { // value reference class + vh.setOpaque(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, 0, (short)1); + }); + checkWMTE(() -> { // index reference class + vh.setOpaque(array, Void.class, (short)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(array, 0, (short)1, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null array + short x = (short) vh.getAcquire(null, 0); + }); + checkCCE(() -> { // array reference class + short x = (short) vh.getAcquire(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + short x = (short) vh.getAcquire(0, 0); + }); + checkWMTE(() -> { // index reference class + short x = (short) vh.getAcquire(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) vh.getAcquire(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + short x = (short) vh.getAcquire(); + }); + checkWMTE(() -> { // > + short x = (short) vh.getAcquire(array, 0, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null array + vh.setRelease(null, 0, (short)1); + }); + checkCCE(() -> { // array reference class + vh.setRelease(Void.class, 0, (short)1); + }); + checkWMTE(() -> { // value reference class + vh.setRelease(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, 0, (short)1); + }); + checkWMTE(() -> { // index reference class + vh.setRelease(array, Void.class, (short)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(array, 0, (short)1, Void.class); + }); + + + + } + + static void testArrayWrongMethodType(Handles hs) throws Throwable { + short[] array = new short[10]; + Arrays.fill(array, (short)1); + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null array + short x = (short) hs.get(am, methodType(short.class, Void.class, int.class)). + invoke(null, 0); + }); + checkCCE(() -> { // array reference class + short x = (short) hs.get(am, methodType(short.class, Class.class, int.class)). + invoke(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + short x = (short) hs.get(am, methodType(short.class, int.class, int.class)). + invoke(0, 0); + }); + checkWMTE(() -> { // index reference class + short x = (short) hs.get(am, methodType(short.class, short[].class, Class.class)). + invoke(array, Void.class); + }); + // Incorrect return type + checkWMTE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class, short[].class, int.class)). + invoke(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, short[].class, int.class)). + invoke(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + short x = (short) hs.get(am, methodType(short.class)). + invoke(); + }); + checkWMTE(() -> { // > + short x = (short) hs.get(am, methodType(short.class, short[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null array + hs.get(am, methodType(void.class, Void.class, int.class, short.class)). + invoke(null, 0, (short)1); + }); + checkCCE(() -> { // array reference class + hs.get(am, methodType(void.class, Class.class, int.class, short.class)). + invoke(Void.class, 0, (short)1); + }); + checkWMTE(() -> { // value reference class + hs.get(am, methodType(void.class, short[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, int.class, short.class)). + invoke(0, 0, (short)1); + }); + checkWMTE(() -> { // index reference class + hs.get(am, methodType(void.class, short[].class, Class.class, short.class)). + invoke(array, Void.class, (short)1); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, short[].class, int.class, Class.class)). + invoke(array, 0, (short)1, Void.class); + }); + } + + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java new file mode 100644 index 00000000000..631fe33466c --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java @@ -0,0 +1,1811 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm VarHandleTestMethodTypeString + * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false 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.*; + +public class VarHandleTestMethodTypeString extends VarHandleBaseTest { + static final String static_final_v = "foo"; + + static String static_v = "foo"; + + final String final_v = "foo"; + + String v = "foo"; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeString.class, "final_v", String.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodTypeString.class, "v", String.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeString.class, "static_final_v", String.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodTypeString.class, "static_v", String.class); + + vhArray = MethodHandles.arrayElementVarHandle(String[].class); + } + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + vhField, vh -> testInstanceFieldWrongMethodType(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field wrong method type", + vhStaticField, VarHandleTestMethodTypeString::testStaticFieldWrongMethodType, + false)); + + cases.add(new VarHandleAccessTestCase("Array wrong method type", + vhArray, VarHandleTestMethodTypeString::testArrayWrongMethodType, + false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + vhStaticField, f, VarHandleTestMethodTypeString::testStaticFieldWrongMethodType, + false)); + + cases.add(new MethodHandleAccessTestCase("Array wrong method type", + vhArray, f, VarHandleTestMethodTypeString::testArrayWrongMethodType, + false)); + } + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeString recv, VarHandle vh) throws Throwable { + // Get + // Incorrect argument types + checkNPE(() -> { // null receiver + String x = (String) vh.get(null); + }); + checkCCE(() -> { // receiver reference class + String x = (String) vh.get(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + String x = (String) vh.get(0); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void x = (Void) vh.get(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.get(); + }); + checkWMTE(() -> { // > + String x = (String) vh.get(recv, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.set(null, "foo"); + }); + checkCCE(() -> { // receiver reference class + vh.set(Void.class, "foo"); + }); + checkCCE(() -> { // value reference class + vh.set(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(recv, "foo", Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + String x = (String) vh.getVolatile(null); + }); + checkCCE(() -> { // receiver reference class + String x = (String) vh.getVolatile(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + String x = (String) vh.getVolatile(0); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void x = (Void) vh.getVolatile(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.getVolatile(); + }); + checkWMTE(() -> { // > + String x = (String) vh.getVolatile(recv, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setVolatile(null, "foo"); + }); + checkCCE(() -> { // receiver reference class + vh.setVolatile(Void.class, "foo"); + }); + checkCCE(() -> { // value reference class + vh.setVolatile(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(recv, "foo", Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + String x = (String) vh.getOpaque(null); + }); + checkCCE(() -> { // receiver reference class + String x = (String) vh.getOpaque(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + String x = (String) vh.getOpaque(0); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void x = (Void) vh.getOpaque(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.getOpaque(); + }); + checkWMTE(() -> { // > + String x = (String) vh.getOpaque(recv, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setOpaque(null, "foo"); + }); + checkCCE(() -> { // receiver reference class + vh.setOpaque(Void.class, "foo"); + }); + checkCCE(() -> { // value reference class + vh.setOpaque(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(recv, "foo", Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + String x = (String) vh.getAcquire(null); + }); + checkCCE(() -> { // receiver reference class + String x = (String) vh.getAcquire(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + String x = (String) vh.getAcquire(0); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void x = (Void) vh.getAcquire(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.getAcquire(); + }); + checkWMTE(() -> { // > + String x = (String) vh.getAcquire(recv, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setRelease(null, "foo"); + }); + checkCCE(() -> { // receiver reference class + vh.setRelease(Void.class, "foo"); + }); + checkCCE(() -> { // value reference class + vh.setRelease(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(recv, "foo", Void.class); + }); + + + // CompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.compareAndSet(null, "foo", "foo"); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.compareAndSet(Void.class, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + boolean r = vh.compareAndSet(recv, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + boolean r = vh.compareAndSet(recv, "foo", Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.compareAndSet(0, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.compareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.compareAndSet(recv, "foo", "foo", Void.class); + }); + + + // WeakCompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSet(null, "foo", "foo"); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSet(Void.class, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + boolean r = vh.weakCompareAndSet(recv, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + boolean r = vh.weakCompareAndSet(recv, "foo", Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSet(0, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSet(recv, "foo", "foo", Void.class); + }); + + + // WeakCompareAndSetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetAcquire(null, "foo", "foo"); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetAcquire(Void.class, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetAcquire(recv, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetAcquire(recv, "foo", Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetAcquire(0, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetAcquire(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetAcquire(recv, "foo", "foo", Void.class); + }); + + + // WeakCompareAndSetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetRelease(null, "foo", "foo"); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetRelease(Void.class, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetRelease(recv, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetRelease(recv, "foo", Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetRelease(0, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetRelease(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetRelease(recv, "foo", "foo", Void.class); + }); + + + // CompareAndExchangeVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + String x = (String) vh.compareAndExchangeVolatile(null, "foo", "foo"); + }); + checkCCE(() -> { // receiver reference class + String x = (String) vh.compareAndExchangeVolatile(Void.class, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + String x = (String) vh.compareAndExchangeVolatile(recv, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + String x = (String) vh.compareAndExchangeVolatile(recv, "foo", Void.class); + }); + checkWMTE(() -> { // reciever primitive class + String x = (String) vh.compareAndExchangeVolatile(0, "foo", "foo"); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeVolatile(recv, "foo", "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeVolatile(recv, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.compareAndExchangeVolatile(); + }); + checkWMTE(() -> { // > + String x = (String) vh.compareAndExchangeVolatile(recv, "foo", "foo", Void.class); + }); + + + // CompareAndExchangeVolatileAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + String x = (String) vh.compareAndExchangeAcquire(null, "foo", "foo"); + }); + checkCCE(() -> { // receiver reference class + String x = (String) vh.compareAndExchangeAcquire(Void.class, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + String x = (String) vh.compareAndExchangeAcquire(recv, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + String x = (String) vh.compareAndExchangeAcquire(recv, "foo", Void.class); + }); + checkWMTE(() -> { // reciever primitive class + String x = (String) vh.compareAndExchangeAcquire(0, "foo", "foo"); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeAcquire(recv, "foo", "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeAcquire(recv, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.compareAndExchangeAcquire(); + }); + checkWMTE(() -> { // > + String x = (String) vh.compareAndExchangeAcquire(recv, "foo", "foo", Void.class); + }); + + + // CompareAndExchangeRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + String x = (String) vh.compareAndExchangeRelease(null, "foo", "foo"); + }); + checkCCE(() -> { // receiver reference class + String x = (String) vh.compareAndExchangeRelease(Void.class, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + String x = (String) vh.compareAndExchangeRelease(recv, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + String x = (String) vh.compareAndExchangeRelease(recv, "foo", Void.class); + }); + checkWMTE(() -> { // reciever primitive class + String x = (String) vh.compareAndExchangeRelease(0, "foo", "foo"); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeRelease(recv, "foo", "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeRelease(recv, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.compareAndExchangeRelease(); + }); + checkWMTE(() -> { // > + String x = (String) vh.compareAndExchangeRelease(recv, "foo", "foo", Void.class); + }); + + + // GetAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + String x = (String) vh.getAndSet(null, "foo"); + }); + checkCCE(() -> { // receiver reference class + String x = (String) vh.getAndSet(Void.class, "foo"); + }); + checkCCE(() -> { // value reference class + String x = (String) vh.getAndSet(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + String x = (String) vh.getAndSet(0, "foo"); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) vh.getAndSet(recv, "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAndSet(recv, "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.getAndSet(); + }); + checkWMTE(() -> { // > + String x = (String) vh.getAndSet(recv, "foo", Void.class); + }); + + } + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeString recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + String x = (String) hs.get(am, methodType(String.class, Void.class)). + invoke(null); + }); + checkCCE(() -> { // receiver reference class + String x = (String) hs.get(am, methodType(String.class, Class.class)). + invoke(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + String x = (String) hs.get(am, methodType(String.class, int.class)). + invoke(0); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class)). + invoke(recv); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class)). + invoke(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) hs.get(am, methodType(String.class)). + invoke(); + }); + checkWMTE(() -> { // > + String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class)). + invoke(recv, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + hs.get(am, methodType(void.class, Void.class, String.class)). + invoke(null, "foo"); + }); + checkCCE(() -> { // receiver reference class + hs.get(am, methodType(void.class, Class.class, String.class)). + invoke(Void.class, "foo"); + }); + checkCCE(() -> { // value reference class + hs.get(am, methodType(void.class, VarHandleTestMethodTypeString.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, String.class)). + invoke(0, "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, VarHandleTestMethodTypeString.class, String.class, Class.class)). + invoke(recv, "foo", Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, String.class, String.class)). + invoke(null, "foo", "foo"); + }); + checkCCE(() -> { // receiver reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, String.class, String.class)). + invoke(Void.class, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, Class.class, String.class)). + invoke(recv, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class, Class.class)). + invoke(recv, "foo", Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , String.class, String.class)). + invoke(0, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + checkWMTE(() -> { // > + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class, String.class, Class.class)). + invoke(recv, "foo", "foo", Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkNPE(() -> { // null receiver + String x = (String) hs.get(am, methodType(String.class, Void.class, String.class, String.class)). + invoke(null, "foo", "foo"); + }); + checkCCE(() -> { // receiver reference class + String x = (String) hs.get(am, methodType(String.class, Class.class, String.class, String.class)). + invoke(Void.class, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class, String.class)). + invoke(recv, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class, Class.class)). + invoke(recv, "foo", Void.class); + }); + checkWMTE(() -> { // reciever primitive class + String x = (String) hs.get(am, methodType(String.class, int.class , String.class, String.class)). + invoke(0, "foo", "foo"); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeString.class , String.class, String.class)). + invoke(recv, "foo", "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class , String.class, String.class)). + invoke(recv, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) hs.get(am, methodType(String.class)). + invoke(); + }); + checkWMTE(() -> { // > + String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class, String.class, Class.class)). + invoke(recv, "foo", "foo", Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkNPE(() -> { // null receiver + String x = (String) hs.get(am, methodType(String.class, Void.class, String.class)). + invoke(null, "foo"); + }); + checkCCE(() -> { // receiver reference class + String x = (String) hs.get(am, methodType(String.class, Class.class, String.class)). + invoke(Void.class, "foo"); + }); + checkCCE(() -> { // value reference class + String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + String x = (String) hs.get(am, methodType(String.class, int.class, String.class)). + invoke(0, "foo"); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeString.class, String.class)). + invoke(recv, "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class)). + invoke(recv, "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) hs.get(am, methodType(String.class)). + invoke(); + }); + checkWMTE(() -> { // > + String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class)). + invoke(recv, "foo", Void.class); + }); + } + + } + + + static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable { + // Get + // Incorrect return type + checkCCE(() -> { // reference class + Void x = (Void) vh.get(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(); + }); + // Incorrect arity + checkWMTE(() -> { // > + String x = (String) vh.get(Void.class); + }); + + + // Set + // Incorrect argument types + checkCCE(() -> { // value reference class + vh.set(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set("foo", Void.class); + }); + + + // GetVolatile + // Incorrect return type + checkCCE(() -> { // reference class + Void x = (Void) vh.getVolatile(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(); + }); + checkWMTE(() -> { // > + String x = (String) vh.getVolatile(Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkCCE(() -> { // value reference class + vh.setVolatile(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile("foo", Void.class); + }); + + + // GetOpaque + // Incorrect return type + checkCCE(() -> { // reference class + Void x = (Void) vh.getOpaque(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(); + }); + checkWMTE(() -> { // > + String x = (String) vh.getOpaque(Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkCCE(() -> { // value reference class + vh.setOpaque(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque("foo", Void.class); + }); + + + // GetAcquire + // Incorrect return type + checkCCE(() -> { // reference class + Void x = (Void) vh.getAcquire(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(); + }); + checkWMTE(() -> { // > + String x = (String) vh.getAcquire(Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkCCE(() -> { // value reference class + vh.setRelease(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease("foo", Void.class); + }); + + + // CompareAndSet + // Incorrect argument types + checkCCE(() -> { // expected reference class + boolean r = vh.compareAndSet(Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + boolean r = vh.compareAndSet("foo", Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.compareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.compareAndSet("foo", "foo", Void.class); + }); + + + // WeakCompareAndSet + // Incorrect argument types + checkCCE(() -> { // expected reference class + boolean r = vh.weakCompareAndSet(Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + boolean r = vh.weakCompareAndSet("foo", Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSet("foo", "foo", Void.class); + }); + + + // WeakCompareAndSetAcquire + // Incorrect argument types + checkCCE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetAcquire(Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetAcquire("foo", Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetAcquire(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetAcquire("foo", "foo", Void.class); + }); + + + // WeakCompareAndSetRelease + // Incorrect argument types + checkCCE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetRelease(Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetRelease("foo", Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetRelease(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetRelease("foo", "foo", Void.class); + }); + + + // CompareAndExchangeVolatile + // Incorrect argument types + checkCCE(() -> { // expected reference class + String x = (String) vh.compareAndExchangeVolatile(Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + String x = (String) vh.compareAndExchangeVolatile("foo", Void.class); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeVolatile("foo", "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeVolatile("foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.compareAndExchangeVolatile(); + }); + checkWMTE(() -> { // > + String x = (String) vh.compareAndExchangeVolatile("foo", "foo", Void.class); + }); + + + // CompareAndExchangeAcquire + // Incorrect argument types + checkCCE(() -> { // expected reference class + String x = (String) vh.compareAndExchangeAcquire(Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + String x = (String) vh.compareAndExchangeAcquire("foo", Void.class); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeAcquire("foo", "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeAcquire("foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.compareAndExchangeAcquire(); + }); + checkWMTE(() -> { // > + String x = (String) vh.compareAndExchangeAcquire("foo", "foo", Void.class); + }); + + + // CompareAndExchangeRelease + // Incorrect argument types + checkCCE(() -> { // expected reference class + String x = (String) vh.compareAndExchangeRelease(Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + String x = (String) vh.compareAndExchangeRelease("foo", Void.class); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeRelease("foo", "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeRelease("foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.compareAndExchangeRelease(); + }); + checkWMTE(() -> { // > + String x = (String) vh.compareAndExchangeRelease("foo", "foo", Void.class); + }); + + + // GetAndSet + // Incorrect argument types + checkCCE(() -> { // value reference class + String x = (String) vh.getAndSet(Void.class); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) vh.getAndSet("foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAndSet("foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.getAndSet(); + }); + checkWMTE(() -> { // > + String x = (String) vh.getAndSet("foo", Void.class); + }); + + } + + static void testStaticFieldWrongMethodType(Handles hs) throws Throwable { + int i = 0; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect return type + checkCCE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class)). + invoke(); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + // Incorrect arity + checkWMTE(() -> { // > + String x = (String) hs.get(am, methodType(Class.class)). + invoke(Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkCCE(() -> { // value reference class + hs.get(am, methodType(void.class, Class.class)). + invoke(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, String.class, Class.class)). + invoke("foo", Void.class); + }); + } + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + // Incorrect argument types + checkCCE(() -> { // expected reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, String.class)). + invoke(Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, String.class, Class.class)). + invoke("foo", Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + checkWMTE(() -> { // > + boolean r = (boolean) hs.get(am, methodType(boolean.class, String.class, String.class, Class.class)). + invoke("foo", "foo", Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + // Incorrect argument types + checkCCE(() -> { // expected reference class + String x = (String) hs.get(am, methodType(String.class, Class.class, String.class)). + invoke(Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + String x = (String) hs.get(am, methodType(String.class, String.class, Class.class)). + invoke("foo", Void.class); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, String.class, String.class)). + invoke("foo", "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, String.class, String.class)). + invoke("foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) hs.get(am, methodType(String.class)). + invoke(); + }); + checkWMTE(() -> { // > + String x = (String) hs.get(am, methodType(String.class, String.class, String.class, Class.class)). + invoke("foo", "foo", Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + // Incorrect argument types + checkCCE(() -> { // value reference class + String x = (String) hs.get(am, methodType(String.class, Class.class)). + invoke(Void.class); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, String.class)). + invoke("foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, String.class)). + invoke("foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) hs.get(am, methodType(String.class)). + invoke(); + }); + checkWMTE(() -> { // > + String x = (String) hs.get(am, methodType(String.class, String.class, Class.class)). + invoke("foo", Void.class); + }); + } + + } + + + static void testArrayWrongMethodType(VarHandle vh) throws Throwable { + String[] array = new String[10]; + Arrays.fill(array, "foo"); + + // Get + // Incorrect argument types + checkNPE(() -> { // null array + String x = (String) vh.get(null, 0); + }); + checkCCE(() -> { // array reference class + String x = (String) vh.get(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + String x = (String) vh.get(0, 0); + }); + checkWMTE(() -> { // index reference class + String x = (String) vh.get(array, Void.class); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void x = (Void) vh.get(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.get(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.get(); + }); + checkWMTE(() -> { // > + String x = (String) vh.get(array, 0, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null array + vh.set(null, 0, "foo"); + }); + checkCCE(() -> { // array reference class + vh.set(Void.class, 0, "foo"); + }); + checkCCE(() -> { // value reference class + vh.set(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, 0, "foo"); + }); + checkWMTE(() -> { // index reference class + vh.set(array, Void.class, "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(array, 0, "foo", Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + String x = (String) vh.getVolatile(null, 0); + }); + checkCCE(() -> { // array reference class + String x = (String) vh.getVolatile(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + String x = (String) vh.getVolatile(0, 0); + }); + checkWMTE(() -> { // index reference class + String x = (String) vh.getVolatile(array, Void.class); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void x = (Void) vh.getVolatile(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getVolatile(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.getVolatile(); + }); + checkWMTE(() -> { // > + String x = (String) vh.getVolatile(array, 0, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + vh.setVolatile(null, 0, "foo"); + }); + checkCCE(() -> { // array reference class + vh.setVolatile(Void.class, 0, "foo"); + }); + checkCCE(() -> { // value reference class + vh.setVolatile(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, 0, "foo"); + }); + checkWMTE(() -> { // index reference class + vh.setVolatile(array, Void.class, "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(array, 0, "foo", Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + String x = (String) vh.getOpaque(null, 0); + }); + checkCCE(() -> { // array reference class + String x = (String) vh.getOpaque(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + String x = (String) vh.getOpaque(0, 0); + }); + checkWMTE(() -> { // index reference class + String x = (String) vh.getOpaque(array, Void.class); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void x = (Void) vh.getOpaque(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getOpaque(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.getOpaque(); + }); + checkWMTE(() -> { // > + String x = (String) vh.getOpaque(array, 0, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + vh.setOpaque(null, 0, "foo"); + }); + checkCCE(() -> { // array reference class + vh.setOpaque(Void.class, 0, "foo"); + }); + checkCCE(() -> { // value reference class + vh.setOpaque(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, 0, "foo"); + }); + checkWMTE(() -> { // index reference class + vh.setOpaque(array, Void.class, "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(array, 0, "foo", Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null array + String x = (String) vh.getAcquire(null, 0); + }); + checkCCE(() -> { // array reference class + String x = (String) vh.getAcquire(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + String x = (String) vh.getAcquire(0, 0); + }); + checkWMTE(() -> { // index reference class + String x = (String) vh.getAcquire(array, Void.class); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void x = (Void) vh.getAcquire(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAcquire(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.getAcquire(); + }); + checkWMTE(() -> { // > + String x = (String) vh.getAcquire(array, 0, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null array + vh.setRelease(null, 0, "foo"); + }); + checkCCE(() -> { // array reference class + vh.setRelease(Void.class, 0, "foo"); + }); + checkCCE(() -> { // value reference class + vh.setRelease(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, 0, "foo"); + }); + checkWMTE(() -> { // index reference class + vh.setRelease(array, Void.class, "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(array, 0, "foo", Void.class); + }); + + + // CompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.compareAndSet(null, 0, "foo", "foo"); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.compareAndSet(Void.class, 0, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + boolean r = vh.compareAndSet(array, 0, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + boolean r = vh.compareAndSet(array, 0, "foo", Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.compareAndSet(0, 0, "foo", "foo"); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.compareAndSet(array, Void.class, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.compareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.compareAndSet(array, 0, "foo", "foo", Void.class); + }); + + + // WeakCompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSet(null, 0, "foo", "foo"); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSet(Void.class, 0, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + boolean r = vh.weakCompareAndSet(array, 0, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + boolean r = vh.weakCompareAndSet(array, 0, "foo", Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSet(0, 0, "foo", "foo"); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.weakCompareAndSet(array, Void.class, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSet(array, 0, "foo", "foo", Void.class); + }); + + + // WeakCompareAndSetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetAcquire(null, 0, "foo", "foo"); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetAcquire(array, 0, "foo", Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetAcquire(0, 0, "foo", "foo"); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.weakCompareAndSetAcquire(array, Void.class, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetAcquire(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetAcquire(array, 0, "foo", "foo", Void.class); + }); + + + // WeakCompareAndSetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetRelease(null, 0, "foo", "foo"); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetRelease(Void.class, 0, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + boolean r = vh.weakCompareAndSetRelease(array, 0, "foo", Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetRelease(0, 0, "foo", "foo"); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.weakCompareAndSetRelease(array, Void.class, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetRelease(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetRelease(array, 0, "foo", "foo", Void.class); + }); + + + // CompareAndExchangeVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + String x = (String) vh.compareAndExchangeVolatile(null, 0, "foo", "foo"); + }); + checkCCE(() -> { // array reference class + String x = (String) vh.compareAndExchangeVolatile(Void.class, 0, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + String x = (String) vh.compareAndExchangeVolatile(array, 0, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + String x = (String) vh.compareAndExchangeVolatile(array, 0, "foo", Void.class); + }); + checkWMTE(() -> { // array primitive class + String x = (String) vh.compareAndExchangeVolatile(0, 0, "foo", "foo"); + }); + checkWMTE(() -> { // index reference class + String x = (String) vh.compareAndExchangeVolatile(array, Void.class, "foo", "foo"); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeVolatile(array, 0, "foo", "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeVolatile(array, 0, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.compareAndExchangeVolatile(); + }); + checkWMTE(() -> { // > + String x = (String) vh.compareAndExchangeVolatile(array, 0, "foo", "foo", Void.class); + }); + + + // CompareAndExchangeAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + String x = (String) vh.compareAndExchangeAcquire(null, 0, "foo", "foo"); + }); + checkCCE(() -> { // array reference class + String x = (String) vh.compareAndExchangeAcquire(Void.class, 0, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + String x = (String) vh.compareAndExchangeAcquire(array, 0, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + String x = (String) vh.compareAndExchangeAcquire(array, 0, "foo", Void.class); + }); + checkWMTE(() -> { // array primitive class + String x = (String) vh.compareAndExchangeAcquire(0, 0, "foo", "foo"); + }); + checkWMTE(() -> { // index reference class + String x = (String) vh.compareAndExchangeAcquire(array, Void.class, "foo", "foo"); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeAcquire(array, 0, "foo", "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeAcquire(array, 0, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.compareAndExchangeAcquire(); + }); + checkWMTE(() -> { // > + String x = (String) vh.compareAndExchangeAcquire(array, 0, "foo", "foo", Void.class); + }); + + + // CompareAndExchangeRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + String x = (String) vh.compareAndExchangeRelease(null, 0, "foo", "foo"); + }); + checkCCE(() -> { // array reference class + String x = (String) vh.compareAndExchangeRelease(Void.class, 0, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + String x = (String) vh.compareAndExchangeRelease(array, 0, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + String x = (String) vh.compareAndExchangeRelease(array, 0, "foo", Void.class); + }); + checkWMTE(() -> { // array primitive class + String x = (String) vh.compareAndExchangeRelease(0, 0, "foo", "foo"); + }); + checkWMTE(() -> { // index reference class + String x = (String) vh.compareAndExchangeRelease(array, Void.class, "foo", "foo"); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) vh.compareAndExchangeRelease(array, 0, "foo", "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.compareAndExchangeRelease(array, 0, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.compareAndExchangeRelease(); + }); + checkWMTE(() -> { // > + String x = (String) vh.compareAndExchangeRelease(array, 0, "foo", "foo", Void.class); + }); + + + // GetAndSet + // Incorrect argument types + checkNPE(() -> { // null array + String x = (String) vh.getAndSet(null, 0, "foo"); + }); + checkCCE(() -> { // array reference class + String x = (String) vh.getAndSet(Void.class, 0, "foo"); + }); + checkCCE(() -> { // value reference class + String x = (String) vh.getAndSet(array, 0, Void.class); + }); + checkWMTE(() -> { // reciarrayever primitive class + String x = (String) vh.getAndSet(0, 0, "foo"); + }); + checkWMTE(() -> { // index reference class + String x = (String) vh.getAndSet(array, Void.class, "foo"); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) vh.getAndSet(array, 0, "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) vh.getAndSet(array, 0, "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) vh.getAndSet(); + }); + checkWMTE(() -> { // > + String x = (String) vh.getAndSet(array, 0, "foo", Void.class); + }); + + } + + static void testArrayWrongMethodType(Handles hs) throws Throwable { + String[] array = new String[10]; + Arrays.fill(array, "foo"); + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null array + String x = (String) hs.get(am, methodType(String.class, Void.class, int.class)). + invoke(null, 0); + }); + checkCCE(() -> { // array reference class + String x = (String) hs.get(am, methodType(String.class, Class.class, int.class)). + invoke(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + String x = (String) hs.get(am, methodType(String.class, int.class, int.class)). + invoke(0, 0); + }); + checkWMTE(() -> { // index reference class + String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class)). + invoke(array, Void.class); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class, String[].class, int.class)). + invoke(array, 0); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class)). + invoke(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) hs.get(am, methodType(String.class)). + invoke(); + }); + checkWMTE(() -> { // > + String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null array + hs.get(am, methodType(void.class, Void.class, int.class, String.class)). + invoke(null, 0, "foo"); + }); + checkCCE(() -> { // array reference class + hs.get(am, methodType(void.class, Class.class, int.class, String.class)). + invoke(Void.class, 0, "foo"); + }); + checkCCE(() -> { // value reference class + hs.get(am, methodType(void.class, String[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, int.class, String.class)). + invoke(0, 0, "foo"); + }); + checkWMTE(() -> { // index reference class + hs.get(am, methodType(void.class, String[].class, Class.class, String.class)). + invoke(array, Void.class, "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, String[].class, int.class, Class.class)). + invoke(array, 0, "foo", Void.class); + }); + } + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, String.class, String.class)). + invoke(null, 0, "foo", "foo"); + }); + checkCCE(() -> { // receiver reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, String.class, String.class)). + invoke(Void.class, 0, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, Class.class, String.class)). + invoke(array, 0, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, Class.class)). + invoke(array, 0, "foo", Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, String.class, String.class)). + invoke(0, 0, "foo", "foo"); + }); + checkWMTE(() -> { // index reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, Class.class, String.class, String.class)). + invoke(array, Void.class, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + checkWMTE(() -> { // > + boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, String.class, Class.class)). + invoke(array, 0, "foo", "foo", Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + String x = (String) hs.get(am, methodType(String.class, Void.class, int.class, String.class, String.class)). + invoke(null, 0, "foo", "foo"); + }); + checkCCE(() -> { // array reference class + String x = (String) hs.get(am, methodType(String.class, Class.class, int.class, String.class, String.class)). + invoke(Void.class, 0, "foo", "foo"); + }); + checkCCE(() -> { // expected reference class + String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class, String.class)). + invoke(array, 0, Void.class, "foo"); + }); + checkCCE(() -> { // actual reference class + String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, Class.class)). + invoke(array, 0, "foo", Void.class); + }); + checkWMTE(() -> { // array primitive class + String x = (String) hs.get(am, methodType(String.class, int.class, int.class, String.class, String.class)). + invoke(0, 0, "foo", "foo"); + }); + checkWMTE(() -> { // index reference class + String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class, String.class, String.class)). + invoke(array, Void.class, "foo", "foo"); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, String[].class, int.class, String.class, String.class)). + invoke(array, 0, "foo", "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, String.class)). + invoke(array, 0, "foo", "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) hs.get(am, methodType(String.class)). + invoke(); + }); + checkWMTE(() -> { // > + String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, String.class, Class.class)). + invoke(array, 0, "foo", "foo", Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + // Incorrect argument types + checkNPE(() -> { // null array + String x = (String) hs.get(am, methodType(String.class, Void.class, int.class, String.class)). + invoke(null, 0, "foo"); + }); + checkCCE(() -> { // array reference class + String x = (String) hs.get(am, methodType(String.class, Class.class, int.class, String.class)). + invoke(Void.class, 0, "foo"); + }); + checkCCE(() -> { // value reference class + String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // array primitive class + String x = (String) hs.get(am, methodType(String.class, int.class, int.class, String.class)). + invoke(0, 0, "foo"); + }); + checkWMTE(() -> { // index reference class + String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class, String.class)). + invoke(array, Void.class, "foo"); + }); + // Incorrect return type + checkCCE(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, String[].class, int.class, String.class)). + invoke(array, 0, "foo"); + }); + checkWMTE(() -> { // primitive class + boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class)). + invoke(array, 0, "foo"); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + String x = (String) hs.get(am, methodType(String.class)). + invoke(); + }); + checkWMTE(() -> { // > + String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, Class.class)). + invoke(array, 0, "foo", Void.class); + }); + } + + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestReflection.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestReflection.java new file mode 100644 index 00000000000..e198c68e9a1 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestReflection.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2014, 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 + * @run testng VarHandleTestReflection + */ + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandleInfo; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; +import java.lang.reflect.Method; +import java.util.stream.Stream; + +public class VarHandleTestReflection extends VarHandleBaseTest { + String string; + + @DataProvider + public static Object[][] accessModesProvider() { + return Stream.of(VarHandle.AccessMode.values()). + map(am -> new Object[]{am}). + toArray(Object[][]::new); + } + + static VarHandle handle() throws Exception { + return MethodHandles.lookup(). + findVarHandle(VarHandleTestReflection.class, "string", String.class); + } + + @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class) + public void methodInvocation(VarHandle.AccessMode accessMode) throws Exception { + VarHandle v = handle(); + + // Try a reflective invoke using a Method + + Method vhm = VarHandle.class.getMethod(accessMode.name(), Object[].class); + vhm.invoke(v, new Object[]{}); + } + + @Test(dataProvider = "accessModesProvider", expectedExceptions = UnsupportedOperationException.class) + public void methodHandleInvoke(VarHandle.AccessMode accessMode) throws Throwable { + VarHandle v = handle(); + + // Try a reflective invoke using a MethodHandle + + MethodHandle mh = MethodHandles.lookup().unreflect( + VarHandle.class.getMethod(accessMode.name(), Object[].class)); + // Use invoke to avoid WrongMethodTypeException for + // non-signature-polymorphic return types + Object o = (Object) mh.invoke(v, new Object[]{}); + } + + @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class) + public void methodInvocationFromMethodInfo(VarHandle.AccessMode accessMode) throws Exception { + VarHandle v = handle(); + + // Try a reflective invoke using a Method obtained from cracking + // a MethodHandle + + MethodHandle mh = MethodHandles.lookup().unreflect( + VarHandle.class.getMethod(accessMode.name(), Object[].class)); + MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh); + Method im = info.reflectAs(Method.class, MethodHandles.lookup()); + im.invoke(v, new Object[]{}); + } + + @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class) + public void reflectAsFromVarHandleInvoker(VarHandle.AccessMode accessMode) throws Exception { + VarHandle v = handle(); + + MethodHandle mh = MethodHandles.varHandleInvoker( + accessMode, v.accessModeType(accessMode)); + + MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh); + + info.reflectAs(Method.class, MethodHandles.lookup()); + } + + @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class) + public void reflectAsFromFindVirtual(VarHandle.AccessMode accessMode) throws Exception { + VarHandle v = handle(); + + MethodHandle mh = MethodHandles.publicLookup().findVirtual( + VarHandle.class, accessMode.name(), v.accessModeType(accessMode)); + + MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh); + + info.reflectAs(Method.class, MethodHandles.lookup()); + } +} diff --git a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template new file mode 100644 index 00000000000..4372df85478 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template @@ -0,0 +1,1026 @@ +/* + * Copyright (c) 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 + * @run testng/othervm -Diters=10 -Xint VarHandleTestAccess$Type$ + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccess$Type$ + * @run testng/othervm -Diters=20000 VarHandleTestAccess$Type$ + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { + static final $type$ static_final_v = $value1$; + + static $type$ static_v; + + final $type$ final_v = $value1$; + + $type$ v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccess$Type$.class, "final_v", $type$.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccess$Type$.class, "v", $type$.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccess$Type$.class, "static_final_v", $type$.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccess$Type$.class, "static_v", $type$.class); + + vhArray = MethodHandles.arrayElementVarHandle($type$[].class); + } + + + @DataProvider + public Object[][] varHandlesProvider() throws Exception { + List vhs = new ArrayList<>(); + vhs.add(vhField); + vhs.add(vhStaticField); + vhs.add(vhArray); + + return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandle vh) { + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + +#if[CAS] + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); +#else[CAS] + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); +#end[CAS] + +#if[AtomicAdd] + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); +#else[AtomicAdd] + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); +#end[AtomicAdd] + } + + + @DataProvider + public Object[][] typesProvider() throws Exception { + List types = new ArrayList<>(); + types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccess$Type$.class)}); + types.add(new Object[] {vhStaticField, Arrays.asList()}); + types.add(new Object[] {vhArray, Arrays.asList($type$[].class, int.class)}); + + return types.stream().toArray(Object[][]::new); + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), $type$.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @Test + public void testLookupInstanceToStatic() { + checkIAE("Lookup of static final field to instance final field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccess$Type$.class, "final_v", $type$.class); + }); + + checkIAE("Lookup of static field to instance field", () -> { + MethodHandles.lookup().findStaticVarHandle( + VarHandleTestAccess$Type$.class, "v", $type$.class); + }); + } + + @Test + public void testLookupStaticToInstance() { + checkIAE("Lookup of instance final field to static final field", () -> { + MethodHandles.lookup().findVarHandle( + VarHandleTestAccess$Type$.class, "static_final_v", $type$.class); + }); + + checkIAE("Lookup of instance field to static field", () -> { + vhStaticField = MethodHandles.lookup().findVarHandle( + VarHandleTestAccess$Type$.class, "static_v", $type$.class); + }); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance final field", + vhFinalField, vh -> testInstanceFinalField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance final field unsupported", + vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static final field", + vhStaticFinalField, VarHandleTestAccess$Type$::testStaticFinalField)); + cases.add(new VarHandleAccessTestCase("Static final field unsupported", + vhStaticFinalField, VarHandleTestAccess$Type$::testStaticFinalFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Instance field", + vhField, vh -> testInstanceField(this, vh))); + cases.add(new VarHandleAccessTestCase("Instance field unsupported", + vhField, vh -> testInstanceFieldUnsupported(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field", + vhStaticField, VarHandleTestAccess$Type$::testStaticField)); + cases.add(new VarHandleAccessTestCase("Static field unsupported", + vhStaticField, VarHandleTestAccess$Type$::testStaticFieldUnsupported, + false)); + + cases.add(new VarHandleAccessTestCase("Array", + vhArray, VarHandleTestAccess$Type$::testArray)); + cases.add(new VarHandleAccessTestCase("Array unsupported", + vhArray, VarHandleTestAccess$Type$::testArrayUnsupported, + false)); + cases.add(new VarHandleAccessTestCase("Array index out of bounds", + vhArray, VarHandleTestAccess$Type$::testArrayIndexOutOfBounds, + false)); + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + + + static void testInstanceFinalField(VarHandleTestAccess$Type$ recv, VarHandle vh) { + // Plain + { + $type$ x = ($type$) vh.get(recv); + assertEquals(x, $value1$, "get $type$ value"); + } + + + // Volatile + { + $type$ x = ($type$) vh.getVolatile(recv); + assertEquals(x, $value1$, "getVolatile $type$ value"); + } + + // Lazy + { + $type$ x = ($type$) vh.getAcquire(recv); + assertEquals(x, $value1$, "getRelease $type$ value"); + } + + // Opaque + { + $type$ x = ($type$) vh.getOpaque(recv); + assertEquals(x, $value1$, "getOpaque $type$ value"); + } + } + + static void testInstanceFinalFieldUnsupported(VarHandleTestAccess$Type$ recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, $value2$); + }); + + checkUOE(() -> { + vh.setVolatile(recv, $value2$); + }); + + checkUOE(() -> { + vh.setRelease(recv, $value2$); + }); + + checkUOE(() -> { + vh.setOpaque(recv, $value2$); + }); + +#if[!CAS] + checkUOE(() -> { + boolean r = vh.compareAndSet(recv, $value1$, $value2$); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value1$, $value2$); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value2$); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value1$, $value2$); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(recv, $value1$, $value2$); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value2$); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$); + }); +#end[CAS] + +#if[!AtomicAdd] + checkUOE(() -> { + $type$ o = ($type$) vh.getAndAdd(recv, $value1$); + }); + + checkUOE(() -> { + $type$ o = ($type$) vh.addAndGet(recv, $value1$); + }); +#end[AtomicAdd] + } + + + static void testStaticFinalField(VarHandle vh) { + // Plain + { + $type$ x = ($type$) vh.get(); + assertEquals(x, $value1$, "get $type$ value"); + } + + + // Volatile + { + $type$ x = ($type$) vh.getVolatile(); + assertEquals(x, $value1$, "getVolatile $type$ value"); + } + + // Lazy + { + $type$ x = ($type$) vh.getAcquire(); + assertEquals(x, $value1$, "getRelease $type$ value"); + } + + // Opaque + { + $type$ x = ($type$) vh.getOpaque(); + assertEquals(x, $value1$, "getOpaque $type$ value"); + } + } + + static void testStaticFinalFieldUnsupported(VarHandle vh) { + checkUOE(() -> { + vh.set($value2$); + }); + + checkUOE(() -> { + vh.setVolatile($value2$); + }); + + checkUOE(() -> { + vh.setRelease($value2$); + }); + + checkUOE(() -> { + vh.setOpaque($value2$); + }); + +#if[!CAS] + checkUOE(() -> { + boolean r = vh.compareAndSet($value1$, $value2$); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeVolatile($value1$, $value2$); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeRelease($value1$, $value2$); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet($value1$, $value2$); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire($value1$, $value2$); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease($value1$, $value2$); + }); +#end[CAS] + +#if[!AtomicAdd] + checkUOE(() -> { + $type$ o = ($type$) vh.getAndAdd($value1$); + }); + + checkUOE(() -> { + $type$ o = ($type$) vh.addAndGet($value1$); + }); +#end[AtomicAdd] + } + + + static void testInstanceField(VarHandleTestAccess$Type$ recv, VarHandle vh) { + // Plain + { + vh.set(recv, $value1$); + $type$ x = ($type$) vh.get(recv); + assertEquals(x, $value1$, "set $type$ value"); + } + + + // Volatile + { + vh.setVolatile(recv, $value2$); + $type$ x = ($type$) vh.getVolatile(recv); + assertEquals(x, $value2$, "setVolatile $type$ value"); + } + + // Lazy + { + vh.setRelease(recv, $value1$); + $type$ x = ($type$) vh.getAcquire(recv); + assertEquals(x, $value1$, "setRelease $type$ value"); + } + + // Opaque + { + vh.setOpaque(recv, $value2$); + $type$ x = ($type$) vh.getOpaque(recv); + assertEquals(x, $value2$, "setOpaque $type$ value"); + } + +#if[CAS] + vh.set(recv, $value1$); + + // Compare + { + 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"); + } + + { + 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"); + } + + { + $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value2$, $value1$); + assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$"); + $type$ x = ($type$) vh.get(recv); + assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value"); + } + + { + $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value2$, $value3$); + assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$"); + $type$ x = ($type$) vh.get(recv); + assertEquals(x, $value1$, "failing compareAndExchangeVolatile $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"); + } + + { + $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"); + } + + { + $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"); + } + + { + $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"); + } + + { + boolean r = vh.weakCompareAndSet(recv, $value1$, $value2$); + assertEquals(r, true, "weakCompareAndSet $type$"); + $type$ x = ($type$) vh.get(recv); + assertEquals(x, $value2$, "weakCompareAndSet $type$ value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(recv, $value2$, $value1$); + assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) vh.get(recv); + assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); + } + + { + boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$); + assertEquals(r, true, "weakCompareAndSetRelease $type$"); + $type$ x = ($type$) vh.get(recv); + assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); + } + + // Compare set and get + { + $type$ o = ($type$) vh.getAndSet(recv, $value1$); + assertEquals(o, $value2$, "getAndSet $type$"); + $type$ x = ($type$) vh.get(recv); + assertEquals(x, $value1$, "getAndSet $type$ value"); + } +#end[CAS] + +#if[AtomicAdd] + vh.set(recv, $value1$); + + // get and add, add and get + { + $type$ o = ($type$) vh.getAndAdd(recv, $value3$); + assertEquals(o, $value1$, "getAndAdd $type$"); + $type$ c = ($type$) vh.addAndGet(recv, $value3$); + assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value"); + } +#end[AtomicAdd] + } + + static void testInstanceFieldUnsupported(VarHandleTestAccess$Type$ recv, VarHandle vh) { +#if[!CAS] + checkUOE(() -> { + boolean r = vh.compareAndSet(recv, $value1$, $value2$); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value1$, $value2$); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value2$); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value1$, $value2$); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(recv, $value1$, $value2$); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value2$); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$); + }); +#end[CAS] + +#if[!AtomicAdd] + checkUOE(() -> { + $type$ o = ($type$) vh.getAndAdd(recv, $value1$); + }); + + checkUOE(() -> { + $type$ o = ($type$) vh.addAndGet(recv, $value1$); + }); +#end[AtomicAdd] + } + + + static void testStaticField(VarHandle vh) { + // Plain + { + vh.set($value1$); + $type$ x = ($type$) vh.get(); + assertEquals(x, $value1$, "set $type$ value"); + } + + + // Volatile + { + vh.setVolatile($value2$); + $type$ x = ($type$) vh.getVolatile(); + assertEquals(x, $value2$, "setVolatile $type$ value"); + } + + // Lazy + { + vh.setRelease($value1$); + $type$ x = ($type$) vh.getAcquire(); + assertEquals(x, $value1$, "setRelease $type$ value"); + } + + // Opaque + { + vh.setOpaque($value2$); + $type$ x = ($type$) vh.getOpaque(); + assertEquals(x, $value2$, "setOpaque $type$ value"); + } + +#if[CAS] + vh.set($value1$); + + // Compare + { + boolean r = vh.compareAndSet($value1$, $value2$); + assertEquals(r, true, "success compareAndSet $type$"); + $type$ x = ($type$) vh.get(); + assertEquals(x, $value2$, "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"); + } + + { + $type$ r = ($type$) vh.compareAndExchangeVolatile($value2$, $value1$); + assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$"); + $type$ x = ($type$) vh.get(); + assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value"); + } + + { + $type$ r = ($type$) vh.compareAndExchangeVolatile($value2$, $value3$); + assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$"); + $type$ x = ($type$) vh.get(); + assertEquals(x, $value1$, "failing compareAndExchangeVolatile $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"); + } + + { + $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"); + } + + { + $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"); + } + + { + $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"); + } + + { + boolean r = (boolean) vh.weakCompareAndSet($value1$, $value2$); + assertEquals(r, true, "weakCompareAndSet $type$"); + $type$ x = ($type$) vh.get(); + assertEquals(x, $value2$, "weakCompareAndSet $type$ value"); + } + + { + boolean r = (boolean) vh.weakCompareAndSetAcquire($value2$, $value1$); + assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) vh.get(); + assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); + } + + { + boolean r = (boolean) vh.weakCompareAndSetRelease( $value1$, $value2$); + assertEquals(r, true, "weakCompareAndSetRelease $type$"); + $type$ x = ($type$) vh.get(); + assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); + } + + // Compare set and get + { + $type$ o = ($type$) vh.getAndSet( $value1$); + assertEquals(o, $value2$, "getAndSet $type$"); + $type$ x = ($type$) vh.get(); + assertEquals(x, $value1$, "getAndSet $type$ value"); + } +#end[CAS] + +#if[AtomicAdd] + vh.set($value1$); + + // get and add, add and get + { + $type$ o = ($type$) vh.getAndAdd( $value3$); + assertEquals(o, $value1$, "getAndAdd $type$"); + $type$ c = ($type$) vh.addAndGet($value3$); + assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value"); + } +#end[AtomicAdd] + } + + static void testStaticFieldUnsupported(VarHandle vh) { +#if[!CAS] + checkUOE(() -> { + boolean r = vh.compareAndSet($value1$, $value2$); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeVolatile($value1$, $value2$); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeRelease($value1$, $value2$); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet($value1$, $value2$); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire($value1$, $value2$); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease($value1$, $value2$); + }); +#end[CAS] + +#if[!AtomicAdd] + checkUOE(() -> { + $type$ o = ($type$) vh.getAndAdd($value1$); + }); + + checkUOE(() -> { + $type$ o = ($type$) vh.addAndGet($value1$); + }); +#end[AtomicAdd] + } + + + static void testArray(VarHandle vh) { + $type$[] array = new $type$[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + vh.set(array, i, $value1$); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, $value1$, "get $type$ value"); + } + + + // Volatile + { + vh.setVolatile(array, i, $value2$); + $type$ x = ($type$) vh.getVolatile(array, i); + assertEquals(x, $value2$, "setVolatile $type$ value"); + } + + // Lazy + { + vh.setRelease(array, i, $value1$); + $type$ x = ($type$) vh.getAcquire(array, i); + assertEquals(x, $value1$, "setRelease $type$ value"); + } + + // Opaque + { + vh.setOpaque(array, i, $value2$); + $type$ x = ($type$) vh.getOpaque(array, i); + assertEquals(x, $value2$, "setOpaque $type$ value"); + } + +#if[CAS] + vh.set(array, i, $value1$); + + // Compare + { + 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"); + } + + { + 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"); + } + + { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, $value2$, $value1$); + assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value"); + } + + { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, $value2$, $value3$); + assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, $value1$, "failing compareAndExchangeVolatile $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"); + } + + { + $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"); + } + + { + $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"); + } + + { + $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"); + } + + { + boolean r = vh.weakCompareAndSet(array, i, $value1$, $value2$); + assertEquals(r, true, "weakCompareAndSet $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, $value2$, "weakCompareAndSet $type$ value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(array, i, $value2$, $value1$); + assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); + } + + { + boolean r = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$); + assertEquals(r, true, "weakCompareAndSetRelease $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); + } + + // Compare set and get + { + $type$ o = ($type$) vh.getAndSet(array, i, $value1$); + assertEquals(o, $value2$, "getAndSet $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, $value1$, "getAndSet $type$ value"); + } +#end[CAS] + +#if[AtomicAdd] + vh.set(array, i, $value1$); + + // get and add, add and get + { + $type$ o = ($type$) vh.getAndAdd(array, i, $value3$); + assertEquals(o, $value1$, "getAndAdd $type$"); + $type$ c = ($type$) vh.addAndGet(array, i, $value3$); + assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value"); + } +#end[AtomicAdd] + } + } + + static void testArrayUnsupported(VarHandle vh) { + $type$[] array = new $type$[10]; + + int i = 0; +#if[!CAS] + checkUOE(() -> { + boolean r = vh.compareAndSet(array, i, $value1$, $value2$); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, $value1$, $value2$); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value2$); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value1$, $value2$); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, i, $value1$, $value2$); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, i, $value1$, $value2$); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$); + }); +#end[CAS] + +#if[!AtomicAdd] + checkUOE(() -> { + $type$ o = ($type$) vh.getAndAdd(array, i, $value1$); + }); + + checkUOE(() -> { + $type$ o = ($type$) vh.addAndGet(array, i, $value1$); + }); +#end[AtomicAdd] + } + + static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable { + $type$[] array = new $type$[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + $type$ x = ($type$) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, $value1$); + }); + + checkIOOBE(() -> { + $type$ x = ($type$) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, $value1$); + }); + + checkIOOBE(() -> { + $type$ x = ($type$) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, $value1$); + }); + + checkIOOBE(() -> { + $type$ x = ($type$) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, $value1$); + }); + +#if[CAS] + checkIOOBE(() -> { + boolean r = vh.compareAndSet(array, ci, $value1$, $value2$); + }); + + checkIOOBE(() -> { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, $value2$, $value1$); + }); + + checkIOOBE(() -> { + $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, $value2$, $value1$); + }); + + checkIOOBE(() -> { + $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, $value2$, $value1$); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, $value1$, $value2$); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, $value1$, $value2$); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, $value1$, $value2$); + }); + + checkIOOBE(() -> { + $type$ o = ($type$) vh.getAndSet(array, ci, $value1$); + }); +#end[CAS] + +#if[AtomicAdd] + checkIOOBE(() -> { + $type$ o = ($type$) vh.getAndAdd(array, ci, $value3$); + }); + + checkIOOBE(() -> { + $type$ o = ($type$) vh.addAndGet(array, ci, $value3$); + }); +#end[AtomicAdd] + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template new file mode 100644 index 00000000000..ab9dac228d1 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template @@ -0,0 +1,1089 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAs$Type$ + * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAs$Type$ + * @run testng/othervm -Diters=20000 -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.*; + +public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { + static final int SIZE = $BoxType$.BYTES; + + static final $type$ VALUE_1 = $value1$; + + static final $type$ VALUE_2 = $value2$; + + static final $type$ VALUE_3 = $value3$; + + + @Override + public void setupVarHandleSources() { + // Combinations of VarHandle byte[] or ByteBuffer + vhss = new ArrayList<>(); + for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) { + VarHandleSource aeh = new VarHandleSource( + MethodHandles.byteArrayViewVarHandle($type$[].class, + endianess == MemoryMode.BIG_ENDIAN), + endianess, MemoryMode.READ_WRITE); + vhss.add(aeh); + + VarHandleSource bbh = new VarHandleSource( + MethodHandles.byteBufferViewVarHandle($type$[].class, + endianess == MemoryMode.BIG_ENDIAN), + endianess, MemoryMode.READ_WRITE); + vhss.add(bbh); + } + } + + + @Test(dataProvider = "varHandlesProvider") + public void testIsAccessModeSupported(VarHandleSource vhs) { + VarHandle vh = vhs.s; + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set)); + + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque)); + +#if[CAS] + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); +#else[CAS] + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet)); +#end[CAS] + +#if[AtomicAdd] + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); +#else[AtomicAdd] + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd)); + assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet)); +#end[AtomicAdd] + } + + @Test(dataProvider = "typesProvider") + public void testTypes(VarHandle vh, List> pts) { + assertEquals(vh.varType(), $type$.class); + + assertEquals(vh.coordinateTypes(), pts); + + testTypes(vh); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (ByteArrayViewSource bav : bavss) { + for (VarHandleSource vh : vhss) { + if (vh.matches(bav)) { + if (bav instanceof ByteArraySource) { + ByteArraySource bas = (ByteArraySource) bav; + + cases.add(new VarHandleSourceAccessTestCase( + "read write", bav, vh, h -> testArrayReadWrite(bas, h), + true)); + cases.add(new VarHandleSourceAccessTestCase( + "unsupported", bav, vh, h -> testArrayUnsupported(bas, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h), + false)); + } + else { + ByteBufferSource bbs = (ByteBufferSource) bav; + + if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) { + cases.add(new VarHandleSourceAccessTestCase( + "read write", bav, vh, h -> testArrayReadWrite(bbs, h), + true)); + } + else { + cases.add(new VarHandleSourceAccessTestCase( + "read only", bav, vh, h -> testArrayReadOnly(bbs, h), + true)); + } + + cases.add(new VarHandleSourceAccessTestCase( + "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h), + false)); + cases.add(new VarHandleSourceAccessTestCase( + "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h), + false)); + } + } + } + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + byte[] array = bs.s; + int ci = 1; + +#if[!CAS] + checkUOE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); + }); +#end[CAS] + +#if[!AtomicAdd] + checkUOE(() -> { + $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkUOE(() -> { + $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); + }); +#end[AtomicAdd] + } + + static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + int ci = 0; + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + + if (readOnly) { + checkROBE(() -> { + vh.set(array, ci, VALUE_1); + }); + } + + if (readOnly) { + checkROBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkROBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkROBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); +#if[CAS] + + checkROBE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkROBE(() -> { + $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkROBE(() -> { + $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkROBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkROBE(() -> { + $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); + }); + checkUOE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); +#else[CAS] + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); + }); +#end[CAS] + +#if[AtomicAdd] + checkROBE(() -> { + $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkROBE(() -> { + $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); + }); +#else[AtomicAdd] + checkUOE(() -> { + $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkUOE(() -> { + $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); + }); +#end[AtomicAdd] + } + else { +#if[!CAS] + checkUOE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkUOE(() -> { + $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); + }); +#end[CAS] +#if[!AtomicAdd] + checkUOE(() -> { + $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkUOE(() -> { + $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); + }); +#end[AtomicAdd] + } + } + + + static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int length = array.length - SIZE + 1; + for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + $type$ x = ($type$) vh.get(array, ci); + }); + + checkIOOBE(() -> { + vh.set(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + $type$ x = ($type$) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + $type$ x = ($type$) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + $type$ x = ($type$) vh.getOpaque(array, ci); + }); + + checkIOOBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); +#if[CAS] + + checkIOOBE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); + }); +#end[CAS] + +#if[AtomicAdd] + checkIOOBE(() -> { + $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); + }); +#end[AtomicAdd] + + } + } + + static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + + int length = array.limit() - SIZE + 1; + for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { + final int ci = i; + + checkIOOBE(() -> { + $type$ x = ($type$) vh.get(array, ci); + }); + + if (!readOnly) { + checkIOOBE(() -> { + vh.set(array, ci, VALUE_1); + }); + } + + checkIOOBE(() -> { + $type$ x = ($type$) vh.getVolatile(array, ci); + }); + + checkIOOBE(() -> { + $type$ x = ($type$) vh.getAcquire(array, ci); + }); + + checkIOOBE(() -> { + $type$ x = ($type$) vh.getOpaque(array, ci); + }); + + if (!readOnly) { + checkIOOBE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + +#if[CAS] + checkIOOBE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkIOOBE(() -> { + $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); + }); +#end[CAS] + +#if[AtomicAdd] + checkIOOBE(() -> { + $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkIOOBE(() -> { + $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); + }); +#end[AtomicAdd] + } + } + } + + static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); + + int length = array.length - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + final int ci = i; + + if (!iAligned) { + checkISE(() -> { + $type$ x = ($type$) vh.getVolatile(array, ci); + }); + + checkISE(() -> { + $type$ x = ($type$) vh.getAcquire(array, ci); + }); + + checkISE(() -> { + $type$ x = ($type$) vh.getOpaque(array, ci); + }); + + checkISE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); +#if[CAS] + + checkISE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); + }); +#end[CAS] + +#if[AtomicAdd] + checkISE(() -> { + $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkISE(() -> { + $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); + }); +#end[AtomicAdd] + + } + } + } + + static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + final int ci = i; + + if (!iAligned) { + checkISE(() -> { + $type$ x = ($type$) vh.getVolatile(array, ci); + }); + + checkISE(() -> { + $type$ x = ($type$) vh.getAcquire(array, ci); + }); + + checkISE(() -> { + $type$ x = ($type$) vh.getOpaque(array, ci); + }); + + if (!readOnly) { + checkISE(() -> { + vh.setVolatile(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setRelease(array, ci, VALUE_1); + }); + + checkISE(() -> { + vh.setOpaque(array, ci, VALUE_1); + }); + +#if[CAS] + checkISE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); + }); + + checkISE(() -> { + $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); + }); +#end[CAS] + +#if[AtomicAdd] + checkISE(() -> { + $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); + }); + + checkISE(() -> { + $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); + }); +#end[AtomicAdd] + } + } + } + } + + static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + byte[] array = bs.s; + + int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); + + bs.fill((byte) 0xff); + int length = array.length - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + // Plain + { + vh.set(array, i, VALUE_1); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_1, "get $type$ value"); + } + + + if (iAligned) { + // Volatile + { + vh.setVolatile(array, i, VALUE_2); + $type$ x = ($type$) vh.getVolatile(array, i); + assertEquals(x, VALUE_2, "setVolatile $type$ value"); + } + + // Lazy + { + vh.setRelease(array, i, VALUE_1); + $type$ x = ($type$) vh.getAcquire(array, i); + assertEquals(x, VALUE_1, "setRelease $type$ value"); + } + + // Opaque + { + vh.setOpaque(array, i, VALUE_2); + $type$ x = ($type$) vh.getOpaque(array, i); + assertEquals(x, VALUE_2, "setOpaque $type$ value"); + } +#if[CAS] + + vh.set(array, i, VALUE_1); + + // Compare + { + 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"); + } + + { + 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"); + } + + { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); + assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value"); + } + + { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); + assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $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"); + } + + { + $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"); + } + + { + $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"); + } + + { + $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"); + } + + { + boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSet $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$"); + } + + { + boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSetRelease $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$"); + } + + // Compare set and get + { + $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1); + assertEquals(o, VALUE_2, "getAndSet $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_1, "getAndSet $type$ value"); + } +#end[CAS] + +#if[AtomicAdd] + vh.set(array, i, VALUE_1); + + // get and add, add and get + { + $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3); + assertEquals(o, VALUE_1, "getAndAdd $type$"); + $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3); + assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value"); + } +#end[AtomicAdd] + } + } + } + + + static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + bs.fill((byte) 0xff); + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + // Plain + { + vh.set(array, i, VALUE_1); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_1, "get $type$ value"); + } + + if (iAligned) { + // Volatile + { + vh.setVolatile(array, i, VALUE_2); + $type$ x = ($type$) vh.getVolatile(array, i); + assertEquals(x, VALUE_2, "setVolatile $type$ value"); + } + + // Lazy + { + vh.setRelease(array, i, VALUE_1); + $type$ x = ($type$) vh.getAcquire(array, i); + assertEquals(x, VALUE_1, "setRelease $type$ value"); + } + + // Opaque + { + vh.setOpaque(array, i, VALUE_2); + $type$ x = ($type$) vh.getOpaque(array, i); + assertEquals(x, VALUE_2, "setOpaque $type$ value"); + } +#if[CAS] + + vh.set(array, i, VALUE_1); + + // Compare + { + 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"); + } + + { + 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"); + } + + { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); + assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value"); + } + + { + $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); + assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $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"); + } + + { + $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"); + } + + { + $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"); + } + + { + $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"); + } + + { + boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSet $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value"); + } + + { + boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$"); + } + + { + boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + assertEquals(r, true, "weakCompareAndSetRelease $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$"); + } + + // Compare set and get + { + $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1); + assertEquals(o, VALUE_2, "getAndSet $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_1, "getAndSet $type$ value"); + } +#end[CAS] + +#if[AtomicAdd] + vh.set(array, i, VALUE_1); + + // get and add, add and get + { + $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3); + assertEquals(o, VALUE_1, "getAndAdd $type$"); + $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3); + assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value"); + } +#end[AtomicAdd] + } + } + } + + static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) { + VarHandle vh = vhs.s; + ByteBuffer array = bs.s; + + int misalignmentAtZero = array.alignmentOffset(0, SIZE); + + ByteBuffer bb = ByteBuffer.allocate(SIZE); + bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); + bs.fill(bb.put$Type$(0, VALUE_2).array()); + + int length = array.limit() - SIZE + 1; + for (int i = 0; i < length; i++) { + boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; + + $type$ v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) + ? rotateLeft(VALUE_2, (i % SIZE) << 3) + : rotateRight(VALUE_2, (i % SIZE) << 3); + // Plain + { + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, v, "get $type$ value"); + } + + if (iAligned) { + // Volatile + { + $type$ x = ($type$) vh.getVolatile(array, i); + assertEquals(x, v, "getVolatile $type$ value"); + } + + // Lazy + { + $type$ x = ($type$) vh.getAcquire(array, i); + assertEquals(x, v, "getRelease $type$ value"); + } + + // Opaque + { + $type$ x = ($type$) vh.getOpaque(array, i); + assertEquals(x, v, "getOpaque $type$ value"); + } + } + } + } + +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template new file mode 100644 index 00000000000..f28ab09da3d --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template @@ -0,0 +1,667 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccess$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.*; + +public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { + static final $type$ static_final_v = $value1$; + + static $type$ static_v; + + final $type$ final_v = $value1$; + + $type$ v; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccess$Type$.class, "final_v", $type$.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodHandleAccess$Type$.class, "v", $type$.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccess$Type$.class, "static_final_v", $type$.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodHandleAccess$Type$.class, "static_v", $type$.class); + + vhArray = MethodHandles.arrayElementVarHandle($type$[].class); + } + + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field", + vhField, f, hs -> testInstanceField(this, hs))); + cases.add(new MethodHandleAccessTestCase("Instance field unsupported", + vhField, f, hs -> testInstanceFieldUnsupported(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field", + vhStaticField, f, VarHandleTestMethodHandleAccess$Type$::testStaticField)); + cases.add(new MethodHandleAccessTestCase("Static field unsupported", + vhStaticField, f, VarHandleTestMethodHandleAccess$Type$::testStaticFieldUnsupported, + false)); + + cases.add(new MethodHandleAccessTestCase("Array", + vhArray, f, VarHandleTestMethodHandleAccess$Type$::testArray)); + cases.add(new MethodHandleAccessTestCase("Array unsupported", + vhArray, f, VarHandleTestMethodHandleAccess$Type$::testArrayUnsupported, + false)); + cases.add(new MethodHandleAccessTestCase("Array index out of bounds", + vhArray, f, VarHandleTestMethodHandleAccess$Type$::testArrayIndexOutOfBounds, + false)); + } + + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + 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"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(recv, $value2$); + $type$ x = ($type$) hs.get(TestAccessMode.getVolatile).invokeExact(recv); + assertEquals(x, $value2$, "setVolatile $type$ value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(recv, $value1$); + $type$ x = ($type$) hs.get(TestAccessMode.getAcquire).invokeExact(recv); + assertEquals(x, $value1$, "setRelease $type$ value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(recv, $value2$); + $type$ x = ($type$) hs.get(TestAccessMode.getOpaque).invokeExact(recv); + assertEquals(x, $value2$, "setOpaque $type$ value"); + } + +#if[CAS] + hs.get(TestAccessMode.set).invokeExact(recv, $value1$); + + // Compare + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).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"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).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"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, $value2$, $value1$); + assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, $value2$, $value3$); + assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).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"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).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"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).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"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).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"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(recv, $value1$, $value2$); + assertEquals(r, true, "weakCompareAndSet $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, $value2$, "weakCompareAndSet $type$ value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(recv, $value2$, $value1$); + assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(recv, $value1$, $value2$); + assertEquals(r, true, "weakCompareAndSetRelease $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); + } + + // Compare set and get + { + $type$ o = ($type$) hs.get(TestAccessMode.getAndSet).invokeExact(recv, $value1$); + assertEquals(o, $value2$, "getAndSet $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv); + assertEquals(x, $value1$, "getAndSet $type$ value"); + } +#end[CAS] + +#if[AtomicAdd] + hs.get(TestAccessMode.set).invokeExact(recv, $value1$); + + // get and add, add and get + { + $type$ o = ($type$) hs.get(TestAccessMode.getAndAdd).invokeExact(recv, $value3$); + assertEquals(o, $value1$, "getAndAdd $type$"); + $type$ c = ($type$) hs.get(TestAccessMode.addAndGet).invokeExact(recv, $value3$); + assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value"); + } +#end[AtomicAdd] + } + + static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccess$Type$ recv, Handles hs) throws Throwable { +#if[!CAS] + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(recv, $value1$, $value2$); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$, $value2$); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$); + }); + } +#end[CAS] + +#if[!AtomicAdd] + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$); + }); + } +#end[AtomicAdd] + } + + + static void testStaticField(Handles hs) throws Throwable { + // Plain + { + hs.get(TestAccessMode.set).invokeExact($value1$); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, $value1$, "set $type$ value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact($value2$); + $type$ x = ($type$) hs.get(TestAccessMode.getVolatile).invokeExact(); + assertEquals(x, $value2$, "setVolatile $type$ value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact($value1$); + $type$ x = ($type$) hs.get(TestAccessMode.getAcquire).invokeExact(); + assertEquals(x, $value1$, "setRelease $type$ value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact($value2$); + $type$ x = ($type$) hs.get(TestAccessMode.getOpaque).invokeExact(); + assertEquals(x, $value2$, "setOpaque $type$ value"); + } + +#if[CAS] + hs.get(TestAccessMode.set).invokeExact($value1$); + + // Compare + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact($value1$, $value2$); + assertEquals(r, true, "success compareAndSet $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, $value2$, "success compareAndSet $type$ value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact($value1$, $value3$); + assertEquals(r, false, "failing compareAndSet $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, $value2$, "failing compareAndSet $type$ value"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact($value2$, $value1$); + assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact($value2$, $value3$); + assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact($value1$, $value2$); + assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact($value1$, $value3$); + assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact($value2$, $value1$); + assertEquals(r, $value2$, "success compareAndExchangeRelease $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact($value2$, $value3$); + assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact($value1$, $value2$); + assertEquals(r, true, "weakCompareAndSet $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, $value2$, "weakCompareAndSet $type$ value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact($value2$, $value1$); + assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact( $value1$, $value2$); + assertEquals(r, true, "weakCompareAndSetRelease $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); + } + + // Compare set and get + { + $type$ o = ($type$) hs.get(TestAccessMode.getAndSet).invokeExact( $value1$); + assertEquals(o, $value2$, "getAndSet $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(); + assertEquals(x, $value1$, "getAndSet $type$ value"); + } +#end[CAS] + +#if[AtomicAdd] + hs.get(TestAccessMode.set).invokeExact($value1$); + + // get and add, add and get + { + $type$ o = ($type$) hs.get(TestAccessMode.getAndAdd).invokeExact( $value3$); + assertEquals(o, $value1$, "getAndAdd $type$"); + $type$ c = ($type$) hs.get(TestAccessMode.addAndGet).invokeExact($value3$); + assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value"); + } +#end[AtomicAdd] + } + + static void testStaticFieldUnsupported(Handles hs) throws Throwable { +#if[!CAS] + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact($value1$, $value2$); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + $type$ r = ($type$) hs.get(am).invokeExact($value1$, $value2$); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + $type$ r = ($type$) hs.get(am).invokeExact($value1$); + }); + } +#end[CAS] + +#if[!AtomicAdd] + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + $type$ r = ($type$) hs.get(am).invokeExact($value1$); + }); + } +#end[AtomicAdd] + } + + + static void testArray(Handles hs) throws Throwable { + $type$[] array = new $type$[10]; + + for (int i = 0; i < array.length; i++) { + // Plain + { + hs.get(TestAccessMode.set).invokeExact(array, i, $value1$); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, $value1$, "get $type$ value"); + } + + + // Volatile + { + hs.get(TestAccessMode.setVolatile).invokeExact(array, i, $value2$); + $type$ x = ($type$) hs.get(TestAccessMode.getVolatile).invokeExact(array, i); + assertEquals(x, $value2$, "setVolatile $type$ value"); + } + + // Lazy + { + hs.get(TestAccessMode.setRelease).invokeExact(array, i, $value1$); + $type$ x = ($type$) hs.get(TestAccessMode.getAcquire).invokeExact(array, i); + assertEquals(x, $value1$, "setRelease $type$ value"); + } + + // Opaque + { + hs.get(TestAccessMode.setOpaque).invokeExact(array, i, $value2$); + $type$ x = ($type$) hs.get(TestAccessMode.getOpaque).invokeExact(array, i); + assertEquals(x, $value2$, "setOpaque $type$ value"); + } + +#if[CAS] + hs.get(TestAccessMode.set).invokeExact(array, i, $value1$); + + // Compare + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).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"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).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"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, $value2$, $value1$); + assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, $value2$, $value3$); + assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).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"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).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"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).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"); + } + + { + $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).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"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(array, i, $value1$, $value2$); + assertEquals(r, true, "weakCompareAndSet $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, $value2$, "weakCompareAndSet $type$ value"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(array, i, $value2$, $value1$); + assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); + } + + { + boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(array, i, $value1$, $value2$); + assertEquals(r, true, "weakCompareAndSetRelease $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); + } + + // Compare set and get + { + $type$ o = ($type$) hs.get(TestAccessMode.getAndSet).invokeExact(array, i, $value1$); + assertEquals(o, $value2$, "getAndSet $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i); + assertEquals(x, $value1$, "getAndSet $type$ value"); + } +#end[CAS] + +#if[AtomicAdd] + hs.get(TestAccessMode.set).invokeExact(array, i, $value1$); + + // get and add, add and get + { + $type$ o = ($type$) hs.get(TestAccessMode.getAndAdd).invokeExact(array, i, $value3$); + assertEquals(o, $value1$, "getAndAdd $type$"); + $type$ c = ($type$) hs.get(TestAccessMode.addAndGet).invokeExact(array, i, $value3$); + assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value"); + } +#end[AtomicAdd] + } + } + + static void testArrayUnsupported(Handles hs) throws Throwable { + $type$[] array = new $type$[10]; + + final int i = 0; +#if[!CAS] + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkUOE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(array, i, $value1$, $value2$); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkUOE(am, () -> { + $type$ r = ($type$) hs.get(am).invokeExact(array, i, $value1$, $value2$); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkUOE(am, () -> { + $type$ r = ($type$) hs.get(am).invokeExact(array, i, $value1$); + }); + } +#end[CAS] + +#if[!AtomicAdd] + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkUOE(am, () -> { + $type$ o = ($type$) hs.get(am).invokeExact(array, i, $value1$); + }); + } +#end[AtomicAdd] + } + + static void testArrayIndexOutOfBounds(Handles hs) throws Throwable { + $type$[] array = new $type$[10]; + + for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { + final int ci = i; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + checkIOOBE(am, () -> { + $type$ x = ($type$) hs.get(am).invokeExact(array, ci); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + checkIOOBE(am, () -> { + hs.get(am).invokeExact(array, ci, $value1$); + }); + } + +#if[CAS] + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + checkIOOBE(am, () -> { + boolean r = (boolean) hs.get(am).invokeExact(array, ci, $value1$, $value2$); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkIOOBE(am, () -> { + $type$ r = ($type$) hs.get(am).invokeExact(array, ci, $value2$, $value1$); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkIOOBE(am, () -> { + $type$ o = ($type$) hs.get(am).invokeExact(array, ci, $value1$); + }); + } +#end[CAS] + +#if[AtomicAdd] + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkIOOBE(am, () -> { + $type$ o = ($type$) hs.get(am).invokeExact(array, ci, $value3$); + }); + } +#end[AtomicAdd] + } + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template new file mode 100644 index 00000000000..85010bc5c5a --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template @@ -0,0 +1,2099 @@ +/* + * Copyright (c) 2015, 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 + * @run testng/othervm VarHandleTestMethodType$Type$ + * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false 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.*; + +public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest { + static final $type$ static_final_v = $value1$; + + static $type$ static_v = $value1$; + + final $type$ final_v = $value1$; + + $type$ v = $value1$; + + VarHandle vhFinalField; + + VarHandle vhField; + + VarHandle vhStaticField; + + VarHandle vhStaticFinalField; + + VarHandle vhArray; + + @BeforeClass + public void setup() throws Exception { + vhFinalField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodType$Type$.class, "final_v", $type$.class); + + vhField = MethodHandles.lookup().findVarHandle( + VarHandleTestMethodType$Type$.class, "v", $type$.class); + + vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodType$Type$.class, "static_final_v", $type$.class); + + vhStaticField = MethodHandles.lookup().findStaticVarHandle( + VarHandleTestMethodType$Type$.class, "static_v", $type$.class); + + vhArray = MethodHandles.arrayElementVarHandle($type$[].class); + } + + @DataProvider + public Object[][] accessTestCaseProvider() throws Exception { + List> cases = new ArrayList<>(); + + cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + vhField, vh -> testInstanceFieldWrongMethodType(this, vh), + false)); + + cases.add(new VarHandleAccessTestCase("Static field wrong method type", + vhStaticField, VarHandleTestMethodType$Type$::testStaticFieldWrongMethodType, + false)); + + cases.add(new VarHandleAccessTestCase("Array wrong method type", + vhArray, VarHandleTestMethodType$Type$::testArrayWrongMethodType, + false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { + cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), + false)); + + cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + vhStaticField, f, VarHandleTestMethodType$Type$::testStaticFieldWrongMethodType, + false)); + + cases.add(new MethodHandleAccessTestCase("Array wrong method type", + vhArray, f, VarHandleTestMethodType$Type$::testArrayWrongMethodType, + false)); + } + // Work around issue with jtreg summary reporting which truncates + // the String result of Object.toString to 30 characters, hence + // the first dummy argument + return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); + } + + @Test(dataProvider = "accessTestCaseProvider") + public void testAccess(String desc, AccessTestCase atc) throws Throwable { + T t = atc.get(); + int iters = atc.requiresLoop() ? ITERS : 1; + for (int c = 0; c < iters; c++) { + atc.testAccess(t); + } + } + + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodType$Type$ recv, VarHandle vh) throws Throwable { + // Get + // Incorrect argument types + checkNPE(() -> { // null receiver + $type$ x = ($type$) vh.get(null); + }); + checkCCE(() -> { // receiver reference class + $type$ x = ($type$) vh.get(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + $type$ x = ($type$) vh.get(0); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void x = (Void) vh.get(recv); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.get(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.get(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.get(recv, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.set(null, $value1$); + }); + checkCCE(() -> { // receiver reference class + vh.set(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + vh.set(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(recv, $value1$, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + $type$ x = ($type$) vh.getVolatile(null); + }); + checkCCE(() -> { // receiver reference class + $type$ x = ($type$) vh.getVolatile(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + $type$ x = ($type$) vh.getVolatile(0); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void x = (Void) vh.getVolatile(recv); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getVolatile(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.getVolatile(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.getVolatile(recv, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setVolatile(null, $value1$); + }); + checkCCE(() -> { // receiver reference class + vh.setVolatile(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + vh.setVolatile(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(recv, $value1$, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + $type$ x = ($type$) vh.getOpaque(null); + }); + checkCCE(() -> { // receiver reference class + $type$ x = ($type$) vh.getOpaque(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + $type$ x = ($type$) vh.getOpaque(0); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void x = (Void) vh.getOpaque(recv); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getOpaque(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.getOpaque(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.getOpaque(recv, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setOpaque(null, $value1$); + }); + checkCCE(() -> { // receiver reference class + vh.setOpaque(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + vh.setOpaque(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(recv, $value1$, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + $type$ x = ($type$) vh.getAcquire(null); + }); + checkCCE(() -> { // receiver reference class + $type$ x = ($type$) vh.getAcquire(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + $type$ x = ($type$) vh.getAcquire(0); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void x = (Void) vh.getAcquire(recv); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAcquire(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.getAcquire(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.getAcquire(recv, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + vh.setRelease(null, $value1$); + }); + checkCCE(() -> { // receiver reference class + vh.setRelease(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + vh.setRelease(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(recv, $value1$, Void.class); + }); + + +#if[CAS] + // CompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.compareAndSet(null, $value1$, $value1$); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.compareAndSet(Void.class, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + boolean r = vh.compareAndSet(recv, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + boolean r = vh.compareAndSet(recv, $value1$, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.compareAndSet(0, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.compareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.compareAndSet(recv, $value1$, $value1$, Void.class); + }); + + + // WeakCompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSet(null, $value1$, $value1$); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSet(Void.class, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + boolean r = vh.weakCompareAndSet(recv, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + boolean r = vh.weakCompareAndSet(recv, $value1$, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSet(0, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSet(recv, $value1$, $value1$, Void.class); + }); + + + // WeakCompareAndSetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetAcquire(null, $value1$, $value1$); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetAcquire(Void.class, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + boolean r = vh.weakCompareAndSetAcquire(recv, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetAcquire(0, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetAcquire(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value1$, Void.class); + }); + + + // WeakCompareAndSetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetRelease(null, $value1$, $value1$); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetRelease(Void.class, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + boolean r = vh.weakCompareAndSetRelease(recv, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + boolean r = vh.weakCompareAndSetRelease(recv, $value1$, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetRelease(0, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetRelease(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value1$, Void.class); + }); + + + // CompareAndExchangeVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + $type$ x = ($type$) vh.compareAndExchangeVolatile(null, $value1$, $value1$); + }); + checkCCE(() -> { // receiver reference class + $type$ x = ($type$) vh.compareAndExchangeVolatile(Void.class, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + $type$ x = ($type$) vh.compareAndExchangeVolatile(recv, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + $type$ x = ($type$) vh.compareAndExchangeVolatile(recv, $value1$, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + $type$ x = ($type$) vh.compareAndExchangeVolatile(0, $value1$, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.compareAndExchangeVolatile(recv, $value1$, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeVolatile(recv, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.compareAndExchangeVolatile(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.compareAndExchangeVolatile(recv, $value1$, $value1$, Void.class); + }); + + + // CompareAndExchangeVolatileAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + $type$ x = ($type$) vh.compareAndExchangeAcquire(null, $value1$, $value1$); + }); + checkCCE(() -> { // receiver reference class + $type$ x = ($type$) vh.compareAndExchangeAcquire(Void.class, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + $type$ x = ($type$) vh.compareAndExchangeAcquire(recv, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + $type$ x = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + $type$ x = ($type$) vh.compareAndExchangeAcquire(0, $value1$, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.compareAndExchangeAcquire(recv, $value1$, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeAcquire(recv, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.compareAndExchangeAcquire(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value1$, Void.class); + }); + + + // CompareAndExchangeRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + $type$ x = ($type$) vh.compareAndExchangeRelease(null, $value1$, $value1$); + }); + checkCCE(() -> { // receiver reference class + $type$ x = ($type$) vh.compareAndExchangeRelease(Void.class, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + $type$ x = ($type$) vh.compareAndExchangeRelease(recv, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + $type$ x = ($type$) vh.compareAndExchangeRelease(recv, $value1$, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + $type$ x = ($type$) vh.compareAndExchangeRelease(0, $value1$, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.compareAndExchangeRelease(recv, $value1$, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeRelease(recv, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.compareAndExchangeRelease(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.compareAndExchangeRelease(recv, $value1$, $value1$, Void.class); + }); + + + // GetAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + $type$ x = ($type$) vh.getAndSet(null, $value1$); + }); + checkCCE(() -> { // receiver reference class + $type$ x = ($type$) vh.getAndSet(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + $type$ x = ($type$) vh.getAndSet(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + $type$ x = ($type$) vh.getAndSet(0, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.getAndSet(recv, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndSet(recv, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.getAndSet(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.getAndSet(recv, $value1$, Void.class); + }); +#end[CAS] + +#if[AtomicAdd] + // GetAndAdd + // Incorrect argument types + checkNPE(() -> { // null receiver + $type$ x = ($type$) vh.getAndAdd(null, $value1$); + }); + checkCCE(() -> { // receiver reference class + $type$ x = ($type$) vh.getAndAdd(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + $type$ x = ($type$) vh.getAndAdd(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + $type$ x = ($type$) vh.getAndAdd(0, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.getAndAdd(recv, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndAdd(recv, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.getAndAdd(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.getAndAdd(recv, $value1$, Void.class); + }); + + + // AddAndGet + // Incorrect argument types + checkNPE(() -> { // null receiver + $type$ x = ($type$) vh.addAndGet(null, $value1$); + }); + checkCCE(() -> { // receiver reference class + $type$ x = ($type$) vh.addAndGet(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + $type$ x = ($type$) vh.addAndGet(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + $type$ x = ($type$) vh.addAndGet(0, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.addAndGet(recv, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.addAndGet(recv, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.addAndGet(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.addAndGet(recv, $value1$, Void.class); + }); +#end[AtomicAdd] + } + + static void testInstanceFieldWrongMethodType(VarHandleTestMethodType$Type$ recv, Handles hs) throws Throwable { + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class)). + invoke(null); + }); + checkCCE(() -> { // receiver reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class)). + invoke(Void.class); + }); + checkWMTE(() -> { // receiver primitive class + $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class)). + invoke(0); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void x = (Void) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class)). + invoke(recv); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class)). + invoke(recv); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) hs.get(am, methodType($type$.class)). + invoke(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class)). + invoke(recv, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + hs.get(am, methodType(void.class, Void.class, $type$.class)). + invoke(null, $value1$); + }); + checkCCE(() -> { // receiver reference class + hs.get(am, methodType(void.class, Class.class, $type$.class)). + invoke(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + hs.get(am, methodType(void.class, VarHandleTestMethodType$Type$.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, $type$.class)). + invoke(0, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, VarHandleTestMethodType$Type$.class, $type$.class, Class.class)). + invoke(recv, $value1$, Void.class); + }); + } + +#if[CAS] + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, $type$.class, $type$.class)). + invoke(null, $value1$, $value1$); + }); + checkCCE(() -> { // receiver reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, $type$.class, $type$.class)). + invoke(Void.class, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodType$Type$.class, Class.class, $type$.class)). + invoke(recv, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodType$Type$.class, $type$.class, Class.class)). + invoke(recv, $value1$, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , $type$.class, $type$.class)). + invoke(0, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + checkWMTE(() -> { // > + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodType$Type$.class, $type$.class, $type$.class, Class.class)). + invoke(recv, $value1$, $value1$, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + checkNPE(() -> { // null receiver + $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, $type$.class, $type$.class)). + invoke(null, $value1$, $value1$); + }); + checkCCE(() -> { // receiver reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class, $type$.class)). + invoke(Void.class, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class, $type$.class)). + invoke(recv, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class, Class.class)). + invoke(recv, $value1$, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class , $type$.class, $type$.class)). + invoke(0, $value1$, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodType$Type$.class , $type$.class, $type$.class)). + invoke(recv, $value1$, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class , $type$.class, $type$.class)). + invoke(recv, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) hs.get(am, methodType($type$.class)). + invoke(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class, $type$.class, Class.class)). + invoke(recv, $value1$, $value1$, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + checkNPE(() -> { // null receiver + $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, $type$.class)). + invoke(null, $value1$); + }); + checkCCE(() -> { // receiver reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class)). + invoke(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, $type$.class)). + invoke(0, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodType$Type$.class, $type$.class)). + invoke(recv, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class, $type$.class)). + invoke(recv, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) hs.get(am, methodType($type$.class)). + invoke(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class)). + invoke(recv, $value1$, Void.class); + }); + } +#end[CAS] + +#if[AtomicAdd] + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + checkNPE(() -> { // null receiver + $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, $type$.class)). + invoke(null, $value1$); + }); + checkCCE(() -> { // receiver reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class)). + invoke(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class)). + invoke(recv, Void.class); + }); + checkWMTE(() -> { // reciever primitive class + $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, $type$.class)). + invoke(0, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodType$Type$.class, $type$.class)). + invoke(recv, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class, $type$.class)). + invoke(recv, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) hs.get(am, methodType($type$.class)). + invoke(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class)). + invoke(recv, $value1$, Void.class); + }); + } +#end[AtomicAdd] + } + + + static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable { + // Get + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void x = (Void) vh.get(); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.get(); + }); + // Incorrect arity + checkWMTE(() -> { // > + $type$ x = ($type$) vh.get(Void.class); + }); + + + // Set + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // value reference class + vh.set(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set($value1$, Void.class); + }); + + + // GetVolatile + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void x = (Void) vh.getVolatile(); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getVolatile(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.getVolatile(Void.class); + }); + + + // SetVolatile + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // value reference class + vh.setVolatile(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile($value1$, Void.class); + }); + + + // GetOpaque + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void x = (Void) vh.getOpaque(); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getOpaque(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.getOpaque(Void.class); + }); + + + // SetOpaque + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // value reference class + vh.setOpaque(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque($value1$, Void.class); + }); + + + // GetAcquire + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void x = (Void) vh.getAcquire(); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAcquire(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.getAcquire(Void.class); + }); + + + // SetRelease + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // value reference class + vh.setRelease(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease($value1$, Void.class); + }); + + +#if[CAS] + // CompareAndSet + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + boolean r = vh.compareAndSet(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + boolean r = vh.compareAndSet($value1$, Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.compareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.compareAndSet($value1$, $value1$, Void.class); + }); + + + // WeakCompareAndSet + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + boolean r = vh.weakCompareAndSet(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + boolean r = vh.weakCompareAndSet($value1$, Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSet($value1$, $value1$, Void.class); + }); + + + // WeakCompareAndSetAcquire + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + boolean r = vh.weakCompareAndSetAcquire(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + boolean r = vh.weakCompareAndSetAcquire($value1$, Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetAcquire(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetAcquire($value1$, $value1$, Void.class); + }); + + + // WeakCompareAndSetRelease + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + boolean r = vh.weakCompareAndSetRelease(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + boolean r = vh.weakCompareAndSetRelease($value1$, Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetRelease(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetRelease($value1$, $value1$, Void.class); + }); + + + // CompareAndExchangeVolatile + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + $type$ x = ($type$) vh.compareAndExchangeVolatile(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + $type$ x = ($type$) vh.compareAndExchangeVolatile($value1$, Void.class); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.compareAndExchangeVolatile($value1$, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeVolatile($value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.compareAndExchangeVolatile(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.compareAndExchangeVolatile($value1$, $value1$, Void.class); + }); + + + // CompareAndExchangeAcquire + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + $type$ x = ($type$) vh.compareAndExchangeAcquire(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + $type$ x = ($type$) vh.compareAndExchangeAcquire($value1$, Void.class); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.compareAndExchangeAcquire($value1$, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeAcquire($value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.compareAndExchangeAcquire(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.compareAndExchangeAcquire($value1$, $value1$, Void.class); + }); + + + // CompareAndExchangeRelease + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + $type$ x = ($type$) vh.compareAndExchangeRelease(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + $type$ x = ($type$) vh.compareAndExchangeRelease($value1$, Void.class); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.compareAndExchangeRelease($value1$, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeRelease($value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.compareAndExchangeRelease(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.compareAndExchangeRelease($value1$, $value1$, Void.class); + }); + + + // GetAndSet + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // value reference class + $type$ x = ($type$) vh.getAndSet(Void.class); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.getAndSet($value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndSet($value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.getAndSet(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.getAndSet($value1$, Void.class); + }); +#end[CAS] + +#if[AtomicAdd] + // GetAndAdd + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // value reference class + $type$ x = ($type$) vh.getAndAdd(Void.class); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.getAndAdd($value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndAdd($value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.getAndAdd(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.getAndAdd($value1$, Void.class); + }); + + + // AddAndGet + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // value reference class + $type$ x = ($type$) vh.addAndGet(Void.class); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.addAndGet($value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.addAndGet($value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.addAndGet(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.addAndGet($value1$, Void.class); + }); +#end[AtomicAdd] + } + + static void testStaticFieldWrongMethodType(Handles hs) throws Throwable { + int i = 0; + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class)). + invoke(); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class)). + invoke(); + }); + // Incorrect arity + checkWMTE(() -> { // > + $type$ x = ($type$) hs.get(am, methodType(Class.class)). + invoke(Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + check{#if[String]?CCE:WMTE}(() -> { // value reference class + hs.get(am, methodType(void.class, Class.class)). + invoke(Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, $type$.class, Class.class)). + invoke($value1$, Void.class); + }); + } +#if[CAS] + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, $type$.class)). + invoke(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$.class, Class.class)). + invoke($value1$, Void.class); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + checkWMTE(() -> { // > + boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$.class, $type$.class, Class.class)). + invoke($value1$, $value1$, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class)). + invoke(Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, Class.class)). + invoke($value1$, Void.class); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, $type$.class, $type$.class)). + invoke($value1$, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$.class, $type$.class)). + invoke($value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) hs.get(am, methodType($type$.class)). + invoke(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, $type$.class, Class.class)). + invoke($value1$, $value1$, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // value reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class)). + invoke(Void.class); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, $type$.class)). + invoke($value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$.class)). + invoke($value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) hs.get(am, methodType($type$.class)). + invoke(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, Class.class)). + invoke($value1$, Void.class); + }); + } +#end[CAS] + +#if[AtomicAdd] + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + // Incorrect argument types + check{#if[String]?CCE:WMTE}(() -> { // value reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class)). + invoke(Void.class); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, $type$.class)). + invoke($value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$.class)). + invoke($value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) hs.get(am, methodType($type$.class)). + invoke(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, Class.class)). + invoke($value1$, Void.class); + }); + } +#end[AtomicAdd] + } + + + static void testArrayWrongMethodType(VarHandle vh) throws Throwable { + $type$[] array = new $type$[10]; + Arrays.fill(array, $value1$); + + // Get + // Incorrect argument types + checkNPE(() -> { // null array + $type$ x = ($type$) vh.get(null, 0); + }); + checkCCE(() -> { // array reference class + $type$ x = ($type$) vh.get(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + $type$ x = ($type$) vh.get(0, 0); + }); + checkWMTE(() -> { // index reference class + $type$ x = ($type$) vh.get(array, Void.class); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void x = (Void) vh.get(array, 0); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.get(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.get(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.get(array, 0, Void.class); + }); + + + // Set + // Incorrect argument types + checkNPE(() -> { // null array + vh.set(null, 0, $value1$); + }); + checkCCE(() -> { // array reference class + vh.set(Void.class, 0, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + vh.set(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.set(0, 0, $value1$); + }); + checkWMTE(() -> { // index reference class + vh.set(array, Void.class, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.set(); + }); + checkWMTE(() -> { // > + vh.set(array, 0, $value1$, Void.class); + }); + + + // GetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + $type$ x = ($type$) vh.getVolatile(null, 0); + }); + checkCCE(() -> { // array reference class + $type$ x = ($type$) vh.getVolatile(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + $type$ x = ($type$) vh.getVolatile(0, 0); + }); + checkWMTE(() -> { // index reference class + $type$ x = ($type$) vh.getVolatile(array, Void.class); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void x = (Void) vh.getVolatile(array, 0); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getVolatile(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.getVolatile(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.getVolatile(array, 0, Void.class); + }); + + + // SetVolatile + // Incorrect argument types + checkNPE(() -> { // null array + vh.setVolatile(null, 0, $value1$); + }); + checkCCE(() -> { // array reference class + vh.setVolatile(Void.class, 0, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + vh.setVolatile(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setVolatile(0, 0, $value1$); + }); + checkWMTE(() -> { // index reference class + vh.setVolatile(array, Void.class, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setVolatile(); + }); + checkWMTE(() -> { // > + vh.setVolatile(array, 0, $value1$, Void.class); + }); + + + // GetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + $type$ x = ($type$) vh.getOpaque(null, 0); + }); + checkCCE(() -> { // array reference class + $type$ x = ($type$) vh.getOpaque(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + $type$ x = ($type$) vh.getOpaque(0, 0); + }); + checkWMTE(() -> { // index reference class + $type$ x = ($type$) vh.getOpaque(array, Void.class); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void x = (Void) vh.getOpaque(array, 0); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getOpaque(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.getOpaque(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.getOpaque(array, 0, Void.class); + }); + + + // SetOpaque + // Incorrect argument types + checkNPE(() -> { // null array + vh.setOpaque(null, 0, $value1$); + }); + checkCCE(() -> { // array reference class + vh.setOpaque(Void.class, 0, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + vh.setOpaque(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setOpaque(0, 0, $value1$); + }); + checkWMTE(() -> { // index reference class + vh.setOpaque(array, Void.class, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setOpaque(); + }); + checkWMTE(() -> { // > + vh.setOpaque(array, 0, $value1$, Void.class); + }); + + + // GetAcquire + // Incorrect argument types + checkNPE(() -> { // null array + $type$ x = ($type$) vh.getAcquire(null, 0); + }); + checkCCE(() -> { // array reference class + $type$ x = ($type$) vh.getAcquire(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + $type$ x = ($type$) vh.getAcquire(0, 0); + }); + checkWMTE(() -> { // index reference class + $type$ x = ($type$) vh.getAcquire(array, Void.class); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void x = (Void) vh.getAcquire(array, 0); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAcquire(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.getAcquire(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.getAcquire(array, 0, Void.class); + }); + + + // SetRelease + // Incorrect argument types + checkNPE(() -> { // null array + vh.setRelease(null, 0, $value1$); + }); + checkCCE(() -> { // array reference class + vh.setRelease(Void.class, 0, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + vh.setRelease(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + vh.setRelease(0, 0, $value1$); + }); + checkWMTE(() -> { // index reference class + vh.setRelease(array, Void.class, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + vh.setRelease(); + }); + checkWMTE(() -> { // > + vh.setRelease(array, 0, $value1$, Void.class); + }); + + +#if[CAS] + // CompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.compareAndSet(null, 0, $value1$, $value1$); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.compareAndSet(Void.class, 0, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + boolean r = vh.compareAndSet(array, 0, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + boolean r = vh.compareAndSet(array, 0, $value1$, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.compareAndSet(0, 0, $value1$, $value1$); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.compareAndSet(array, Void.class, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.compareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.compareAndSet(array, 0, $value1$, $value1$, Void.class); + }); + + + // WeakCompareAndSet + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSet(null, 0, $value1$, $value1$); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSet(Void.class, 0, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + boolean r = vh.weakCompareAndSet(array, 0, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + boolean r = vh.weakCompareAndSet(array, 0, $value1$, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSet(0, 0, $value1$, $value1$); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.weakCompareAndSet(array, Void.class, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSet(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSet(array, 0, $value1$, $value1$, Void.class); + }); + + + // WeakCompareAndSetAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetAcquire(null, 0, $value1$, $value1$); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + boolean r = vh.weakCompareAndSetAcquire(array, 0, $value1$, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetAcquire(0, 0, $value1$, $value1$); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.weakCompareAndSetAcquire(array, Void.class, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetAcquire(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetAcquire(array, 0, $value1$, $value1$, Void.class); + }); + + + // WeakCompareAndSetRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = vh.weakCompareAndSetRelease(null, 0, $value1$, $value1$); + }); + checkCCE(() -> { // receiver reference class + boolean r = vh.weakCompareAndSetRelease(Void.class, 0, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + boolean r = vh.weakCompareAndSetRelease(array, 0, $value1$, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = vh.weakCompareAndSetRelease(0, 0, $value1$, $value1$); + }); + checkWMTE(() -> { // index reference class + boolean r = vh.weakCompareAndSetRelease(array, Void.class, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = vh.weakCompareAndSetRelease(); + }); + checkWMTE(() -> { // > + boolean r = vh.weakCompareAndSetRelease(array, 0, $value1$, $value1$, Void.class); + }); + + + // CompareAndExchangeVolatile + // Incorrect argument types + checkNPE(() -> { // null receiver + $type$ x = ($type$) vh.compareAndExchangeVolatile(null, 0, $value1$, $value1$); + }); + checkCCE(() -> { // array reference class + $type$ x = ($type$) vh.compareAndExchangeVolatile(Void.class, 0, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + $type$ x = ($type$) vh.compareAndExchangeVolatile(array, 0, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + $type$ x = ($type$) vh.compareAndExchangeVolatile(array, 0, $value1$, Void.class); + }); + checkWMTE(() -> { // array primitive class + $type$ x = ($type$) vh.compareAndExchangeVolatile(0, 0, $value1$, $value1$); + }); + checkWMTE(() -> { // index reference class + $type$ x = ($type$) vh.compareAndExchangeVolatile(array, Void.class, $value1$, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.compareAndExchangeVolatile(array, 0, $value1$, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeVolatile(array, 0, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.compareAndExchangeVolatile(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.compareAndExchangeVolatile(array, 0, $value1$, $value1$, Void.class); + }); + + + // CompareAndExchangeAcquire + // Incorrect argument types + checkNPE(() -> { // null receiver + $type$ x = ($type$) vh.compareAndExchangeAcquire(null, 0, $value1$, $value1$); + }); + checkCCE(() -> { // array reference class + $type$ x = ($type$) vh.compareAndExchangeAcquire(Void.class, 0, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + $type$ x = ($type$) vh.compareAndExchangeAcquire(array, 0, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + $type$ x = ($type$) vh.compareAndExchangeAcquire(array, 0, $value1$, Void.class); + }); + checkWMTE(() -> { // array primitive class + $type$ x = ($type$) vh.compareAndExchangeAcquire(0, 0, $value1$, $value1$); + }); + checkWMTE(() -> { // index reference class + $type$ x = ($type$) vh.compareAndExchangeAcquire(array, Void.class, $value1$, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.compareAndExchangeAcquire(array, 0, $value1$, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeAcquire(array, 0, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.compareAndExchangeAcquire(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.compareAndExchangeAcquire(array, 0, $value1$, $value1$, Void.class); + }); + + + // CompareAndExchangeRelease + // Incorrect argument types + checkNPE(() -> { // null receiver + $type$ x = ($type$) vh.compareAndExchangeRelease(null, 0, $value1$, $value1$); + }); + checkCCE(() -> { // array reference class + $type$ x = ($type$) vh.compareAndExchangeRelease(Void.class, 0, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + $type$ x = ($type$) vh.compareAndExchangeRelease(array, 0, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + $type$ x = ($type$) vh.compareAndExchangeRelease(array, 0, $value1$, Void.class); + }); + checkWMTE(() -> { // array primitive class + $type$ x = ($type$) vh.compareAndExchangeRelease(0, 0, $value1$, $value1$); + }); + checkWMTE(() -> { // index reference class + $type$ x = ($type$) vh.compareAndExchangeRelease(array, Void.class, $value1$, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.compareAndExchangeRelease(array, 0, $value1$, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeRelease(array, 0, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.compareAndExchangeRelease(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.compareAndExchangeRelease(array, 0, $value1$, $value1$, Void.class); + }); + + + // GetAndSet + // Incorrect argument types + checkNPE(() -> { // null array + $type$ x = ($type$) vh.getAndSet(null, 0, $value1$); + }); + checkCCE(() -> { // array reference class + $type$ x = ($type$) vh.getAndSet(Void.class, 0, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + $type$ x = ($type$) vh.getAndSet(array, 0, Void.class); + }); + checkWMTE(() -> { // reciarrayever primitive class + $type$ x = ($type$) vh.getAndSet(0, 0, $value1$); + }); + checkWMTE(() -> { // index reference class + $type$ x = ($type$) vh.getAndSet(array, Void.class, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.getAndSet(array, 0, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndSet(array, 0, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.getAndSet(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.getAndSet(array, 0, $value1$, Void.class); + }); +#end[CAS] + +#if[AtomicAdd] + // GetAndAdd + // Incorrect argument types + checkNPE(() -> { // null array + $type$ x = ($type$) vh.getAndAdd(null, 0, $value1$); + }); + checkCCE(() -> { // array reference class + $type$ x = ($type$) vh.getAndAdd(Void.class, 0, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + $type$ x = ($type$) vh.getAndAdd(array, 0, Void.class); + }); + checkWMTE(() -> { // array primitive class + $type$ x = ($type$) vh.getAndAdd(0, 0, $value1$); + }); + checkWMTE(() -> { // index reference class + $type$ x = ($type$) vh.getAndAdd(array, Void.class, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.getAndAdd(array, 0, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndAdd(array, 0, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.getAndAdd(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.getAndAdd(array, 0, $value1$, Void.class); + }); + + + // AddAndGet + // Incorrect argument types + checkNPE(() -> { // null array + $type$ x = ($type$) vh.addAndGet(null, 0, $value1$); + }); + checkCCE(() -> { // array reference class + $type$ x = ($type$) vh.addAndGet(Void.class, 0, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + $type$ x = ($type$) vh.addAndGet(array, 0, Void.class); + }); + checkWMTE(() -> { // array primitive class + $type$ x = ($type$) vh.addAndGet(0, 0, $value1$); + }); + checkWMTE(() -> { // index reference class + $type$ x = ($type$) vh.addAndGet(array, Void.class, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) vh.addAndGet(array, 0, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.addAndGet(array, 0, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) vh.addAndGet(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) vh.addAndGet(array, 0, $value1$, Void.class); + }); +#end[AtomicAdd] + } + + static void testArrayWrongMethodType(Handles hs) throws Throwable { + $type$[] array = new $type$[10]; + Arrays.fill(array, $value1$); + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) { + // Incorrect argument types + checkNPE(() -> { // null array + $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class)). + invoke(null, 0); + }); + checkCCE(() -> { // array reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class)). + invoke(Void.class, 0); + }); + checkWMTE(() -> { // array primitive class + $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class)). + invoke(0, 0); + }); + checkWMTE(() -> { // index reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class)). + invoke(array, Void.class); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class)). + invoke(array, 0); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class)). + invoke(array, 0); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) hs.get(am, methodType($type$.class)). + invoke(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) { + // Incorrect argument types + checkNPE(() -> { // null array + hs.get(am, methodType(void.class, Void.class, int.class, $type$.class)). + invoke(null, 0, $value1$); + }); + checkCCE(() -> { // array reference class + hs.get(am, methodType(void.class, Class.class, int.class, $type$.class)). + invoke(Void.class, 0, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + hs.get(am, methodType(void.class, $type$[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + hs.get(am, methodType(void.class, int.class, int.class, $type$.class)). + invoke(0, 0, $value1$); + }); + checkWMTE(() -> { // index reference class + hs.get(am, methodType(void.class, $type$[].class, Class.class, $type$.class)). + invoke(array, Void.class, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + hs.get(am, methodType(void.class)). + invoke(); + }); + checkWMTE(() -> { // > + hs.get(am, methodType(void.class, $type$[].class, int.class, Class.class)). + invoke(array, 0, $value1$, Void.class); + }); + } +#if[CAS] + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, $type$.class, $type$.class)). + invoke(null, 0, $value1$, $value1$); + }); + checkCCE(() -> { // receiver reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, $type$.class, $type$.class)). + invoke(Void.class, 0, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, int.class, Class.class, $type$.class)). + invoke(array, 0, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, int.class, $type$.class, Class.class)). + invoke(array, 0, $value1$, Void.class); + }); + checkWMTE(() -> { // receiver primitive class + boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, $type$.class, $type$.class)). + invoke(0, 0, $value1$, $value1$); + }); + checkWMTE(() -> { // index reference class + boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, Class.class, $type$.class, $type$.class)). + invoke(array, Void.class, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + boolean r = (boolean) hs.get(am, methodType(boolean.class)). + invoke(); + }); + checkWMTE(() -> { // > + boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, int.class, $type$.class, $type$.class, Class.class)). + invoke(array, 0, $value1$, $value1$, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) { + // Incorrect argument types + checkNPE(() -> { // null receiver + $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class, $type$.class, $type$.class)). + invoke(null, 0, $value1$, $value1$); + }); + checkCCE(() -> { // array reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class, $type$.class, $type$.class)). + invoke(Void.class, 0, $value1$, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // expected reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class, $type$.class)). + invoke(array, 0, Void.class, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // actual reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, Class.class)). + invoke(array, 0, $value1$, Void.class); + }); + checkWMTE(() -> { // array primitive class + $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class, $type$.class, $type$.class)). + invoke(0, 0, $value1$, $value1$); + }); + checkWMTE(() -> { // index reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class, $type$.class, $type$.class)). + invoke(array, Void.class, $value1$, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class, $type$.class, $type$.class)). + invoke(array, 0, $value1$, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class, $type$.class, $type$.class)). + invoke(array, 0, $value1$, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) hs.get(am, methodType($type$.class)). + invoke(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, $type$.class, Class.class)). + invoke(array, 0, $value1$, $value1$, Void.class); + }); + } + + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) { + // Incorrect argument types + checkNPE(() -> { // null array + $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class, $type$.class)). + invoke(null, 0, $value1$); + }); + checkCCE(() -> { // array reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class, $type$.class)). + invoke(Void.class, 0, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // array primitive class + $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class, $type$.class)). + invoke(0, 0, $value1$); + }); + checkWMTE(() -> { // index reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class, $type$.class)). + invoke(array, Void.class, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class, $type$.class)). + invoke(array, 0, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class, $type$.class)). + invoke(array, 0, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) hs.get(am, methodType($type$.class)). + invoke(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, Class.class)). + invoke(array, 0, $value1$, Void.class); + }); + } +#end[CAS] + +#if[AtomicAdd] + for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) { + // Incorrect argument types + checkNPE(() -> { // null array + $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class, $type$.class)). + invoke(null, 0, $value1$); + }); + checkCCE(() -> { // array reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class, $type$.class)). + invoke(Void.class, 0, $value1$); + }); + check{#if[String]?CCE:WMTE}(() -> { // value reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class)). + invoke(array, 0, Void.class); + }); + checkWMTE(() -> { // array primitive class + $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class, $type$.class)). + invoke(0, 0, $value1$); + }); + checkWMTE(() -> { // index reference class + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class, $type$.class)). + invoke(array, Void.class, $value1$); + }); + // Incorrect return type + check{#if[String]?CCE:WMTE}(() -> { // reference class + Void r = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class, $type$.class)). + invoke(array, 0, $value1$); + }); + checkWMTE(() -> { // primitive class + $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class, $type$.class)). + invoke(array, 0, $value1$); + }); + // Incorrect arity + checkWMTE(() -> { // 0 + $type$ x = ($type$) hs.get(am, methodType($type$.class)). + invoke(); + }); + checkWMTE(() -> { // > + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, Class.class)). + invoke(array, 0, $value1$, Void.class); + }); + } +#end[AtomicAdd] + } +} + diff --git a/jdk/test/java/lang/invoke/VarHandles/accessibility/TestFieldLookupAccessibility.java b/jdk/test/java/lang/invoke/VarHandles/accessibility/TestFieldLookupAccessibility.java new file mode 100644 index 00000000000..636751f2290 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/accessibility/TestFieldLookupAccessibility.java @@ -0,0 +1,226 @@ +/* + * Copyright (c) 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 + * @bug 8152645 + * @summary test field lookup accessibility of MethodHandles and VarHandles + * @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 TestFieldLookupAccessibility + */ + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import pkg.B_extends_A; + +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class TestFieldLookupAccessibility { + + // The set of possible field lookup mechanisms + enum FieldLookup { + MH_GETTER() { + Object lookup(MethodHandles.Lookup l, Field f) throws Exception { + return l.findGetter(f.getDeclaringClass(), f.getName(), f.getType()); + } + + boolean isAccessible(Field f) { + return !Modifier.isStatic(f.getModifiers()); + } + }, + MH_SETTER() { + Object lookup(MethodHandles.Lookup l, Field f) throws Exception { + return l.findSetter(f.getDeclaringClass(), f.getName(), f.getType()); + } + + boolean isAccessible(Field f) { + return !Modifier.isStatic(f.getModifiers()) && !Modifier.isFinal(f.getModifiers()); + } + }, + MH_STATIC_GETTER() { + Object lookup(MethodHandles.Lookup l, Field f) throws Exception { + return l.findStaticGetter(f.getDeclaringClass(), f.getName(), f.getType()); + } + + boolean isAccessible(Field f) { + return Modifier.isStatic(f.getModifiers()); + } + }, + MH_STATIC_SETTER() { + Object lookup(MethodHandles.Lookup l, Field f) throws Exception { + return l.findStaticSetter(f.getDeclaringClass(), f.getName(), f.getType()); + } + + boolean isAccessible(Field f) { + return Modifier.isStatic(f.getModifiers()) && !Modifier.isFinal(f.getModifiers()); + } + }, + MH_UNREFLECT_GETTER() { + Object lookup(MethodHandles.Lookup l, Field f) throws Exception { + return l.unreflectGetter(f); + } + }, + MH_UNREFLECT_GETTER_ACCESSIBLE() { + Object lookup(MethodHandles.Lookup l, Field f) throws Exception { + return l.unreflectGetter(cloneAndSetAccessible(f)); + } + }, + MH_UNREFLECT_SETTER() { + Object lookup(MethodHandles.Lookup l, Field f) throws Exception { + return l.unreflectSetter(f); + } + + boolean isAccessible(Field f) { + return f.isAccessible() || !Modifier.isFinal(f.getModifiers()); + } + }, + MH_UNREFLECT_SETTER_ACCESSIBLE() { + Object lookup(MethodHandles.Lookup l, Field f) throws Exception { + return l.unreflectSetter(cloneAndSetAccessible(f)); + } + }, + VH() { + Object lookup(MethodHandles.Lookup l, Field f) throws Exception { + return l.findVarHandle(f.getDeclaringClass(), f.getName(), f.getType()); + } + + boolean isAccessible(Field f) { + return !Modifier.isStatic(f.getModifiers()); + } + }, + VH_STATIC() { + Object lookup(MethodHandles.Lookup l, Field f) throws Exception { + return l.findStaticVarHandle(f.getDeclaringClass(), f.getName(), f.getType()); + } + + boolean isAccessible(Field f) { + return Modifier.isStatic(f.getModifiers()); + } + }, + VH_UNREFLECT() { + Object lookup(MethodHandles.Lookup l, Field f) throws Exception { + return l.unreflectVarHandle(f); + } + }; + + // Look up a handle to a field + abstract Object lookup(MethodHandles.Lookup l, Field f) throws Exception; + + boolean isAccessible(Field f) { + return true; + } + + static Field cloneAndSetAccessible(Field f) throws Exception { + // Clone to avoid mutating source field + f = f.getDeclaringClass().getDeclaredField(f.getName()); + f.setAccessible(true); + return f; + } + } + + @DataProvider + public Object[][] lookupProvider() throws Exception { + Stream> baseCases = Stream.of( + // Look up from same package + List.of(pkg.A.class, pkg.A.lookup(), pkg.A.inaccessibleFields()), + List.of(pkg.A.class, pkg.A.lookup(), pkg.A.inaccessibleFields()), + List.of(pkg.A.class, B_extends_A.lookup(), B_extends_A.inaccessibleFields()), + List.of(pkg.A.class, pkg.C.lookup(), pkg.C.inaccessibleFields()), + + // Look up from sub-package + List.of(pkg.A.class, pkg.subpkg.B_extends_A.lookup(), pkg.subpkg.B_extends_A.inaccessibleFields()), + List.of(pkg.A.class, pkg.subpkg.C.lookup(), pkg.subpkg.C.inaccessibleFields()) + ); + + // Cross product base cases with the field lookup classes + return baseCases. + flatMap(l -> Stream.of(FieldLookup.values()).map(fl -> prepend(fl, l))). + toArray(Object[][]::new); + } + + private static Object[] prepend(Object o, List l) { + List pl = new ArrayList<>(); + pl.add(o); + pl.addAll(l); + return pl.toArray(); + } + + @Test(dataProvider = "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 = new HashSet<>(inaccessibleFields); + Map actual = new HashMap<>(); + + for (Field f : fields(src)) { + // Add to the expected failures all inaccessible fields due to static/final modifiers + if (!fl.isAccessible(f)) { + expected.add(f.getName()); + } + + try { + fl.lookup(l, f); + } + catch (Throwable t) { + // Lookup failed, add to the actual failures + actual.put(f, t); + } + } + + Set actualFieldNames = actual.keySet().stream().map(Field::getName). + collect(Collectors.toSet()); + if (!actualFieldNames.equals(expected)) { + if (actualFieldNames.isEmpty()) { + // Setting the accessibility bit of a Field grants access under + // all conditions for MethodHander getters and setters + if (fl != FieldLookup.MH_UNREFLECT_GETTER_ACCESSIBLE && + fl != FieldLookup.MH_UNREFLECT_SETTER_ACCESSIBLE) { + Assert.assertEquals(actualFieldNames, expected, "No accessibility failures:"); + } + } + else { + Assert.assertEquals(actualFieldNames, expected, "Accessibility failures differ:"); + } + } + else { + if (!actual.values().stream().allMatch(IllegalAccessException.class::isInstance)) { + Assert.fail("Expecting an IllegalArgumentException for all failures " + actual); + } + } + } + + static List fields(Class src) { + return List.of(src.getDeclaredFields()); + } +} diff --git a/jdk/test/java/lang/invoke/VarHandles/accessibility/pkg/A.java b/jdk/test/java/lang/invoke/VarHandles/accessibility/pkg/A.java new file mode 100644 index 00000000000..c81bf4dbecc --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/accessibility/pkg/A.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 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. + */ + +package pkg; + + +import java.lang.invoke.MethodHandles; +import java.util.Set; + +public class A { + public static Object f_public_static; + protected static Object f_protected_static; + static /*package*/ Object f_package_static; + private static Object f_private_static; + + public static final Object f_public_static_final = null; + protected static final Object f_protected_static_final = null; + static /*package*/ final Object f_package_static_final = null; + private static final Object f_private_static_final = null; + + public Object f_public; + protected Object f_protected; + /*package*/ Object f_package; + private Object f_private; + + public final Object f_public_final = null; + protected final Object f_protected_final = null; + /*package*/ final Object f_package_final = null; + private final Object f_private_final = null; + + // + + public static MethodHandles.Lookup lookup() { + return MethodHandles.lookup(); + } + + public static Set inaccessibleFields() { + // All fields of pkg.A are accessible to itself + return Set.of(); + } +} diff --git a/jdk/test/sun/net/InetAddress/nameservice/chaining/Simple1NameServiceDescriptor.java b/jdk/test/java/lang/invoke/VarHandles/accessibility/pkg/B_extends_A.java similarity index 60% rename from jdk/test/sun/net/InetAddress/nameservice/chaining/Simple1NameServiceDescriptor.java rename to jdk/test/java/lang/invoke/VarHandles/accessibility/pkg/B_extends_A.java index b2572817fb3..026f7ccfcbb 100644 --- a/jdk/test/sun/net/InetAddress/nameservice/chaining/Simple1NameServiceDescriptor.java +++ b/jdk/test/java/lang/invoke/VarHandles/accessibility/pkg/B_extends_A.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -21,29 +21,25 @@ * questions. */ -/* - */ - -import sun.net.spi.nameservice.*; +package pkg; -public class Simple1NameServiceDescriptor implements NameServiceDescriptor { - public NameService createNameService() { - SimpleNameService ns = new SimpleNameService(); +import java.lang.invoke.MethodHandles; +import java.util.Set; - // both providers know this host, but the address is different - ns.put("blade", "10.0.0.1"); - // only this provider knows this host - ns.put("blade.domain1", "10.0.0.2"); - - return ns; +public class B_extends_A extends A { + public static MethodHandles.Lookup lookup() { + return MethodHandles.lookup(); } - public String getProviderName() { - return "sun"; - } - - public String getType() { - return "simple1"; + public static Set inaccessibleFields() { + // Only private fields of pkg.A are not accessible to subclass pkg.B + // Note: protected fields are also package accessible + return Set.of( + "f_private", + "f_private_final", + "f_private_static", + "f_private_static_final" + ); } } diff --git a/jdk/test/sun/net/InetAddress/nameservice/chaining/Simple2NameServiceDescriptor.java b/jdk/test/java/lang/invoke/VarHandles/accessibility/pkg/C.java similarity index 60% rename from jdk/test/sun/net/InetAddress/nameservice/chaining/Simple2NameServiceDescriptor.java rename to jdk/test/java/lang/invoke/VarHandles/accessibility/pkg/C.java index 91eae198d44..fcf1f0b6389 100644 --- a/jdk/test/sun/net/InetAddress/nameservice/chaining/Simple2NameServiceDescriptor.java +++ b/jdk/test/java/lang/invoke/VarHandles/accessibility/pkg/C.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -21,28 +21,26 @@ * questions. */ -/* - */ - -import sun.net.spi.nameservice.*; +package pkg; -public class Simple2NameServiceDescriptor implements NameServiceDescriptor { - public NameService createNameService() { - SimpleNameService ns = new SimpleNameService(); - // both providers know this host, but the address of it is different - ns.put("blade", "20.0.0.1"); - // only this provider knows this host - ns.put("blade.domain2", "20.0.0.2"); +import java.lang.invoke.MethodHandles; +import java.util.Set; - return ns; +public class C { + public static MethodHandles.Lookup lookup() { + return MethodHandles.lookup(); } - public String getProviderName() { - return "sun"; - } - - public String getType() { - return "simple2"; + public static Set inaccessibleFields() { + // Only private fields of pkg.A are not accessible to independent + // class pkg.C + // Note: protected fields are also package accessible + return Set.of( + "f_private", + "f_private_final", + "f_private_static", + "f_private_static_final" + ); } } diff --git a/jdk/test/java/lang/invoke/VarHandles/accessibility/pkg/subpkg/B_extends_A.java b/jdk/test/java/lang/invoke/VarHandles/accessibility/pkg/subpkg/B_extends_A.java new file mode 100644 index 00000000000..0ee5fba8a67 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/accessibility/pkg/subpkg/B_extends_A.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 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. + */ + +package pkg.subpkg; + + +import pkg.A; + +import java.lang.invoke.MethodHandles; +import java.util.Set; + +public class B_extends_A extends A { + public static MethodHandles.Lookup lookup() { + return MethodHandles.lookup(); + } + + public static Set inaccessibleFields() { + // Only public and protected fields of pkg.A are accessible to subclass + // pkg.subpkg.B + return Set.of( + "f_private", + "f_private_final", + "f_package", + "f_package_final", + "f_private_static", + "f_private_static_final", + "f_package_static", + "f_package_static_final" + ); + } +} diff --git a/jdk/test/java/lang/invoke/VarHandles/accessibility/pkg/subpkg/C.java b/jdk/test/java/lang/invoke/VarHandles/accessibility/pkg/subpkg/C.java new file mode 100644 index 00000000000..c2fd8ac4a67 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/accessibility/pkg/subpkg/C.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 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. + */ + +package pkg.subpkg; + + +import java.lang.invoke.MethodHandles; +import java.util.Set; + +public class C { + public static MethodHandles.Lookup lookup() { + return MethodHandles.lookup(); + } + + public static Set inaccessibleFields() { + // Only public fields of pkg.A are accessible to independent + // class pkg.subpkg.C + return Set.of( + "f_private", + "f_private_final", + "f_protected", + "f_protected_final", + "f_package", + "f_package_final", + "f_private_static", + "f_private_static_final", + "f_protected_static", + "f_protected_static_final", + "f_package_static", + "f_package_static_final" + ); + } +} diff --git a/jdk/test/java/lang/invoke/VarHandles/generate-vh-tests.sh b/jdk/test/java/lang/invoke/VarHandles/generate-vh-tests.sh new file mode 100644 index 00000000000..7d6afc7b206 --- /dev/null +++ b/jdk/test/java/lang/invoke/VarHandles/generate-vh-tests.sh @@ -0,0 +1,155 @@ +#!/bin/bash + +javac -d . ../../../../../make/src/classes/build/tools/spp/Spp.java + +SPP=build.tools.spp.Spp + +# Generates variable handle tests for objects and all primitive types +# This is likely to be a temporary testing approach as it may be more +# desirable to generate code using ASM which will allow more flexibility +# in the kinds of tests that are generated. + +for type in boolean byte short char int long float double String +do + Type="$(tr '[:lower:]' '[:upper:]' <<< ${type:0:1})${type:1}" + args="-K$type -Dtype=$type -DType=$Type" + + case $type in + String|int|long) + args="$args -KCAS" + ;; + esac + + case $type in + int|long) + args="$args -KAtomicAdd" + ;; + esac + + wrong_primitive_type=boolean + + case $type in + boolean) + value1=true + value2=false + value3=false + wrong_primitive_type=int + ;; + byte) + value1=(byte)1 + value2=(byte)2 + value3=(byte)3 + ;; + short) + value1=(short)1 + value2=(short)2 + value3=(short)3 + ;; + char) + value1=\'a\' + value2=\'b\' + value3=\'c\' + ;; + int) + value1=1 + value2=2 + value3=3 + ;; + long) + value1=1L + value2=2L + value3=3L + ;; + float) + value1=1.0f + value2=2.0f + value3=3.0f + ;; + double) + value1=1.0d + value2=2.0d + value3=3.0d + ;; + String) + value1=\"foo\" + value2=\"bar\" + value3=\"baz\" + ;; + esac + + args="$args -Dvalue1=$value1 -Dvalue2=$value2 -Dvalue3=$value3 -Dwrong_primitive_type=$wrong_primitive_type" + + echo $args + java $SPP -nel $args < X-VarHandleTestAccess.java.template > VarHandleTestAccess${Type}.java + java $SPP -nel $args < X-VarHandleTestMethodHandleAccess.java.template > VarHandleTestMethodHandleAccess${Type}.java + java $SPP -nel $args < X-VarHandleTestMethodType.java.template > VarHandleTestMethodType${Type}.java +done + +for type in short char int long float double +do + Type="$(tr '[:lower:]' '[:upper:]' <<< ${type:0:1})${type:1}" + args="-K$type -Dtype=$type -DType=$Type" + + BoxType=$Type + case $type in + char) + BoxType=Character + ;; + int) + BoxType=Integer + ;; + esac + args="$args -DBoxType=$BoxType" + + case $type in + int|long|float|double) + args="$args -KCAS" + ;; + esac + + case $type in + int|long) + args="$args -KAtomicAdd" + ;; + esac + + case $type in + short) + value1=(short)0x0102 + value2=(short)0x1112 + value3=(short)0x2122 + ;; + char) + value1=(char)0x0102 + value2=(char)0x1112 + value3=(char)0x2122 + ;; + int) + value1=0x01020304 + value2=0x11121314 + value3=0x21222324 + ;; + long) + value1=0x0102030405060708L + value2=0x1112131415161718L + value3=0x2122232425262728L + ;; + float) + value1=0x01020304 + value2=0x11121314 + value3=0x21222324 + ;; + double) + value1=0x0102030405060708L + value2=0x1112131415161718L + value3=0x2122232425262728L + ;; + esac + + args="$args -Dvalue1=$value1 -Dvalue2=$value2 -Dvalue3=$value3" + + echo $args + java $SPP -nel $args < X-VarHandleTestByteArrayView.java.template > VarHandleTestByteArrayAs${Type}.java +done + +rm -fr build diff --git a/jdk/test/sun/net/InetAddress/nameservice/deadlock/ThrowingNameServiceDescriptor.java b/jdk/test/java/lang/reflect/ClassLoaderValue/Driver.java similarity index 70% rename from jdk/test/sun/net/InetAddress/nameservice/deadlock/ThrowingNameServiceDescriptor.java rename to jdk/test/java/lang/reflect/ClassLoaderValue/Driver.java index 3075412857f..e20d9da7641 100644 --- a/jdk/test/sun/net/InetAddress/nameservice/deadlock/ThrowingNameServiceDescriptor.java +++ b/jdk/test/java/lang/reflect/ClassLoaderValue/Driver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -21,20 +21,15 @@ * questions. */ -import sun.net.spi.nameservice.*; - -public class ThrowingNameServiceDescriptor implements NameServiceDescriptor { - public NameService createNameService() { - return new ThrowingNameService(); - } - - @Override - public String getProviderName() { - return "sun"; - } - - @Override - public String getType() { - return "throwing"; +/** + * @test + * @bug 8152115 + * @summary functional and concurrency test for ClassLoaderValue + * @build java.base/java.lang.reflect.ClassLoaderValueTest + * @run main Driver + */ +public class Driver { + public static void main(String[] args) throws Exception { + java.lang.reflect.ClassLoaderValueTest.main(args); } } diff --git a/jdk/test/java/lang/reflect/ClassLoaderValue/java.base/java/lang/reflect/ClassLoaderValueTest.java b/jdk/test/java/lang/reflect/ClassLoaderValue/java.base/java/lang/reflect/ClassLoaderValueTest.java new file mode 100644 index 00000000000..ff928c13ac4 --- /dev/null +++ b/jdk/test/java/lang/reflect/ClassLoaderValue/java.base/java/lang/reflect/ClassLoaderValueTest.java @@ -0,0 +1,249 @@ +/* + * Copyright (c) 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. + */ + +package java.lang.reflect; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Functional and concurrency test for ClassLoaderValue + * + * @author Peter Levart + */ +public class ClassLoaderValueTest { + + @SuppressWarnings("unchecked") + public static void main(String[] args) throws Exception { + + ClassLoaderValue[] clvs = {new ClassLoaderValue<>(), + new ClassLoaderValue<>()}; + + ClassLoader[] lds = {ClassLoader.getSystemClassLoader(), + ClassLoader.getPlatformClassLoader(), + null /* bootstrap class loader */}; + + Integer[] keys = new Integer[32]; + for (int i = 0; i < keys.length; i++) { + keys[i] = i + 128; + } + + try (AutoCloseable cleanup = () -> { + for (ClassLoaderValue clv : clvs) { + for (ClassLoader ld : lds) { + clv.removeAll(ld); + } + } + }) { + // 1st just one sequential pass of single-threaded validation + // which is easier to debug if it fails... + for (ClassLoaderValue clv : clvs) { + for (ClassLoader ld : lds) { + writeValidateOps(clv, ld, keys); + } + } + for (ClassLoaderValue clv : clvs) { + for (ClassLoader ld : lds) { + readValidateOps(clv, ld, keys); + } + } + + // 2nd the same in concurrent setting that also validates + // failure-isolation between threads and data-isolation between + // regions - (ClassLoader, ClassLoaderValue) pairs - of the storage + testConcurrentIsolation(clvs, lds, keys, TimeUnit.SECONDS.toMillis(3)); + } + } + + static void writeValidateOps(ClassLoaderValue clv, + ClassLoader ld, + Object[] keys) { + for (int i = 0; i < keys.length; i++) { + Object k = keys[i]; + Integer v1 = i; + Integer v2 = i + 333; + Integer pv; + boolean success; + + pv = clv.sub(k).putIfAbsent(ld, v1); + assertEquals(pv, null); + assertEquals(clv.sub(k).get(ld), v1); + + pv = clv.sub(k).putIfAbsent(ld, v2); + assertEquals(pv, v1); + assertEquals(clv.sub(k).get(ld), v1); + + success = clv.sub(k).remove(ld, v2); + assertEquals(success, false); + assertEquals(clv.sub(k).get(ld), v1); + + success = clv.sub(k).remove(ld, v1); + assertEquals(success, true); + assertEquals(clv.sub(k).get(ld), null); + + pv = clv.sub(k).putIfAbsent(ld, v2); + assertEquals(pv, null); + assertEquals(clv.sub(k).get(ld), v2); + + pv = clv.sub(k).computeIfAbsent(ld, (_ld, _clv) -> v1); + assertEquals(pv, v2); + assertEquals(clv.sub(k).get(ld), v2); + + success = clv.sub(k).remove(ld, v1); + assertEquals(success, false); + assertEquals(clv.sub(k).get(ld), v2); + + success = clv.sub(k).remove(ld, v2); + assertEquals(success, true); + assertEquals(clv.sub(k).get(ld), null); + + pv = clv.sub(k).computeIfAbsent(ld, (_ld, clv_k) -> { + try { + // nested get for same key should throw + clv_k.get(_ld); + throw new AssertionError("Unexpected code path"); + } catch (IllegalStateException e) { + // expected + } + try { + // nested putIfAbsent for same key should throw + clv_k.putIfAbsent(_ld, v1); + throw new AssertionError("Unexpected code path"); + } catch (IllegalStateException e) { + // expected + } + // nested remove for for same key and any value (even null) + // should return false + assertEquals(clv_k.remove(_ld, null), false); + assertEquals(clv_k.remove(_ld, v1), false); + assertEquals(clv_k.remove(_ld, v2), false); + try { + // nested computeIfAbsent for same key should throw + clv_k.computeIfAbsent(_ld, (__ld, _clv_k) -> v1); + throw new AssertionError("Unexpected code path"); + } catch (IllegalStateException e) { + // expected + } + // if everything above has been handled, we should succeed... + return v2; + }); + // ... and the result should be reflected in the CLV + assertEquals(pv, v2); + assertEquals(clv.sub(k).get(ld), v2); + + success = clv.sub(k).remove(ld, v2); + assertEquals(success, true); + assertEquals(clv.sub(k).get(ld), null); + + try { + clv.sub(k).computeIfAbsent(ld, (_ld, clv_k) -> { + throw new UnsupportedOperationException(); + }); + throw new AssertionError("Unexpected code path"); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(clv.sub(k).get(ld), null); + } + } + + static void readValidateOps(ClassLoaderValue clv, + ClassLoader ld, + Object[] keys) { + for (int i = 0; i < keys.length; i++) { + Object k = keys[i]; + Integer v1 = i; + Integer v2 = i + 333; + Integer rv = clv.sub(k).get(ld); + if (!(rv == null || rv.equals(v1) || rv.equals(v2))) { + throw new AssertionError("Unexpected value: " + rv + + ", expected one of: null, " + v1 + ", " + v2); + } + } + } + + static void testConcurrentIsolation(ClassLoaderValue[] clvs, + ClassLoader[] lds, + Object[] keys, + long millisRuntime) { + ExecutorService exe = Executors.newCachedThreadPool(); + List> futures = new ArrayList<>(); + AtomicBoolean stop = new AtomicBoolean(); + for (ClassLoaderValue clv : clvs) { + for (ClassLoader ld : lds) { + // submit a task that exercises a mix of modifying + // and reading-validating operations in an isolated + // part of the storage. If isolation is violated, + // validation operations are expected to fail. + futures.add(exe.submit(() -> { + do { + writeValidateOps(clv, ld, keys); + } while (!stop.get()); + })); + // submit a task that just reads from the same part of + // the storage as above task. It should not disturb + // above task in any way and this task should never + // exhibit any failure although above task produces + // regular failures during lazy computation + futures.add(exe.submit(() -> { + do { + readValidateOps(clv, ld, keys); + } while (!stop.get()); + })); + } + } + // wait for some time + try { + Thread.sleep(millisRuntime); + } catch (InterruptedException e) { + throw new AssertionError(e); + } + // stop tasks + stop.set(true); + // collect results + AssertionError error = null; + for (Future future : futures) { + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + if (error == null) error = new AssertionError("Failure"); + error.addSuppressed(e); + } + } + exe.shutdown(); + if (error != null) throw error; + } + + static void assertEquals(Object actual, Object expected) { + if (!Objects.equals(actual, expected)) { + throw new AssertionError("Expected: " + expected + ", actual: " + actual); + } + } +} diff --git a/jdk/test/java/net/Authenticator/B4933582.sh b/jdk/test/java/net/Authenticator/B4933582.sh index 728de44a0c9..a9cff3e6a62 100644 --- a/jdk/test/java/net/Authenticator/B4933582.sh +++ b/jdk/test/java/net/Authenticator/B4933582.sh @@ -44,7 +44,7 @@ case "$OS" in ;; esac -EXTRAOPTS="-XaddExports:java.base/sun.net.www=ALL-UNNAMED,java.base/sun.net.www.protocol.http=ALL-UNNAMED" +EXTRAOPTS="-XaddExports:java.base/sun.net.www=ALL-UNNAMED -XaddExports:java.base/sun.net.www.protocol.http=ALL-UNNAMED" export EXTRAOPTS ${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} ${EXTRAOPTS} -d . \ diff --git a/jdk/test/java/net/Inet4Address/TestToNumericFormatHosts b/jdk/test/java/net/Inet4Address/TestToNumericFormatHosts new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/jdk/test/java/net/Inet4Address/TestToNumericFormatHosts @@ -0,0 +1 @@ + diff --git a/jdk/test/java/net/Inet4Address/textToNumericFormat.java b/jdk/test/java/net/Inet4Address/textToNumericFormat.java index bcc57d80d25..1d010d0b912 100644 --- a/jdk/test/java/net/Inet4Address/textToNumericFormat.java +++ b/jdk/test/java/net/Inet4Address/textToNumericFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -25,9 +25,7 @@ * @test * @bug 4749938 8087190 * @summary Bug in the parsing IPv4 literal addresses - * @modules java.base/sun.net.spi.nameservice - * @compile -XDignore.symbol.file=true DummyNameService.java DummyNameServiceDescriptor.java - * @run main/othervm -Dsun.net.spi.nameservice.provider.1=dummy,oracle textToNumericFormat + * @run main/othervm textToNumericFormat */ /** @@ -68,6 +66,8 @@ public class textToNumericFormat { "1..1.1", "1.1.1.", "..." }; + String hostsFileName = System.getProperty("test.src", ".") + "/TestToNumericFormatHosts"; + System.setProperty("jdk.net.hosts.file", hostsFileName); for (int i=0; i b.alignmentOffset(-1, (short) 1)); + + // unit size values + tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, (short) 0)); + for (int us = 1; us < 65; us++) { + int _us = us; + if ((us & (us - 1)) != 0) { + // unit size not a power of two + tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, _us)); + } else { + if (direct || us <= 8) { + b.alignmentOffset(0, us); + } else { + // unit size > 8 with non-direct buffer + tryCatch(b, UnsupportedOperationException.class, () -> b.alignmentOffset(0, _us)); + } + } + } + + // Probe for long misalignment at index zero for a newly created buffer + ByteBuffer empty = direct ? ByteBuffer.allocateDirect(0) : ByteBuffer.allocate(0); + int longMisalignmentAtZero = empty.alignmentOffset(0, 8); + + if (direct) { + // Freshly created direct byte buffers should be aligned at index 0 + // for ref and primitive values (see Unsafe.allocateMemory) + if (longMisalignmentAtZero != 0) + fail("Direct byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero); + } else { + // For heap byte buffers misalignment may occur on 32-bit systems + // where Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 == 4 and not 0 + // Note the GC will preserve alignment of the base address of the + // array + if (jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 != longMisalignmentAtZero) + fail("Heap byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero); + } + + // Ensure test buffer is correctly aligned at index 0 + if (b.alignmentOffset(0, 8) != longMisalignmentAtZero) + fail("Test input buffer not correctly aligned at index 0", b); + + // Test misalignment values + for (int us : new int[]{1, 2, 4, 8}) { + for (int i = 0; i < us * 2; i++) { + int am = b.alignmentOffset(i, us); + int expectedAm = (longMisalignmentAtZero + i) % us; + + if (am != expectedAm) + fail(String.format("b.alignmentOffset(%d, %d) == %d incorrect, expected %d", i, us, am, expectedAm)); + } + } + + // Created aligned slice to test against + int ap = 8 - longMisalignmentAtZero; + int al = b.limit() - b.alignmentOffset(b.limit(), 8); + ByteBuffer ab = b.position(ap).limit(al). + slice(); + if (ab.limit() == 0) + fail("Test input buffer not sufficiently sized to cover an aligned region for all values", b); + if (ab.alignmentOffset(0, 8) != 0) + fail("Aligned test input buffer not correctly aligned at index 0", ab); + + for (int us : new int[]{1, 2, 4, 8}) { + for (int p = 1; p < 16; p++) { + int l = ab.limit() - p; + + ByteBuffer as = ab.slice().position(p).limit(l). + alignedSlice(us); + + ck(as, 0, as.position()); + ck(as, as.capacity(), as.limit()); + if (b.isDirect() != as.isDirect()) + fail("Lost direction", as); + if (b.isReadOnly() != as.isReadOnly()) + fail("Lost read-only", as); + + if (as.alignmentOffset(0, us) != 0) + fail("Buffer not correctly aligned at index 0", as); + + if (as.alignmentOffset(as.limit(), us) != 0) + fail("Buffer not correctly aligned at limit", as); + + int p_mod = ab.alignmentOffset(p, us); + int l_mod = ab.alignmentOffset(l, us); + // Round up position + p = (p_mod > 0) ? p + (us - p_mod) : p; + // Round down limit + l = l - l_mod; + + int ec = l - p; + if (as.limit() != ec) + fail("Buffer capacity incorrect, expected: " + ec, as); + } + } + } #end[byte] private static void fail(String problem, @@ -854,6 +951,11 @@ public class Basic$Type$ relPut(b); // Required by testViews +#if[byte] + // Test alignment + + testAlign(b, direct); +#end[byte] } #if[char] diff --git a/jdk/test/java/nio/Buffer/Basic.java b/jdk/test/java/nio/Buffer/Basic.java index cf592ced1a9..957d1fc12e4 100644 --- a/jdk/test/java/nio/Buffer/Basic.java +++ b/jdk/test/java/nio/Buffer/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -26,6 +26,8 @@ * @bug 4413135 4414911 4416536 4416562 4418782 4471053 4472779 4490253 4523725 * 4526177 4463011 4660660 4661219 4663521 4782970 4804304 4938424 6231529 * 6221101 6234263 6535542 6591971 6593946 6795561 7190219 7199551 8065556 + * 8149469 + * @modules java.base/jdk.internal.misc * @author Mark Reinhold */ diff --git a/jdk/test/java/nio/Buffer/BasicByte.java b/jdk/test/java/nio/Buffer/BasicByte.java index 0c9c9b3d02b..2d165449fa6 100644 --- a/jdk/test/java/nio/Buffer/BasicByte.java +++ b/jdk/test/java/nio/Buffer/BasicByte.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -336,6 +336,103 @@ public class BasicByte } + private static void testAlign(final ByteBuffer b, boolean direct) { + // index out-of bounds + tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(-1, (short) 1)); + + // unit size values + tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, (short) 0)); + for (int us = 1; us < 65; us++) { + int _us = us; + if ((us & (us - 1)) != 0) { + // unit size not a power of two + tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, _us)); + } else { + if (direct || us <= 8) { + b.alignmentOffset(0, us); + } else { + // unit size > 8 with non-direct buffer + tryCatch(b, UnsupportedOperationException.class, () -> b.alignmentOffset(0, _us)); + } + } + } + + // Probe for long misalignment at index zero for a newly created buffer + ByteBuffer empty = direct ? ByteBuffer.allocateDirect(0) : ByteBuffer.allocate(0); + int longMisalignmentAtZero = empty.alignmentOffset(0, 8); + + if (direct) { + // Freshly created direct byte buffers should be aligned at index 0 + // for ref and primitive values (see Unsafe.allocateMemory) + if (longMisalignmentAtZero != 0) + fail("Direct byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero); + } else { + // For heap byte buffers misalignment may occur on 32-bit systems + // where Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 == 4 and not 0 + // Note the GC will preserve alignment of the base address of the + // array + if (jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 != longMisalignmentAtZero) + fail("Heap byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero); + } + + // Ensure test buffer is correctly aligned at index 0 + if (b.alignmentOffset(0, 8) != longMisalignmentAtZero) + fail("Test input buffer not correctly aligned at index 0", b); + + // Test misalignment values + for (int us : new int[]{1, 2, 4, 8}) { + for (int i = 0; i < us * 2; i++) { + int am = b.alignmentOffset(i, us); + int expectedAm = (longMisalignmentAtZero + i) % us; + + if (am != expectedAm) + fail(String.format("b.alignmentOffset(%d, %d) == %d incorrect, expected %d", i, us, am, expectedAm)); + } + } + + // Created aligned slice to test against + int ap = 8 - longMisalignmentAtZero; + int al = b.limit() - b.alignmentOffset(b.limit(), 8); + ByteBuffer ab = b.position(ap).limit(al). + slice(); + if (ab.limit() == 0) + fail("Test input buffer not sufficiently sized to cover an aligned region for all values", b); + if (ab.alignmentOffset(0, 8) != 0) + fail("Aligned test input buffer not correctly aligned at index 0", ab); + + for (int us : new int[]{1, 2, 4, 8}) { + for (int p = 1; p < 16; p++) { + int l = ab.limit() - p; + + ByteBuffer as = ab.slice().position(p).limit(l). + alignedSlice(us); + + ck(as, 0, as.position()); + ck(as, as.capacity(), as.limit()); + if (b.isDirect() != as.isDirect()) + fail("Lost direction", as); + if (b.isReadOnly() != as.isReadOnly()) + fail("Lost read-only", as); + + if (as.alignmentOffset(0, us) != 0) + fail("Buffer not correctly aligned at index 0", as); + + if (as.alignmentOffset(as.limit(), us) != 0) + fail("Buffer not correctly aligned at limit", as); + + int p_mod = ab.alignmentOffset(p, us); + int l_mod = ab.alignmentOffset(l, us); + // Round up position + p = (p_mod > 0) ? p + (us - p_mod) : p; + // Round down limit + l = l - l_mod; + + int ec = l - p; + if (as.limit() != ec) + fail("Buffer capacity incorrect, expected: " + ec, as); + } + } + } private static void fail(String problem, @@ -854,6 +951,11 @@ public class BasicByte relPut(b); // Required by testViews + + // Test alignment + + testAlign(b, direct); + } diff --git a/jdk/test/java/nio/Buffer/BasicChar.java b/jdk/test/java/nio/Buffer/BasicChar.java index 1005d3c18ed..b8dc950b68c 100644 --- a/jdk/test/java/nio/Buffer/BasicChar.java +++ b/jdk/test/java/nio/Buffer/BasicChar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -317,6 +317,103 @@ public class BasicChar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -854,6 +951,11 @@ public class BasicChar relPut(b); // Required by testViews + + + + + } diff --git a/jdk/test/java/nio/Buffer/BasicDouble.java b/jdk/test/java/nio/Buffer/BasicDouble.java index 9e334608e68..b25fe15aa52 100644 --- a/jdk/test/java/nio/Buffer/BasicDouble.java +++ b/jdk/test/java/nio/Buffer/BasicDouble.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -317,6 +317,103 @@ public class BasicDouble + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -854,6 +951,11 @@ public class BasicDouble relPut(b); // Required by testViews + + + + + } diff --git a/jdk/test/java/nio/Buffer/BasicFloat.java b/jdk/test/java/nio/Buffer/BasicFloat.java index c9a22b5d96b..c4d42867b2b 100644 --- a/jdk/test/java/nio/Buffer/BasicFloat.java +++ b/jdk/test/java/nio/Buffer/BasicFloat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -317,6 +317,103 @@ public class BasicFloat + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -854,6 +951,11 @@ public class BasicFloat relPut(b); // Required by testViews + + + + + } diff --git a/jdk/test/java/nio/Buffer/BasicInt.java b/jdk/test/java/nio/Buffer/BasicInt.java index 71377168850..46ad7578d24 100644 --- a/jdk/test/java/nio/Buffer/BasicInt.java +++ b/jdk/test/java/nio/Buffer/BasicInt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -317,6 +317,103 @@ public class BasicInt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -854,6 +951,11 @@ public class BasicInt relPut(b); // Required by testViews + + + + + } diff --git a/jdk/test/java/nio/Buffer/BasicLong.java b/jdk/test/java/nio/Buffer/BasicLong.java index 05b1a5fb4c3..d3a0ff98c10 100644 --- a/jdk/test/java/nio/Buffer/BasicLong.java +++ b/jdk/test/java/nio/Buffer/BasicLong.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -317,6 +317,103 @@ public class BasicLong + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -854,6 +951,11 @@ public class BasicLong relPut(b); // Required by testViews + + + + + } diff --git a/jdk/test/java/nio/Buffer/BasicShort.java b/jdk/test/java/nio/Buffer/BasicShort.java index aed3d070ce0..eef47f23e21 100644 --- a/jdk/test/java/nio/Buffer/BasicShort.java +++ b/jdk/test/java/nio/Buffer/BasicShort.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -317,6 +317,103 @@ public class BasicShort + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -854,6 +951,11 @@ public class BasicShort relPut(b); // Required by testViews + + + + + } diff --git a/jdk/test/java/nio/Buffer/CopyDirectMemory.java b/jdk/test/java/nio/Buffer/CopyDirectMemory.java index 918fc0eece8..beb0b81865e 100644 --- a/jdk/test/java/nio/Buffer/CopyDirectMemory.java +++ b/jdk/test/java/nio/Buffer/CopyDirectMemory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -25,6 +25,7 @@ * @summary Test view buffer bulk operations for large buffers. * @bug 4463011 * + * @modules java.base/jdk.internal.misc * @build Basic * @run main CopyDirectMemory */ diff --git a/jdk/test/java/nio/channels/Selector/SelectAndClose.java b/jdk/test/java/nio/channels/Selector/SelectAndClose.java index a694f3d4347..a545e945bc6 100644 --- a/jdk/test/java/nio/channels/Selector/SelectAndClose.java +++ b/jdk/test/java/nio/channels/Selector/SelectAndClose.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -23,6 +23,7 @@ /* @test * @bug 5004077 + * @key intermittent * @summary Check blocking of select and close */ diff --git a/jdk/test/java/nio/channels/SocketChannel/Connect.java b/jdk/test/java/nio/channels/SocketChannel/Connect.java index 76a32e732e9..d427d9e6b4b 100644 --- a/jdk/test/java/nio/channels/SocketChannel/Connect.java +++ b/jdk/test/java/nio/channels/SocketChannel/Connect.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -22,7 +22,7 @@ */ /* @test - * @bug 4650679 + * @bug 4650679 8037360 * @summary Unit test for socket channels * @library .. */ @@ -42,9 +42,7 @@ public class Connect { test1(echoServer); } try { - TestServers.RefusingServer refusingServer - = TestServers.RefusingServer.startNewServer(); - test1(refusingServer); + test1(TestServers.RefusingServer.newRefusingServer()); throw new Exception("Refused connection throws no exception"); } catch (ConnectException ce) { // Correct result diff --git a/jdk/test/java/nio/channels/TestServers.java b/jdk/test/java/nio/channels/TestServers.java index 22d45233392..a5f6c8b408b 100644 --- a/jdk/test/java/nio/channels/TestServers.java +++ b/jdk/test/java/nio/channels/TestServers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -80,13 +80,12 @@ public class TestServers { return address; } - public static RefusingServer startNewServer() throws IOException { - ServerSocket socket = new ServerSocket(0, 100, - InetAddress.getLocalHost()); - RefusingServer server = new RefusingServer(socket.getInetAddress(), - socket.getLocalPort()); - socket.close(); - return server; + public static RefusingServer newRefusingServer() throws IOException { + // The port 1 is reserved for TCPMUX(RFC 1078), which is seldom used, + // and it's not used on all the test platform through JPRT. + // So we choose to use it as a refusing "server"'s "listen" port, + // it's much more stable than "open->close a server socket". + return new RefusingServer(InetAddress.getLocalHost(), 1); } } diff --git a/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh b/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh index 70e9c2b221b..ce870264855 100644 --- a/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh +++ b/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh @@ -51,6 +51,10 @@ rm classes/ExtLoadedImpl.class classes/ExtLoadedImpl_Stub.class classes/CheckLoa mkdir -p ext $COMPILEJAVA/bin/jar ${TESTTOOLVMOPTS} cf ext/ext.jar -C $TESTCLASSES ExtLoadedImpl.class -C $TESTCLASSES ExtLoadedImpl_Stub.class -C $TESTCLASSES CheckLoader.class -TESTVMOPTS="${TESTVMOPTS} -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED,java.rmi/sun.rmi.server=ALL-UNNAMED,java.rmi/sun.rmi.transport=ALL-UNNAMED,java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" +TESTVMOPTS="${TESTVMOPTS} \ + -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED \ + -XaddExports:java.rmi/sun.rmi.server=ALL-UNNAMED \ + -XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED \ + -XaddExports:java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" $TESTJAVA/bin/java ${TESTVMOPTS} -cp classes -Dtest.src=$TESTSRC -Dtest.classes=$TESTCLASSES -Djava.security.policy=$TESTSRC/security.policy -Djava.ext.dirs=ext ExtLoadedImplTest diff --git a/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java b/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java index 1b2288c7786..5906f991a40 100644 --- a/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java +++ b/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java @@ -138,9 +138,11 @@ public class DownloadActivationGroup p.put("java.security.policy", TestParams.defaultGroupPolicy); CommandEnvironment cmd = new ActivationGroupDesc.CommandEnvironment( null, - new String[] { "-XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED," - + "java.rmi/sun.rmi.server=ALL-UNNAMED,java.rmi/sun.rmi.transport=ALL-UNNAMED," - + "java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" }); + new String[] { + "-XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED", + "-XaddExports:java.rmi/sun.rmi.server=ALL-UNNAMED", + "-XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED", + "-XaddExports:java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" }); ActivationGroupDesc groupDesc = new ActivationGroupDesc("MyActivationGroupImpl", diff --git a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java index 2ee592f7591..393db7ee6fc 100644 --- a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java +++ b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java @@ -120,9 +120,12 @@ public class StubClassesPermitted // System.err.println("Create activation group, in a new VM"); CommandEnvironment cmd = new ActivationGroupDesc.CommandEnvironment(null, - new String[] { "-XaddExports:java.base/sun.security.provider=ALL-UNNAMED," - + "java.rmi/sun.rmi.registry=ALL-UNNAMED,java.rmi/sun.rmi.server=ALL-UNNAMED," - + "java.rmi/sun.rmi.transport=ALL-UNNAMED,java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" }); + new String[] { + "-XaddExports:java.base/sun.security.provider=ALL-UNNAMED", + "-XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED", + "-XaddExports:java.rmi/sun.rmi.server=ALL-UNNAMED", + "-XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED", + "-XaddExports:java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" }); ActivationGroupDesc groupDesc = new ActivationGroupDesc(p, cmd); diff --git a/jdk/test/java/rmi/registry/readTest/readTest.sh b/jdk/test/java/rmi/registry/readTest/readTest.sh index 5c5490eceb4..3bee78b65e4 100644 --- a/jdk/test/java/rmi/registry/readTest/readTest.sh +++ b/jdk/test/java/rmi/registry/readTest/readTest.sh @@ -98,7 +98,11 @@ case "$OS" in ;; esac # trailing / after code base is important for rmi codebase property. -TESTVMOPTS="${TESTVMOPTS} -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED,java.rmi/sun.rmi.server=ALL-UNNAMED,java.rmi/sun.rmi.transport=ALL-UNNAMED,java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" +TESTVMOPTS="${TESTVMOPTS} \ + -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED \ + -XaddExports:java.rmi/sun.rmi.server=ALL-UNNAMED \ + -XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED \ + -XaddExports:java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -cp $TEST_CLASSPATH ${ARGS} -Djava.rmi.server.codebase=${FILEURL}$CODEBASE/ readTest > OUT.TXT 2>&1 & TEST_PID=$! #bulk of testcase - let it run for a while diff --git a/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java b/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java index 1dc6d1fbc07..289772a3782 100644 --- a/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java +++ b/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java @@ -123,9 +123,10 @@ public class CheckFQDN extends UnicastRemoteObject propOption + property + equal + propertyValue + extraProp + - " -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED," - + "java.rmi/sun.rmi.server=ALL-UNNAMED,java.rmi/sun.rmi.transport=ALL-UNNAMED," - + "java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" + + " -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED" + + " -XaddExports:java.rmi/sun.rmi.server=ALL-UNNAMED" + + " -XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED" + + " -XaddExports:java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" + " -Drmi.registry.port=" + REGISTRY_PORT, ""); diff --git a/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java b/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java index a02e6a39273..fc7ae3cd818 100644 --- a/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java +++ b/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java @@ -74,10 +74,10 @@ public class DGCDeadLock implements Runnable { try { String options = " -Djava.security.policy=" + TestParams.defaultPolicy + - " -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED," + - "java.rmi/sun.rmi.server=ALL-UNNAMED," + - "java.rmi/sun.rmi.transport=ALL-UNNAMED," + - "java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" + + " -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED" + + " -XaddExports:java.rmi/sun.rmi.server=ALL-UNNAMED" + + " -XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED" + + " -XaddExports:java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" + " -Djava.rmi.dgc.leaseValue=500000" + " -Dsun.rmi.dgc.checkInterval=" + (HOLD_TARGET_TIME - 5000) + diff --git a/jdk/test/java/net/Inet4Address/DummyNameServiceDescriptor.java b/jdk/test/java/text/Format/DateFormat/DateFormatSymbolsCloneTest.java similarity index 58% rename from jdk/test/java/net/Inet4Address/DummyNameServiceDescriptor.java rename to jdk/test/java/text/Format/DateFormat/DateFormatSymbolsCloneTest.java index fd2ba233e31..7214d1fa8d5 100644 --- a/jdk/test/java/net/Inet4Address/DummyNameServiceDescriptor.java +++ b/jdk/test/java/text/Format/DateFormat/DateFormatSymbolsCloneTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -22,33 +22,29 @@ */ /* - * Descriptor for the dummy name service + * @test + * @bug 8151431 + * @summary Make sure that clone() of a DateFormatSymbols subclass is not + * called from DateFormatSymbols constructor. */ +import java.text.DateFormatSymbols; -import sun.net.spi.nameservice.*; +public class DateFormatSymbolsCloneTest extends DateFormatSymbols { + private int value; -public final class DummyNameServiceDescriptor implements NameServiceDescriptor { - - /** - * Create a new instance of the corresponding name service. - */ - public NameService createNameService() throws Exception { - return new DummyNameService(); + public DateFormatSymbolsCloneTest() { + value = 1; } - /** - * Returns this service provider's name - * - */ - public String getProviderName() { - return "oracle"; + @Override + public Object clone() { + if (this.value == 0) { + throw new RuntimeException("clone() should not be called from a DateFormatSymbols constructor"); + } + return super.clone(); } - /** - * Returns this name service type - * "dns" "nis" etc - */ - public String getType() { - return "dummy"; + public static void main(String[] args) { + new DateFormatSymbolsCloneTest(); } } diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java index 87462db27eb..4b96c2a4b07 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -68,11 +68,16 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import java.time.ZoneId; import java.time.Clock; import java.time.DateTimeException; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; import java.time.chrono.ChronoLocalDate; import java.time.chrono.Chronology; +import java.time.chrono.Era; import java.time.chrono.HijrahChronology; import java.time.chrono.HijrahEra; import java.time.chrono.IsoChronology; @@ -97,6 +102,14 @@ import org.testng.annotations.Test; @Test public class TCKChronology { + private static final ZoneOffset OFFSET_P0100 = ZoneOffset.ofHours(1); + private static final ZoneOffset OFFSET_M0100 = ZoneOffset.ofHours(-1); + + private static final int YDIFF_MEIJI = 1867; + private static final int YDIFF_SHOWA = 1925; + private static final int YDIFF_HEISEI = 1988; + private static final int YDIFF_MINGUO = 1911; + private static final int YDIFF_THAIBUDDHIST = 543; //----------------------------------------------------------------------- // regular data factory for ID and calendarType of available calendars //----------------------------------------------------------------------- @@ -323,7 +336,7 @@ public class TCKChronology { } } - @Test(expectedExceptions=DateTimeException.class) + @Test(expectedExceptions = DateTimeException.class) public void test_lookupLocale() { Locale.Builder builder = new Locale.Builder().setLanguage("en").setRegion("CA"); builder.setUnicodeLocaleKeyword("ca", "xxx"); @@ -337,4 +350,78 @@ public class TCKChronology { Chronology chrono = Chronology.of("FooFoo"); } + @DataProvider(name = "epochSecond_dataProvider") + Object[][] data_epochSecond() { + return new Object[][] { + {JapaneseChronology.INSTANCE, 1873, 9, 7, 1, 2, 2, OFFSET_P0100}, + {JapaneseChronology.INSTANCE, 1928, 2, 28, 1, 2, 2, OFFSET_M0100}, + {JapaneseChronology.INSTANCE, 1989, 1, 8, 1, 2, 2, OFFSET_P0100}, + {HijrahChronology.INSTANCE, 1434, 9, 7, 1, 2, 2, OFFSET_P0100}, + {MinguoChronology.INSTANCE, 1873, 9, 7, 1, 2, 2, OFFSET_P0100}, + {MinguoChronology.INSTANCE, 1928, 2, 28, 1, 2, 2, OFFSET_M0100}, + {MinguoChronology.INSTANCE, 1989, 1, 8, 1, 2, 2, OFFSET_P0100}, + {ThaiBuddhistChronology.INSTANCE, 1873, 9, 7, 1, 2, 2, OFFSET_P0100}, + {ThaiBuddhistChronology.INSTANCE, 1928, 2, 28, 1, 2, 2, OFFSET_M0100}, + {ThaiBuddhistChronology.INSTANCE, 1989, 1, 8, 1, 2, 2, OFFSET_P0100}, + {IsoChronology.INSTANCE, 1873, 9, 7, 1, 2, 2, OFFSET_P0100}, + {IsoChronology.INSTANCE, 1928, 2, 28, 1, 2, 2, OFFSET_M0100}, + {IsoChronology.INSTANCE, 1989, 1, 8, 1, 2, 2, OFFSET_P0100}, + + }; + } + + @Test(dataProvider = "epochSecond_dataProvider") + public void test_epochSecond(Chronology chrono, int y, int m, int d, int h, int min, int s, ZoneOffset offset) { + ChronoLocalDate chronoLd = chrono.date(y, m, d); + assertEquals(chrono.epochSecond(y, m, d, h, min, s, offset), + OffsetDateTime.of(LocalDate.from(chronoLd), LocalTime.of(h, min, s), offset) + .toEpochSecond()); + } + + @DataProvider(name = "era_epochSecond_dataProvider") + Object[][] data_era_epochSecond() { + return new Object[][] { + {JapaneseChronology.INSTANCE, JapaneseEra.MEIJI, 1873 - YDIFF_MEIJI, 9, 7, 1, 2, 2, OFFSET_P0100}, + {JapaneseChronology.INSTANCE, JapaneseEra.SHOWA, 1928 - YDIFF_SHOWA, 2, 28, 1, 2, 2, OFFSET_M0100}, + {JapaneseChronology.INSTANCE, JapaneseEra.HEISEI, 1989 - YDIFF_HEISEI, 1, 8, 1, 2, 2, OFFSET_P0100}, + {HijrahChronology.INSTANCE, HijrahEra.AH, 1434, 9, 7, 1, 2, 2, OFFSET_P0100}, + {MinguoChronology.INSTANCE, MinguoEra.BEFORE_ROC, 1873 - YDIFF_MINGUO, 9, 7, 1, 2, 2, OFFSET_P0100}, + {MinguoChronology.INSTANCE, MinguoEra.ROC, 1928 - YDIFF_MINGUO, 2, 28, 1, 2, 2, OFFSET_M0100}, + {MinguoChronology.INSTANCE, MinguoEra.ROC, 1989 - YDIFF_MINGUO, 1, 8, 1, 2, 2, OFFSET_P0100}, + {ThaiBuddhistChronology.INSTANCE, ThaiBuddhistEra.BE, 1873 + YDIFF_THAIBUDDHIST, 9, 7, 1, 2, 2, OFFSET_P0100}, + {ThaiBuddhistChronology.INSTANCE, ThaiBuddhistEra.BE, 1928 + YDIFF_THAIBUDDHIST, 2, 28, 1, 2, 2, OFFSET_M0100}, + {ThaiBuddhistChronology.INSTANCE, ThaiBuddhistEra.BE, 1989 + YDIFF_THAIBUDDHIST, 1, 8, 1, 2, 2, OFFSET_P0100}, + {IsoChronology.INSTANCE, IsoEra.CE, 1873, 9, 7, 1, 2, 2, OFFSET_P0100}, + {IsoChronology.INSTANCE, IsoEra.CE, 1928, 2, 28, 1, 2, 2, OFFSET_M0100}, + {IsoChronology.INSTANCE, IsoEra.CE, 1989, 1, 8, 1, 2, 2, OFFSET_P0100}, + + }; + } + + @Test(dataProvider = "era_epochSecond_dataProvider") + public void test_epochSecond(Chronology chrono, Era era, int y, int m, int d, int h, int min, int s, ZoneOffset offset) { + ChronoLocalDate chronoLd = chrono.date(era, y, m, d); + assertEquals(chrono.epochSecond(era, y, m, d, h, min, s, offset), + OffsetDateTime.of(LocalDate.from(chronoLd), LocalTime.of(h, min, s), offset) + .toEpochSecond()); + } + + @DataProvider(name = "bad_epochSecond_dataProvider") + Object[][] bad_data_epochSecond() { + return new Object[][] { + {JapaneseChronology.INSTANCE, 1873, 13, 7, 1, 2, 2, OFFSET_P0100}, + {HijrahChronology.INSTANCE, 1434, 9, 32, 1, 2, 2, OFFSET_P0100}, + {MinguoChronology.INSTANCE, 1873, 9, 7, 31, 2, 2, OFFSET_P0100}, + {ThaiBuddhistChronology.INSTANCE, 1928, 2, 28, -1, 2, 2, OFFSET_M0100}, + {IsoChronology.INSTANCE, 1928, 2, 28, 1, 60, 2, OFFSET_M0100}, + {IsoChronology.INSTANCE, 1989, 1, 8, 1, 2, -2, OFFSET_P0100}, + + }; + } + + @Test(dataProvider = "bad_epochSecond_dataProvider", expectedExceptions = DateTimeException.class) + public void test_bad_epochSecond(Chronology chrono, int y, int m, int d, int h, int min, int s, ZoneOffset offset) { + chrono.epochSecond(y, m, d, h, min, s, offset); + } + } diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKIsoChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKIsoChronology.java index 0cd8eed5fed..d753917a746 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKIsoChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKIsoChronology.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -63,10 +63,16 @@ import java.time.DateTimeException; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; -import java.time.ZoneId; +import java.time.OffsetDateTime; +import java.time.Year; import java.time.ZonedDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; import java.time.chrono.Chronology; +import java.time.chrono.Era; +import java.time.chrono.HijrahEra; import java.time.chrono.IsoChronology; +import java.time.chrono.IsoEra; import java.time.format.ResolverStyle; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; @@ -87,6 +93,8 @@ import org.testng.annotations.Test; public class TCKIsoChronology { // Can only work with IsoChronology here // others may be in separate module + private static final ZoneOffset OFFSET_P0100 = ZoneOffset.ofHours(1); + private static final ZoneOffset OFFSET_M0100 = ZoneOffset.ofHours(-1); @Test public void factory_from_TemporalAccessor_dateWithChronlogy() { @@ -675,9 +683,114 @@ public class TCKIsoChronology { } } + @DataProvider(name = "epochSecond_dataProvider") + Object[][] data_epochSecond() { + return new Object[][] { + {2008, 3, 3, 1, 2, 2, OFFSET_P0100}, + {2008, 3, 3, 1, 2, 2, OFFSET_M0100}, + {2008, 2, 28, 1, 2, 2, OFFSET_P0100}, + {2009, 3, 3, 1, 2, 2, OFFSET_P0100}, + {2009, 3, 3, 1, 2, 2, OFFSET_M0100}, + {2009, 2, 28, 1, 2, 2, OFFSET_P0100}, + {1968, 3, 3, 1, 2, 2, OFFSET_P0100}, + {1968, 3, 3, 1, 2, 2, OFFSET_M0100}, + {1968, 2, 28, 1, 2, 2, OFFSET_P0100}, + {1969, 3, 3 , 1, 2, 2, OFFSET_P0100}, + {1969, 3, 3, 1, 2, 2, OFFSET_M0100}, + {1969, 2, 28, 1, 2, 2, OFFSET_P0100}, + {1970, 1, 1, 1, 2, 2, OFFSET_P0100}, + {1970, 1, 1, 1, 2, 2, OFFSET_M0100}, + {-4, 3, 3 , 1, 2, 2, OFFSET_P0100}, + {-1, 3, 3 , 1, 2, 2, OFFSET_P0100}, + }; + } + + @Test(dataProvider = "epochSecond_dataProvider") + public void test_epochSecond_1(int y, int m, int d, int h , int min, int s, ZoneOffset offset) { + assertEquals(IsoChronology.INSTANCE.epochSecond(y, m, d, h, min, s, offset), + OffsetDateTime.of(y, m, d, h, min, s, 0, offset).toEpochSecond()); + } + + @Test + public void test_epochSecond_2() { + assertEquals(IsoChronology.INSTANCE.epochSecond(2008, 3, 3, 1, 2, 2, OFFSET_P0100), + ZonedDateTime.of(2008, 3, 3, 1, 2, 2, 0, ZoneId.of("+01:00")).toEpochSecond()); + assertEquals(IsoChronology.INSTANCE.epochSecond(1969, 3, 3, 1, 2, 2, OFFSET_P0100), + ZonedDateTime.of(1969, 3, 3, 1, 2, 2, 0, ZoneId.of("+01:00")).toEpochSecond()); + } + + @Test + public void test_epochSecond_max() { + assertEquals(IsoChronology.INSTANCE.epochSecond(Year.MAX_VALUE, 12, 31, 23, 59, 59, ZoneOffset.MIN), + OffsetDateTime.of(Year.MAX_VALUE, 12, 31, 23, 59, 59, 0, ZoneOffset.MIN).toEpochSecond()); + } + + @Test + public void test_epochSecond_min() { + assertEquals(IsoChronology.INSTANCE.epochSecond(Year.MIN_VALUE, 1, 1, 0, 0, 0, ZoneOffset.MAX), + OffsetDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0, 0, 0, ZoneOffset.MAX).toEpochSecond()); + } + + @DataProvider(name = "bad_epochSecond_dataProvider") + Object[][] bad_data_epochSecond() { + return new Object[][] { + {2009, 13, 1, 1, 1, 1, OFFSET_P0100}, + {2009, 2, 29, 1, 1, 1, OFFSET_P0100}, + {2009, 1, 1, 25, 1, 1, OFFSET_P0100}, + {2009, 1, 1, 1, 60, 1, OFFSET_P0100}, + {2009, 1, 1, 1, 1, -11, OFFSET_P0100}, + }; + } + @Test(dataProvider = "bad_epochSecond_dataProvider", expectedExceptions = DateTimeException.class) + public void test_epochSecond_bad(int y, int m, int d, int h , int min, int s, ZoneOffset offset) { + IsoChronology.INSTANCE.epochSecond(y, m, d, h, min, s, offset); + } + + @DataProvider(name = "era_epochSecond_dataProvider") + Object[][] data_era_epochSecond() { + return new Object[][] { + {IsoEra.CE, 2008, 3, 3, 1, 2, 2, OFFSET_P0100}, + {IsoEra.CE, 2008, 3, 3, 1, 2, 2, OFFSET_M0100}, + {IsoEra.CE, 2008, 2, 28, 1, 2, 2, OFFSET_P0100}, + {IsoEra.CE, 2009, 3, 3, 1, 2, 2, OFFSET_P0100}, + {IsoEra.CE, 2009, 3, 3, 1, 2, 2, OFFSET_M0100}, + {IsoEra.CE, 2009, 2, 28, 1, 2, 2, OFFSET_P0100}, + {IsoEra.CE, 1968, 3, 3, 1, 2, 2, OFFSET_P0100}, + {IsoEra.CE, 1968, 3, 3, 1, 2, 2, OFFSET_M0100}, + {IsoEra.CE, 1968, 2, 28, 1, 2, 2, OFFSET_P0100}, + {IsoEra.CE, 1969, 3, 3 , 1, 2, 2, OFFSET_P0100}, + {IsoEra.CE, 1969, 3, 3, 1, 2, 2, OFFSET_M0100}, + {IsoEra.CE, 1969, 2, 28, 1, 2, 2, OFFSET_P0100}, + {IsoEra.CE, 1970, 1, 1, 1, 2, 2, OFFSET_P0100}, + {IsoEra.CE, 1970, 1, 1, 1, 2, 2, OFFSET_M0100}, + {IsoEra.BCE, 5, 3, 3 , 1, 2, 2, OFFSET_P0100}, + {IsoEra.BCE, 2, 3, 3 , 1, 2, 2, OFFSET_P0100}, + }; + } + + @Test(dataProvider = "era_epochSecond_dataProvider") + public void test_era_epochSecond_1(Era era, int y, int m, int d, int h , int min, int s, ZoneOffset offset) { + assertEquals(IsoChronology.INSTANCE.epochSecond(era, y, m, d, h, min, s, offset), + OffsetDateTime.of(IsoChronology.INSTANCE.date(era, y, m, d), LocalTime.of(h, min, s), offset) + .toEpochSecond()); + } + + @Test + public void test_era_epochSecond_2() { + assertEquals(IsoChronology.INSTANCE.epochSecond(IsoEra.CE, 2008, 3, 3, 1, 2, 2, OFFSET_P0100), + ZonedDateTime.of(2008, 3, 3, 1, 2, 2, 0, ZoneId.of("+01:00")).toEpochSecond()); + assertEquals(IsoChronology.INSTANCE.epochSecond(IsoEra.CE, 1969, 3, 3, 1, 2, 2, OFFSET_P0100), + ZonedDateTime.of(1969, 3, 3, 1, 2, 2, 0, ZoneId.of("+01:00")).toEpochSecond()); + } + + @Test(expectedExceptions = ClassCastException.class) + public void test_era_epochSecond_bad() { + IsoChronology.INSTANCE.epochSecond(HijrahEra.AH, 2009, 2, 29, 1, 2, 2, OFFSET_P0100); + } + + //----------------------------------------------------------------------- private static LocalDate date(int y, int m, int d) { return LocalDate.of(y, m, d); } - } diff --git a/jdk/test/java/util/Currency/PropertiesTest.sh b/jdk/test/java/util/Currency/PropertiesTest.sh index 10dd24e519f..a6f8a76d189 100644 --- a/jdk/test/java/util/Currency/PropertiesTest.sh +++ b/jdk/test/java/util/Currency/PropertiesTest.sh @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 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 @@ -23,7 +23,7 @@ # # @test -# @bug 6332666 6863624 7180362 8003846 8074350 8074351 8130246 +# @bug 6332666 6863624 7180362 8003846 8074350 8074351 8130246 8149735 # @summary tests the capability of replacing the currency data with user # specified currency properties file # @build PropertiesTest @@ -85,12 +85,13 @@ PROPS=${TESTSRC}${FS}currency.properties # Dump built-in currency data run PropertiesTest -d dump1 - +if [ ! -f dump1 ]; then echo "file dump1 not created. Test cannot execute. Failed."; exit 1; fi # Dump built-in currency data + overrides in properties file specified # by system property. run -Djava.util.currency.data=${PROPS} PropertiesTest -d dump2 +if [ ! -f dump2 ]; then echo "file dump2 not created. Test cannot execute. Failed."; exit 1; fi run PropertiesTest -c dump1 dump2 ${PROPS} @@ -102,7 +103,7 @@ run PropertiesTest -c dump1 dump2 ${PROPS} WRITABLEJDK=.${FS}testjava cp -H -R $TESTJAVA $WRITABLEJDK || exit 1 PROPLOCATION=${WRITABLEJDK}${FS}lib -chmod -R +w $WRITABLEJDK || exit 1 +chmod -R a+rx $WRITABLEJDK || exit 1 cp ${PROPS} $PROPLOCATION || exit 1 echo "Properties location: ${PROPLOCATION}" @@ -110,6 +111,7 @@ echo "Properties location: ${PROPLOCATION}" echo '' ${WRITABLEJDK}${FS}bin${FS}java ${TESTVMOPTS} -cp ${TESTCLASSES} PropertiesTest -d dump3 if [ $? != 0 ]; then failures=`expr $failures + 1`; fi +if [ ! -f dump3 ]; then echo "file dump3 not created. Test cannot execute. Failed."; exit 1; fi # Cleanup rm -rf $WRITABLEJDK diff --git a/jdk/test/java/util/Locale/LocaleProviders.sh b/jdk/test/java/util/Locale/LocaleProviders.sh index cddb4274805..07f8f00eae2 100644 --- a/jdk/test/java/util/Locale/LocaleProviders.sh +++ b/jdk/test/java/util/Locale/LocaleProviders.sh @@ -122,7 +122,8 @@ tznp tznp8013086 EOF -EXTRAOPTS="-XaddExports:java.base/sun.util.locale=ALL-UNNAMED,java.base/sun.util.locale.provider=ALL-UNNAMED" +EXTRAOPTS="-XaddExports:java.base/sun.util.locale=ALL-UNNAMED \ + -XaddExports:java.base/sun.util.locale.provider=ALL-UNNAMED" ${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d ${SPIDIR}${FS}dest \ ${SPIDIR}${FS}src${FS}tznp.java \ diff --git a/jdk/test/java/util/PluggableLocale/ExecTest.sh b/jdk/test/java/util/PluggableLocale/ExecTest.sh index 190d5abb7fd..643895ed75f 100644 --- a/jdk/test/java/util/PluggableLocale/ExecTest.sh +++ b/jdk/test/java/util/PluggableLocale/ExecTest.sh @@ -93,7 +93,8 @@ case "$1" in esac -EXTRA_OPTS="-XaddExports:java.base/sun.util.locale.provider=ALL-UNNAMED,java.base/sun.util.resources=ALL-UNNAMED" +EXTRA_OPTS="-XaddExports:java.base/sun.util.locale.provider=ALL-UNNAMED \ + -XaddExports:java.base/sun.util.resources=ALL-UNNAMED" # compile cp ${TESTSRC}${FS}ProviderTest.java . diff --git a/jdk/test/java/util/ResourceBundle/Bug6299235Test.sh b/jdk/test/java/util/ResourceBundle/Bug6299235Test.sh index 35725bc0e71..62bc96cdba9 100644 --- a/jdk/test/java/util/ResourceBundle/Bug6299235Test.sh +++ b/jdk/test/java/util/ResourceBundle/Bug6299235Test.sh @@ -25,6 +25,7 @@ # @test # @bug 6299235 # @summary test Bug 6299235 to make sure the third-party provided sun resources could be picked up. +# @modules java.desktop # @build Bug6299235Test # @run shell Bug6299235Test.sh diff --git a/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java b/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java index 5a078a83ea5..5ad9d068a2a 100644 --- a/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java +++ b/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java @@ -37,9 +37,11 @@ * @summary Stress test looks for lost unparks * @library /lib/testlibrary/ * @modules java.management + * @run main/timeout=1200 ParkLoops */ import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; @@ -53,6 +55,7 @@ import java.util.concurrent.locks.LockSupport; import jdk.testlibrary.Utils; public final class ParkLoops { + static final long TEST_TIMEOUT_SECONDS = Utils.adjustTimeout(1000); static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000); static final int THREADS = 4; static final int ITERS = 30_000; @@ -130,7 +133,7 @@ public final class ParkLoops { pool.submit(unparker); } try { - if (!done.await(LONG_DELAY_MS, MILLISECONDS)) { + if (!done.await(TEST_TIMEOUT_SECONDS, SECONDS)) { dumpAllStacks(); throw new AssertionError("lost unpark"); } diff --git a/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java b/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java index f814ef5d732..340e7f972a4 100644 --- a/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java +++ b/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java @@ -3952,6 +3952,38 @@ public class CompletableFutureTest extends JSR166TestCase { Monad.plus(godot, Monad.unit(5L))); } + /** + * A single CompletableFuture with many dependents. + * A demo of scalability - runtime is O(n). + */ + public void testManyDependents() throws Throwable { + final int n = 1_000; + final CompletableFuture head = new CompletableFuture<>(); + final CompletableFuture complete = CompletableFuture.completedFuture((Void)null); + final AtomicInteger count = new AtomicInteger(0); + for (int i = 0; i < n; i++) { + head.thenRun(() -> count.getAndIncrement()); + head.thenAccept((x) -> count.getAndIncrement()); + head.thenApply((x) -> count.getAndIncrement()); + + head.runAfterBoth(complete, () -> count.getAndIncrement()); + head.thenAcceptBoth(complete, (x, y) -> count.getAndIncrement()); + head.thenCombine(complete, (x, y) -> count.getAndIncrement()); + complete.runAfterBoth(head, () -> count.getAndIncrement()); + complete.thenAcceptBoth(head, (x, y) -> count.getAndIncrement()); + complete.thenCombine(head, (x, y) -> count.getAndIncrement()); + + head.runAfterEither(new CompletableFuture(), () -> count.getAndIncrement()); + head.acceptEither(new CompletableFuture(), (x) -> count.getAndIncrement()); + head.applyToEither(new CompletableFuture(), (x) -> count.getAndIncrement()); + new CompletableFuture().runAfterEither(head, () -> count.getAndIncrement()); + new CompletableFuture().acceptEither(head, (x) -> count.getAndIncrement()); + new CompletableFuture().applyToEither(head, (x) -> count.getAndIncrement()); + } + head.complete(null); + assertEquals(5 * 3 * n, count.get()); + } + // static U join(CompletionStage stage) { // CompletableFuture f = new CompletableFuture<>(); // stage.whenComplete((v, ex) -> { diff --git a/jdk/test/java/util/concurrent/tck/JSR166TestCase.java b/jdk/test/java/util/concurrent/tck/JSR166TestCase.java index 78e7d684046..b189ce6b128 100644 --- a/jdk/test/java/util/concurrent/tck/JSR166TestCase.java +++ b/jdk/test/java/util/concurrent/tck/JSR166TestCase.java @@ -211,10 +211,13 @@ public class JSR166TestCase extends TestCase { private static final int suiteRuns = Integer.getInteger("jsr166.suiteRuns", 1); - private static float systemPropertyValue(String name, float defaultValue) { + /** + * Returns the value of the system property, or NaN if not defined. + */ + private static float systemPropertyValue(String name) { String floatString = System.getProperty(name); if (floatString == null) - return defaultValue; + return Float.NaN; try { return Float.parseFloat(floatString); } catch (NumberFormatException ex) { @@ -226,16 +229,25 @@ public class JSR166TestCase extends TestCase { /** * The scaling factor to apply to standard delays used in tests. + * May be initialized from any of: + * - the "jsr166.delay.factor" system property + * - the "test.timeout.factor" system property (as used by jtreg) + * See: http://openjdk.java.net/jtreg/tag-spec.html + * - hard-coded fuzz factor when using a known slowpoke VM */ - private static final float delayFactor = - systemPropertyValue("jsr166.delay.factor", 1.0f); + private static final float delayFactor = delayFactor(); - /** - * The timeout factor as used in the jtreg test harness. - * See: http://openjdk.java.net/jtreg/tag-spec.html - */ - private static final float jtregTestTimeoutFactor - = systemPropertyValue("test.timeout.factor", 1.0f); + private static float delayFactor() { + float x; + if (!Float.isNaN(x = systemPropertyValue("jsr166.delay.factor"))) + return x; + if (!Float.isNaN(x = systemPropertyValue("test.timeout.factor"))) + return x; + String prop = System.getProperty("java.vm.version"); + if (prop != null && prop.matches(".*debug.*")) + return 4.0f; // How much slower is fastdebug than product?! + return 1.0f; + } public JSR166TestCase() { super(); } public JSR166TestCase(String name) { super(name); } @@ -526,6 +538,7 @@ public class JSR166TestCase extends TestCase { "StampedLockTest", "SubmissionPublisherTest", "ThreadLocalRandom8Test", + "TimeUnit8Test", }; addNamedTestClasses(suite, java8TestClassNames); } @@ -616,7 +629,7 @@ public class JSR166TestCase extends TestCase { * http://openjdk.java.net/jtreg/command-help.html */ protected long getShortDelay() { - return (long) (50 * delayFactor * jtregTestTimeoutFactor); + return (long) (50 * delayFactor); } /** diff --git a/jdk/test/java/util/logging/Logger/getLogger/TestInferCaller.java b/jdk/test/java/util/logging/Logger/getLogger/TestInferCaller.java new file mode 100644 index 00000000000..952f615c6fe --- /dev/null +++ b/jdk/test/java/util/logging/Logger/getLogger/TestInferCaller.java @@ -0,0 +1,388 @@ +/* + * Copyright (c) 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. + */ + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.Objects; +import java.util.Queue; +import java.util.ResourceBundle; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +/** + * @test + * @bug 8152389 + * @summary Verify the correct behavior of LogRecord.inferCaller() in particular + * when a message is directly logged through the root logger. + * @run main/othervm TestInferCaller + * @author danielfuchs + */ +public class TestInferCaller { + + static final class LogEvent { + public final String className; + public final String methodName; + public final LogRecord record; + + public LogEvent(String className, String methodName, LogRecord record) { + this.className = className; + this.methodName = methodName; + this.record = record; + } + + } + + static final class TestHandler extends Handler { + + public static final Queue PUBLISHED = new LinkedList(); + + public TestHandler() { + initLevel(Level.ALL); + } + + @Override + public void close() throws SecurityException { } + @Override + public void publish(LogRecord record) { + LogEvent event = new LogEvent(record.getSourceClassName(), + record.getSourceMethodName(), + record); + PUBLISHED.add(event); + } + @Override + public void flush() {} + + private void initLevel(Level newLevel) { + super.setLevel(newLevel); + } + + } + + public void test1(Logger logger) { + System.out.println("test1: " + loggerName(logger)); + + AtomicInteger count = new AtomicInteger(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + logger.setLevel(Level.ALL); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + + logger.severe("message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + LogEvent event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test1", "message " + count.get()); + + logger.warning("message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test1", "message " + count.get()); + + logger.info("message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test1", "message " + count.get()); + + logger.config("message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test1", "message " + count.get()); + + logger.fine("message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test1", "message " + count.get()); + + logger.finer("message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test1", "message " + count.get()); + + logger.finest("message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test1", "message " + count.get()); + } + + void test2(Logger logger) { + AtomicInteger count = new AtomicInteger(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + logger.setLevel(Level.ALL); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + + for (Level l : Arrays.asList(Level.SEVERE, Level.WARNING, Level.INFO, + Level.CONFIG, Level.FINE, Level.FINER, Level.FINEST)) { + System.out.println("test2: " + loggerName(logger) + " " + l); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + + logger.log(l, "message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + LogEvent event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test2", "message " + count.get()); + + logger.log(l, "message " + count.incrementAndGet(), "param"); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test2", "message " + count.get()); + + logger.log(l, "message " + count.incrementAndGet(), new Object[] {"foo", "bar"}); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test2", "message " + count.get()); + + logger.log(l, "message " + count.incrementAndGet(), new RuntimeException()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test2", "message " + count.get()); + + // JDK 8 & 9 only (uses lambda) + logger.log(l, () -> "message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test2", "message " + count.get()); + + // JDK 8 & 9 only (uses lambda) + logger.log(l, new RuntimeException(), () -> "message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test2", "message " + count.get()); + + // JDK 9 only: new API + logger.logrb(l, (ResourceBundle)null, "message " + count.incrementAndGet(), (Object[]) null); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test2", "message " + count.get()); + + // JDK 9 only: new API + logger.logrb(l, (ResourceBundle)null, "message " + count.incrementAndGet(), new RuntimeException()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test2", "message " + count.get()); + + } + } + + void test3(Logger logger) { + System.out.println("test3: " + loggerName(logger)); + AtomicInteger count = new AtomicInteger(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + logger.setLevel(Level.ALL); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + + testReflection(logger, count, "severe", "testReflection"); + testReflection(logger, count, "warning", "testReflection"); + testReflection(logger, count, "info", "testReflection"); + testReflection(logger, count, "config", "testReflection"); + testReflection(logger, count, "fine", "testReflection"); + testReflection(logger, count, "finer", "testReflection"); + testReflection(logger, count, "finest", "testReflection"); + } + + void testReflection(Logger logger, AtomicInteger count, String logm, String method) { + try { + Method m = Logger.class.getMethod(logm, String.class); + m.invoke(logger, "message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + LogEvent event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), method, "message " + count.get()); + + Method m2 = Method.class.getMethod("invoke", Object.class, new Object[0].getClass()); + m2.invoke(m, logger, new Object[] { "message " + count.incrementAndGet() }); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), method, "message " + count.get()); + + m2.invoke(m2, m, new Object[] {logger, new Object[] { "message " + count.incrementAndGet() }}); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), method, "message " + count.get()); + + m2.invoke(m2, m2, new Object[] { m, new Object[] {logger, new Object[] { "message " + count.incrementAndGet() }}}); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), method, "message " + count.get()); + + } catch (Error | RuntimeException x ) { + throw x; + } catch (Exception x) { + throw new RuntimeException(x); + } + } + + // JDK 8 & 9 only (uses lambda) + public void test4(Logger logger) { + System.out.println("test4: " + loggerName(logger)); + AtomicInteger count = new AtomicInteger(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + logger.setLevel(Level.ALL); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + + logger.severe(() -> "message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + LogEvent event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test4", "message " + count.get()); + + logger.warning(() -> "message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test4", "message " + count.get()); + + logger.info(() -> "message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test4", "message " + count.get()); + + logger.config(() -> "message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test4", "message " + count.get()); + + logger.fine(() -> "message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test4", "message " + count.get()); + + logger.finer(() -> "message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test4", "message " + count.get()); + + logger.finest(() -> "message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), "test4", "message " + count.get()); + } + + // JDK 8 & 9 only (uses lambda) + void test5(Logger logger) { + System.out.println("test5: " + loggerName(logger)); + AtomicInteger count = new AtomicInteger(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + logger.setLevel(Level.ALL); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + + testLambda(count, logger::severe, "testLambda"); + testLambda(count, logger::warning, "testLambda"); + testLambda(count, logger::info, "testLambda"); + testLambda(count, logger::config, "testLambda"); + testLambda(count, logger::fine, "testLambda"); + testLambda(count, logger::finer, "testLambda"); + testLambda(count, logger::finest, "testLambda"); + } + + // JDK 8 & 9 only (uses lambda) + void testLambda(AtomicInteger count, Consumer logm, String method) { + logm.accept("message " + count.incrementAndGet()); + assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: "); + LogEvent event = TestHandler.PUBLISHED.remove(); + assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: "); + checkEvent(event, this.getClass().getName(), method, "message " + count.get()); + } + + private static String loggerName(Logger logger) { + String name = logger.getName(); + if (name == null) return ""; + if (name.isEmpty()) return ""; + return "\"" + name + "\""; + } + + public void test(Logger logger) { + test1(logger); + test2(logger); + test3(logger); + + // JDK 8 & 9 only (uses lambda) + test4(logger); + test5(logger); + } + + public static void main(String[] args) { + TestInferCaller test = new TestInferCaller(); + Logger root = Logger.getLogger(""); + for (Handler h : root.getHandlers()) { + h.setLevel(Level.OFF); + } + root.addHandler(new TestHandler()); + + for (Logger logger : Arrays.asList(root, Logger.getGlobal(), + Logger.getAnonymousLogger(), Logger.getLogger("foo.bar"))) { + System.out.println("Testing with: " + loggerName(logger) + " " + logger.getClass()); + test.test(logger); + } + } + + private static void assertEquals(int expected, int actual, String what) { + if (expected != actual) { + throw new RuntimeException(what + + "\n\texpected: " + expected + + "\n\tactual: " + actual); + } + } + + private static void assertEquals(String expected, String actual, String what) { + if (!Objects.equals(expected, actual)) { + throw new RuntimeException(what + + "\n\texpected: " + expected + + "\n\tactual: " + actual); + } + } + + private void checkEvent(LogEvent event, String className, String methodName, String message) { + assertEquals(className, event.className, "Bad class name: "); + assertEquals(className, event.record.getSourceClassName(), "Bad source class name: "); + assertEquals(methodName, event.methodName, "Bad method name: "); + assertEquals(methodName, event.record.getSourceMethodName(), "Bad source method name: "); + assertEquals(message, event.record.getMessage(), "Bad message: "); + } + + +} diff --git a/jdk/test/javax/imageio/plugins/shared/RepeatingWriteTest.java b/jdk/test/javax/imageio/plugins/shared/RepeatingWriteTest.java new file mode 100644 index 00000000000..28c0f04aa8a --- /dev/null +++ b/jdk/test/javax/imageio/plugins/shared/RepeatingWriteTest.java @@ -0,0 +1,221 @@ +/* + * Copyright (c) 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 + * + * @bug 8144991 8150154 + * @ignore 8150154 + * @author a.stepanov + * @summary Check if repeating image writing doesn't fail + * (particularly, no AIOOB occurs) + * + * @run main RepeatingWriteTest + */ + + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.*; +import javax.imageio.*; +import javax.imageio.stream.*; +import java.util.Iterator; +import java.util.Locale; +import javax.imageio.plugins.bmp.BMPImageWriteParam; +import javax.imageio.plugins.jpeg.JPEGImageWriteParam; + +public class RepeatingWriteTest { + + private static final int TYPES[] = new int[]{ + BufferedImage.TYPE_INT_RGB, BufferedImage.TYPE_INT_ARGB, + BufferedImage.TYPE_INT_ARGB_PRE, BufferedImage.TYPE_INT_BGR, + BufferedImage.TYPE_3BYTE_BGR, BufferedImage.TYPE_4BYTE_ABGR, + BufferedImage.TYPE_4BYTE_ABGR_PRE, BufferedImage.TYPE_BYTE_GRAY, + BufferedImage.TYPE_USHORT_GRAY, BufferedImage.TYPE_BYTE_BINARY, + BufferedImage.TYPE_BYTE_INDEXED, BufferedImage.TYPE_USHORT_565_RGB, + BufferedImage.TYPE_USHORT_555_RGB}; + + private static final String NAMES[] = new String[]{ + "TYPE_INT_RGB", "TYPE_INT_ARGB", + "TYPE_INT_ARGB_PRE", "TYPE_INT_BGR", + "TYPE_3BYTE_BGR", "TYPE_4BYTE_ABGR", + "TYPE_4BYTE_ABGR_PRE", "TYPE_BYTE_GRAY", + "TYPE_USHORT_GRAY", "TYPE_BYTE_BINARY", + "TYPE_BYTE_INDEXED", "TYPE_USHORT_565_RGB", + "TYPE_USHORT_555_RGB"}; + + private static final int SZ1 = 200, SZ2 = 100; + private static final Color C1 = Color.BLACK, C2 = Color.WHITE; + + private static ImageWriter getWriter(String format) { + Iterator writers = + ImageIO.getImageWritersByFormatName(format); + if (!writers.hasNext()) { + throw new RuntimeException("no writers available for " + format); + } + return writers.next(); + } + + private static ImageReader getReader(String format) { + Iterator readers = + ImageIO.getImageReadersByFormatName(format); + if (!readers.hasNext()) { + throw new RuntimeException("no readers available for " + format); + } + return readers.next(); + } + + private static class ImageCheckException extends Exception { + public ImageCheckException(String msg) { super(msg); } + } + + private final String format; + + public RepeatingWriteTest(String format) { this.format = format; } + + private void checkImage(String fileName, boolean is1st) throws Exception { + + Color cRef = is1st ? C1 : C2; + int szRef = is1st ? SZ1 : SZ2; + + ImageReader reader = getReader(format); + ImageInputStream iis = ImageIO.createImageInputStream(new File(fileName)); + reader.setInput(iis); + BufferedImage img = reader.read(0); + Color c = new Color(img.getRGB(szRef / 2, szRef / 2)); + + int w = img.getWidth(), h = img.getHeight(); + + if (w != szRef || h != szRef) { + throw new ImageCheckException(fileName + + ": invalid image size " + w + " x " + h); + } + + if (!c.equals(cRef)) { + throw new ImageCheckException(fileName + + ": invalid image color " + c); + } + } + + private void doTest(int i, int j) throws Exception { + + String pair = NAMES[i] + " " + NAMES[j]; + + // some type checks: avoid IO exceptions + if ((format.equals("jpeg") || format.equals("bmp")) && + (pair.contains("USHORT_GRAY") || + pair.contains("ARGB") || pair.contains("ABGR"))) { + return; + } + + + String f1 = "test-1-" + NAMES[i] + "." + format; + String f2 = "test-2-" + NAMES[j] + "." + format; + + ImageWriter writer = getWriter(format); + + // --- write 1st image --- + OutputStream s = new BufferedOutputStream(new FileOutputStream(f1)); + ImageOutputStream ios = ImageIO.createImageOutputStream(s); + writer.setOutput(ios); + + BufferedImage img = new BufferedImage(SZ1, SZ1, TYPES[i]); + Graphics g = img.getGraphics(); + g.setColor(C1); + g.fillRect(0, 0, SZ1, SZ1); + g.dispose(); + + if (format.equals("jpeg")) { + writer.write(null, new IIOImage(img, null, null), + new JPEGImageWriteParam(Locale.getDefault())); + } if (format.equals("bmp")) { + writer.write(null, new IIOImage(img, null, null), + new BMPImageWriteParam()); + } else { + writer.write(img); + } + ios.flush(); + s.close(); + + // --- write 2nd image --- + s = new BufferedOutputStream(new FileOutputStream(f2)); + ios = ImageIO.createImageOutputStream(s); + writer.setOutput(ios); + + img = new BufferedImage(SZ2, SZ2, TYPES[j]); + g = img.getGraphics(); + g.setColor(C2); + g.fillRect(0, 0, SZ2, SZ2); + g.dispose(); + + if (format.equals("jpeg")) { + writer.write(null, new IIOImage(img, null, null), + new JPEGImageWriteParam(Locale.getDefault())); + } if (format.equals("bmp")) { + writer.write(null, new IIOImage(img, null, null), + new BMPImageWriteParam()); + } else { + writer.write(img); + } + ios.flush(); + s.close(); + + // --- check files --- + checkImage(f1, true); + checkImage(f2, false); + } + + public static void main(String args[]) throws Exception { + + + int n = TYPES.length; + int nAIOOB = 0, nChecksFailed = 0; + + String formats[] = {"bmp", "jpeg", "gif", "png", "tiff"}; + + for (String f: formats) { + System.out.println("\nformat: " + f); + RepeatingWriteTest test = new RepeatingWriteTest(f); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < n; ++j) { + try { + test.doTest(i, j); + } catch (ArrayIndexOutOfBoundsException e) { + System.err.println(f + ": AIOOB for pair " + + NAMES[i] + ", " + NAMES[j] + ": " + e.getMessage()); + nAIOOB++; + } catch (ImageCheckException e) { + System.err.println(f + + ": image check failed for " + e.getMessage()); + nChecksFailed++; + } + } + } + } + + if (nAIOOB > 0 || nChecksFailed > 0) { + throw new RuntimeException("test failed: " + nAIOOB + " AIOOBs, " + + nChecksFailed + " image check failures"); + } + } +} diff --git a/jdk/test/javax/imageio/plugins/tiff/MultiPageTest/MultiPageTest.java b/jdk/test/javax/imageio/plugins/tiff/MultiPageTest/MultiPageTest.java index 2edb9a1f1c5..823b9ea1bc4 100644 --- a/jdk/test/javax/imageio/plugins/tiff/MultiPageTest/MultiPageTest.java +++ b/jdk/test/javax/imageio/plugins/tiff/MultiPageTest/MultiPageTest.java @@ -97,7 +97,7 @@ public class MultiPageTest { } - private ImageWriter getTIFFWriter() throws Exception { + private ImageWriter getTIFFWriter() { Iterator writers = ImageIO.getImageWritersByFormatName("TIFF"); if (!writers.hasNext()) { @@ -106,7 +106,7 @@ public class MultiPageTest { return writers.next(); } - private ImageReader getTIFFReader() throws Exception { + private ImageReader getTIFFReader() { Iterator readers = ImageIO.getImageReadersByFormatName("TIFF"); if (!readers.hasNext()) { diff --git a/jdk/test/javax/net/ssl/DTLS/TEST.properties b/jdk/test/javax/net/ssl/DTLS/TEST.properties index 939f9c06596..080af05306b 100644 --- a/jdk/test/javax/net/ssl/DTLS/TEST.properties +++ b/jdk/test/javax/net/ssl/DTLS/TEST.properties @@ -4,6 +4,4 @@ modules = \ java.security.jgss/sun.security.krb5.internal.ccache \ java.security.jgss/sun.security.krb5.internal \ java.security.jgss/sun.security.krb5.internal.ktab \ - java.base/sun.net.spi.nameservice \ - java.base/sun.security.util \ - java.base/sun.misc + java.base/sun.security.util diff --git a/jdk/test/javax/net/ssl/DTLSv10/TEST.properties b/jdk/test/javax/net/ssl/DTLSv10/TEST.properties index 939f9c06596..080af05306b 100644 --- a/jdk/test/javax/net/ssl/DTLSv10/TEST.properties +++ b/jdk/test/javax/net/ssl/DTLSv10/TEST.properties @@ -4,6 +4,4 @@ modules = \ java.security.jgss/sun.security.krb5.internal.ccache \ java.security.jgss/sun.security.krb5.internal \ java.security.jgss/sun.security.krb5.internal.ktab \ - java.base/sun.net.spi.nameservice \ - java.base/sun.security.util \ - java.base/sun.misc + java.base/sun.security.util diff --git a/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorer.java b/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorer.java index 3ef485b6982..439f3f2fd90 100644 --- a/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorer.java +++ b/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorer.java @@ -31,7 +31,6 @@ * @bug 7068321 * @summary Support TLS Server Name Indication (SNI) Extension in JSSE Server * @library ../SSLEngine ../templates - * @modules java.base/sun.misc * @build SSLEngineService SSLCapabilities SSLExplorer * @run main/othervm SSLEngineExplorer SSLv2Hello,SSLv3 * @run main/othervm SSLEngineExplorer SSLv3 diff --git a/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerMatchedSNI.java b/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerMatchedSNI.java index ccfdbac0c64..b9854dd3e94 100644 --- a/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerMatchedSNI.java +++ b/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerMatchedSNI.java @@ -31,7 +31,6 @@ * @bug 7068321 * @summary Support TLS Server Name Indication (SNI) Extension in JSSE Server * @library ../SSLEngine ../templates - * @modules java.base/sun.misc * @build SSLEngineService SSLCapabilities SSLExplorer * @run main/othervm SSLEngineExplorerMatchedSNI www.example.com * www\.example\.com diff --git a/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerUnmatchedSNI.java b/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerUnmatchedSNI.java index 8ae4b68e3fe..ff8678ba6a8 100644 --- a/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerUnmatchedSNI.java +++ b/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerUnmatchedSNI.java @@ -31,7 +31,6 @@ * @bug 7068321 * @summary Support TLS Server Name Indication (SNI) Extension in JSSE Server * @library ../SSLEngine ../templates - * @modules java.base/sun.misc * @build SSLEngineService SSLCapabilities SSLExplorer * @run main/othervm SSLEngineExplorerUnmatchedSNI www.example.com * www\.example\.org diff --git a/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerWithCli.java b/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerWithCli.java index 7c8e6a275c9..f9888839929 100644 --- a/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerWithCli.java +++ b/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerWithCli.java @@ -31,7 +31,6 @@ * @bug 7068321 * @summary Support TLS Server Name Indication (SNI) Extension in JSSE Server * @library ../SSLEngine ../templates - * @modules java.base/sun.misc * @build SSLEngineService SSLCapabilities SSLExplorer * @run main/othervm SSLEngineExplorerWithCli */ diff --git a/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerWithSrv.java b/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerWithSrv.java index f0baeefbf53..0517a7750aa 100644 --- a/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerWithSrv.java +++ b/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorerWithSrv.java @@ -31,7 +31,6 @@ * @bug 7068321 * @summary Support TLS Server Name Indication (SNI) Extension in JSSE Server * @library ../SSLEngine ../templates - * @modules java.base/sun.misc * @build SSLEngineService SSLCapabilities SSLExplorer * @run main/othervm SSLEngineExplorerWithSrv */ diff --git a/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorer.java b/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorer.java index f91c6c2365b..887b624fda4 100644 --- a/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorer.java +++ b/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorer.java @@ -31,7 +31,6 @@ * @bug 7068321 * @summary Support TLS Server Name Indication (SNI) Extension in JSSE Server * @library ../templates - * @modules java.base/sun.misc * @build SSLCapabilities SSLExplorer * @run main/othervm SSLSocketExplorer SSLv2Hello,SSLv3 * @run main/othervm SSLSocketExplorer SSLv3 diff --git a/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerFailure.java b/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerFailure.java index 9e12e9b4b2f..aaf8d299486 100644 --- a/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerFailure.java +++ b/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerFailure.java @@ -31,7 +31,6 @@ * @bug 7068321 * @summary Support TLS Server Name Indication (SNI) Extension in JSSE Server * @library ../templates - * @modules java.base/sun.misc * @build SSLCapabilities SSLExplorer * @run main/othervm SSLSocketExplorerFailure SSLv2Hello,SSLv3 * @run main/othervm SSLSocketExplorerFailure SSLv3 diff --git a/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerMatchedSNI.java b/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerMatchedSNI.java index bde4f6cc0d9..724a37e1a80 100644 --- a/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerMatchedSNI.java +++ b/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerMatchedSNI.java @@ -31,7 +31,6 @@ * @bug 7068321 * @summary Support TLS Server Name Indication (SNI) Extension in JSSE Server * @library ../templates - * @modules java.base/sun.misc * @build SSLCapabilities SSLExplorer * @run main/othervm SSLSocketExplorerMatchedSNI www.example.com * www\.example\.com diff --git a/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerUnmatchedSNI.java b/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerUnmatchedSNI.java index a266f5f4beb..732e0cf3097 100644 --- a/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerUnmatchedSNI.java +++ b/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerUnmatchedSNI.java @@ -31,7 +31,6 @@ * @bug 7068321 * @summary Support TLS Server Name Indication (SNI) Extension in JSSE Server * @library ../templates - * @modules java.base/sun.misc * @build SSLCapabilities SSLExplorer * @run main/othervm SSLSocketExplorerUnmatchedSNI www.example.com * www\.example\.org diff --git a/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerWithCliSNI.java b/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerWithCliSNI.java index 183a23fa260..8f2b7816864 100644 --- a/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerWithCliSNI.java +++ b/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerWithCliSNI.java @@ -31,7 +31,6 @@ * @bug 7068321 * @summary Support TLS Server Name Indication (SNI) Extension in JSSE Server * @library ../templates - * @modules java.base/sun.misc * @build SSLCapabilities SSLExplorer * @run main/othervm SSLSocketExplorerWithCliSNI */ diff --git a/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerWithSrvSNI.java b/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerWithSrvSNI.java index 20b8a6991c7..f026f32e781 100644 --- a/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerWithSrvSNI.java +++ b/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorerWithSrvSNI.java @@ -31,7 +31,6 @@ * @bug 7068321 * @summary Support TLS Server Name Indication (SNI) Extension in JSSE Server * @library ../templates - * @modules java.base/sun.misc * @build SSLCapabilities SSLExplorer * @run main/othervm SSLSocketExplorerWithSrvSNI */ diff --git a/jdk/test/javax/net/ssl/TLS/TEST.properties b/jdk/test/javax/net/ssl/TLS/TEST.properties index 264f568ca14..8c058b4a7d0 100644 --- a/jdk/test/javax/net/ssl/TLS/TEST.properties +++ b/jdk/test/javax/net/ssl/TLS/TEST.properties @@ -4,6 +4,5 @@ modules = \ java.security.jgss/sun.security.krb5 \ java.security.jgss/sun.security.krb5.internal.ccache \ java.security.jgss/sun.security.krb5.internal \ - java.base/sun.net.spi.nameservice \ java.base/sun.security.util \ jdk.crypto.ec/sun.security.ec diff --git a/jdk/test/javax/net/ssl/TLSv1/TEST.properties b/jdk/test/javax/net/ssl/TLSv1/TEST.properties index 0413b8e22df..080af05306b 100644 --- a/jdk/test/javax/net/ssl/TLSv1/TEST.properties +++ b/jdk/test/javax/net/ssl/TLSv1/TEST.properties @@ -4,5 +4,4 @@ modules = \ java.security.jgss/sun.security.krb5.internal.ccache \ java.security.jgss/sun.security.krb5.internal \ java.security.jgss/sun.security.krb5.internal.ktab \ - java.base/sun.net.spi.nameservice \ java.base/sun.security.util diff --git a/jdk/test/javax/net/ssl/TLSv11/TEST.properties b/jdk/test/javax/net/ssl/TLSv11/TEST.properties index 0413b8e22df..080af05306b 100644 --- a/jdk/test/javax/net/ssl/TLSv11/TEST.properties +++ b/jdk/test/javax/net/ssl/TLSv11/TEST.properties @@ -4,5 +4,4 @@ modules = \ java.security.jgss/sun.security.krb5.internal.ccache \ java.security.jgss/sun.security.krb5.internal \ java.security.jgss/sun.security.krb5.internal.ktab \ - java.base/sun.net.spi.nameservice \ java.base/sun.security.util diff --git a/jdk/test/javax/security/auth/Subject/SubjectNullTests.java b/jdk/test/javax/security/auth/Subject/SubjectNullTests.java index 29b1a667734..a14092427fa 100644 --- a/jdk/test/javax/security/auth/Subject/SubjectNullTests.java +++ b/jdk/test/javax/security/auth/Subject/SubjectNullTests.java @@ -24,8 +24,7 @@ /* * @test * @bug 8015081 - * @modules java.base/sun.misc - * java.management + * @modules java.management * java.security.jgss * @compile Subject.java * @compile SubjectNullTests.java diff --git a/jdk/test/javax/sound/sampled/spi/AudioFileReader/RecognizeHugeWaveExtFiles.java b/jdk/test/javax/sound/sampled/spi/AudioFileReader/RecognizeHugeWaveExtFiles.java new file mode 100644 index 00000000000..88b231d62d7 --- /dev/null +++ b/jdk/test/javax/sound/sampled/spi/AudioFileReader/RecognizeHugeWaveExtFiles.java @@ -0,0 +1,245 @@ +/* + * Copyright (c) 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. + */ + +import java.io.ByteArrayInputStream; + +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 8132782 + */ +public final class RecognizeHugeWaveExtFiles { + + /** + * The maximum size in bytes per WAVE specification. + */ + private static final /*unsigned int */ long MAX_UNSIGNED_INT = 0xffffffffL; + + /** + * The supported wave ext format and sample size in bits. + */ + private static final int[][] waveTypeBits = { + {0xFFFE/*WAVE_FORMAT_EXTENSIBLE*/, 8} + }; + + /** + * The list of supported sample rates(stored as unsigned int). + */ + private static final int[] sampleRates = { + 8000, 11025, 16000, 22050, 32000, 37800, 44056, 44100, 47250, 48000, + 50000, 50400, 88200, 96000, 176400, 192000, 352800, 2822400, + 5644800, Integer.MAX_VALUE + }; + + /** + * The list of supported channels (stored as unsigned int). + */ + private static final int[] channels = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 + }; + + /** + * The list of supported size of data (stored as unsigned int). + *

      + * The {@code MAX_UNSIGNED_INT} is a maximum size. + */ + private static final long[] dataSizes = { + 0, 1, 2, 3, Integer.MAX_VALUE - 1, Integer.MAX_VALUE, + (long) Integer.MAX_VALUE + 1, MAX_UNSIGNED_INT - 1, MAX_UNSIGNED_INT + }; + + public static void main(final String[] args) throws Exception { + for (final int[] type : waveTypeBits) { + for (final int sampleRate : sampleRates) { + for (final int channel : channels) { + for (final long dataSize : dataSizes) { + testAFF(type, sampleRate, channel, dataSize); + testAIS(type, sampleRate, channel, dataSize); + } + } + } + } + } + + /** + * Tests the {@code AudioFileFormat} fetched from the fake header. + *

      + * Note that the frameLength and byteLength are stored as int which means + * that {@code AudioFileFormat} will store the data above {@code MAX_INT} as + * NOT_SPECIFIED. + */ + private static void testAFF(final int[] type, final int rate, + final int channel, final long size) + throws Exception { + final byte[] header = createHeader(type, rate, channel, size); + final ByteArrayInputStream fake = new ByteArrayInputStream(header); + final AudioFileFormat aff = AudioSystem.getAudioFileFormat(fake); + final AudioFormat format = aff.getFormat(); + + if (aff.getType() != AudioFileFormat.Type.WAVE) { + throw new RuntimeException("Error"); + } + + final long frameLength = size / format.getFrameSize(); + if (frameLength <= Integer.MAX_VALUE) { + if (aff.getFrameLength() != frameLength) { + System.err.println("Expected: " + frameLength); + System.err.println("Actual: " + aff.getFrameLength()); + throw new RuntimeException(); + } + } else { + if (aff.getFrameLength() != AudioSystem.NOT_SPECIFIED) { + System.err.println("Expected: " + AudioSystem.NOT_SPECIFIED); + System.err.println("Actual: " + aff.getFrameLength()); + throw new RuntimeException(); + } + } + validateFormat(type[1], rate, channel, aff.getFormat()); + } + + /** + * Tests the {@code AudioInputStream} fetched from the fake header. + *

      + * Note that the frameLength is stored as long which means that {@code + * AudioInputStream} must store all possible data from au file. + */ + private static void testAIS(final int[] type, final int rate, + final int channel, final long size) + throws Exception { + final byte[] header = createHeader(type, rate, channel, size); + final ByteArrayInputStream fake = new ByteArrayInputStream(header); + final AudioInputStream ais = AudioSystem.getAudioInputStream(fake); + final AudioFormat format = ais.getFormat(); + final long frameLength = size / format.getFrameSize(); + if (frameLength != ais.getFrameLength()) { + System.err.println("Expected: " + frameLength); + System.err.println("Actual: " + ais.getFrameLength()); + throw new RuntimeException(); + } + if (ais.available() < 0) { + System.err.println("available should be >=0: " + ais.available()); + throw new RuntimeException(); + } + + validateFormat(type[1], rate, channel, format); + } + + /** + * Tests that format contains the same data as were provided to the fake + * stream. + */ + private static void validateFormat(final int bits, final int rate, + final int channel, + final AudioFormat format) { + + if (Float.compare(format.getSampleRate(), rate) != 0) { + System.err.println("Expected: " + rate); + System.err.println("Actual: " + format.getSampleRate()); + throw new RuntimeException(); + } + if (format.getChannels() != channel) { + System.err.println("Expected: " + channel); + System.err.println("Actual: " + format.getChannels()); + throw new RuntimeException(); + } + if (format.getFrameSize() != ((bits + 7) / 8) * channel) { + System.err.println("Expected: " + (bits * channel + 1) / 8); + System.err.println("Actual: " + format.getFrameSize()); + throw new RuntimeException(); + } + } + + /** + * Creates the custom header of the WAVE file. It is expected that all + * passed data are supported. + */ + private static byte[] createHeader(final int[] type, final int rate, + final int channel, final long size) { + final int frameSize = ((type[1] + 7) / 8) * channel; + return new byte[]{ + // RIFF_MAGIC + 0x52, 0x49, 0x46, 0x46, + // fileLength + -1, -1, -1, -1, + // waveMagic + 0x57, 0x41, 0x56, 0x45, + // FMT_MAGIC + 0x66, 0x6d, 0x74, 0x20, + // size + 40, 0, 0, 0, + // wav_type WAVE_FORMAT_EXTENSIBLE + (byte) (type[0]), (byte) (type[0] >> 8), + // channels + (byte) (channel), (byte) (channel >> 8), + // samplerate + (byte) (rate), (byte) (rate >> 8), (byte) (rate >> 16), + (byte) (rate >> 24), + // framerate + 1, 0, 0, 0, + // framesize + (byte) (frameSize), (byte) (frameSize >> 8), + // bits + (byte) type[1], 0, + // cbsize + 22, 0, + // validBitsPerSample + 8, 0, + // channelMask + 0, 0, 0, 0, + // SUBTYPE_IEEE_FLOAT + // i1 + 0x3, 0x0, 0x0, 0x0, + //s1 + 0x0, 0x0, + //s2 + 0x10, 0, + //x1 + (byte) 0x80, + //x2 + 0x0, + //x3 + 0x0, + //x4 + (byte) 0xaa, + //x5 + 0x0, + //x6 + 0x38, + //x7 + (byte) 0x9b, + //x8 + 0x71, + // DATA_MAGIC + 0x64, 0x61, 0x74, 0x61, + // data size + (byte) (size), (byte) (size >> 8), (byte) (size >> 16), + (byte) (size >> 24) + // data + , 0, 0, 0, 0, 0 + }; + } +} diff --git a/jdk/test/javax/sound/sampled/spi/AudioFileReader/RecognizeHugeWaveFloatFiles.java b/jdk/test/javax/sound/sampled/spi/AudioFileReader/RecognizeHugeWaveFloatFiles.java new file mode 100644 index 00000000000..e36a7e2b180 --- /dev/null +++ b/jdk/test/javax/sound/sampled/spi/AudioFileReader/RecognizeHugeWaveFloatFiles.java @@ -0,0 +1,216 @@ +/* + * Copyright (c) 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. + */ + +import java.io.ByteArrayInputStream; + +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 8132782 + */ +public final class RecognizeHugeWaveFloatFiles { + + /** + * The maximum size in bytes per WAVE specification. + */ + private static final /*unsigned int */ long MAX_UNSIGNED_INT = 0xffffffffL; + + /** + * The supported wave pcm_float format and sample size in bits. + */ + private static final byte[][] waveTypeBits = { + {0x0003/*WAVE_FORMAT_IEEE_FLOAT*/, 32} + }; + + /** + * The list of supported sample rates(stored as unsigned int). + */ + private static final int[] sampleRates = { + 8000, 11025, 16000, 22050, 32000, 37800, 44056, 44100, 47250, 48000, + 50000, 50400, 88200, 96000, 176400, 192000, 352800, 2822400, + 5644800, Integer.MAX_VALUE + }; + + /** + * The list of supported channels (stored as unsigned int). + */ + private static final int[] channels = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 + }; + + /** + * The list of supported size of data (stored as unsigned int). + *

      + * The {@code MAX_UNSIGNED_INT} is a maximum size. + */ + private static final long[] dataSizes = { + 0, 1, 2, 3, Integer.MAX_VALUE - 1, Integer.MAX_VALUE, + (long) Integer.MAX_VALUE + 1, MAX_UNSIGNED_INT - 1, MAX_UNSIGNED_INT + }; + + public static void main(final String[] args) throws Exception { + for (final byte[] type : waveTypeBits) { + for (final int sampleRate : sampleRates) { + for (final int channel : channels) { + for (final long dataSize : dataSizes) { + testAFF(type, sampleRate, channel, dataSize); + testAIS(type, sampleRate, channel, dataSize); + } + } + } + } + } + + /** + * Tests the {@code AudioFileFormat} fetched from the fake header. + *

      + * Note that the frameLength and byteLength are stored as int which means + * that {@code AudioFileFormat} will store the data above {@code MAX_INT} as + * NOT_SPECIFIED. + */ + private static void testAFF(final byte[] type, final int rate, + final int channel, final long size) + throws Exception { + final byte[] header = createHeader(type, rate, channel, size); + final ByteArrayInputStream fake = new ByteArrayInputStream(header); + final AudioFileFormat aff = AudioSystem.getAudioFileFormat(fake); + final AudioFormat format = aff.getFormat(); + + if (aff.getType() != AudioFileFormat.Type.WAVE) { + throw new RuntimeException("Error"); + } + + final long frameLength = size / format.getFrameSize(); + if (frameLength <= Integer.MAX_VALUE) { + if (aff.getFrameLength() != frameLength) { + System.err.println("Expected: " + frameLength); + System.err.println("Actual: " + aff.getFrameLength()); + throw new RuntimeException(); + } + } else { + if (aff.getFrameLength() != AudioSystem.NOT_SPECIFIED) { + System.err.println("Expected: " + AudioSystem.NOT_SPECIFIED); + System.err.println("Actual: " + aff.getFrameLength()); + throw new RuntimeException(); + } + } + validateFormat(type[1], rate, channel, aff.getFormat()); + } + + /** + * Tests the {@code AudioInputStream} fetched from the fake header. + *

      + * Note that the frameLength is stored as long which means that {@code + * AudioInputStream} must store all possible data from au file. + */ + private static void testAIS(final byte[] type, final int rate, + final int channel, final long size) + throws Exception { + final byte[] header = createHeader(type, rate, channel, size); + final ByteArrayInputStream fake = new ByteArrayInputStream(header); + final AudioInputStream ais = AudioSystem.getAudioInputStream(fake); + final AudioFormat format = ais.getFormat(); + final long frameLength = size / format.getFrameSize(); + if (frameLength != ais.getFrameLength()) { + System.err.println("Expected: " + frameLength); + System.err.println("Actual: " + ais.getFrameLength()); + throw new RuntimeException(); + } + if (ais.available() < 0) { + System.err.println("available should be >=0: " + ais.available()); + throw new RuntimeException(); + } + + validateFormat(type[1], rate, channel, format); + } + + /** + * Tests that format contains the same data as were provided to the fake + * stream. + */ + private static void validateFormat(final byte bits, final int rate, + final int channel, + final AudioFormat format) { + + if (Float.compare(format.getSampleRate(), rate) != 0) { + System.err.println("Expected: " + rate); + System.err.println("Actual: " + format.getSampleRate()); + throw new RuntimeException(); + } + if (format.getChannels() != channel) { + System.err.println("Expected: " + channel); + System.err.println("Actual: " + format.getChannels()); + throw new RuntimeException(); + } + if (format.getFrameSize() != ((bits + 7) / 8) * channel) { + System.err.println("Expected: " + (bits * channel + 1) / 8); + System.err.println("Actual: " + format.getFrameSize()); + throw new RuntimeException(); + } + } + + /** + * Creates the custom header of the WAVE file. It is expected that all + * passed data are supported. + */ + private static byte[] createHeader(final byte[] type, final int rate, + final int channel, final long size) { + final int frameSize = ((type[1] + 7) / 8) * channel; + return new byte[]{ + // RIFF_MAGIC + 0x52, 0x49, 0x46, 0x46, + // fileLength + -1, -1, -1, -1, + // waveMagic + 0x57, 0x41, 0x56, 0x45, + // FMT_MAGIC + 0x66, 0x6d, 0x74, 0x20, + // size + 16, 0, 0, 0, + // wav_type WAVE_FORMAT_IEEE_FLOAT + type[0], 0, + // channels + (byte) (channel), (byte) (channel >> 8), + // samplerate + (byte) (rate), (byte) (rate >> 8), (byte) (rate >> 16), + (byte) (rate >> 24), + // framerate + 1, 0, 0, 0, + // framesize + (byte) (frameSize), (byte) (frameSize >> 8), + // bits + type[1], 0, + // DATA_MAGIC + 0x64, 0x61, 0x74, 0x61, + // data size + (byte) (size), (byte) (size >> 8), (byte) (size >> 16), + (byte) (size >> 24) + // data + , 0, 0, 0, 0, 0 + }; + } +} diff --git a/jdk/test/javax/swing/Action/8133039/bug8133039.java b/jdk/test/javax/swing/Action/8133039/bug8133039.java index 94ad929707b..3bfbe2d6e08 100644 --- a/jdk/test/javax/swing/Action/8133039/bug8133039.java +++ b/jdk/test/javax/swing/Action/8133039/bug8133039.java @@ -37,6 +37,7 @@ import sun.swing.UIAction; * @test * @bug 8133039 * @summary Provide public API to sun.swing.UIAction#isEnabled(Object) + * @modules java.desktop/sun.swing * @author Alexander Scherbatiy */ public class bug8133039 { diff --git a/jdk/test/javax/swing/JDesktopPane/DesktopPaneBackgroundTest.java b/jdk/test/javax/swing/JDesktopPane/DesktopPaneBackgroundTest.java new file mode 100644 index 00000000000..e8007e218d2 --- /dev/null +++ b/jdk/test/javax/swing/JDesktopPane/DesktopPaneBackgroundTest.java @@ -0,0 +1,63 @@ +/* +* Copyright (c) 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 +* @bug 7012008 +* @summary Verify JDesktopPane Background Color for WLAF +* @requires (os.family == "windows") +* @run main DesktopPaneBackgroundTest + */ +import java.awt.Color; +import java.awt.Toolkit; +import javax.swing.JDesktopPane; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +public class DesktopPaneBackgroundTest { + + private static Color defaultBackgroudColor; + + public static void main(String[] args) throws Exception { + defaultBackgroudColor = (Color) Toolkit.getDefaultToolkit() + .getDesktopProperty("win.mdi.backgroundColor"); + + String[] lookAndFeel = new String[]{ + "com.sun.java.swing.plaf.windows.WindowsLookAndFeel", + "com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel"}; + + for (String laf : lookAndFeel) { + UIManager.setLookAndFeel(laf); + + SwingUtilities.invokeAndWait(() -> { + JDesktopPane desktopPane = new JDesktopPane(); + + Color background = desktopPane.getBackground(); + if (!background.equals(defaultBackgroudColor)) { + throw new RuntimeException("Invalid JDesktopPane " + + "Background Color for WLAF"); + } + }); + } + } +} diff --git a/jdk/test/javax/swing/JInternalFrame/8069348/bug8069348.java b/jdk/test/javax/swing/JInternalFrame/8069348/bug8069348.java new file mode 100644 index 00000000000..d9deeefb99b --- /dev/null +++ b/jdk/test/javax/swing/JInternalFrame/8069348/bug8069348.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 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. + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.InputEvent; +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import static sun.awt.OSInfo.*; + +/** + * @test + * @bug 8069348 + * @summary SunGraphics2D.copyArea() does not properly work for scaled graphics + * @author Alexandr Scherbatiy + * @modules java.desktop/sun.awt + * @run main/othervm -Dsun.java2d.uiScale=2 bug8069348 + * @run main/othervm -Dsun.java2d.opengl=true -Dsun.java2d.uiScale=2 bug8069348 + * @run main/othervm -Dsun.java2d.d3d=true -Dsun.java2d.uiScale=2 bug8069348 + */ +public class bug8069348 { + + private static final int WIN_WIDTH = 500; + private static final int WIN_HEIGHT = 500; + + private static final Color DESKTOPPANE_COLOR = Color.YELLOW; + private static final Color FRAME_COLOR = Color.ORANGE; + + private static JFrame frame; + private static JInternalFrame internalFrame; + + public static void main(String[] args) throws Exception { + + if (!isSupported()) { + return; + } + + try { + + SwingUtilities.invokeAndWait(bug8069348::createAndShowGUI); + + Robot robot = new Robot(); + robot.setAutoDelay(50); + robot.waitForIdle(); + + Rectangle screenBounds = getInternalFrameScreenBounds(); + + int x = screenBounds.x + screenBounds.width / 2; + int y = screenBounds.y + 10; + int dx = screenBounds.width / 2; + int dy = screenBounds.height / 2; + + robot.mouseMove(x, y); + robot.waitForIdle(); + + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseMove(x + dx, y + dy); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + + int cx = screenBounds.x + screenBounds.width + dx / 2; + int cy = screenBounds.y + screenBounds.height + dy / 2; + + robot.mouseMove(cx, cy); + if (!FRAME_COLOR.equals(robot.getPixelColor(cx, cy))) { + throw new RuntimeException("Internal frame is not correctly dragged!"); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + + private static boolean isSupported() { + String d3d = System.getProperty("sun.java2d.d3d"); + return !Boolean.getBoolean(d3d) || getOSType() == OSType.WINDOWS; + } + + private static Rectangle getInternalFrameScreenBounds() throws Exception { + Rectangle[] points = new Rectangle[1]; + SwingUtilities.invokeAndWait(() -> { + points[0] = new Rectangle(internalFrame.getLocationOnScreen(), + internalFrame.getSize()); + }); + return points[0]; + } + + private static void createAndShowGUI() { + + frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + JDesktopPane desktopPane = new JDesktopPane(); + desktopPane.setBackground(DESKTOPPANE_COLOR); + + internalFrame = new JInternalFrame("Test") { + + @Override + public void paint(Graphics g) { + super.paint(g); + g.setColor(FRAME_COLOR); + g.fillRect(0, 0, getWidth(), getHeight()); + } + }; + internalFrame.setSize(WIN_WIDTH / 3, WIN_HEIGHT / 3); + internalFrame.setVisible(true); + desktopPane.add(internalFrame); + + JPanel panel = new JPanel(); + panel.setLayout(new BorderLayout()); + panel.add(desktopPane, BorderLayout.CENTER); + frame.add(panel); + frame.setSize(WIN_WIDTH, WIN_HEIGHT); + frame.setVisible(true); + frame.requestFocus(); + } +} diff --git a/jdk/test/javax/swing/JInternalFrame/8145896/TestJInternalFrameMaximize.java b/jdk/test/javax/swing/JInternalFrame/8145896/TestJInternalFrameMaximize.java new file mode 100644 index 00000000000..267a9708931 --- /dev/null +++ b/jdk/test/javax/swing/JInternalFrame/8145896/TestJInternalFrameMaximize.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 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 + * @bug 8145896 + * @summary JInternalFrame setMaximum before adding to desktop throws null pointer exception + * @library ../../regtesthelpers + * @build Util + * @run main TestJInternalFrameMaximize + */ +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.beans.PropertyVetoException; +import javax.swing.JFrame; +import javax.swing.JDesktopPane; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JInternalFrame; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +public class TestJInternalFrameMaximize { + + private static JDesktopPane desktopPane; + private static JFrame frame; + private static int count = 0; + private static JMenu menu; + private static JMenuBar menuBar; + private static JMenuItem menuItem; + private static Robot robot; + private static volatile String errorMessage = ""; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + UIManager.LookAndFeelInfo[] lookAndFeelArray + = UIManager.getInstalledLookAndFeels(); + for (UIManager.LookAndFeelInfo lookAndFeelItem : lookAndFeelArray) { + String lookAndFeelString = lookAndFeelItem.getClassName(); + if (tryLookAndFeel(lookAndFeelString)) { + createUI(); + robot.waitForIdle(); + executeTest(); + } + } + if (!"".equals(errorMessage)) { + throw new RuntimeException(errorMessage); + } + } + + private static boolean tryLookAndFeel(String lookAndFeelString) { + try { + UIManager.setLookAndFeel(lookAndFeelString); + return true; + } catch (UnsupportedLookAndFeelException | ClassNotFoundException | + InstantiationException | IllegalAccessException e) { + errorMessage += e.getMessage() + "\n"; + System.err.println("Caught Exception: " + e.getMessage()); + return false; + } + } + + private static void createUI() throws Exception { + + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("Test Frame"); + desktopPane = new JDesktopPane(); + frame.getContentPane().add(desktopPane); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + menuBar = new JMenuBar(); + frame.setJMenuBar(menuBar); + + menu = new JMenu("File"); + menuBar.add(menu); + + menuItem = new JMenuItem("New Child"); + menuItem.addActionListener((ActionEvent e) -> { + try { + JInternalFrame f = new JInternalFrame("Child " + + (++count), true, true, true, true); + f.setSize(200, 300); + f.setLocation(count * 20, count * 20); + f.setMaximum(true); + desktopPane.add(f); + f.setVisible(true); + } catch (PropertyVetoException ex) { + } catch (RuntimeException ex) { + errorMessage = "Test Failed"; + } finally { + frame.dispose(); + } + }); + menu.add(menuItem); + frame.setSize(500, 500); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + } + + private static void executeTest() throws Exception { + + Point point = Util.getCenterPoint(menu); + performMouseOperations(point); + point = Util.getCenterPoint(menuItem); + performMouseOperations(point); + } + + private static void performMouseOperations(Point point) { + robot.mouseMove(point.x, point.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.delay(1000); + robot.waitForIdle(); + } +} diff --git a/jdk/test/javax/swing/JInternalFrame/8146321/JInternalFrameIconTest.java b/jdk/test/javax/swing/JInternalFrame/8146321/JInternalFrameIconTest.java index 4ff95c5bc30..fb3480d3785 100644 --- a/jdk/test/javax/swing/JInternalFrame/8146321/JInternalFrameIconTest.java +++ b/jdk/test/javax/swing/JInternalFrame/8146321/JInternalFrameIconTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -22,7 +22,7 @@ */ /* @test - * @bug 8146321 + * @bug 8146321 8151282 * @summary verifies JInternalFrame Icon and ImageIcon * @library ../../regtesthelpers * @build Util @@ -53,8 +53,9 @@ public class JInternalFrameIconTest { private static Icon titleIcon; private static BufferedImage imageIconImage; private static BufferedImage iconImage; - private static Robot robot; + private static volatile String errorString = ""; + public static void main(String[] args) throws Exception { robot = new Robot(); @@ -64,6 +65,9 @@ public class JInternalFrameIconTest { for (UIManager.LookAndFeelInfo lookAndFeelItem : lookAndFeelArray) { executeCase(lookAndFeelItem.getClassName()); } + if (!"".equals(errorString)) { + throw new RuntimeException("Error Log:\n" + errorString); + } } @@ -72,17 +76,18 @@ public class JInternalFrameIconTest { createImageIconUI(lookAndFeelString); robot.delay(1000); getImageIconBufferedImage(); - robot.waitForIdle(); + robot.delay(1000); cleanUp(); robot.waitForIdle(); createIconUI(lookAndFeelString); robot.delay(1000); getIconBufferedImage(); - robot.waitForIdle(); + robot.delay(1000); cleanUp(); robot.waitForIdle(); - testIfSame(); + + testIfSame(lookAndFeelString); robot.waitForIdle(); } @@ -198,11 +203,16 @@ public class JInternalFrameIconTest { = robot.createScreenCapture(captureRect); } - private static void testIfSame() throws Exception { + private static void testIfSame(final String lookAndFeelString) + throws Exception { if (!bufferedImagesEqual(imageIconImage, iconImage)) { - System.err.println("ERROR: icon and imageIcon not same."); + String error ="[" + lookAndFeelString + + "] : ERROR: icon and imageIcon not same."; + errorString += error; + System.err.println(error); } else { - System.out.println("SUCCESS: icon and imageIcon same."); + System.out.println("[" + lookAndFeelString + + "] : SUCCESS: icon and imageIcon same."); } } @@ -260,6 +270,11 @@ public class JInternalFrameIconTest { private static boolean tryLookAndFeel(String lookAndFeelString) throws Exception { + //This test case is not applicable for Motif and gtk LAFs + if(lookAndFeelString.contains("motif") + || lookAndFeelString.contains("gtk")) { + return false; + } try { UIManager.setLookAndFeel( lookAndFeelString); diff --git a/jdk/test/javax/swing/JPopupMenu/6544309/bug6544309.java b/jdk/test/javax/swing/JPopupMenu/6544309/bug6544309.java index ee30642f069..f0c76a48712 100644 --- a/jdk/test/javax/swing/JPopupMenu/6544309/bug6544309.java +++ b/jdk/test/javax/swing/JPopupMenu/6544309/bug6544309.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -30,9 +30,14 @@ @run main bug6544309 */ -import javax.swing.*; -import java.awt.event.*; -import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; + +import javax.swing.JDialog; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; public class bug6544309 { private JDialog dialog; @@ -41,6 +46,8 @@ public class bug6544309 { public static void main(String[] args) throws Exception { robot = new ExtendedRobot(); + // move mouse outside menu to prevent auto selection + robot.mouseMove(100,100); final bug6544309 test = new bug6544309(); try { SwingUtilities.invokeAndWait(new Runnable() { diff --git a/jdk/test/javax/swing/JTextArea/8148555/JTextAreaEmojiTest.java b/jdk/test/javax/swing/JTextArea/8148555/JTextAreaEmojiTest.java new file mode 100644 index 00000000000..5b16e3c53e3 --- /dev/null +++ b/jdk/test/javax/swing/JTextArea/8148555/JTextAreaEmojiTest.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 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. + */ + +import java.awt.Color; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import static javax.swing.WindowConstants.EXIT_ON_CLOSE; + +/* @test + * @bug 8148555 + * @summary verifies JTextArea emoji enter exception. Emoji is not supported. + * @requires (os.family=="mac") + * @run main JTextAreaEmojiTest + */ +public class JTextAreaEmojiTest implements + ActionListener { + + private static GridBagLayout layout; + private static JPanel textAreaPanel; + private static JPanel mainControlPanel; + private static JPanel instructionPanel; + private static JPanel resultButtonPanel; + private static JPanel controlPanel; + private static JTextArea instructionTextArea; + private static JTextArea emojiTextArea; + private static JButton passButton; + private static JButton failButton; + + private static JFrame mainFrame; + + public static void main(String[] args) throws Exception { + + JTextAreaEmojiTest test = new JTextAreaEmojiTest(); + } + + public JTextAreaEmojiTest() throws Exception { + createControlPanelUI(); + } + + public final void createControlPanelUI() throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + layout = new GridBagLayout(); + mainControlPanel = new JPanel(layout); + instructionPanel = new JPanel(layout); + resultButtonPanel = new JPanel(layout); + textAreaPanel = new JPanel(layout); + controlPanel = new JPanel(layout); + + GridBagConstraints gbc = new GridBagConstraints(); + String instructions + = "1) Text Area size should be zero" + + "\n2) Select one emoji from Character Viewer" + + "\n3) If Text Area size increases displaying" + + "Blank or supported emoji for default font, click pass" + + "\n4) Else press fail"; + instructionTextArea = new JTextArea(); + instructionTextArea.setText(instructions); + instructionTextArea.setEnabled(false); + instructionTextArea.setDisabledTextColor(Color.black); + instructionTextArea.setBackground(Color.white); + instructionTextArea.setBorder( + BorderFactory.createLineBorder(Color.black)); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.fill = GridBagConstraints.HORIZONTAL; + instructionPanel.add(instructionTextArea, gbc); + + emojiTextArea = new JTextArea(); + emojiTextArea.setEnabled(true); + emojiTextArea.setDisabledTextColor(Color.black); + emojiTextArea.setBackground(Color.white); + emojiTextArea.setBorder( + BorderFactory.createLineBorder(Color.black)); + gbc.gridx = 0; + gbc.gridy = 1; + gbc.fill = GridBagConstraints.HORIZONTAL; + textAreaPanel.add(emojiTextArea, gbc); + + passButton = new JButton("Pass"); + passButton.setActionCommand("Pass"); + passButton.addActionListener(JTextAreaEmojiTest.this); + failButton = new JButton("Fail"); + failButton.setActionCommand("Fail"); + failButton.addActionListener(JTextAreaEmojiTest.this); + gbc.gridx = 0; + gbc.gridy = 0; + resultButtonPanel.add(passButton, gbc); + gbc.gridx = 1; + gbc.gridy = 0; + resultButtonPanel.add(failButton, gbc); + + gbc.gridx = 0; + gbc.gridy = 0; + mainControlPanel.add(instructionPanel, gbc); + gbc.gridx = 0; + gbc.gridy = 1; + mainControlPanel.add(textAreaPanel, gbc); + gbc.gridx = 0; + gbc.gridy = 2; + mainControlPanel.add(resultButtonPanel, gbc); + + mainControlPanel.add(controlPanel, gbc); + mainFrame = new JFrame("Control Panel"); + mainFrame.add(mainControlPanel); + mainFrame.pack(); + mainFrame.setDefaultCloseOperation(EXIT_ON_CLOSE); + mainFrame.setVisible(true); + } + }); + } + + @Override + public void actionPerformed(ActionEvent evt) { + if (evt.getSource() instanceof JButton) { + JButton btn = (JButton) evt.getSource(); + cleanUp(); + + switch (btn.getActionCommand()) { + case "Pass": + break; + case "Fail": + throw new AssertionError("Test case has failed!"); + } + } + } + + private static void cleanUp() { + mainFrame.dispose(); + } +} diff --git a/jdk/test/javax/swing/JTextArea/8149849/DNDTextToScaledArea.java b/jdk/test/javax/swing/JTextArea/8149849/DNDTextToScaledArea.java new file mode 100644 index 00000000000..501fa199620 --- /dev/null +++ b/jdk/test/javax/swing/JTextArea/8149849/DNDTextToScaledArea.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 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. + */ + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; + +/** + * @test + * @bug 8149849 + * @summary [hidpi] DnD issues (cannot DnD from JFileChooser to JEditorPane or + * other text component) when scale > 1 + * @run main/othervm -Dsun.java2d.uiScale=2 DNDTextToScaledArea + */ +public class DNDTextToScaledArea { + + private static final String TEXT = "ABCDEFGH"; + private static JFrame frame; + private static JTextArea srcTextArea; + private static JTextArea dstTextArea; + private static volatile Point srcPoint; + private static volatile Point dstPoint; + private static volatile boolean passed = false; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(50); + + SwingUtilities.invokeAndWait(DNDTextToScaledArea::createAndShowGUI); + robot.waitForIdle(); + + SwingUtilities.invokeAndWait(() -> { + srcPoint = getPoint(srcTextArea, 0.1); + dstPoint = getPoint(dstTextArea, 0.75); + }); + robot.waitForIdle(); + + dragAndDrop(robot, srcPoint, dstPoint); + robot.waitForIdle(); + + SwingUtilities.invokeAndWait(() -> { + passed = TEXT.equals(dstTextArea.getText()); + frame.dispose(); + }); + robot.waitForIdle(); + + if (!passed) { + throw new RuntimeException("Text Drag and Drop failed!"); + } + } + + private static void createAndShowGUI() { + + frame = new JFrame(); + frame.setSize(300, 300); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + JPanel panel = new JPanel(new BorderLayout()); + + srcTextArea = new JTextArea(TEXT); + srcTextArea.setDragEnabled(true); + srcTextArea.selectAll(); + dstTextArea = new JTextArea(); + + panel.add(dstTextArea, BorderLayout.CENTER); + panel.add(srcTextArea, BorderLayout.SOUTH); + + frame.getContentPane().add(panel); + frame.setVisible(true); + } + + private static Point getPoint(Component component, double scale) { + Point point = component.getLocationOnScreen(); + Dimension bounds = component.getSize(); + point.translate((int) (bounds.width * scale), (int) (bounds.height * scale)); + return point; + } + + public static void dragAndDrop(Robot robot, Point src, Point dst) throws Exception { + + int x1 = src.x; + int y1 = src.y; + int x2 = dst.x; + int y2 = dst.y; + robot.mouseMove(x1, y1); + robot.mousePress(InputEvent.BUTTON1_MASK); + + float dmax = (float) Math.max(Math.abs(x2 - x1), Math.abs(y2 - y1)); + float dx = (x2 - x1) / dmax; + float dy = (y2 - y1) / dmax; + + for (int i = 0; i <= dmax; i += 5) { + robot.mouseMove((int) (x1 + dx * i), (int) (y1 + dy * i)); + } + + robot.mouseRelease(InputEvent.BUTTON1_MASK); + } +} diff --git a/jdk/test/javax/swing/LookAndFeel/6439354/TitledBorderTest.java b/jdk/test/javax/swing/LookAndFeel/6439354/TitledBorderTest.java new file mode 100644 index 00000000000..f74a14d99ee --- /dev/null +++ b/jdk/test/javax/swing/LookAndFeel/6439354/TitledBorderTest.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 1999, 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 + * @bug 6439354 + * @summary Verify TitleBorder appearance Color/Visibility for WLAF + * @requires (os.family == "windows") + * @run main/manual TitledBorderTest + */ +import java.awt.Color; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +public class TitledBorderTest implements ActionListener { + + private static GridBagLayout layout; + private static JPanel mainControlPanel; + private static JPanel resultButtonPanel; + private static JTextArea instructionTextArea; + private static JButton passButton; + private static JButton failButton; + private static JFrame mainFrame; + + public static void main(String[] args) throws Exception { + TitledBorderTest titledBorderTest = new TitledBorderTest(); + } + + public TitledBorderTest() throws Exception { + createUI(); + } + + public final void createUI() throws Exception { + + UIManager.setLookAndFeel("com.sun.java.swing.plaf." + + "windows.WindowsLookAndFeel"); + + SwingUtilities.invokeAndWait(() -> { + + mainFrame = new JFrame("Window LAF TitledBorder Test"); + layout = new GridBagLayout(); + mainControlPanel = new JPanel(layout); + resultButtonPanel = new JPanel(layout); + + GridBagConstraints gbc = new GridBagConstraints(); + String instructions + = "INSTRUCTIONS:" + + "\n set Windows Theme to HighContrast#1." + + "\n (ControlPanel->Personalization->High Contrast#1)" + + "\n If Titled Border(Border Line) is visible then test" + + " passes else failed."; + + instructionTextArea = new JTextArea(); + instructionTextArea.setText(instructions); + instructionTextArea.setEnabled(false); + instructionTextArea.setDisabledTextColor(Color.black); + instructionTextArea.setBackground(Color.white); + + gbc.gridx = 0; + gbc.gridy = 0; + gbc.fill = GridBagConstraints.HORIZONTAL; + mainControlPanel.add(instructionTextArea, gbc); + + mainControlPanel.setBorder(BorderFactory. + createTitledBorder("Titled Border")); + + passButton = new JButton("Pass"); + passButton.setActionCommand("Pass"); + passButton.addActionListener(TitledBorderTest.this); + failButton = new JButton("Fail"); + failButton.setActionCommand("Fail"); + failButton.addActionListener(TitledBorderTest.this); + gbc.gridx = 0; + gbc.gridy = 0; + resultButtonPanel.add(passButton, gbc); + gbc.gridx = 1; + gbc.gridy = 0; + resultButtonPanel.add(failButton, gbc); + + gbc.gridx = 0; + gbc.gridy = 1; + mainControlPanel.add(resultButtonPanel, gbc); + + mainFrame.add(mainControlPanel); + mainFrame.pack(); + mainFrame.setVisible(true); + }); + } + + @Override + public void actionPerformed(ActionEvent evt) { + if (evt.getSource() instanceof JButton) { + JButton btn = (JButton) evt.getSource(); + cleanUp(); + switch (btn.getActionCommand()) { + case "Pass": + break; + case "Fail": + throw new AssertionError("User Clicked Fail!"); + } + } + } + + private static void cleanUp() { + mainFrame.dispose(); + } + +} diff --git a/jdk/test/javax/swing/border/8152159/TitledBorderLabelUITest.java b/jdk/test/javax/swing/border/8152159/TitledBorderLabelUITest.java new file mode 100644 index 00000000000..b6c5bdf0358 --- /dev/null +++ b/jdk/test/javax/swing/border/8152159/TitledBorderLabelUITest.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 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. + */ + +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.SwingUtilities; +import javax.swing.UIDefaults; +import javax.swing.UIManager; +import javax.swing.border.TitledBorder; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; +import javax.swing.plaf.metal.MetalLabelUI; +import javax.swing.plaf.metal.MetalLookAndFeel; +import javax.swing.plaf.nimbus.NimbusLookAndFeel; + +/** + * @test + * @bug 8152159 + * @summary LabelUI is not updated for TitledBorder + * @run main/othervm TitledBorderLabelUITest LAF + * @run main/othervm TitledBorderLabelUITest LabelUI + */ + +public class TitledBorderLabelUITest { + + private static final int SIZE = 50; + private static boolean useLAF; + + public static void main(String[] args) throws Exception { + useLAF = "LAF".equals(args[0]); + SwingUtilities.invokeAndWait(TitledBorderLabelUITest::createAndShowGUI); + } + + private static void createAndShowGUI() { + + try { + UIManager.setLookAndFeel(new TestLookAndFeel()); + + JLabel label = new JLabel("Test Label"); + label.setSize(SIZE, SIZE); + TitledBorder border = new TitledBorder("ABCDEF"); + label.setBorder(new TitledBorder(border)); + + if (useLAF) { + UIManager.setLookAndFeel(new NimbusLookAndFeel()); + } else { + UIManager.getDefaults().put("LabelUI", MetalLabelUI.class.getName()); + } + + SwingUtilities.updateComponentTreeUI(label); + + paintToImage(label); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static void paintToImage(JComponent comp) { + BufferedImage image = new BufferedImage(SIZE, SIZE, BufferedImage.TYPE_INT_RGB); + Graphics2D g = image.createGraphics(); + comp.paint(g); + g.dispose(); + } + + public static class TestLookAndFeel extends MetalLookAndFeel { + + @Override + protected void initClassDefaults(UIDefaults table) { + super.initClassDefaults(table); + table.put("LabelUI", TestLabelUI.class.getName()); + } + } + + public static class TestLabelUI extends MetalLabelUI implements UIResource { + + public static ComponentUI createUI(JComponent c) { + return new TestLabelUI(); + } + + @Override + public void paint(Graphics g, JComponent c) { + super.paint(g, c); + throw new RuntimeException("New LabelUI is not installed!"); + } + } +} \ No newline at end of file diff --git a/jdk/test/javax/swing/text/TableView/I18nLayoutTest.java b/jdk/test/javax/swing/text/TableView/I18nLayoutTest.java new file mode 100644 index 00000000000..49f7a4d64cf --- /dev/null +++ b/jdk/test/javax/swing/text/TableView/I18nLayoutTest.java @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2007, 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 + * @bug 8133864 + * @summary Wrong display, when the document I18n properties is true. + * @author Semyon Sadetsky + * @run main I18nLayoutTest + */ + +import javax.swing.*; +import javax.swing.text.*; +import java.awt.*; +import java.util.ArrayList; + +public class I18nLayoutTest extends JFrame { + + private static int height; + JEditorPane edit = new JEditorPane(); + private static I18nLayoutTest frame; + + public I18nLayoutTest() { + super("Code example for a TableView bug"); + setUndecorated(true); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + edit.setEditorKit(new CodeBugEditorKit()); + initCodeBug(); + this.getContentPane().add(new JScrollPane(edit)); + this.pack(); + this.setLocationRelativeTo(null); + + } + + private void initCodeBug() { + CodeBugDocument doc = (CodeBugDocument) edit.getDocument(); + try { + doc.insertString(0, "TextB TextE", null); + } catch (BadLocationException ex) { + } + doc.insertTable(6, 4, 3); + try { + doc.insertString(7, "Cell11", null); + doc.insertString(14, "Cell12", null); + doc.insertString(21, "Cell13", null); + doc.insertString(28, "Cell21", null); + doc.insertString(35, "Cell22", null); + doc.insertString(42, "Cell23", null); + doc.insertString(49, "Cell31", null); + doc.insertString(56, "Cell32", null); + doc.insertString(63, "Cell33", null); + doc.insertString(70, "Cell41", null); + doc.insertString(77, "Cell42", null); + doc.insertString(84, "Cell43", null); + } catch (BadLocationException ex) { + } + } + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + frame = new I18nLayoutTest(); + frame.setVisible(true); + } + }); + Robot robot = new Robot(); + robot.delay(200); + robot.waitForIdle(); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + height = frame.getHeight(); + } + }); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + frame.dispose(); + } + }); + if (height < 32) { + throw new RuntimeException( + "TableView layout height is wrong " + height); + } + System.out.println("ok"); + } +} + +//------------------------------------------------------------------------------ +class CodeBugEditorKit extends StyledEditorKit { + + ViewFactory defaultFactory = new TableFactory(); + + @Override + public ViewFactory getViewFactory() { + return defaultFactory; + } + + @Override + public Document createDefaultDocument() { + return new CodeBugDocument(); + } +} +//------------------------------------------------------------------------------ + +class TableFactory implements ViewFactory { + + @Override + public View create(Element elem) { + String kind = elem.getName(); + if (kind != null) { + if (kind.equals(AbstractDocument.ContentElementName)) { + return new LabelView(elem); + } else if (kind.equals(AbstractDocument.ParagraphElementName)) { + return new ParagraphView(elem); + } else if (kind.equals(AbstractDocument.SectionElementName)) { + return new BoxView(elem, View.Y_AXIS); + } else if (kind.equals(StyleConstants.ComponentElementName)) { + return new ComponentView(elem); + } else if (kind.equals(CodeBugDocument.ELEMENT_TABLE)) { + return new tableView(elem); + } else if (kind.equals(StyleConstants.IconElementName)) { + return new IconView(elem); + } + } + // default to text display + return new LabelView(elem); + + } +} +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +class tableView extends TableView implements ViewFactory { + + public tableView(Element elem) { + super(elem); + } + + @Override + public void setParent(View parent) { + super.setParent(parent); + } + + @Override + public void setSize(float width, float height) { + super.setSize(width, height); + } + + @Override + public ViewFactory getViewFactory() { + return this; + } + + @Override + public float getMinimumSpan(int axis) { + return getPreferredSpan(axis); + } + + @Override + public float getMaximumSpan(int axis) { + return getPreferredSpan(axis); + } + + @Override + public float getAlignment(int axis) { + return 0.5f; + } + + @Override + public float getPreferredSpan(int axis) { + if (axis == 0) return super.getPreferredSpan(0); + float preferredSpan = super.getPreferredSpan(axis); + return preferredSpan; + } + + @Override + public void paint(Graphics g, Shape allocation) { + super.paint(g, allocation); + Rectangle alloc = allocation.getBounds(); + int lastY = alloc.y + alloc.height - 1; + g.drawLine(alloc.x, lastY, alloc.x + alloc.width, lastY); + } + + @Override + protected void paintChild(Graphics g, Rectangle alloc, int index) { + super.paintChild(g, alloc, index); + int lastX = alloc.x + alloc.width; + g.drawLine(alloc.x, alloc.y, lastX, alloc.y); + } + + @Override + public View create(Element elem) { + String kind = elem.getName(); + if (kind != null) { + if (kind.equals(CodeBugDocument.ELEMENT_TR)) { + return new trView(elem); + } else if (kind.equals(CodeBugDocument.ELEMENT_TD)) { + return new BoxView(elem, View.Y_AXIS); + + } + } + + // default is to delegate to the normal factory + View p = getParent(); + if (p != null) { + ViewFactory f = p.getViewFactory(); + if (f != null) { + return f.create(elem); + } + } + + return null; + } + + public class trView extends TableRow { + @Override + public void setParent(View parent) { + super.setParent(parent); + } + + public trView(Element elem) { + super(elem); + } + + public float getMinimumSpan(int axis) { + return getPreferredSpan(axis); + } + + public float getMaximumSpan(int axis) { + return getPreferredSpan(axis); + } + + public float getAlignment(int axis) { + return 0f; + } + + @Override + protected void paintChild(Graphics g, Rectangle alloc, int index) { + super.paintChild(g, alloc, index); + int lastY = alloc.y + alloc.height - 1; + g.drawLine(alloc.x, alloc.y, alloc.x, lastY); + int lastX = alloc.x + alloc.width; + g.drawLine(lastX, alloc.y, lastX, lastY); + } + } + + ; +} + +//------------------------------------------------------------------------------ +class CodeBugDocument extends DefaultStyledDocument { + + public static final String ELEMENT_TABLE = "table"; + public static final String ELEMENT_TR = "table cells row"; + public static final String ELEMENT_TD = "table data cell"; + + public CodeBugDocument() { + putProperty("i18n", Boolean.TRUE); + } + + + protected void insertTable(int offset, int rowCount, int colCount) { + try { + ArrayList Specs = new ArrayList(); + ElementSpec gapTag = new ElementSpec(new SimpleAttributeSet(), + ElementSpec.ContentType, "\n".toCharArray(), 0, 1); + Specs.add(gapTag); + + SimpleAttributeSet tableAttrs = new SimpleAttributeSet(); + tableAttrs.addAttribute(ElementNameAttribute, ELEMENT_TABLE); + ElementSpec tableStart = + new ElementSpec(tableAttrs, ElementSpec.StartTagType); + Specs.add(tableStart); //start table tag + + + fillRowSpecs(Specs, rowCount, colCount); + + ElementSpec[] spec = new ElementSpec[Specs.size()]; + Specs.toArray(spec); + + this.insert(offset, spec); + } catch (BadLocationException ex) { + } + } + + protected void fillRowSpecs(ArrayList Specs, int rowCount, int colCount) { + SimpleAttributeSet rowAttrs = new SimpleAttributeSet(); + rowAttrs.addAttribute(ElementNameAttribute, ELEMENT_TR); + for (int i = 0; i < rowCount; i++) { + ElementSpec rowStart = + new ElementSpec(rowAttrs, ElementSpec.StartTagType); + Specs.add(rowStart); + + fillCellSpecs(Specs, colCount); + + ElementSpec rowEnd = + new ElementSpec(rowAttrs, ElementSpec.EndTagType); + Specs.add(rowEnd); + } + + } + + protected void fillCellSpecs(ArrayList Specs, int colCount) { + for (int i = 0; i < colCount; i++) { + SimpleAttributeSet cellAttrs = new SimpleAttributeSet(); + cellAttrs.addAttribute(ElementNameAttribute, ELEMENT_TD); + + ElementSpec cellStart = + new ElementSpec(cellAttrs, ElementSpec.StartTagType); + Specs.add(cellStart); + + ElementSpec parStart = new ElementSpec(new SimpleAttributeSet(), + ElementSpec.StartTagType); + Specs.add(parStart); + ElementSpec parContent = new ElementSpec(new SimpleAttributeSet(), + ElementSpec.ContentType, "\n".toCharArray(), 0, 1); + Specs.add(parContent); + ElementSpec parEnd = new ElementSpec(new SimpleAttributeSet(), + ElementSpec.EndTagType); + Specs.add(parEnd); + ElementSpec cellEnd = + new ElementSpec(cellAttrs, ElementSpec.EndTagType); + Specs.add(cellEnd); + } + } +} \ No newline at end of file diff --git a/jdk/test/javax/swing/text/html/HTMLEditorKit/7104635/HTMLEditorKitWriterBug.java b/jdk/test/javax/swing/text/html/HTMLEditorKit/7104635/HTMLEditorKitWriterBug.java index d37f9fd69d6..8a681e22325 100644 --- a/jdk/test/javax/swing/text/html/HTMLEditorKit/7104635/HTMLEditorKitWriterBug.java +++ b/jdk/test/javax/swing/text/html/HTMLEditorKit/7104635/HTMLEditorKitWriterBug.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 7104635 + * @bug 7104635 8150225 * @summary HTMLEditorKit fails to write down some html files * @run main HTMLEditorKitWriterBug */ diff --git a/jdk/test/javax/swing/text/rtf/RTFWriteParagraphAlignTest.java b/jdk/test/javax/swing/text/rtf/RTFWriteParagraphAlignTest.java new file mode 100644 index 00000000000..31b605334a6 --- /dev/null +++ b/jdk/test/javax/swing/text/rtf/RTFWriteParagraphAlignTest.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 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 + @bug 8139215 + @summary RTFEditorKit does not save alignment + @author Semyon Sadetsky + */ + +import javax.swing.*; +import javax.swing.text.*; +import javax.swing.text.rtf.RTFEditorKit; +import java.awt.*; +import java.io.*; + +public class RTFWriteParagraphAlignTest { + + public static final String RTF_DATA[] = { + "{\\rtf1\\ansi\\ansicpg1252\\" + + "cocoartf949\\cocoasubrtf350" + + "{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}" + + "{\\colortbl;\\red255\\green255\\blue255;}" + + "\\margl1440\\margr1440\\vieww9000\\viewh8400\\viewkind0" + + "\\pard\\ql\\pardirnatural" + + "\\f0\\fs24 \\cf0 left}", + "{\\rtf1\\ansi\\ansicpg1252\\" + + "cocoartf949\\cocoasubrtf350" + + "{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}" + + "{\\colortbl;\\red255\\green255\\blue255;}" + + "\\margl1440\\margr1440\\vieww9000\\viewh8400\\viewkind0" + + "\\pard\\qc\\pardirnatural" + + "\\f0\\fs24 \\cf0 center}", + "{\\rtf1\\ansi\\ansicpg1252\\" + + "cocoartf949\\cocoasubrtf350" + + "{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}" + + "{\\colortbl;\\red255\\green255\\blue255;}" + + "\\margl1440\\margr1440\\vieww9000\\viewh8400\\viewkind0" + + "\\pard\\qr\\pardirnatural" + + "\\f0\\fs24 \\cf0 right}", + "{\\rtf1\\ansi\\ansicpg1252\\" + + "cocoartf949\\cocoasubrtf350" + + "{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}" + + "{\\colortbl;\\red255\\green255\\blue255;}" + + "\\margl1440\\margr1440\\vieww9000\\viewh8400\\viewkind0" + + "\\pard\\qj\\pardirnatural" + + "\\f0\\fs24 \\cf0 justifiedtextjustifiedtext " + + "justifiedtextjustifiedtext justifiedtextjustifiedtext " + + "justifiedtextjustifiedtext justifiedtextjustifiedtext }", + }; + private static JFrame frame; + private static JTextPane jTextPane; + private static int position1; + private static int position2; + private static RTFEditorKit rtfEditorKit; + private static Robot robot; + + public static void main(String[] args) throws Exception{ + rtfEditorKit = new RTFEditorKit(); + robot = new Robot(); + + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame(); + frame.setUndecorated(true); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setSize(600, 200); + jTextPane = new JTextPane(); + frame.getContentPane().add(jTextPane); + frame.setVisible(true); + }); + + test(StyleConstants.ALIGN_LEFT); + test(StyleConstants.ALIGN_CENTER); + test(StyleConstants.ALIGN_RIGHT); + test(StyleConstants.ALIGN_JUSTIFIED); + + SwingUtilities.invokeAndWait(()->frame.dispose()); + + System.out.println("ok"); + } + + static void test(int align) throws Exception { + SwingUtilities.invokeAndWait(()->{ + jTextPane.setDocument(rtfEditorKit.createDefaultDocument()); + try { + rtfEditorKit.read(new ByteArrayInputStream(RTF_DATA[align]. + getBytes()), jTextPane.getDocument(), 0); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + + robot.waitForIdle(); + SwingUtilities.invokeAndWait(()->{ + try { + int endOffset = jTextPane.getDocument().getRootElements()[0]. + getElement(0).getEndOffset(); + position1 = jTextPane.modelToView(endOffset - 1).x; + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + + File tempFile = File.createTempFile("aaaa", ".rtf"); + tempFile.deleteOnExit(); + rtfEditorKit.write(new FileOutputStream(tempFile), + jTextPane.getDocument(), 0, jTextPane.getDocument().getLength()); + Document d = rtfEditorKit.createDefaultDocument(); + rtfEditorKit.read(new FileInputStream(tempFile), d, 0); + SwingUtilities.invokeAndWait(() -> jTextPane.setDocument(d)); + + robot.waitForIdle(); + SwingUtilities.invokeAndWait(()->{ + try { + int endOffset = jTextPane.getDocument().getRootElements()[0]. + getElement(0).getEndOffset(); + position2 = jTextPane.modelToView(endOffset-1).x; + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + + if (position1 != position2) { + throw new RuntimeException("Alignment is not preserved after the " + + "document write/read"); + } + } +} diff --git a/jdk/test/jdk/internal/ref/Cleaner/ExitOnThrow.java b/jdk/test/jdk/internal/ref/Cleaner/ExitOnThrow.java index a4296eccbf0..f3308c480e6 100644 --- a/jdk/test/jdk/internal/ref/Cleaner/ExitOnThrow.java +++ b/jdk/test/jdk/internal/ref/Cleaner/ExitOnThrow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -26,6 +26,7 @@ * @bug 4954921 8009259 * @library /test/lib/share/classes * @modules java.base/jdk.internal.ref + * java.base/jdk.internal.misc * @build jdk.test.lib.* * @build jdk.test.lib.process.* * @run main ExitOnThrow diff --git a/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java b/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java index 6594a5ca449..4c40455cf62 100644 --- a/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java +++ b/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java @@ -26,7 +26,7 @@ * @summary Verify the defining class loader of each module never delegates * to its child class loader. Also sanity check java.compact2 * requires. - * @run testng VerifyModuleDelegation + * @run testng/othervm -Djdk.launcher.addmods=ALL-SYSTEM VerifyModuleDelegation */ import java.lang.module.ModuleDescriptor; diff --git a/jdk/test/sun/java2d/marlin/CrashNaNTest.java b/jdk/test/sun/java2d/marlin/CrashNaNTest.java index 01e32dd6c11..f25be866f85 100644 --- a/jdk/test/sun/java2d/marlin/CrashNaNTest.java +++ b/jdk/test/sun/java2d/marlin/CrashNaNTest.java @@ -21,14 +21,22 @@ * questions. */ +import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; import java.awt.geom.Path2D; +import java.awt.geom.PathIterator; import java.awt.image.BufferedImage; +import java.awt.image.Raster; import java.io.File; import java.io.IOException; +import static java.lang.Double.NEGATIVE_INFINITY; +import static java.lang.Double.POSITIVE_INFINITY; import static java.lang.Double.NaN; +import java.util.Arrays; import java.util.Locale; import java.util.logging.Handler; import java.util.logging.LogRecord; @@ -37,8 +45,9 @@ import javax.imageio.ImageIO; /** * @test - * @bug 8149338 - * @summary Verifies that Marlin supports NaN coordinates and no JVM crash happens ! + * @bug 8149338 8144938 + * @summary Verifies that Marlin supports NaN coordinates (no JVM crash) + * but also it skips properly point coordinates with NaN / Infinity values * @run main CrashNaNTest */ public class CrashNaNTest { @@ -77,23 +86,31 @@ public class CrashNaNTest { System.setProperty("sun.java2d.renderer.useLogger", "true"); System.setProperty("sun.java2d.renderer.doChecks", "true"); + testFillDefaultAt(); + testDrawComplexAt(); + + testPathClosed(); + + testStrokedShapes(); + } + + private static void testFillDefaultAt() { final int width = 400; final int height = 400; final BufferedImage image = new BufferedImage(width, height, - BufferedImage.TYPE_INT_ARGB); + BufferedImage.TYPE_INT_ARGB); final Graphics2D g2d = (Graphics2D) image.getGraphics(); try { g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); + RenderingHints.VALUE_ANTIALIAS_ON); g2d.setBackground(Color.WHITE); g2d.clearRect(0, 0, width, height); final Path2D.Double path = new Path2D.Double(); - path.moveTo(30, 30); - path.lineTo(100, 100); + path.moveTo(100, 100); for (int i = 0; i < 20000; i++) { path.lineTo(110 + 0.01 * i, 110); @@ -105,39 +122,301 @@ public class CrashNaNTest { path.lineTo(200, NaN); path.lineTo(300, 300); path.lineTo(NaN, NaN); - path.lineTo(100, 100); + path.lineTo(100, 200); path.closePath(); final Path2D.Double path2 = new Path2D.Double(); - path2.moveTo(0,0); - path2.lineTo(width,height); - path2.lineTo(10, 10); + path2.moveTo(0, 0); + path2.lineTo(100, height); + path2.lineTo(0, 200); path2.closePath(); - for (int i = 0; i < 1; i++) { - final long start = System.nanoTime(); - g2d.setColor(Color.BLUE); - g2d.fill(path); + g2d.setColor(Color.BLUE); + g2d.fill(path); + g2d.setColor(Color.GREEN); + g2d.fill(path2); - g2d.fill(path2); - - final long time = System.nanoTime() - start; - System.out.println("paint: duration= " + (1e-6 * time) + " ms."); - } + g2d.setColor(Color.BLACK); + g2d.draw(path); + g2d.draw(path2); if (SAVE_IMAGE) { try { - final File file = new File("CrashNaNTest.png"); + final File file = new File("CrashNaNTest-fill.png"); System.out.println("Writing file: " - + file.getAbsolutePath()); + + file.getAbsolutePath()); ImageIO.write(image, "PNG", file); } catch (IOException ex) { System.out.println("Writing file failure:"); ex.printStackTrace(); } } + + // Check image on few pixels: + final Raster raster = image.getData(); + + checkPixel(raster, 200, 195, Color.BLUE.getRGB()); + checkPixel(raster, 105, 195, Color.BLUE.getRGB()); + checkPixel(raster, 286, 290, Color.BLUE.getRGB()); + + checkPixel(raster, 108, 105, Color.WHITE.getRGB()); + checkPixel(raster, 205, 200, Color.WHITE.getRGB()); + + checkPixel(raster, 5, 200, Color.GREEN.getRGB()); + } finally { g2d.dispose(); } } + + private static void testDrawComplexAt() { + final int width = 400; + final int height = 400; + + final BufferedImage image = new BufferedImage(width, height, + BufferedImage.TYPE_INT_ARGB); + + final Graphics2D g2d = (Graphics2D) image.getGraphics(); + try { + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, + RenderingHints.VALUE_STROKE_PURE); + + g2d.setBackground(Color.WHITE); + g2d.clearRect(0, 0, width, height); + + final Path2D.Double path = new Path2D.Double(); + path.moveTo(100, 100); + + for (int i = 0; i < 20000; i++) { + path.lineTo(110 + 0.01 * i, 110); + path.lineTo(111 + 0.01 * i, 100); + } + + path.lineTo(NaN, 200); + path.lineTo(200, 200); + path.lineTo(200, NaN); + path.lineTo(300, 300); + path.lineTo(NaN, NaN); + path.lineTo(100, 200); + path.closePath(); + + final Path2D.Double path2 = new Path2D.Double(); + path2.moveTo(0, 0); + path2.lineTo(100, height); + path2.lineTo(0, 200); + path2.closePath(); + + // Define an non-uniform transform: + g2d.scale(0.5, 1.0); + g2d.rotate(Math.PI / 31); + + g2d.setColor(Color.BLACK); + g2d.draw(path); + g2d.draw(path2); + + if (SAVE_IMAGE) { + try { + final File file = new File("CrashNaNTest-draw.png"); + System.out.println("Writing file: " + + file.getAbsolutePath()); + ImageIO.write(image, "PNG", file); + } catch (IOException ex) { + System.out.println("Writing file failure:"); + ex.printStackTrace(); + } + } + + // Check image on few pixels: + final Raster raster = image.getData(); + + checkPixelNotWhite(raster, 40, 210); + checkPixelNotWhite(raster, 44, 110); + checkPixelNotWhite(raster, 60, 120); + checkPixelNotWhite(raster, 89, 219); + checkPixelNotWhite(raster, 28, 399); + checkPixelNotWhite(raster, 134, 329); + + } finally { + g2d.dispose(); + } + } + private static void testPathClosed() { + final int width = 100; + final int height = 100; + + final BufferedImage image = new BufferedImage(width, height, + BufferedImage.TYPE_INT_ARGB); + + final Graphics2D g2d = (Graphics2D) image.getGraphics(); + try { + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + g2d.setBackground(Color.WHITE); + g2d.clearRect(0, 0, width, height); + + final Path2D.Double path = new Path2D.Double(); + path.moveTo(40, 40); + path.lineTo(0, 0); + path.lineTo(80, 0); + path.closePath(); + path.lineTo(80, 80); + path.lineTo(0, 80); + path.closePath(); + + g2d.setColor(Color.BLUE); + g2d.fill(path); + + g2d.setColor(Color.BLACK); + g2d.draw(path); + + if (SAVE_IMAGE) { + try { + final File file = new File("CrashNaNTest-path-closed.png"); + System.out.println("Writing file: " + + file.getAbsolutePath()); + ImageIO.write(image, "PNG", file); + } catch (IOException ex) { + System.out.println("Writing file failure:"); + ex.printStackTrace(); + } + } + + // Check image on few pixels: + final Raster raster = image.getData(); + + checkPixel(raster, 10, 05, Color.BLUE.getRGB()); + checkPixel(raster, 70, 05, Color.BLUE.getRGB()); + checkPixel(raster, 40, 35, Color.BLUE.getRGB()); + + checkPixel(raster, 10, 75, Color.BLUE.getRGB()); + checkPixel(raster, 70, 75, Color.BLUE.getRGB()); + checkPixel(raster, 40, 45, Color.BLUE.getRGB()); + + } finally { + g2d.dispose(); + } + } + + private static void testStrokedShapes() { + final Stroke stroke = new BasicStroke(); + + final Path2D.Double path = new Path2D.Double(); + Shape s; + + // Check filtering NaN values: + path.reset(); + path.moveTo(100, NaN); + path.lineTo(NaN, 100); + path.lineTo(NaN, NaN); + + path.quadTo(NaN, 100, NaN, 100); + path.quadTo(100, NaN, 100, NaN); + path.quadTo(NaN, NaN, NaN, NaN); + + path.curveTo(NaN, 100, NaN, 100, NaN, 100); + path.curveTo(100, NaN, 100, NaN, 100, NaN); + path.curveTo(NaN, NaN, NaN, NaN, NaN, NaN); + path.closePath(); + + s = stroke.createStrokedShape(path); + checkEmptyPath(s); + + // Check filtering +Infinity values: + path.reset(); + path.moveTo(100, POSITIVE_INFINITY); + path.lineTo(POSITIVE_INFINITY, 100); + path.lineTo(POSITIVE_INFINITY, POSITIVE_INFINITY); + + path.quadTo(POSITIVE_INFINITY, 100, + POSITIVE_INFINITY, 100); + path.quadTo(100, POSITIVE_INFINITY, + 100, POSITIVE_INFINITY); + path.quadTo(POSITIVE_INFINITY, POSITIVE_INFINITY, + POSITIVE_INFINITY, POSITIVE_INFINITY); + + path.curveTo(POSITIVE_INFINITY, 100, + POSITIVE_INFINITY, 100, + POSITIVE_INFINITY, 100); + path.curveTo(100, POSITIVE_INFINITY, + 100, POSITIVE_INFINITY, + 100, POSITIVE_INFINITY); + path.curveTo(POSITIVE_INFINITY, POSITIVE_INFINITY, + POSITIVE_INFINITY, POSITIVE_INFINITY, + POSITIVE_INFINITY, POSITIVE_INFINITY); + path.closePath(); + + s = stroke.createStrokedShape(path); + checkEmptyPath(s); + + // Check filtering -Infinity values: + path.reset(); + path.moveTo(100, NEGATIVE_INFINITY); + path.lineTo(NEGATIVE_INFINITY, 100); + path.lineTo(NEGATIVE_INFINITY, NEGATIVE_INFINITY); + + path.quadTo(NEGATIVE_INFINITY, 100, + NEGATIVE_INFINITY, 100); + path.quadTo(100, NEGATIVE_INFINITY, + 100, NEGATIVE_INFINITY); + path.quadTo(NEGATIVE_INFINITY, NEGATIVE_INFINITY, + NEGATIVE_INFINITY, NEGATIVE_INFINITY); + + path.curveTo(NEGATIVE_INFINITY, 100, + NEGATIVE_INFINITY, 100, + NEGATIVE_INFINITY, 100); + path.curveTo(100, NEGATIVE_INFINITY, + 100, NEGATIVE_INFINITY, + 100, NEGATIVE_INFINITY); + path.curveTo(NEGATIVE_INFINITY, NEGATIVE_INFINITY, + NEGATIVE_INFINITY, NEGATIVE_INFINITY, + NEGATIVE_INFINITY, NEGATIVE_INFINITY); + path.closePath(); + + s = stroke.createStrokedShape(path); + checkEmptyPath(s); + } + + private static void checkEmptyPath(final Shape s) { + final float[] coords = new float[6]; + final PathIterator it = s.getPathIterator(null); + + int n = 0; + for (; !it.isDone(); it.next()) { + int type = it.currentSegment(coords); + System.out.println("unexpected segment type= " + type + + " with coords: " + Arrays.toString(coords)); + n++; + } + if (n != 0) { + System.out.println("path elements = " + n); + throw new IllegalStateException("Not empty path: " + + n + " path elements !"); + } + } + + private static void checkPixel(final Raster raster, + final int x, final int y, + final int expected) { + + final int[] rgb = (int[]) raster.getDataElements(x, y, null); + + if (rgb[0] != expected) { + throw new IllegalStateException("bad pixel at (" + x + ", " + y + + ") = " + rgb[0] + " expected: " + expected); + } + } + + private static void checkPixelNotWhite(final Raster raster, + final int x, final int y) { + + final int[] rgb = (int[]) raster.getDataElements(x, y, null); + + if (rgb[0] == Color.WHITE.getRGB()) { + throw new IllegalStateException("bad pixel at (" + x + ", " + y + + ") is white (empty)"); + } + } } diff --git a/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh b/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh index 5efd6e2400e..f0a93a6f78a 100644 --- a/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh +++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh @@ -51,7 +51,8 @@ chmod -R 777 ${TESTCLASSES}/ssl DEBUGOPTIONS="" export DEBUGOPTIONS -EXTRAOPTIONS="-XaddExports:java.management/sun.management=ALL-UNNAMED,java.management/sun.management.jmxremote=ALL-UNNAMED" +EXTRAOPTIONS="-XaddExports:java.management/sun.management=ALL-UNNAMED \ + -XaddExports:java.management/sun.management.jmxremote=ALL-UNNAMED" export EXTRAOPTIONS # Call the common generic test diff --git a/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh b/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh index 16db84cb5d1..30f3a179149 100644 --- a/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh +++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh @@ -49,7 +49,8 @@ chmod -R 777 ${TESTCLASSES}/ssl DEBUGOPTIONS="" export DEBUGOPTIONS -EXTRAOPTIONS="-XaddExports:java.management/sun.management=ALL-UNNAMED,java.management/sun.management.jmxremote=ALL-UNNAMED" +EXTRAOPTIONS="-XaddExports:java.management/sun.management=ALL-UNNAMED \ + -XaddExports:java.management/sun.management.jmxremote=ALL-UNNAMED" export EXTRAOPTIONS # Call the common generic test diff --git a/jdk/test/sun/management/jmxremote/bootstrap/RmiSslNoKeyStoreTest.sh b/jdk/test/sun/management/jmxremote/bootstrap/RmiSslNoKeyStoreTest.sh index 86ab964c85f..8cccc837ba0 100644 --- a/jdk/test/sun/management/jmxremote/bootstrap/RmiSslNoKeyStoreTest.sh +++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiSslNoKeyStoreTest.sh @@ -48,7 +48,8 @@ chmod -R 777 ${TESTCLASSES}/ssl DEBUGOPTIONS="" export DEBUGOPTIONS -EXTRAOPTIONS="-XaddExports:java.management/sun.management=ALL-UNNAMED,java.management/sun.management.jmxremote=ALL-UNNAMED" +EXTRAOPTIONS="-XaddExports:java.management/sun.management=ALL-UNNAMED \ + -XaddExports:java.management/sun.management.jmxremote=ALL-UNNAMED" export EXTRAOPTIONS # Call the common generic test diff --git a/jdk/test/sun/misc/CopyMemory.java b/jdk/test/sun/misc/CopyMemory.java index 6e11c6362c4..bd45ca3875c 100644 --- a/jdk/test/sun/misc/CopyMemory.java +++ b/jdk/test/sun/misc/CopyMemory.java @@ -24,7 +24,8 @@ /* @test * @bug 6565543 * @summary Minimal test for unsafe.copyMemory() and unsafe.setMemory() - * @modules java.base/sun.nio.ch java.base/sun.misc + * @modules java.base/sun.nio.ch + * jdk.unsupported * @key randomness */ diff --git a/jdk/test/sun/misc/Safe.java b/jdk/test/sun/misc/Safe.java index c2e938c0fa9..c499a0a2c90 100644 --- a/jdk/test/sun/misc/Safe.java +++ b/jdk/test/sun/misc/Safe.java @@ -25,7 +25,7 @@ * @bug 4495577 * @summary Ensure that sun.misc.Unsafe cannot (easily) * be accessed from user code - * @modules java.base/sun.misc + * @modules jdk.unsupported */ diff --git a/jdk/test/sun/misc/SunMiscSignalTest.java b/jdk/test/sun/misc/SunMiscSignalTest.java index dd4376ddde7..2e998ba8d77 100644 --- a/jdk/test/sun/misc/SunMiscSignalTest.java +++ b/jdk/test/sun/misc/SunMiscSignalTest.java @@ -44,6 +44,8 @@ import sun.misc.SignalHandler; /* * @test * @library /test/lib/share/classes + * @modules jdk.unsupported + * java.base/jdk.internal.misc * @build jdk.test.lib.Platform jdk.test.lib.Utils * @run testng/othervm -Xrs -DXrs=true SunMiscSignalTest * @run testng/othervm SunMiscSignalTest diff --git a/jdk/test/sun/net/InetAddress/nameservice/chaining/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor b/jdk/test/sun/net/InetAddress/nameservice/chaining/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor deleted file mode 100644 index 5a2e7dedb20..00000000000 --- a/jdk/test/sun/net/InetAddress/nameservice/chaining/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. -# 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. - -Simple1NameServiceDescriptor -Simple2NameServiceDescriptor diff --git a/jdk/test/sun/net/InetAddress/nameservice/chaining/Providers.java b/jdk/test/sun/net/InetAddress/nameservice/chaining/Providers.java deleted file mode 100644 index 5213b5f4a57..00000000000 --- a/jdk/test/sun/net/InetAddress/nameservice/chaining/Providers.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. - * 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 4762344 - * @summary 2nd nameservice provider is non functional - * @modules java.base/sun.net.spi.nameservice - * @compile -XDignore.symbol.file=true SimpleNameService.java - * Simple1NameServiceDescriptor.java - * Simple2NameServiceDescriptor.java - * @run main/othervm -Dsun.net.spi.nameservice.provider.1=simple1,sun -Dsun.net.spi.nameservice.provider.2=simple2,sun Providers - */ - -import java.net.*; -import java.util.*; - - -public class Providers { - private static String[][] hostnames = new String[][] { - // both providers know this host, but with different address - new String[] {"blade", "10.0.0.1"}, - // provider1 knwos this host - new String[] {"blade.domain1", "10.0.0.2"}, - // provider2 knows this host - new String[] {"blade.domain2", "20.0.0.2"} - }; - private static String[][] hostaddrs = new String[][] { - new String[] {"10.0.0.1", "blade"}, - new String[] {"10.0.0.2", "blade.domain1"}, - new String[] {"20.0.0.2", "blade.domain2"} - }; - - public static void main(String[] args) throws Exception { - for (int i = 0; i < hostnames.length; i++) { - doLookup(hostnames[i][0], hostnames[i][1]); - } - for (int i = 0; i < hostaddrs.length; i++) { - doReverseLookup(hostaddrs[i][0], hostaddrs[i][1]); - } - } - - private static void doLookup(String host, String addr) throws Exception { - String res = InetAddress.getByName(host).getHostAddress(); - if (!res.equals(addr)) { - throw new RuntimeException("Test failed: wrong address for host " + host); - } - } - - private static void doReverseLookup(String addr, String host) throws Exception { - StringTokenizer tokenizer = new StringTokenizer(addr, "."); - byte addrs[] = new byte[4]; - for (int i = 0; i < 4; i++) { - addrs[i] = (byte)Integer.parseInt(tokenizer.nextToken()); - } - String res = InetAddress.getByAddress(addrs).getHostName(); - if (!res.equals(host)) { - throw new RuntimeException("Test failed: wrong host name for address " + addr); - } - } -} diff --git a/jdk/test/sun/net/InetAddress/nameservice/chaining/SimpleNameService.java b/jdk/test/sun/net/InetAddress/nameservice/chaining/SimpleNameService.java deleted file mode 100644 index b3697f2f3db..00000000000 --- a/jdk/test/sun/net/InetAddress/nameservice/chaining/SimpleNameService.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - */ - -import java.net.*; -import java.util.*; -import sun.net.spi.nameservice.*; - - -public class SimpleNameService implements NameService { - // host name <-> host addr mapping - private HashMap hosts = new LinkedHashMap(); - - public void put(String host, String addr) { - hosts.put(host, addr); - } - - private static String addrToString(byte addr[]) { - return Byte.toString(addr[0]) + "." + - Byte.toString(addr[1]) + "." + - Byte.toString(addr[2]) + "." + - Byte.toString(addr[3]); - } - - public SimpleNameService() { - } - - public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException { - String addr = hosts.get(host); - if (addr == null) { - throw new UnknownHostException(host); - } - - StringTokenizer tokenizer = new StringTokenizer(addr, "."); - byte addrs[] = new byte[4]; - for (int i = 0; i < 4; i++) { - addrs[i] = (byte)Integer.parseInt(tokenizer.nextToken()); - } - InetAddress[] ret = new InetAddress[1]; - ret[0] = InetAddress.getByAddress(host, addrs); - return ret; - } - - public String getHostByAddr(byte[] addr) throws UnknownHostException { - String addrString = addrToString(addr); - Iterator i = hosts.keySet().iterator(); - while (i.hasNext()) { - String host = (String)i.next(); - String value = (String)hosts.get(host); - if (value.equals(addrString)) { - return host; - } - } - throw new UnknownHostException(); - } -} diff --git a/jdk/test/sun/net/InetAddress/nameservice/deadlock/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor b/jdk/test/sun/net/InetAddress/nameservice/deadlock/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor deleted file mode 100644 index 3490a904f5f..00000000000 --- a/jdk/test/sun/net/InetAddress/nameservice/deadlock/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. -# 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. - -ThrowingNameServiceDescriptor diff --git a/jdk/test/sun/net/InetAddress/nameservice/dns/cname.sh b/jdk/test/sun/net/InetAddress/nameservice/dns/cname.sh index 13c922aed4d..b47a5efcf0c 100644 --- a/jdk/test/sun/net/InetAddress/nameservice/dns/cname.sh +++ b/jdk/test/sun/net/InetAddress/nameservice/dns/cname.sh @@ -66,8 +66,8 @@ echo "};" >> ${POLICY} np="-Dsun.net.spi.nameservice.provider.1=dns,sun" sm="-Djava.security.manager -Djava.security.policy=${POLICY}" -go "$np" "$HOST" -go "$np $sm" "$HOST" +go "" "$HOST" +go "$sm" "$HOST" # diff --git a/jdk/test/sun/net/InetAddress/nameservice/simple/CacheTest.java b/jdk/test/sun/net/InetAddress/nameservice/simple/CacheTest.java index 387a08f947a..ab3f75787b6 100644 --- a/jdk/test/sun/net/InetAddress/nameservice/simple/CacheTest.java +++ b/jdk/test/sun/net/InetAddress/nameservice/simple/CacheTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -26,14 +26,14 @@ * @summary Check that InetAddress doesn't continue to throw UHE * after the name service has recovered and the negative ttl * on the initial lookup has expired. - * @modules java.base/sun.net.spi.nameservice - * @compile -XDignore.symbol.file=true SimpleNameService.java - * SimpleNameServiceDescriptor.java - * @run main/othervm/timeout=200 -Dsun.net.spi.nameservice.provider.1=simple,sun CacheTest + * @run main/othervm/timeout=200 CacheTest */ import java.net.InetAddress; import java.net.UnknownHostException; import java.security.Security; +import java.io.PrintWriter; +import java.io.FileWriter; +import java.io.BufferedWriter; public class CacheTest { @@ -59,6 +59,8 @@ public class CacheTest { return; } + String hostsFileName = System.getProperty("test.src", ".") + "/CacheTestHosts"; + System.setProperty("jdk.net.hosts.file", hostsFileName); /* * The following outlines how the test works :- @@ -78,7 +80,7 @@ public class CacheTest { */ // name service needs to resolve this. - SimpleNameService.put("theclub", "129.156.220.219"); + addMappingToHostsFile("theclub", "129.156.220.219", hostsFileName, false); // this lookup will succeed InetAddress.getByName("theclub"); @@ -89,12 +91,12 @@ public class CacheTest { try { InetAddress.getByName("luster"); throw new RuntimeException("Test internal error " + - " - luster is bring resolved by name service"); + " - luster is being resolved by name service"); } catch (UnknownHostException x) { } // name service now needs to know about luster - SimpleNameService.put("luster", "10.5.18.21"); + addMappingToHostsFile("luster", "10.5.18.21", hostsFileName, true); // wait for the cache entry to expire and lookup should // succeed. @@ -102,4 +104,16 @@ public class CacheTest { InetAddress.getByName("luster"); } + private static void addMappingToHostsFile ( String host, + String addr, + String hostsFileName, + boolean append) + throws Exception { + String mapping = addr + " " + host; + try (PrintWriter hfPWriter = new PrintWriter(new BufferedWriter( + new FileWriter(hostsFileName, append)))) { + hfPWriter.println(mapping); +} + } + } diff --git a/jdk/test/sun/net/InetAddress/nameservice/simple/CacheTestHosts b/jdk/test/sun/net/InetAddress/nameservice/simple/CacheTestHosts new file mode 100644 index 00000000000..a44d05a2644 --- /dev/null +++ b/jdk/test/sun/net/InetAddress/nameservice/simple/CacheTestHosts @@ -0,0 +1,2 @@ +129.156.220.219 theclub +10.5.18.21 luster diff --git a/jdk/test/sun/net/InetAddress/nameservice/simple/DefaultCaching.java b/jdk/test/sun/net/InetAddress/nameservice/simple/DefaultCaching.java index 6f9e60c7be4..df3aef6e232 100644 --- a/jdk/test/sun/net/InetAddress/nameservice/simple/DefaultCaching.java +++ b/jdk/test/sun/net/InetAddress/nameservice/simple/DefaultCaching.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -25,35 +25,40 @@ * @bug 6442088 * @summary Change default DNS caching behavior for code not running under * security manager. - * @modules java.base/sun.net.spi.nameservice - * @compile -XDignore.symbol.file=true SimpleNameService.java - * SimpleNameServiceDescriptor.java - * @run main/othervm/timeout=200 -Dsun.net.inetaddr.ttl=20 -Dsun.net.spi.nameservice.provider.1=simple,sun DefaultCaching + * @run main/othervm/timeout=200 -Dsun.net.inetaddr.ttl=20 DefaultCaching */ import java.net.InetAddress; import java.net.UnknownHostException; import java.security.Security; +import java.io.FileWriter; +import java.io.PrintWriter; +import java.io.BufferedWriter; public class DefaultCaching { public static void main(String args[]) throws Exception { + String hostsFileName = System.getProperty("test.src", ".") + "/DefaultCachingHosts"; + System.setProperty("jdk.net.hosts.file", hostsFileName); + // initial mapping // name service needs to resolve this. - SimpleNameService.put("theclub", "129.156.220.219"); + addMappingToHostsFile("theclub", "129.156.220.219", hostsFileName, false); test ("theclub", "129.156.220.219", true); // lk: 1 test ("luster", "1.16.20.2", false); // lk: 2 // name service now needs to know about luster - SimpleNameService.put("luster", "10.5.18.21"); + addMappingToHostsFile("luster", "10.5.18.21", hostsFileName, true); test ("luster", "1.16.20.2", false); // lk: 2 sleep (10+1); test("luster", "10.5.18.21", true, 3); // lk: 3 sleep (5); - SimpleNameService.put("foo", "10.5.18.22"); - SimpleNameService.put("theclub", "129.156.220.1"); + // new mapping for theclub and rewrite existing foo and luster mappings + addMappingToHostsFile("theclub", "129.156.220.1", hostsFileName, false); + addMappingToHostsFile("foo", "10.5.18.22", hostsFileName, true); + addMappingToHostsFile("luster", "10.5.18.21", hostsFileName, true); test ("theclub", "129.156.220.219", true, 3); test ("luster", "10.5.18.21", true, 3); @@ -84,10 +89,6 @@ public class DefaultCaching { static void test (String host, String address, boolean shouldSucceed, int count) { test (host, address, shouldSucceed); - int got = SimpleNameService.lookupCalls(); - if (got != count) { - throw new RuntimeException ("lookups exp/got: " + count+"/"+got); - } } static void sleep (int seconds) { @@ -114,4 +115,16 @@ public class DefaultCaching { } } + + private static void addMappingToHostsFile (String host, + String addr, + String hostsFileName, + boolean append) + throws Exception { + String mapping = addr + " " + host; + try (PrintWriter hfPWriter = new PrintWriter(new BufferedWriter( + new FileWriter(hostsFileName, append)))) { + hfPWriter.println(mapping); +} + } } diff --git a/jdk/test/sun/net/InetAddress/nameservice/simple/DefaultCachingHosts b/jdk/test/sun/net/InetAddress/nameservice/simple/DefaultCachingHosts new file mode 100644 index 00000000000..87c6136d25a --- /dev/null +++ b/jdk/test/sun/net/InetAddress/nameservice/simple/DefaultCachingHosts @@ -0,0 +1,3 @@ +129.156.220.1 theclub +10.5.18.22 foo +10.5.18.21 luster diff --git a/jdk/test/sun/net/InetAddress/nameservice/simple/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor b/jdk/test/sun/net/InetAddress/nameservice/simple/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor deleted file mode 100644 index b7527c07074..00000000000 --- a/jdk/test/sun/net/InetAddress/nameservice/simple/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. -# 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. - -SimpleNameServiceDescriptor # name service provider descriptor diff --git a/jdk/test/sun/net/InetAddress/nameservice/simple/SimpleNameService.java b/jdk/test/sun/net/InetAddress/nameservice/simple/SimpleNameService.java deleted file mode 100644 index 9d584558b30..00000000000 --- a/jdk/test/sun/net/InetAddress/nameservice/simple/SimpleNameService.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. - * 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. - */ - -/* - * A simple name service based on an in-memory HashMap. - */ -import java.net.UnknownHostException; -import java.net.InetAddress; -import sun.net.spi.nameservice.*; -import java.util.*; - -public final class SimpleNameService implements NameService { - - private static LinkedHashMap hosts = new LinkedHashMap(); - - private static String addrToString(byte addr[]) { - return Byte.toString(addr[0]) + "." + - Byte.toString(addr[1]) + "." + - Byte.toString(addr[2]) + "." + - Byte.toString(addr[3]); - } - - // ------------ - - public static void put(String host, String addr) { - hosts.put(host, addr); - } - - public static void put(String host, byte addr[]) { - hosts.put(host, addrToString(addr)); - } - - public static void remove(String host) { - hosts.remove(host); - } - - public static int entries () { - return hosts.size(); - } - - public static int lookupCalls() { - return lookupCalls; - } - - static int lookupCalls = 0; - - // ------------ - - public SimpleNameService() throws Exception { - } - - public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException { - - lookupCalls ++; - - String value = (String)hosts.get(host); - if (value == null) { - throw new UnknownHostException(host); - } - StringTokenizer st = new StringTokenizer(value, "."); - byte addr[] = new byte[4]; - for (int i=0; i<4; i++) { - addr[i] = (byte)Integer.parseInt(st.nextToken()); - } - InetAddress[] res = new InetAddress[1]; - res[0] = InetAddress.getByAddress(host, addr); - return res; - } - - public String getHostByAddr(byte[] addr) throws UnknownHostException { - String addrString = addrToString(addr); - Iterator i = hosts.keySet().iterator(); - while (i.hasNext()) { - String host = (String)i.next(); - String value = (String)hosts.get(host); - if (value.equals(addrString)) { - return host; - } - } - throw new UnknownHostException(); - } -} diff --git a/jdk/test/sun/net/InetAddress/nameservice/simple/SimpleNameServiceDescriptor.java b/jdk/test/sun/net/InetAddress/nameservice/simple/SimpleNameServiceDescriptor.java deleted file mode 100644 index 373d10b2dc7..00000000000 --- a/jdk/test/sun/net/InetAddress/nameservice/simple/SimpleNameServiceDescriptor.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. - * 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. - */ - -/* - * Descriptor for the simple name service - */ -import sun.net.spi.nameservice.*; - -public final class SimpleNameServiceDescriptor implements NameServiceDescriptor { - /** - * Create a new instance of the corresponding name service. - */ - public NameService createNameService() throws Exception { - return new SimpleNameService(); - } - - /** - * Returns this service provider's name - * - */ - public String getProviderName() { - return "sun"; - } - - /** - * Returns this name service type - * "dns" "nis" etc - */ - public String getType() { - return "simple"; - } -} diff --git a/jdk/test/sun/net/ftp/FtpURLConnectionLeak.java b/jdk/test/sun/net/ftp/FtpURLConnectionLeak.java new file mode 100644 index 00000000000..eea7a61e5ec --- /dev/null +++ b/jdk/test/sun/net/ftp/FtpURLConnectionLeak.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 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 + * @bug 7167293 + * @summary FtpURLConnection doesn't close FTP connection when FileNotFoundException is thrown + * @library ../www/ftptest/ + * @build FtpServer FtpCommandHandler FtpAuthHandler FtpFileSystemHandler + * @run main FtpURLConnectionLeak + */ +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; + +public class FtpURLConnectionLeak { + + public static void main(String[] args) throws Exception { + FtpServer server = new FtpServer(0); + server.setFileSystemHandler(new CustomFileSystemHandler("/")); + server.setAuthHandler(new MyAuthHandler()); + int port = server.getLocalPort(); + server.start(); + URL url = new URL("ftp://localhost:" + port + "/filedoesNotExist.txt"); + for (int i = 0; i < 3; i++) { + try { + InputStream stream = url.openStream(); + } catch (FileNotFoundException expectedFirstTimeAround) { + // should always reach this point since the path does not exist + } catch (IOException expected) { + System.out.println("caught expected " + expected); + int times = 1; + do { + // give some time to close the connection... + System.out.println("sleeping... " + times); + Thread.sleep(times * 1000); + } while (server.activeClientsCount() > 0 && times++ < 5); + + if (server.activeClientsCount() > 0) { + server.killClients(); + throw new RuntimeException("URLConnection didn't close the" + + " FTP connection on FileNotFoundException"); + } + } finally { + server.terminate(); + } + } + } + + static class CustomFileSystemHandler implements FtpFileSystemHandler { + + private String currentDir; + + public CustomFileSystemHandler(String path) { + currentDir = path; + } + + @Override + public boolean cd(String path) { + currentDir = path; + return true; + } + + @Override + public boolean cdUp() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String pwd() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean fileExists(String name) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public InputStream getFile(String name) { + return null; //return null so that server will return 550 File not found. + } + + @Override + public long getFileSize(String name) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public InputStream listCurrentDir() { + return null; + } + + @Override + public OutputStream putFile(String name) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean removeFile(String name) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean mkdir(String name) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean rename(String from, String to) { + throw new UnsupportedOperationException("Not supported yet."); + } + + } + + static class MyAuthHandler implements FtpAuthHandler { + + @Override + public int authType() { + return 0; + } + + @Override + public boolean authenticate(String user, String password) { + return true; + } + + @Override + public boolean authenticate(String user, String password, String account) { + return true; + } + } +} diff --git a/jdk/test/sun/net/www/ftptest/FtpCommandHandler.java b/jdk/test/sun/net/www/ftptest/FtpCommandHandler.java index 151b3df8eae..24193362320 100644 --- a/jdk/test/sun/net/www/ftptest/FtpCommandHandler.java +++ b/jdk/test/sun/net/www/ftptest/FtpCommandHandler.java @@ -442,7 +442,9 @@ public class FtpCommandHandler extends Thread { // cmd.setSoTimeout(2000); in = new BufferedReader(new InputStreamReader(cmd.getInputStream())); out = new PrintStream(cmd.getOutputStream(), true, "ISO8859_1"); - out.println("220 Java FTP test server (j2se 6.0) ready."); + out.println("---------------------------------\n220 Java FTP test server" + + " (j2se 6.0) ready.\n \n Please send commands\n" + + "-----------------------------\n\n\n"); out.flush(); if (auth.authType() == 0) // No auth needed logged = true; diff --git a/jdk/test/sun/reflect/AnonymousNewInstance/ManyNewInstanceAnonTest.java b/jdk/test/sun/reflect/AnonymousNewInstance/ManyNewInstanceAnonTest.java index 4bce96791b1..07f94d63508 100644 --- a/jdk/test/sun/reflect/AnonymousNewInstance/ManyNewInstanceAnonTest.java +++ b/jdk/test/sun/reflect/AnonymousNewInstance/ManyNewInstanceAnonTest.java @@ -25,7 +25,7 @@ * @test * @bug 7194897 * @summary JSR 292: Cannot create more than 16 instances of an anonymous class - * @modules java.base/sun.misc + * @modules java.base/jdk.internal.misc * java.management * @library /lib/testlibrary * @author Robert Field @@ -37,7 +37,7 @@ */ import java.io.ByteArrayOutputStream; import java.io.InputStream; -import sun.misc.Unsafe; +import jdk.internal.misc.Unsafe; public class ManyNewInstanceAnonTest { diff --git a/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java b/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java index 36414cc087b..a75a0420678 100644 --- a/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java +++ b/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java @@ -68,9 +68,10 @@ public class NoConsoleOutput { // (neither on standard output, nor on standard err streams). JavaVM vm = new JavaVM( DoRMIStuff.class.getName(), - "-XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED," - + "java.rmi/sun.rmi.server=ALL-UNNAMED,java.rmi/sun.rmi.transport=ALL-UNNAMED," - + "java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" + "-XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED" + + " -XaddExports:java.rmi/sun.rmi.server=ALL-UNNAMED" + + " -XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED" + + " -XaddExports:java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" + " -Djava.util.logging.config.file=" + loggingPropertiesFile, "", out, err); vm.execute(); diff --git a/jdk/test/sun/security/krb5/auto/BogusKDC.java b/jdk/test/sun/security/krb5/auto/BogusKDC.java index 15d9adddd37..c5f9d9e366c 100644 --- a/jdk/test/sun/security/krb5/auto/BogusKDC.java +++ b/jdk/test/sun/security/krb5/auto/BogusKDC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -82,7 +82,7 @@ public class BogusKDC { // and wrong port for slave KDC try (PrintWriter w = new PrintWriter(new FileWriter(KRB5_CONF))) { w.write(String.format(KRB5_CONF_TEMPLATE, - KDC.KDCNameService.NOT_EXISTING_HOST, WRONG_KDC_PORT)); + KDC.NOT_EXISTING_HOST, WRONG_KDC_PORT)); w.flush(); } @@ -98,7 +98,7 @@ public class BogusKDC { // but correct port for slave KDC try (PrintWriter w = new PrintWriter(new FileWriter(KRB5_CONF))) { w.write(String.format(KRB5_CONF_TEMPLATE, - KDC.KDCNameService.NOT_EXISTING_HOST, kdc.getPort())); + KDC.NOT_EXISTING_HOST, kdc.getPort())); w.flush(); } diff --git a/jdk/test/sun/security/krb5/auto/HttpNegotiateServer.java b/jdk/test/sun/security/krb5/auto/HttpNegotiateServer.java index 101f4d785d4..2ef37651374 100644 --- a/jdk/test/sun/security/krb5/auto/HttpNegotiateServer.java +++ b/jdk/test/sun/security/krb5/auto/HttpNegotiateServer.java @@ -24,8 +24,7 @@ /* * @test * @bug 6578647 6829283 - * @modules java.base/sun.net.spi.nameservice - * java.base/sun.security.util + * @modules java.base/sun.security.util * java.security.jgss/sun.security.jgss * java.security.jgss/sun.security.krb5 * java.security.jgss/sun.security.krb5.internal diff --git a/jdk/test/sun/security/krb5/auto/KDC.java b/jdk/test/sun/security/krb5/auto/KDC.java index 1976c3d8a2b..073e964d288 100644 --- a/jdk/test/sun/security/krb5/auto/KDC.java +++ b/jdk/test/sun/security/krb5/auto/KDC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -35,8 +35,6 @@ import java.time.temporal.TemporalUnit; import java.util.*; import java.util.concurrent.*; -import sun.net.spi.nameservice.NameService; -import sun.net.spi.nameservice.NameServiceDescriptor; import sun.security.krb5.*; import sun.security.krb5.internal.*; import sun.security.krb5.internal.ccache.CredentialsCache; @@ -129,6 +127,8 @@ public class KDC { public static final int DEFAULT_LIFETIME = 39600; public static final int DEFAULT_RENEWTIME = 86400; + public static String NOT_EXISTING_HOST = "not.existing.host"; + // Under the hood. // The random generator to generate random keys (including session keys) @@ -219,7 +219,8 @@ public class KDC { }; static { - System.setProperty("sun.net.spi.nameservice.provider.1", "ns,mock"); + String hostsFileName = System.getProperty("test.src", ".") + "/TestHosts"; + System.setProperty("jdk.net.hosts.file", hostsFileName); } /** @@ -1448,45 +1449,6 @@ public class KDC { } } - public static class KDCNameService implements NameServiceDescriptor { - - public static String NOT_EXISTING_HOST = "not.existing.host"; - - @Override - public NameService createNameService() throws Exception { - NameService ns = new NameService() { - @Override - public InetAddress[] lookupAllHostAddr(String host) - throws UnknownHostException { - // Everything is localhost except NOT_EXISTING_HOST - if (NOT_EXISTING_HOST.equals(host)) { - throw new UnknownHostException("Unknown host name: " - + NOT_EXISTING_HOST); - } - return new InetAddress[]{ - InetAddress.getByAddress(host, new byte[]{127,0,0,1}) - }; - } - @Override - public String getHostByAddr(byte[] addr) - throws UnknownHostException { - // No reverse lookup, PrincipalName use original string - throw new UnknownHostException(); - } - }; - return ns; - } - - @Override - public String getProviderName() { - return "mock"; - } - - @Override - public String getType() { - return "ns"; - } - } // Calling private methods thru reflections private static final Field getPADataField; diff --git a/jdk/test/sun/security/krb5/auto/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor b/jdk/test/sun/security/krb5/auto/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor deleted file mode 100644 index b87d67ad274..00000000000 --- a/jdk/test/sun/security/krb5/auto/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor +++ /dev/null @@ -1 +0,0 @@ -KDC$KDCNameService diff --git a/jdk/test/sun/security/krb5/auto/NoAddresses.java b/jdk/test/sun/security/krb5/auto/NoAddresses.java index 04c5b71e52a..cce53006412 100644 --- a/jdk/test/sun/security/krb5/auto/NoAddresses.java +++ b/jdk/test/sun/security/krb5/auto/NoAddresses.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -24,6 +24,7 @@ /* * @test * @bug 7032354 + * @run main/othervm NoAddresses setup * @run main/othervm NoAddresses 1 * @run main/othervm NoAddresses 2 * @run main/othervm/fail NoAddresses 3 @@ -34,12 +35,24 @@ import java.net.InetAddress; import org.ietf.jgss.ChannelBinding; import sun.security.jgss.GSSUtil; import sun.security.krb5.Config; +import java.io.PrintWriter; +import java.io.FileWriter; +import java.io.BufferedWriter; public class NoAddresses { public static void main(String[] args) throws Exception { + if (args[0].equalsIgnoreCase("setup")) { + // add a mapping of test host name to 127.0.0.1 to test's hosts file + InetAddress localHost = InetAddress.getLocalHost(); + String localHostName = localHost.getHostName(); + String hostsFileName = System.getProperty("test.src", ".") + "/TestHosts"; + String loopBackAddress = "127.0.0.1"; + System.setProperty("jdk.net.hosts.file", hostsFileName); + addMappingToHostsFile(localHostName, loopBackAddress, hostsFileName, true); + } else { OneKDC kdc = new OneKDC(null); kdc.writeJAASConf(); KDC.saveConfig(OneKDC.KRB5_CONF, kdc, @@ -79,3 +92,16 @@ public class NoAddresses { Context.handshake(c, s); } } + + private static void addMappingToHostsFile (String host, + String addr, + String hostsFileName, + boolean append) + throws Exception { + String mapping = addr + " " + host; + try (PrintWriter hfPWriter = new PrintWriter(new BufferedWriter( + new FileWriter(hostsFileName, append)))) { + hfPWriter.println(mapping); + } + } +} diff --git a/jdk/test/sun/security/krb5/auto/Renew.java b/jdk/test/sun/security/krb5/auto/Renew.java index a8327cddd9b..f6c8932289b 100644 --- a/jdk/test/sun/security/krb5/auto/Renew.java +++ b/jdk/test/sun/security/krb5/auto/Renew.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -26,8 +26,7 @@ * @bug 8058290 * @summary JAAS Krb5LoginModule has suspect ticket-renewal logic, * relies on clockskew grace - * @modules java.base/sun.net.spi.nameservice - * java.base/sun.security.util + * @modules java.base/sun.security.util * java.security.jgss/sun.security.krb5 * java.security.jgss/sun.security.krb5.internal * java.security.jgss/sun.security.krb5.internal.ccache diff --git a/jdk/test/sun/security/krb5/auto/Renewal.java b/jdk/test/sun/security/krb5/auto/Renewal.java index 36cf3148569..3ddf84f7cc6 100644 --- a/jdk/test/sun/security/krb5/auto/Renewal.java +++ b/jdk/test/sun/security/krb5/auto/Renewal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -45,8 +45,11 @@ public class Renewal { static OneKDC kdc; static String clazz = "sun.security.krb5.internal.tools.Kinit"; + static String hostsFileName = null; public static void main(String[] args) throws Exception { + hostsFileName = System.getProperty("test.src", ".") + "/TestHosts"; + System.setProperty("jdk.net.hosts.file", hostsFileName); kdc = new OneKDC(null); kdc.writeJAASConf(); @@ -95,7 +98,7 @@ public class Renewal { count++; p.args(OneKDC.USER, new String(OneKDC.PASS)) .inheritIO() - .prop("sun.net.spi.nameservice.provider.1", "ns,mock") + .prop("jdk.net.hosts.file", hostsFileName) .prop("java.security.krb5.conf", OneKDC.KRB5_CONF) .env("KRB5CCNAME", "ccache" + count) .start(); @@ -114,10 +117,11 @@ public class Renewal { } static void checkKinitRenew() throws Exception { + Proc p = Proc.create(clazz) .args("-R") .inheritIO() - .prop("sun.net.spi.nameservice.provider.1", "ns,mock") + .prop("jdk.net.hosts.file", hostsFileName) .prop("java.security.krb5.conf", OneKDC.KRB5_CONF) .env("KRB5CCNAME", "ccache" + count) .start(); diff --git a/jdk/test/sun/security/krb5/auto/SSLwithPerms.java b/jdk/test/sun/security/krb5/auto/SSLwithPerms.java index 9d195e350f0..8569d3580d0 100644 --- a/jdk/test/sun/security/krb5/auto/SSLwithPerms.java +++ b/jdk/test/sun/security/krb5/auto/SSLwithPerms.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -84,19 +84,21 @@ public class SSLwithPerms { ).getBytes()); fos.close(); + String hostsFileName = System.getProperty("test.src", ".") + "/TestHosts"; + Proc pc = Proc.create("SSLwithPerms") .args("client") .inheritIO() .prop("java.security.manager", "") .prop("java.security.krb5.conf", KRB5_CONF) - .prop("sun.net.spi.nameservice.provider.1", "ns,mock") + .prop("jdk.net.hosts.file", hostsFileName) .prop("javax.net.ssl", "handshake") .prop("sun.security.krb5.debug", "true") .perm(new SecurityPermission("setProperty.jdk.tls.disabledAlgorithms")) .perm(new PropertyPermission("sun.security.krb5.principal", "read")) .perm(new FilePermission("port", "read")) + .perm(new FilePermission(hostsFileName, "read")) .perm(new FilePermission(KTAB, "read")) - .perm(new RuntimePermission("accessClassInPackage.sun.net.spi.nameservice")) .perm(new AuthPermission("modifyPrincipals")) .perm(new AuthPermission("modifyPrivateCredentials")) .perm(new AuthPermission("doAs")) @@ -110,11 +112,13 @@ public class SSLwithPerms { .prop("java.security.manager", "") .prop("java.security.krb5.conf", KRB5_CONF) .prop("java.security.auth.login.config", JAAS_CONF) + .prop("jdk.net.hosts.file", hostsFileName) .prop("javax.net.ssl", "handshake") .prop("sun.security.krb5.debug", "true") .perm(new SecurityPermission("setProperty.jdk.tls.disabledAlgorithms")) .perm(new AuthPermission("createLoginContext.ssl")) .perm(new AuthPermission("doAs")) + .perm(new FilePermission(hostsFileName, "read")) .perm(new FilePermission("port", "write")) .perm(new SocketPermission("127.0.0.1", "accept")) .perm(new ServicePermission("host/host.realm@REALM", "accept")) diff --git a/jdk/test/sun/security/krb5/auto/TEST.properties b/jdk/test/sun/security/krb5/auto/TEST.properties index bdf806533a5..35a55e5d17c 100644 --- a/jdk/test/sun/security/krb5/auto/TEST.properties +++ b/jdk/test/sun/security/krb5/auto/TEST.properties @@ -1,6 +1,4 @@ modules java.base/jdk.internal.misc \ - java.base/sun.misc \ - java.base/sun.net.spi.nameservice \ java.base/sun.security.util \ java.security.jgss/sun.security.jgss \ java.security.jgss/sun.security.krb5 \ diff --git a/jdk/test/sun/security/krb5/auto/TestHosts b/jdk/test/sun/security/krb5/auto/TestHosts new file mode 100644 index 00000000000..1fe0422a5a5 --- /dev/null +++ b/jdk/test/sun/security/krb5/auto/TestHosts @@ -0,0 +1,16 @@ +127.0.0.1 host.rabbit.hole +127.0.0.1 kdc.rabbit.hole +127.0.0.1 kdc.snake.hole +127.0.0.1 kdc.web.domain +127.0.0.1 host.web.domain +127.0.0.1 host.proxy.domain +127.0.0.1 kdc.proxy.domain +127.0.0.1 client.rabbit.hole +127.0.0.1 localhost +127.0.0.1 host.r3.local +127.0.0.1 kdc.r1 +127.0.0.1 kdc.r2 +127.0.0.1 kdc.r3 +127.0.0.1 host.realm +127.0.0.1 realm +127.0.0.1 irlga09 diff --git a/jdk/test/sun/security/krb5/auto/principalProperty/TestHosts b/jdk/test/sun/security/krb5/auto/principalProperty/TestHosts new file mode 100644 index 00000000000..75721cd5afd --- /dev/null +++ b/jdk/test/sun/security/krb5/auto/principalProperty/TestHosts @@ -0,0 +1 @@ +127.0.0.1 localhost diff --git a/jdk/test/sun/security/krb5/auto/principalProperty/principalSystemPropTest.policy b/jdk/test/sun/security/krb5/auto/principalProperty/principalSystemPropTest.policy index ac9ef4861c1..40105cf6f52 100644 --- a/jdk/test/sun/security/krb5/auto/principalProperty/principalSystemPropTest.policy +++ b/jdk/test/sun/security/krb5/auto/principalProperty/principalSystemPropTest.policy @@ -11,6 +11,7 @@ grant { permission javax.security.auth.AuthPermission "modifyPrincipals"; permission javax.security.auth.AuthPermission "getSubject"; permission java.util.PropertyPermission "*", "read,write"; + permission java.io.FilePermission "/-", "read,write,delete"; permission java.io.FilePermission "*", "read,write,delete"; permission java.lang.RuntimePermission "accessDeclaredMembers"; permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; diff --git a/jdk/test/sun/security/krb5/auto/unbound.ssl.policy b/jdk/test/sun/security/krb5/auto/unbound.ssl.policy index 12bab4559f1..5cfc1e46f64 100644 --- a/jdk/test/sun/security/krb5/auto/unbound.ssl.policy +++ b/jdk/test/sun/security/krb5/auto/unbound.ssl.policy @@ -1,6 +1,7 @@ grant { permission java.util.PropertyPermission "*", "read,write"; permission java.net.SocketPermission "*:*", "listen,resolve,accept,connect"; + permission java.io.FilePermission "/-", "read"; permission java.io.FilePermission "*", "read,write,delete"; permission java.lang.RuntimePermission "accessDeclaredMembers"; permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; diff --git a/jdk/test/sun/security/krb5/canonicalize/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor b/jdk/test/sun/security/krb5/canonicalize/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor deleted file mode 100644 index 345e6aef713..00000000000 --- a/jdk/test/sun/security/krb5/canonicalize/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor +++ /dev/null @@ -1 +0,0 @@ -Test diff --git a/jdk/test/sun/security/krb5/canonicalize/Test.java b/jdk/test/sun/security/krb5/canonicalize/Test.java index 53012b3be51..8d21a50727f 100644 --- a/jdk/test/sun/security/krb5/canonicalize/Test.java +++ b/jdk/test/sun/security/krb5/canonicalize/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -24,20 +24,19 @@ * @test * @bug 6682516 * @summary SPNEGO_HTTP_AUTH/WWW_KRB and SPNEGO_HTTP_AUTH/WWW_SPNEGO failed on all non-windows platforms - * @modules java.base/sun.net.spi.nameservice - * java.security.jgss/sun.security.krb5 - * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock -Djava.security.krb5.conf=krb5.conf Test + * @modules java.security.jgss/sun.security.krb5 + * @run main/othervm -Djava.security.krb5.conf=krb5.conf Test */ import java.net.InetAddress; import java.net.UnknownHostException; -import sun.net.spi.nameservice.NameService; -import sun.net.spi.nameservice.NameServiceDescriptor; import sun.security.krb5.PrincipalName; -public class Test implements NameServiceDescriptor { +public class Test { public static void main(String[] args) throws Exception { // This config file is generated using Kerberos.app on a Mac + String hostsFileName = System.getProperty("test.src", ".") + "/TestHosts"; + System.setProperty("jdk.net.hosts.file", hostsFileName); System.setProperty("java.security.krb5.realm", "THIS.REALM"); System.setProperty("java.security.krb5.kdc", "localhost"); @@ -64,42 +63,4 @@ public class Test implements NameServiceDescriptor { throw new Exception("Output is " + pn); } } - - @Override - public NameService createNameService() throws Exception { - NameService ns = new NameService() { - @Override - public InetAddress[] lookupAllHostAddr(String host) - throws UnknownHostException { - // All c.* goes to 127.0.0.n - int i = Integer.valueOf(host.split("\\.")[0].substring(1)); - return new InetAddress[]{ - InetAddress.getByAddress(host, new byte[]{127,0,0,(byte)i}) - }; } - @Override - public String getHostByAddr(byte[] addr) - throws UnknownHostException { - int i = addr[3]; - switch (i) { - case 1: return "c1.this.domain"; // Good - case 2: return "127.0.0.2"; // Only IP - case 3: return "d3.this.domain"; // name change - default: - throw new UnknownHostException(); - } - } - }; - return ns; - } - - @Override - public String getProviderName() { - return "mock"; - } - - @Override - public String getType() { - return "ns"; - } -} diff --git a/jdk/test/sun/security/krb5/canonicalize/TestHosts b/jdk/test/sun/security/krb5/canonicalize/TestHosts new file mode 100644 index 00000000000..c14912cc7c1 --- /dev/null +++ b/jdk/test/sun/security/krb5/canonicalize/TestHosts @@ -0,0 +1,6 @@ +127.0.0.1 c1.this.domain +127.0.0.1 c1 +127.0.0.2 127.0.0.2 +127.0.0.2 c2 +127.0.0.3 c3 +127.0.0.1 c1.this diff --git a/jdk/test/sun/security/krb5/tools/ktcheck.sh b/jdk/test/sun/security/krb5/tools/ktcheck.sh index 48a01a78e6b..e7077b42e89 100644 --- a/jdk/test/sun/security/krb5/tools/ktcheck.sh +++ b/jdk/test/sun/security/krb5/tools/ktcheck.sh @@ -61,7 +61,8 @@ rm $KEYTAB EXTRA_OPTIONS="-Djava.security.krb5.conf=${TESTSRC}${FS}onlythree.conf" KTAB="${TESTJAVA}${FS}bin${FS}ktab -J${EXTRA_OPTIONS} -k $KEYTAB -f" CHECK="${TESTJAVA}${FS}bin${FS}java -cp ${TESTCLASSES} ${TESTVMOPTS} ${EXTRA_OPTIONS} \ - -XaddExports:java.security.jgss/sun.security.krb5.internal.ktab=ALL-UNNAMED,java.security.jgss/sun.security.krb5=ALL-UNNAMED \ + -XaddExports:java.security.jgss/sun.security.krb5.internal.ktab=ALL-UNNAMED \ + -XaddExports:java.security.jgss/sun.security.krb5=ALL-UNNAMED \ KtabCheck $KEYTAB" echo ${EXTRA_OPTIONS} diff --git a/jdk/test/sun/security/pkcs/pkcs8/PKCS8Test.java b/jdk/test/sun/security/pkcs/pkcs8/PKCS8Test.java index de6a614f33d..9c3f40b900a 100644 --- a/jdk/test/sun/security/pkcs/pkcs8/PKCS8Test.java +++ b/jdk/test/sun/security/pkcs/pkcs8/PKCS8Test.java @@ -30,7 +30,6 @@ * java.base/sun.security.util * java.base/sun.security.provider * java.base/sun.security.x509 - * java.base/sun.misc * @compile -XDignore.symbol.file PKCS8Test.java * @run main PKCS8Test */ diff --git a/jdk/test/sun/security/pkcs/pkcs9/UnknownAttribute.java b/jdk/test/sun/security/pkcs/pkcs9/UnknownAttribute.java index af8a9fd5184..1bfdc21e688 100644 --- a/jdk/test/sun/security/pkcs/pkcs9/UnknownAttribute.java +++ b/jdk/test/sun/security/pkcs/pkcs9/UnknownAttribute.java @@ -25,8 +25,7 @@ * @test * @bug 8011867 * @summary Accept unknown PKCS #9 attributes - * @modules java.base/sun.misc - * java.base/sun.security.pkcs + * @modules java.base/sun.security.pkcs * java.base/sun.security.util */ diff --git a/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java b/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java index 026b424ea72..3481e43b3ef 100644 --- a/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java +++ b/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java @@ -30,8 +30,7 @@ import jdk.testlibrary.JarUtils; * @bug 8024302 8026037 * @summary The test signs and verifies a jar file with -tsacert option * @library /lib/testlibrary - * @modules java.base/sun.misc - * java.base/sun.security.pkcs + * @modules java.base/sun.security.pkcs * java.base/sun.security.timestamp * java.base/sun.security.util * java.base/sun.security.x509 diff --git a/jdk/test/sun/security/tools/jarsigner/ts.sh b/jdk/test/sun/security/tools/jarsigner/ts.sh index 9b7bd89af1d..386e0507b66 100644 --- a/jdk/test/sun/security/tools/jarsigner/ts.sh +++ b/jdk/test/sun/security/tools/jarsigner/ts.sh @@ -24,8 +24,7 @@ # @test # @bug 6543842 6543440 6939248 8009636 8024302 # @summary checking response of timestamp -# @modules java.base/sun.misc -# java.base/sun.security.pkcs +# @modules java.base/sun.security.pkcs # java.base/sun.security.timestamp # java.base/sun.security.x509 # java.base/sun.security.util @@ -95,7 +94,10 @@ $KT -alias tsbad3 -certreq | \ $KT -alias ca -gencert -ext eku:critical=cs | \ $KT -alias tsbad3 -importcert -EXTRAOPTS="-XaddExports:java.base/sun.misc=ALL-UNNAMED,java.base/sun.security.pkcs=ALL-UNNAMED,java.base/sun.security.timestamp=ALL-UNNAMED,java.base/sun.security.x509=ALL-UNNAMED,java.base/sun.security.util=ALL-UNNAMED" +EXTRAOPTS="-XaddExports:java.base/sun.security.pkcs=ALL-UNNAMED \ + -XaddExports:java.base/sun.security.timestamp=ALL-UNNAMED \ + -XaddExports:java.base/sun.security.x509=ALL-UNNAMED \ + -XaddExports:java.base/sun.security.util=ALL-UNNAMED" $JAVAC ${EXTRAOPTS} -d . ${TESTSRC}/TimestampCheck.java $JAVA ${TESTVMOPTS} ${EXTRAOPTS} "-Dtest.tool.vm.opts=${TESTTOOLVMOPTS}" TimestampCheck diff --git a/jdk/test/sun/security/tools/keytool/autotest.sh b/jdk/test/sun/security/tools/keytool/autotest.sh index d798f7a811e..de8d94ffa5d 100644 --- a/jdk/test/sun/security/tools/keytool/autotest.sh +++ b/jdk/test/sun/security/tools/keytool/autotest.sh @@ -100,7 +100,9 @@ fi echo "Using NSS lib at $LIBNAME" -EXTRAOPTS="-XaddExports:java.base/sun.security.tools.keytool=ALL-UNNAMED,java.base/sun.security.util=ALL-UNNAMED,java.base/sun.security.x509=ALL-UNNAMED" +EXTRAOPTS="-XaddExports:java.base/sun.security.tools.keytool=ALL-UNNAMED \ + -XaddExports:java.base/sun.security.util=ALL-UNNAMED \ + -XaddExports:java.base/sun.security.x509=ALL-UNNAMED" ${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} ${EXTRAOPTS} -d . -XDignore.symbol.file \ ${TESTSRC}${FS}KeyToolTest.java || exit 10 diff --git a/jdk/test/sun/security/tools/keytool/standard.sh b/jdk/test/sun/security/tools/keytool/standard.sh index f84bd1930ed..8106ee44dcb 100644 --- a/jdk/test/sun/security/tools/keytool/standard.sh +++ b/jdk/test/sun/security/tools/keytool/standard.sh @@ -57,7 +57,9 @@ case "$OS" in ;; esac -EXTRAOPTS="-XaddExports:java.base/sun.security.tools.keytool=ALL-UNNAMED,java.base/sun.security.util=ALL-UNNAMED,java.base/sun.security.x509=ALL-UNNAMED" +EXTRAOPTS="-XaddExports:java.base/sun.security.tools.keytool=ALL-UNNAMED \ + -XaddExports:java.base/sun.security.util=ALL-UNNAMED \ + -XaddExports:java.base/sun.security.x509=ALL-UNNAMED" ${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} ${EXTRAOPTS} -d . -XDignore.symbol.file ${TESTSRC}${FS}KeyToolTest.java || exit 10 diff --git a/jdk/test/sun/security/x509/URICertStore/ExtensionsWithLDAP.java b/jdk/test/sun/security/x509/URICertStore/ExtensionsWithLDAP.java index 1cccda64f75..e495a4ac5d1 100644 --- a/jdk/test/sun/security/x509/URICertStore/ExtensionsWithLDAP.java +++ b/jdk/test/sun/security/x509/URICertStore/ExtensionsWithLDAP.java @@ -44,14 +44,11 @@ import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; -import sun.net.spi.nameservice.NameService; -import sun.net.spi.nameservice.NameServiceDescriptor; /* * @test * @bug 8134708 * @summary Check if LDAP resources from CRLDP and AIA extensions can be loaded - * @modules java.base/sun.net.spi.nameservice * @run main/othervm ExtensionsWithLDAP */ public class ExtensionsWithLDAP { @@ -149,7 +146,8 @@ public class ExtensionsWithLDAP { System.setProperty("com.sun.security.enableAIAcaIssuers", "true"); // register a local name service - System.setProperty("sun.net.spi.nameservice.provider.1", "ns,localdns"); + String hostsFileName = System.getProperty("test.src", ".") + "/ExtensionsWithLDAPHosts"; + System.setProperty("jdk.net.hosts.file", hostsFileName); X509Certificate trustedCert = loadCertificate(CA_CERT); X509Certificate eeCert = loadCertificate(EE_CERT); @@ -201,48 +199,8 @@ public class ExtensionsWithLDAP { } // a local name service which log requested host names - public static class LocalNameService implements NameServiceDescriptor { + public static class LocalNameService { static final List requestedHosts = new ArrayList<>(); - - @Override - public NameService createNameService() throws Exception { - System.out.println("LocalNameService: createNameService() called"); - NameService ns = new NameService() { - - @Override - public InetAddress[] lookupAllHostAddr(String host) - throws UnknownHostException { - - System.out.println("LocalNameService: " - + "NameService.lookupAllHostAddr(): " + host); - - requestedHosts.add(host); - - throw new UnknownHostException(); } - - @Override - public String getHostByAddr(byte[] addr) - throws UnknownHostException { - System.out.println("LocalNameService: " - + "NameService.getHostByAddr(): " - + Arrays.toString(addr)); - throw new UnknownHostException("No reverse lookup"); } - }; - return ns; - } - - @Override - public String getProviderName() { - return "localdns"; - } - - @Override - public String getType() { - return "ns"; - } - } - -} diff --git a/jdk/test/sun/security/x509/URICertStore/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor b/jdk/test/sun/security/x509/URICertStore/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor deleted file mode 100644 index 8a0bb39635a..00000000000 --- a/jdk/test/sun/security/x509/URICertStore/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor +++ /dev/null @@ -1 +0,0 @@ -ExtensionsWithLDAP$LocalNameService diff --git a/jdk/test/sun/security/x509/X500Name/NullX500Name.java b/jdk/test/sun/security/x509/X500Name/NullX500Name.java index ab03596b6f7..fe0b1d3874c 100644 --- a/jdk/test/sun/security/x509/X500Name/NullX500Name.java +++ b/jdk/test/sun/security/x509/X500Name/NullX500Name.java @@ -24,8 +24,7 @@ /* @test * @bug 4118818 * @summary allow null X.500 Names - * @modules java.base/sun.misc - * java.base/sun.security.util + * @modules java.base/sun.security.util * java.base/sun.security.x509 */ diff --git a/jdk/test/tools/jimage/VerifyJimage.java b/jdk/test/tools/jimage/VerifyJimage.java index c31eb883fba..9c33cc3fa74 100644 --- a/jdk/test/tools/jimage/VerifyJimage.java +++ b/jdk/test/tools/jimage/VerifyJimage.java @@ -49,6 +49,7 @@ import jdk.internal.jimage.ImageLocation; * @test * @summary Verify jimage * @modules java.base/jdk.internal.jimage + * @run main/othervm -Djdk.launcher.addmods=ALL-SYSTEM VerifyJimage */ /** diff --git a/jdk/test/tools/launcher/modules/addexports/AddExportsTest.java b/jdk/test/tools/launcher/modules/addexports/AddExportsTest.java index 8f92cf2b2ad..fcb693c6285 100644 --- a/jdk/test/tools/launcher/modules/addexports/AddExportsTest.java +++ b/jdk/test/tools/launcher/modules/addexports/AddExportsTest.java @@ -71,7 +71,7 @@ public class AddExportsTest { boolean compiled = CompilerUtils.compile( SRC_DIR.resolve(TEST1_MODULE), MODS_DIR.resolve(TEST1_MODULE), - "-XaddExports:java.base/sun.misc=m1"); + "-XaddExports:java.base/jdk.internal.misc=m1"); assertTrue(compiled, "module " + TEST1_MODULE + " did not compile"); // javac -d upgrademods/java.transaction src/java.transaction/** @@ -118,16 +118,16 @@ public class AddExportsTest { /** - * Run class path application that uses sun.misc.Unsafe + * Run class path application that uses jdk.internal.misc.Unsafe */ public void testUnnamedModule() throws Exception { - // java -XaddExports:java.base/sun.misc=ALL-UNNAMED \ + // java -XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED \ // -cp mods/$TESTMODULE jdk.test.UsesUnsafe String classpath = MODS_DIR.resolve(TEST1_MODULE).toString(); int exitValue - = executeTestJava("-XaddExports:java.base/sun.misc=ALL-UNNAMED", + = executeTestJava("-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED", "-cp", classpath, TEST1_MAIN_CLASS) .outputTo(System.out) @@ -139,16 +139,16 @@ public class AddExportsTest { /** - * Run named module that uses sun.misc.Unsafe + * Run named module that uses jdk.internal.misc.Unsafe */ public void testNamedModule() throws Exception { - // java -XaddExports:java.base/sun.misc=test \ + // java -XaddExports:java.base/jdk.internal.misc=test \ // -mp mods -m $TESTMODULE/$MAIN_CLASS String mid = TEST1_MODULE + "/" + TEST1_MAIN_CLASS; int exitValue = - executeTestJava("-XaddExports:java.base/sun.misc=" + TEST1_MODULE, + executeTestJava("-XaddExports:java.base/jdk.internal.misc=" + TEST1_MODULE, "-mp", MODS_DIR.toString(), "-m", mid) .outputTo(System.out) @@ -240,13 +240,13 @@ public class AddExportsTest { public Object[][] badValues() { return new Object[][]{ - { "java.base/sun.misc", null }, // missing target - { "java.base/sun.misc=sun.monkey", null }, // unknown target - { "java.monkey/sun.monkey=ALL-UNNAMED", null }, // unknown module - { "java.base/sun.monkey=ALL-UNNAMED", null }, // unknown package - { "java.monkey/sun.monkey=ALL-UNNAMED", null }, // unknown module/package - { "java.base=ALL-UNNAMED", null }, // missing package - { "java.base/=ALL-UNNAMED", null } // missing package + { "java.base/jdk.internal.misc", null }, // missing target + { "java.base/jdk.internal.misc=sun.monkey", null }, // unknown target + { "java.monkey/sun.monkey=ALL-UNNAMED", null }, // unknown module + { "java.base/sun.monkey=ALL-UNNAMED", null }, // unknown package + { "java.monkey/sun.monkey=ALL-UNNAMED", null }, // unknown module/package + { "java.base=ALL-UNNAMED", null }, // missing package + { "java.base/=ALL-UNNAMED", null } // missing package }; } diff --git a/jdk/test/tools/launcher/modules/addexports/src/m1/jdk/test1/Main.java b/jdk/test/tools/launcher/modules/addexports/src/m1/jdk/test1/Main.java index a047c91d80d..6efbbdf90fa 100644 --- a/jdk/test/tools/launcher/modules/addexports/src/m1/jdk/test1/Main.java +++ b/jdk/test/tools/launcher/modules/addexports/src/m1/jdk/test1/Main.java @@ -24,7 +24,7 @@ package jdk.test1; import java.lang.reflect.Field; -import sun.misc.Unsafe; +import jdk.internal.misc.Unsafe; public class Main { public static void main(String[] args) throws Exception { diff --git a/jdk/test/tools/launcher/modules/limitmods/LimitModsTest.java b/jdk/test/tools/launcher/modules/limitmods/LimitModsTest.java index 0cafaf42e66..f11aa003e00 100644 --- a/jdk/test/tools/launcher/modules/limitmods/LimitModsTest.java +++ b/jdk/test/tools/launcher/modules/limitmods/LimitModsTest.java @@ -103,9 +103,10 @@ public class LimitModsTest { public void testWithAddMods() throws Exception { int exitValue; - // java -limitmods java.base -addmods java.logging -listmods + // java -limitmods java.base -addmods java.logging,jdk.unsupported -listmods exitValue = executeTestJava("-limitmods", "java.base", - "-addmods", "java.logging", + "-addmods", + "java.logging,jdk.unsupported", // TODO: add bug No. "-listmods") .outputTo(System.out) .errorTo(System.out) diff --git a/jdk/test/tools/launcher/modules/patch/PatchTest.java b/jdk/test/tools/launcher/modules/patch/PatchTest.java index 215882f1e4b..ba0ce877145 100644 --- a/jdk/test/tools/launcher/modules/patch/PatchTest.java +++ b/jdk/test/tools/launcher/modules/patch/PatchTest.java @@ -128,18 +128,15 @@ public class PatchTest { // value for -Xpatch String patchPath = PATCHES1_DIR + File.pathSeparator + PATCHES2_DIR; - // value for -XaddExports - String addExportsValue = "java.base/java.lang2=test" - + ",jdk.naming.dns/com.sun.jndi.dns=test" - + ",jdk.naming.dns/com.sun.jndi.dns2=test" - + ",jdk.compiler/com.sun.tools.javac2=test"; - // the argument to the test is the list of classes overridden or added String arg = Stream.of(CLASSES).collect(Collectors.joining(",")); int exitValue = executeTestJava("-Xpatch:" + patchPath, - "-XaddExports:" + addExportsValue, + "-XaddExports:java.base/java.lang2=test", + "-XaddExports:jdk.naming.dns/com.sun.jndi.dns=test", + "-XaddExports:jdk.naming.dns/com.sun.jndi.dns2=test", + "-XaddExports:jdk.compiler/com.sun.tools.javac2=test", "-addmods", "jdk.naming.dns,jdk.compiler", "-mp", MODS_DIR.toString(), "-m", "test/jdk.test.Main", arg) diff --git a/jdk/test/tools/pack200/ModuleAttributes.java b/jdk/test/tools/pack200/ModuleAttributes.java index a3df72bf766..6ac5297aa7a 100644 --- a/jdk/test/tools/pack200/ModuleAttributes.java +++ b/jdk/test/tools/pack200/ModuleAttributes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -39,38 +39,10 @@ public class ModuleAttributes { } public void run() throws Exception { - File file = createModuleJar(); + File file = Utils.createRtJar(".*module-info\\.class"); Utils.testWithRepack(file, "--effort=1", "--unknown-attribute=error"); - } - - File createModuleJar() throws IOException { - File libDir = new File(Utils.JavaHome, "lib"); - File modules = new File(libDir, "modules"); - File outDir = new File("out"); - - List cmdList = new ArrayList<>(); - cmdList.add(Utils.getJimageCmd()); - cmdList.add("extract"); - cmdList.add(modules.getAbsolutePath()); - cmdList.add("--dir"); - cmdList.add(outDir.getName()); - Utils.runExec(cmdList); - - FileFilter filter = (File file) -> file.getName().equals("module-info.class"); - List mfiles = Utils.findFiles(outDir, filter); - - List contents = new ArrayList<>(mfiles.size()); - mfiles.stream().forEach((f) -> { - contents.add(f.getAbsolutePath()); - }); - - File listFile = new File("mfiles.list"); - Utils.createFile(listFile, contents); - File testFile = new File("test.jar"); - Utils.jar("cvf", testFile.getName(), "@" + listFile.getName()); - Utils.recursiveDelete(outDir); - return testFile; + Utils.cleanup(); } } diff --git a/jdk/test/tools/pack200/Pack200Props.java b/jdk/test/tools/pack200/Pack200Props.java index fbb671649c9..26fe5a075ea 100644 --- a/jdk/test/tools/pack200/Pack200Props.java +++ b/jdk/test/tools/pack200/Pack200Props.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -31,13 +31,13 @@ */ import java.io.File; -import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.jar.Pack200; import java.util.jar.Pack200.Packer; +import java.util.logging.Logger; /* * Run this against a large jar file, by default the packer should generate only @@ -46,20 +46,22 @@ import java.util.jar.Pack200.Packer; public class Pack200Props { - public static void main(String... args) throws IOException { + final static Logger log = Logger.getLogger("Pack200Props"); + + public static void main(String... args) throws Exception { verifyDefaults(); File out = new File("test" + Utils.PACK_FILE_EXT); out.delete(); verifySegmentLimit(out); + log.info("cleanup"); Utils.cleanup(); } - static void verifySegmentLimit(File outFile) throws IOException { - File sdkHome = Utils.JavaSDK; + static void verifySegmentLimit(File outFile) throws Exception { + log.info("creating jar"); File testJar = Utils.createRtJar(); - System.out.println("using pack200: " + Utils.getPack200Cmd()); - + log.info("using pack200: " + Utils.getPack200Cmd()); List cmdsList = new ArrayList<>(); cmdsList.add(Utils.getPack200Cmd()); cmdsList.add("-J-Xshare:off"); @@ -71,6 +73,7 @@ public class Pack200Props { cmdsList.add(testJar.getAbsolutePath()); List outList = Utils.runExec(cmdsList); + log.info("verifying"); int count = 0; for (String line : outList) { System.out.println(line); @@ -78,6 +81,7 @@ public class Pack200Props { count++; } } + log.info("fini"); if (count == 0) { throw new RuntimeException("no segments or no output ????"); } else if (count > 1) { @@ -86,6 +90,7 @@ public class Pack200Props { } private static void verifyDefaults() { + log.info("start"); Map expectedDefaults = new HashMap<>(); Packer p = Pack200.newPacker(); expectedDefaults.put("com.sun.java.util.jar.pack.disable.native", @@ -121,6 +126,7 @@ public class Pack200Props { } } } + log.info("fini"); if (errors > 0) { throw new RuntimeException(errors + " error(s) encountered in default properties verification"); diff --git a/jdk/test/tools/pack200/PackChecksum.java b/jdk/test/tools/pack200/PackChecksum.java index 3d6a3b07a29..a33c10f2902 100644 --- a/jdk/test/tools/pack200/PackChecksum.java +++ b/jdk/test/tools/pack200/PackChecksum.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -31,65 +31,136 @@ import java.util.jar.JarOutputStream; /* * @test - * @bug 8000650 + * @bug 8000650 8150469 * @summary unpack200.exe should check gzip crc * @compile -XDignore.symbol.file Utils.java PackChecksum.java * @run main PackChecksum * @author kizune */ public class PackChecksum { + final int TRAILER_LEN = 8; + final List cmdsList = new ArrayList<>(); + static enum Case { + CRC32, + ISIZE, + BOTH; + }; public static void main(String... args) throws Exception { - testChecksum(); + new PackChecksum().run(); + } + void run() throws Exception { + testBrokenTrailer(Case.CRC32); // negative + testBrokenTrailer(Case.ISIZE); // negative + testBrokenTrailer(Case.BOTH); // negative + testMultipleSegments(); } - static void testChecksum() throws Exception { + void testMultipleSegments() throws Exception { + File inputJar = new File("input.jar"); + Utils.copyFile(Utils.getGoldenJar(), inputJar); + cmdsList.clear(); + File testPack = new File("out.jar.pack.gz"); + + cmdsList.clear(); + cmdsList.add(Utils.getPack200Cmd()); + // force multiple segments + cmdsList.add("--segment-limit=100"); + cmdsList.add(testPack.getName()); + cmdsList.add(inputJar.getName()); + Utils.runExec(cmdsList); + + File destFile = new File("dst.jar"); + cmdsList.clear(); + cmdsList.add(Utils.getUnpack200Cmd()); + cmdsList.add(testPack.getName()); + cmdsList.add(destFile.getName()); + try { + Utils.runExec(cmdsList); + if (!destFile.exists()) { + throw new Exception("file not created: " + destFile); + } + } finally { + if (inputJar.exists()) + inputJar.delete(); + if (testPack.exists()) + testPack.delete(); + if (destFile.exists()) + destFile.delete(); + } + } + + void testBrokenTrailer(Case type) throws Exception { + System.out.println("Testing: case " + type); // Create a fresh .jar file File testFile = new File("src_tools.jar"); File testPack = new File("src_tools.pack.gz"); generateJar(testFile); - List cmdsList = new ArrayList<>(); + cmdsList.clear(); // Create .pack file cmdsList.add(Utils.getPack200Cmd()); cmdsList.add(testPack.getName()); cmdsList.add(testFile.getName()); Utils.runExec(cmdsList); - // Mess up with the checksum of the packed file + // mutate the checksum of the packed file RandomAccessFile raf = new RandomAccessFile(testPack, "rw"); - raf.seek(raf.length() - 8); - int val = raf.readInt(); - val = Integer.MAX_VALUE - val; - raf.seek(raf.length() - 8); - raf.writeInt(val); + + switch (type) { + case CRC32: + raf.seek(raf.length() - TRAILER_LEN); + raf.writeInt(0x0dea0a0d); + break; + case ISIZE: + raf.seek(raf.length() - (TRAILER_LEN/2)); + raf.writeInt(0x0b0e0e0f); + break; + default: + raf.seek(raf.length() - (TRAILER_LEN)); + raf.writeLong(0x0dea0a0d0b0e0e0fL); + break; + } + raf.close(); File dstFile = new File("dst_tools.jar"); + if (dstFile.exists()) { + dstFile.delete(); + } cmdsList.clear(); cmdsList.add(Utils.getUnpack200Cmd()); cmdsList.add(testPack.getName()); cmdsList.add(dstFile.getName()); - boolean passed = false; + boolean processFailed = false; try { Utils.runExec(cmdsList); } catch (RuntimeException re) { // unpack200 should exit with non-zero exit code - passed = true; - } + processFailed = true; + } finally { + // tidy up + if (testFile.exists()) + testFile.delete(); - // tidy up - if (testFile.exists()) testFile.delete(); - if (testPack.exists()) testPack.delete(); - if (dstFile.exists()) dstFile.delete(); - if (!passed) { - throw new Exception("File with incorrect CRC unpacked without the error."); + if (testPack.exists()) + testPack.delete(); + + if (!processFailed) { + throw new Exception("case " + type + + ": file with incorrect CRC, unpacked without the error."); + } + if (dstFile.exists()) { + dstFile.delete(); + throw new Exception("case " + type + + ": file exists: " + dstFile); + } } } - static void generateJar(File result) throws IOException { + void generateJar(File result) throws IOException { if (result.exists()) { result.delete(); } diff --git a/jdk/test/tools/pack200/Utils.java b/jdk/test/tools/pack200/Utils.java index 663cdc38247..f4641987e73 100644 --- a/jdk/test/tools/pack200/Utils.java +++ b/jdk/test/tools/pack200/Utils.java @@ -32,22 +32,33 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; +import java.net.URI; +import java.net.URL; import java.nio.charset.Charset; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.HashMap; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; import java.util.jar.Pack200; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import static java.nio.file.StandardCopyOption.*; import static java.nio.file.StandardOpenOption.*; + /** * * @author ksrini @@ -544,10 +555,6 @@ class Utils { return getAjavaCmd("jar"); } - static String getJimageCmd() { - return getAjavaCmd("jimage"); - } - static String getAjavaCmd(String cmdStr) { File binDir = new File(JavaHome, "bin"); File unpack200File = IsWindows @@ -562,29 +569,88 @@ class Utils { return cmd; } - static File createRtJar() throws IOException { - File libDir = new File(JavaHome, "lib"); - File modules = new File(libDir, "modules"); - List cmdList = new ArrayList<>(); - cmdList.add(getJimageCmd()); - cmdList.add("extract"); - cmdList.add(modules.getAbsolutePath()); - cmdList.add("--dir"); - cmdList.add("out"); - runExec(cmdList); - + // used to get all classes + static File createRtJar() throws Exception { File rtJar = new File("rt.jar"); - cmdList.clear(); - cmdList.add(getJarCmd()); - // cmdList.add("cvf"); too noisy - cmdList.add("cf"); - cmdList.add(rtJar.getName()); - cmdList.add("-C"); - cmdList.add("out"); - cmdList.add("."); - runExec(cmdList); - - recursiveDelete(new File("out")); + new JrtToZip(".*\\.class", rtJar).run(); return rtJar; } + + // used to select the contents + static File createRtJar(String pattern) throws Exception { + File rtJar = new File("rt.jar"); + new JrtToZip(pattern, rtJar).run(); + return rtJar; + } + + /* + * A helper class to create a pseudo rt.jar. + */ + static class JrtToZip { + + final File outFile; + final Pattern pattern; + + public static void main(String[] args) throws Exception { + new JrtToZip(args[0], new File(args[1])).run(); + } + + JrtToZip(String pattern, File outFile) throws Exception { + this.pattern = Pattern.compile(pattern); + this.outFile = outFile; + } + + void run() throws Exception { + URI uri = URI.create("jar:" + outFile.toURI()); + Map env = new HashMap<>(); + env.put("create", "true"); + try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) { + toZipfs(zipfs); + } + } + + void toZipfs(FileSystem zipfs) throws Exception { + FileSystem jrtfs = FileSystems.getFileSystem(URI.create("jrt:/")); + for (Path root : jrtfs.getRootDirectories()) { + Files.walkFileTree(root, new FileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) throws IOException { + // ignore unneeded directory + if (dir.startsWith("/packages")) + return FileVisitResult.SKIP_SUBTREE; + + // pre-create required directories + Path zpath = zipfs.getPath(dir.toString()); + Files.createDirectories(zpath); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) throws IOException { + Matcher matcher = pattern.matcher(file.toString()); + if (matcher.matches()) { + // System.out.println("x: " + file); + Path zpath = zipfs.getPath(file.toString()); + Files.copy(file, zpath, REPLACE_EXISTING); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, + IOException exc) throws IOException { + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, + IOException exc) throws IOException { + return FileVisitResult.CONTINUE; + } + }); + } + } + } } diff --git a/make/CompileJavaModules.gmk b/make/CompileJavaModules.gmk index a2650d730bb..306b7c88bc6 100644 --- a/make/CompileJavaModules.gmk +++ b/make/CompileJavaModules.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 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 @@ -111,16 +111,6 @@ java.desktop_EXCLUDES += \ sun/awt/X11/doc-files \ # -# The exception handling of swing beaninfo -# These resources violates the convention of having code and resources together under -# $(JDK_TOPDIR)/src/.../classes directories -$(eval $(call SetupCopyFiles,COPY_BEANINFO, \ - SRC := $(JDK_TOPDIR)/make/data/swingbeaninfo/images, \ - DEST := $(JDK_OUTPUTDIR)/modules/java.desktop/javax/swing/beaninfo/images, \ - FILES := $(wildcard $(JDK_TOPDIR)/make/data/swingbeaninfo/images/*.gif))) - -java.desktop_COPY_EXTRA += $(COPY_BEANINFO) - java.desktop_EXCLUDE_FILES += \ javax/swing/plaf/nimbus/InternalFrameTitlePanePainter.java \ javax/swing/plaf/nimbus/OptionPaneMessageAreaPainter.java \ diff --git a/make/Javadoc.gmk b/make/Javadoc.gmk index f0b170186cf..4ab8d5a0b21 100644 --- a/make/Javadoc.gmk +++ b/make/Javadoc.gmk @@ -74,6 +74,7 @@ ATTACH_FIRST_COPYRIGHT_YEAR = 2005 JCONSOLE_FIRST_COPYRIGHT_YEAR = 2006 SCTPAPI_FIRST_COPYRIGHT_YEAR = 2009 TRACING_FIRST_COPYRIGHT_YEAR = 2008 +JSHELLAPI_FIRST_COPYRIGHT_YEAR = 2015 TREEAPI_FIRST_COPYRIGHT_YEAR = 2005 NASHORNAPI_FIRST_COPYRIGHT_YEAR = 2014 DYNALINKAPI_FIRST_COPYRIGHT_YEAR = 2015 @@ -1197,6 +1198,65 @@ $(JCONSOLE_PACKAGES_FILE): $(call PackageDependencies,$(JCONSOLE_PKGS)) $(prep-target) $(call PackageFilter,$(JCONSOLE_PKGS)) +############################################################# +# +# jshellapidocs +# + +ALL_OTHER_TARGETS += jshellapidocs + +JSHELLAPI_DOCDIR := $(JDK_API_DOCSDIR)/jshell +JSHELLAPI2COREAPI := ../../$(JDKJRE2COREAPI) +JSHELLAPI_DOCTITLE := JShell API +JSHELLAPI_WINDOWTITLE := JShell API +JSHELLAPI_HEADER := JSHELL API +JSHELLAPI_BOTTOM := $(call CommonBottom,$(JSHELLAPI_FIRST_COPYRIGHT_YEAR)) +JSHELLAPI_GROUPNAME := Packages +JSHELLAPI_REGEXP := jdk.jshell.* +# JSHELLAPI_PKGS is located in NON_CORE_PKGS.gmk + +JSHELLAPI_INDEX_HTML = $(JSHELLAPI_DOCDIR)/index.html +JSHELLAPI_OPTIONS_FILE = $(DOCSTMPDIR)/jshellapi.options +JSHELLAPI_PACKAGES_FILE = $(DOCSTMPDIR)/jshellapi.packages + +# The modules required to be documented +JSHELLAPI_MODULES = jdk.jshell + +jshellapidocs: $(JSHELLAPI_INDEX_HTML) + +# Set relative location to core api document root +$(JSHELLAPI_INDEX_HTML): GET2DOCSDIR=$(JSHELLAPI2COREAPI)/.. + +# Run javadoc if the index file is out of date or missing +$(JSHELLAPI_INDEX_HTML): $(JSHELLAPI_OPTIONS_FILE) $(JSHELLAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE) + $(prep-javadoc) + $(call JavadocSummary,$(JSHELLAPI_OPTIONS_FILE),$(JSHELLAPI_PACKAGES_FILE)) + $(JAVADOC_CMD_SMALL) -d $(@D) \ + @$(JSHELLAPI_OPTIONS_FILE) @$(JSHELLAPI_PACKAGES_FILE) + +# Create file with javadoc options in it +$(JSHELLAPI_OPTIONS_FILE): + $(prep-target) + @($(call COMMON_JAVADOCFLAGS) ; \ + $(call COMMON_JAVADOCTAGS) ; \ + $(call OptionOnly,-Xdoclint:all) ; \ + $(call OptionPair,-system,none) ; \ + $(call OptionPair,-modulesourcepath,$(RELEASEDOCS_MODULESOURCEPATH)) ; \ + $(call OptionPair,-addmods,$(JSHELLAPI_MODULES)) ; \ + $(call OptionPair,-encoding,ascii) ; \ + $(call OptionPair,-doctitle,$(JSHELLAPI_DOCTITLE)) ; \ + $(call OptionPair,-windowtitle,$(JSHELLAPI_WINDOWTITLE) $(DRAFT_WINTITLE)); \ + $(call OptionPair,-header,$(JSHELLAPI_HEADER)$(DRAFT_HEADER)) ; \ + $(call OptionPair,-bottom,$(JSHELLAPI_BOTTOM)$(DRAFT_BOTTOM)) ; \ + $(call OptionTrip,-group,$(JSHELLAPI_GROUPNAME),$(JSHELLAPI_REGEXP)); \ + $(call OptionTrip,-linkoffline,$(JSHELLAPI2COREAPI),$(COREAPI_DOCSDIR)/); \ + ) >> $@ + +# Create a file with the package names in it +$(JSHELLAPI_PACKAGES_FILE): $(call PackageDependencies,$(JSHELLAPI_PKGS)) + $(prep-target) + $(call PackageFilter,$(JSHELLAPI_PKGS)) + ############################################################# # # treeapidocs diff --git a/make/Main.gmk b/make/Main.gmk index 5d8137f2b47..045a1da46c7 100644 --- a/make/Main.gmk +++ b/make/Main.gmk @@ -341,7 +341,8 @@ ALL_TARGETS += docs-javadoc docs-jvmtidoc ifeq ($(CREATE_BUILDJDK), true) # This target is only called by the recursive call below. create-buildjdk-compile-hotspot-helper: hotspot - create-buildjdk-compile-modules-helper: jdk.jlink-launchers java.base-copy + create-buildjdk-compile-modules-helper: jdk.jlink-launchers java.base-copy \ + jdk.jdeps-launchers endif create-buildjdk-copy: diff --git a/make/common/CORE_PKGS.gmk b/make/common/CORE_PKGS.gmk index 850073385a4..3223460f098 100644 --- a/make/common/CORE_PKGS.gmk +++ b/make/common/CORE_PKGS.gmk @@ -82,6 +82,7 @@ CORE_PKGS = \ java.awt \ java.awt.color \ java.awt.datatransfer \ + java.awt.desktop \ java.awt.dnd \ java.awt.event \ java.awt.font \ diff --git a/make/common/Modules.gmk b/make/common/Modules.gmk index 6e7d360c718..5930e2627a3 100644 --- a/make/common/Modules.gmk +++ b/make/common/Modules.gmk @@ -66,6 +66,7 @@ BOOT_MODULES += \ jdk.sctp \ jdk.security.auth \ jdk.security.jgss \ + jdk.unsupported \ jdk.vm.ci \ # @@ -115,6 +116,7 @@ PLATFORM_MODULES += \ # JRE_TOOL_MODULES += \ + jdk.jdwp.agent \ jdk.pack200 \ jdk.scripting.nashorn.shell \ # diff --git a/make/common/NON_CORE_PKGS.gmk b/make/common/NON_CORE_PKGS.gmk index 7e63750d28f..f6fbcd3a63b 100644 --- a/make/common/NON_CORE_PKGS.gmk +++ b/make/common/NON_CORE_PKGS.gmk @@ -80,6 +80,8 @@ ATTACH_PKGS = com.sun.tools.attach \ JCONSOLE_PKGS = com.sun.tools.jconsole +JSHELLAPI_PKGS = jdk.jshell + TREEAPI_PKGS = com.sun.source.doctree \ com.sun.source.tree \ com.sun.source.util diff --git a/test/lib/share/classes/jdk/test/lib/Utils.java b/test/lib/share/classes/jdk/test/lib/Utils.java index 5634e088074..95e2bbab48a 100644 --- a/test/lib/share/classes/jdk/test/lib/Utils.java +++ b/test/lib/share/classes/jdk/test/lib/Utils.java @@ -48,7 +48,7 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; -import sun.misc.Unsafe; +import jdk.internal.misc.Unsafe; import jdk.test.lib.process.*; import static jdk.test.lib.Asserts.assertTrue;