This commit is contained in:
Phil Race 2017-10-23 13:06:04 -07:00
commit 05adede5f5
50 changed files with 1919 additions and 98 deletions

@ -452,3 +452,4 @@ e5357aa85dadacc6562175ff74714fecfb4470cf jdk-10+22
8eb5e3ccee560c28ac9b1df2670adac2b3d36fad jdk-10+25
1129253d3bc728a2963ba411ab9dd1adf358fb6b jdk-10+26
b87d7b5d5dedc1185e5929470f945b7378cdb3ad jdk-10+27
92f08900cb3c0d694e5c529a676c1c9e5909193f jdk-10+28

@ -97,13 +97,25 @@ JAVADOC_TAGS := \
$(CUSTOM_JAVADOC_TAGS) \
#
# The reference tags must stay stable to allow for comparisons across the
# development cycle. If JAVADOC_TAGS needs to change, make sure that
# REFERENCE_TAGS remains unchanged, by copying and hardcoding, if necessary.
REFERENCE_TAGS := $(JAVADOC_TAGS)
# Which doclint checks to ignore
JAVADOC_DISABLED_DOCLINT := accessibility html missing syntax reference
# The initial set of options for javadoc
JAVADOC_OPTIONS := -use -keywords -notimestamp \
-serialwarn -encoding ISO-8859-1 -docencoding UTF-8 -breakiterator \
-splitIndex --system none -html5 -javafx --expand-requires transitive
-splitIndex --system none -html5 -javafx --expand-requires transitive \
--override-methods=summary
# The reference options must stay stable to allow for comparisons across the
# development cycle.
REFERENCE_OPTIONS := -XDignore.symbol.file=true -use -keywords -notimestamp \
-serialwarn -encoding ISO-8859-1 -breakiterator -splitIndex --system none \
-html5 -javafx --expand-requires transitive
# Should we add DRAFT stamps to the generated javadoc?
ifeq ($(VERSION_IS_GA), true)
@ -129,6 +141,11 @@ ifeq ($(IS_DRAFT), true)
endif
DRAFT_TEXT := This specification is not final and is subject to change. \
Use is subject to <a href="$(LICENSE_URL)">license terms</a>.
# Workaround stylesheet bug
HEADER_STYLE := style="margin-top: 9px;"
else
HEADER_STYLE := style="margin-top: 14px;"
endif
JAVADOC_BOTTOM := \
@ -147,12 +164,19 @@ JAVADOC_BOTTOM := \
<a href="$(REDISTRIBUTION_URL)">documentation redistribution policy</a>. \
$(DRAFT_MARKER_STR) <!-- Version $(VERSION_STRING) -->
JAVADOC_TOP := \
<div style="padding: 6px; text-align: center; font-size: 80%; \
font-family: DejaVu Sans, Arial, Helvetica, sans-serif; \
font-weight: normal;">$(DRAFT_TEXT)</div>
JDK_INDEX_CONTENT := \
<!DOCTYPE html> \
<html lang="en"> \
<head> \
<meta http-equiv="refresh" content="0;url=api/index.html"> \
</head> \
</html>
################################################################################
# JDK javadoc titles/text snippets
@ -257,8 +281,14 @@ define SetupApiDocsGenerationBody
$1_JAVA_ARGS += -DenableModuleGraph=true
endif
# Always include tags and basic options
$1_OPTIONS := $$(JAVADOC_TAGS) $$(JAVADOC_OPTIONS)
# Start with basic options and tags
ifeq ($$($1_OPTIONS), )
$1_OPTIONS := $$(JAVADOC_OPTIONS)
endif
ifeq ($$($1_TAGS), )
$1_TAGS := $$(JAVADOC_TAGS)
endif
$1_OPTIONS += $$($1_TAGS)
$1_OPTIONS += --module-source-path $$(MODULES_SOURCE_PATH)
$1_OPTIONS += --module $$(call CommaList, $$($1_MODULES))
@ -267,15 +297,10 @@ define SetupApiDocsGenerationBody
$1_OPTIONS += -Xdoclint:all,$$(call CommaList, $$(addprefix -, \
$$(JAVADOC_DISABLED_DOCLINT)))
$1_DOC_TITLE := $$($1_LONG_NAME)<br>Version $$(VERSION_SPECIFICATION) API Specification
$1_WINDOW_TITLE := $$(subst &amp;,&,$$($1_SHORT_NAME)) \
$$(DRAFT_MARKER_TITLE)
ifeq ($(VERSION_IS_GA), true) # Workaround stylesheet bug
$1_HEADER_PAD := 14
else
$1_HEADER_PAD := 9
endif
$1_HEADER_TITLE := <div style="margin-top: $$($1_HEADER_PAD)px;"><strong>$$($1_SHORT_NAME)</strong> \
$1_DOC_TITLE := $$($1_LONG_NAME)<br>Version $$(VERSION_SPECIFICATION) API \
Specification
$1_WINDOW_TITLE := $$(subst &amp;,&,$$($1_SHORT_NAME)) $$(DRAFT_MARKER_TITLE)
$1_HEADER_TITLE := <div $$(HEADER_STYLE)><strong>$$($1_SHORT_NAME)</strong> \
$$(DRAFT_MARKER_STR)</div>
$1_OPTIONS += -doctitle '$$($1_DOC_TITLE)'
@ -302,8 +327,13 @@ define SetupApiDocsGenerationBody
$$(eval $1_OPTIONS += -group "$$($$g_GROUP_NAME)" "$$($$g_GROUP_MODULES)") \
)
ifeq ($$($1_JAVADOC_CMD), )
$1_JAVADOC_CMD := $$(JAVA) -Djava.awt.headless=true $$($1_JAVA_ARGS) \
$$(NEW_JAVADOC)
endif
$1_VARDEPS := $$($1_JAVA_ARGS) $$($1_OPTIONS) $$(MODULES_SOURCE_PATH) \
$$($1_ALL_MODULES)
$$($1_ALL_MODULES) $$($1_JAVADOC_CMD)
$1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, \
$$(SUPPORT_OUTPUTDIR)/docs/$1.vardeps)
@ -319,9 +349,8 @@ define SetupApiDocsGenerationBody
$$(call LogInfo, Javadoc modules: $$($1_ALL_MODULES))
$$(call MakeDir, $$($1_TARGET_DIR))
$$(call ExecuteWithLog, $$(SUPPORT_OUTPUTDIR)/docs/$1, \
$$(JAVA) -Djava.awt.headless=true $$($1_JAVA_ARGS) \
$$(NEW_JAVADOC) -d $$($1_TARGET_DIR) \
$$(JAVADOC_TAGS) $$($1_OPTIONS) $$($1_LOG_OPTION))
$$($1_JAVADOC_CMD) -d $$($1_TARGET_DIR) \
$$($1_OPTIONS) $$($1_LOG_OPTION))
$1_JAVADOC_TARGETS := $$($1_TARGET_DIR)/index.html
@ -430,19 +459,30 @@ $(eval $(call SetupApiDocsGeneration, JAVASE_API, \
# Targets generated are returned in JAVASE_API_JAVADOC_TARGETS and
# JAVASE_API_MODULEGRAPH_TARGETS.
################################################################################
# Setup generation of the reference Java SE API documentation (javadoc + modulegraph)
# The reference javadoc is just the same as javase, but using the BootJDK javadoc
# and a stable set of javadoc options.
$(eval $(call SetupApiDocsGeneration, REFERENCE_API, \
MODULES := $(JAVASE_MODULES), \
SHORT_NAME := $(JAVASE_SHORT_NAME), \
LONG_NAME := $(JAVASE_LONG_NAME), \
TARGET_DIR := $(IMAGES_OUTPUTDIR)/reference-docs/api, \
JAVADOC_CMD := $(JAVADOC), \
OPTIONS := $(REFERENCE_OPTIONS), \
TAGS := $(REFERENCE_TAGS), \
))
# Targets generated are returned in REFERENCE_API_JAVADOC_TARGETS and
# REFERENCE_API_MODULEGRAPH_TARGETS.
################################################################################
JDK_INDEX_HTML := $(DOCS_OUTPUTDIR)/index.html
JDK_INDEX_CONTENT := \
<!DOCTYPE html> \
<html lang="en"> \
<head> \
<meta http-equiv="refresh" content="0;url=api/index.html"> \
</head> \
</html>
$(JDK_INDEX_HTML):
$(JDK_INDEX_HTML):
$(ECHO) '$(JDK_INDEX_CONTENT)' > $@
JDK_INDEX_TARGETS += $(JDK_INDEX_HTML)
@ -553,6 +593,10 @@ docs-javase-api-javadoc: $(JAVASE_API_JAVADOC_TARGETS) $(JAVASE_API_CUSTOM_TARGE
docs-javase-api-modulegraph: $(JAVASE_API_MODULEGRAPH_TARGETS)
docs-reference-api-javadoc: $(REFERENCE_API_JAVADOC_TARGETS) $(REFERENCE_API_CUSTOM_TARGETS)
docs-reference-api-modulegraph: $(REFERENCE_API_MODULEGRAPH_TARGETS)
docs-jdk-specs: $(JDK_SPECS_TARGETS)
docs-jdk-index: $(JDK_INDEX_TARGETS)
@ -560,8 +604,10 @@ docs-jdk-index: $(JDK_INDEX_TARGETS)
docs-zip: $(ZIP_TARGETS)
all: docs-jdk-api-javadoc docs-jdk-api-modulegraph docs-javase-api-javadoc \
docs-javase-api-modulegraph docs-jdk-specs docs-jdk-index docs-zip
docs-javase-api-modulegraph docs-reference-api-javadoc \
docs-reference-api-modulegraph docs-jdk-specs docs-jdk-index docs-zip
.PHONY: default all docs-jdk-api-javadoc docs-jdk-api-modulegraph \
docs-javase-api-javadoc docs-javase-api-modulegraph docs-jdk-specs \
docs-javase-api-javadoc docs-javase-api-modulegraph \
docs-reference-api-javadoc docs-reference-api-modulegraph docs-jdk-specs \
docs-jdk-index docs-zip

@ -382,6 +382,12 @@ docs-javase-api-javadoc:
docs-javase-api-modulegraph:
+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-javase-api-modulegraph)
docs-reference-api-javadoc:
+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-reference-api-javadoc)
docs-reference-api-modulegraph:
+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-reference-api-modulegraph)
docs-jdk-specs:
+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-jdk-specs)
@ -395,7 +401,8 @@ update-build-docs:
+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f UpdateBuildDocs.gmk)
ALL_TARGETS += docs-jdk-api-javadoc docs-jdk-api-modulegraph \
docs-javase-api-javadoc docs-javase-api-modulegraph docs-jdk-specs \
docs-javase-api-javadoc docs-javase-api-modulegraph \
docs-reference-api-javadoc docs-reference-api-modulegraph docs-jdk-specs \
docs-jdk-index docs-zip update-build-docs
################################################################################
@ -810,10 +817,14 @@ else
docs-javase-api-javadoc: $(GENSRC_TARGETS) rmic
docs-reference-api-javadoc: $(GENSRC_TARGETS) rmic
docs-jdk-api-modulegraph: exploded-image buildtools-modules
docs-javase-api-modulegraph: exploded-image buildtools-modules
docs-reference-api-modulegraph: exploded-image buildtools-modules
# The gensrc steps for hotspot and jdk.jdi create html spec files.
docs-jdk-specs: hotspot-$(JVM_VARIANT_MAIN)-gensrc jdk.jdi-gensrc \
docs-jdk-index
@ -943,16 +954,19 @@ create-buildjdk: create-buildjdk-copy create-buildjdk-interim-image
docs-jdk-api: docs-jdk-api-javadoc
docs-javase-api: docs-javase-api-javadoc
docs-reference-api: docs-reference-api-javadoc
# If we're building full docs, we must also generate the module graphs to
# get non-broken api documentation.
ifeq ($(ENABLE_FULL_DOCS), true)
docs-jdk-api: docs-jdk-api-modulegraph
docs-javase-api: docs-javase-api-modulegraph
docs-reference-api: docs-reference-api-modulegraph
endif
docs-jdk: docs-jdk-api docs-jdk-specs docs-jdk-index
docs-javase: docs-javase-api
docs-reference: docs-reference-api
# alias for backwards compatibility
docs-javadoc: docs-jdk-api
@ -1005,8 +1019,8 @@ ALL_TARGETS += buildtools hotspot hotspot-libs hotspot-gensrc gensrc gendata \
copy java rmic libs launchers jmods \
jdk.jdwp.agent-gensrc $(ALL_MODULES) demos \
exploded-image-base exploded-image \
create-buildjdk docs-jdk-api docs-javase-api docs-jdk docs-javase \
docs-javadoc mac-bundles product-images \
create-buildjdk docs-jdk-api docs-javase-api docs-reference-api docs-jdk \
docs-javase docs-reference docs-javadoc mac-bundles product-images \
profiles profiles-images \
docs-image test-image all-images \
all-bundles

@ -296,6 +296,7 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK],
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVA, java)
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVAC, javac)
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVAH, javah)
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVADOC, javadoc)
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAR, jar)
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JARSIGNER, jarsigner)

@ -881,6 +881,7 @@ JAVAC_FLAGS
BOOT_JDK_SOURCETARGET
JARSIGNER
JAR
JAVADOC
JAVAH
JAVAC
JAVA
@ -1294,6 +1295,7 @@ PKG_CONFIG
JAVA
JAVAC
JAVAH
JAVADOC
JAR
JARSIGNER
CC
@ -2237,6 +2239,7 @@ Some influential environment variables:
JAVA Override default value for JAVA
JAVAC Override default value for JAVAC
JAVAH Override default value for JAVAH
JAVADOC Override default value for JAVADOC
JAR Override default value for JAR
JARSIGNER Override default value for JARSIGNER
CC C compiler command
@ -5114,7 +5117,7 @@ VS_SDK_PLATFORM_NAME_2013=
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
DATE_WHEN_GENERATED=1508497666
DATE_WHEN_GENERATED=1508746828
###############################################################################
#
@ -31169,6 +31172,144 @@ $as_echo "$tool_specified" >&6; }
# Use user overridden value if available, otherwise locate tool in the Boot JDK.
# Publish this variable in the help.
if [ -z "${JAVADOC+x}" ]; then
# The variable is not set by user, try to locate tool using the code snippet
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for javadoc in Boot JDK" >&5
$as_echo_n "checking for javadoc in Boot JDK... " >&6; }
JAVADOC=$BOOT_JDK/bin/javadoc
if test ! -x $JAVADOC; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
$as_echo "not found" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: Your Boot JDK seems broken. This might be fixed by explicitly setting --with-boot-jdk" >&5
$as_echo "$as_me: Your Boot JDK seems broken. This might be fixed by explicitly setting --with-boot-jdk" >&6;}
as_fn_error $? "Could not find javadoc in the Boot JDK" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
$as_echo "ok" >&6; }
else
# The variable is set, but is it from the command line or the environment?
# Try to remove the string !JAVADOC! from our list.
try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!JAVADOC!/}
if test "x$try_remove_var" = "x$CONFIGURE_OVERRIDDEN_VARIABLES"; then
# If it failed, the variable was not from the command line. Ignore it,
# but warn the user (except for BASH, which is always set by the calling BASH).
if test "xJAVADOC" != xBASH; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of JAVADOC from the environment. Use command line variables instead." >&5
$as_echo "$as_me: WARNING: Ignoring value of JAVADOC from the environment. Use command line variables instead." >&2;}
fi
# Try to locate tool using the code snippet
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for javadoc in Boot JDK" >&5
$as_echo_n "checking for javadoc in Boot JDK... " >&6; }
JAVADOC=$BOOT_JDK/bin/javadoc
if test ! -x $JAVADOC; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
$as_echo "not found" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: Your Boot JDK seems broken. This might be fixed by explicitly setting --with-boot-jdk" >&5
$as_echo "$as_me: Your Boot JDK seems broken. This might be fixed by explicitly setting --with-boot-jdk" >&6;}
as_fn_error $? "Could not find javadoc in the Boot JDK" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
$as_echo "ok" >&6; }
else
# If it succeeded, then it was overridden by the user. We will use it
# for the tool.
# First remove it from the list of overridden variables, so we can test
# for unknown variables in the end.
CONFIGURE_OVERRIDDEN_VARIABLES="$try_remove_var"
# Check if we try to supply an empty value
if test "x$JAVADOC" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool JAVADOC= (no value)" >&5
$as_echo "$as_me: Setting user supplied tool JAVADOC= (no value)" >&6;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for JAVADOC" >&5
$as_echo_n "checking for JAVADOC... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
$as_echo "disabled" >&6; }
else
# Check if the provided tool contains a complete path.
tool_specified="$JAVADOC"
tool_basename="${tool_specified##*/}"
if test "x$tool_basename" = "x$tool_specified"; then
# A command without a complete path is provided, search $PATH.
{ $as_echo "$as_me:${as_lineno-$LINENO}: Will search for user supplied tool JAVADOC=$tool_basename" >&5
$as_echo "$as_me: Will search for user supplied tool JAVADOC=$tool_basename" >&6;}
# Extract the first word of "$tool_basename", so it can be a program name with args.
set dummy $tool_basename; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_JAVADOC+:} false; then :
$as_echo_n "(cached) " >&6
else
case $JAVADOC in
[\\/]* | ?:[\\/]*)
ac_cv_path_JAVADOC="$JAVADOC" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_JAVADOC="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
JAVADOC=$ac_cv_path_JAVADOC
if test -n "$JAVADOC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVADOC" >&5
$as_echo "$JAVADOC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test "x$JAVADOC" = x; then
as_fn_error $? "User supplied tool $tool_basename could not be found" "$LINENO" 5
fi
else
# Otherwise we believe it is a complete path. Use it as it is.
{ $as_echo "$as_me:${as_lineno-$LINENO}: Will use user supplied tool JAVADOC=$tool_specified" >&5
$as_echo "$as_me: Will use user supplied tool JAVADOC=$tool_specified" >&6;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for JAVADOC" >&5
$as_echo_n "checking for JAVADOC... " >&6; }
if test ! -x "$tool_specified"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
$as_echo "not found" >&6; }
as_fn_error $? "User supplied tool JAVADOC=$tool_specified does not exist or is not executable" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tool_specified" >&5
$as_echo "$tool_specified" >&6; }
fi
fi
fi
fi
# Use user overridden value if available, otherwise locate tool in the Boot JDK.
# Publish this variable in the help.

@ -532,6 +532,7 @@ SJAVAC_SERVER_JAVA_FLAGS:=@SJAVAC_SERVER_JAVA_FLAGS@
JAVA_CMD:=@JAVA@
JAVAC_CMD:=@JAVAC@
JAVAH_CMD:=@JAVAH@
JAVADOC_CMD:=@JAVADOC@
JAR_CMD:=@JAR@
JLINK_CMD := @JLINK@
JMOD_CMD := @JMOD@
@ -544,6 +545,7 @@ JAVA_SMALL=@FIXPATH@ $(JAVA_CMD) $(JAVA_FLAGS_SMALL) $(JAVA_FLAGS)
JAVA_JAVAC=@FIXPATH@ $(JAVA_CMD) $(JAVA_FLAGS_JAVAC) $(JAVA_FLAGS)
JAVAC=@FIXPATH@ $(JAVAC_CMD)
JAVAH=@FIXPATH@ $(JAVAH_CMD)
JAVADOC=@FIXPATH@ $(JAVADOC_CMD)
JAR=@FIXPATH@ $(JAR_CMD)
JLINK = @FIXPATH@ $(JLINK_CMD) $(JAVA_TOOL_FLAGS_SMALL)
JMOD = @FIXPATH@ $(JMOD_CMD) $(JAVA_TOOL_FLAGS_SMALL)

@ -737,6 +737,7 @@ define AddFileToCopy
$$($$(strip $4))
$3 += $2
$3_SOURCES += $1
endef
# Returns the value of the first argument
@ -749,6 +750,8 @@ identity = \
# Parameter 1 is the name of the rule. This name is used as variable prefix,
# and the targets generated are listed in a variable by that name.
#
# The list of all source files is returned in $1_SOURCES.
#
# Remaining parameters are named arguments. These include:
# SRC : Source root dir (defaults to dir of first file)
# DEST : Dest root dir

@ -998,7 +998,7 @@ var getJibProfilesProfiles = function (input, common, data) {
var getJibProfilesDependencies = function (input, common) {
var devkit_platform_revisions = {
linux_x64: "gcc4.9.2-OEL6.4+1.1",
linux_x64: "gcc4.9.2-OEL6.4+1.2",
macosx_x64: "Xcode6.3-MacOSX10.9+1.0",
solaris_x64: "SS12u4-Solaris11u1+1.0",
solaris_sparcv9: "SS12u4-Solaris11u1+1.0",

@ -84,7 +84,8 @@ RPM_LIST := \
libXau libXau-devel \
libgcc \
zlib zlib-devel \
libffi libffi-devel
libffi libffi-devel \
fontconfig fontconfig-devel
ifeq ($(ARCH),x86_64)
RPM_DIR ?= $(RPM_DIR_x86_64)

@ -1,5 +1,5 @@
#
# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -63,7 +63,7 @@ endif
define generate-preproc-src
$(call MakeDir, $(@D))
( $(NAWK) '/@@END_COPYRIGHT@@/{exit}1' $< && \
$(CPP) $(CPP_FLAGS) $(SYSROOT_CFLAGS) $< \
$(CPP) $(CPP_FLAGS) $(SYSROOT_CFLAGS) $(CFLAGS_JDKLIB) $< \
2> >($(GREP) -v '^$(<F)$$' >&2) \
| $(NAWK) '/@@START_HERE@@/,0' \
| $(SED) -e 's/@@START_HERE@@/\/\/ AUTOMATICALLY GENERATED FILE - DO NOT EDIT/' \

@ -180,7 +180,8 @@ jprt.test.bundle.targets=\
${my.make.rule.test.targets.hotspot.reg}, \
${my.make.rule.test.targets.hotspot.gtest} \
${my.make.rule.test.targets.nativesanity} \
${my.test.target.set:TESTNAME=jdk_lang}
${my.test.target.set:TESTNAME=jdk_lang} \
${my.test.target.set:TESTNAME=jdk_nio}
# 7155453: Work-around to prevent popups on OSX from blocking test completion
# but the work-around is added to all platforms to be consistent

@ -75,6 +75,7 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_FileDispatcherImpl_truncate0;
Java_sun_nio_ch_FileDispatcherImpl_write0;
Java_sun_nio_ch_FileDispatcherImpl_writev0;
Java_sun_nio_ch_FileDispatcherImpl_setDirect0;
Java_sun_nio_ch_FileKey_init;
Java_sun_nio_ch_FileKey_initIDs;
Java_sun_nio_ch_InheritedChannel_close0;

@ -63,6 +63,7 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_FileDispatcherImpl_truncate0;
Java_sun_nio_ch_FileDispatcherImpl_write0;
Java_sun_nio_ch_FileDispatcherImpl_writev0;
Java_sun_nio_ch_FileDispatcherImpl_setDirect0;
Java_sun_nio_ch_FileKey_init;
Java_sun_nio_ch_FileKey_initIDs;
Java_sun_nio_ch_InheritedChannel_close0;

@ -47,6 +47,10 @@ BUILD_JDK_JTREG_NATIVE_SRC += \
$(TOPDIR)/test/jdk/java/lang/String/nativeEncoding \
#
ifneq ($(OPENJDK_TARGET_OS), windows)
BUILD_JDK_JTREG_NATIVE_SRC += $(TOPDIR)/test/jdk/java/nio/channels/FileChannel/directio
endif
BUILD_JDK_JTREG_OUTPUT_DIR := $(OUTPUTDIR)/support/test/jdk/jtreg/native
BUILD_JDK_JTREG_IMAGE_DIR := $(TEST_IMAGE_DIR)/jdk/jtreg
@ -56,8 +60,10 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := $(WIN_LIB_JAVA)
else ifeq ($(OPENJDK_TARGET_OS), solaris)
BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := -ljava -lc
BUILD_JDK_JTREG_LIBRARIES_LIBS_libDirectIO := -ljava -lc
else
BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := -ljava
BUILD_JDK_JTREG_LIBRARIES_LIBS_libDirectIO := -ljava
endif
$(eval $(call SetupTestFilesCompilation, BUILD_JDK_JTREG_LIBRARIES, \

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -111,6 +111,31 @@ public abstract class FileStore {
*/
public abstract long getUsableSpace() throws IOException;
/**
* Returns the number of bytes per block in this file store.
*
* <p> File storage is typically organized into discrete sequences of bytes
* called <i>blocks</i>. A block is the smallest storage unit of a file store.
* Every read and write operation is performed on a multiple of blocks.
*
* @implSpec The implementation in this class throws an
* {@code UnsupportedOperationException}.
*
* @return a positive value representing the block size of this file store,
* in bytes
*
* @throws IOException
* if an I/O error occurs
*
* @throws UnsupportedOperationException
* if the operation is not supported
*
* @since 10
*/
public long getBlockSize() throws IOException {
throw new UnsupportedOperationException();
}
/**
* Returns the number of unallocated bytes in the file store.
*

@ -41,6 +41,11 @@ import java.nio.channels.OverlappingFileLockException;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SelectableChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.file.Files;
import java.nio.file.FileStore;
import java.nio.file.FileSystemException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
@ -87,6 +92,12 @@ public class FileChannelImpl
// Positional-read is not interruptible
private volatile boolean uninterruptible;
// DirectIO flag
private final boolean direct;
// IO alignment value for DirectIO
private final int alignment;
// Cleanable with an action which closes this channel's file descriptor
private final Cleanable closer;
@ -103,14 +114,22 @@ public class FileChannelImpl
}
private FileChannelImpl(FileDescriptor fd, String path, boolean readable,
boolean writable, Object parent)
boolean writable, boolean direct, Object parent)
{
this.fd = fd;
this.readable = readable;
this.writable = writable;
this.parent = parent;
this.path = path;
this.direct = direct;
this.nd = new FileDispatcherImpl();
if (direct) {
assert path != null;
this.alignment = nd.setDirectIO(fd, path);
} else {
this.alignment = -1;
}
// Register a cleaning action if and only if there is no parent
// as the parent will take care of closing the file descriptor.
// FileChannel is used by the LambdaMetaFactory so a lambda cannot
@ -125,7 +144,14 @@ public class FileChannelImpl
boolean readable, boolean writable,
Object parent)
{
return new FileChannelImpl(fd, path, readable, writable, parent);
return new FileChannelImpl(fd, path, readable, writable, false, parent);
}
public static FileChannel open(FileDescriptor fd, String path,
boolean readable, boolean writable,
boolean direct, Object parent)
{
return new FileChannelImpl(fd, path, readable, writable, direct, parent);
}
private void ensureOpen() throws IOException {
@ -181,6 +207,8 @@ public class FileChannelImpl
if (!readable)
throw new NonReadableChannelException();
synchronized (positionLock) {
if (direct)
Util.checkChannelPositionAligned(position(), alignment);
int n = 0;
int ti = -1;
try {
@ -189,7 +217,7 @@ public class FileChannelImpl
if (!isOpen())
return 0;
do {
n = IOUtil.read(fd, dst, -1, nd);
n = IOUtil.read(fd, dst, -1, direct, alignment, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
@ -209,6 +237,8 @@ public class FileChannelImpl
if (!readable)
throw new NonReadableChannelException();
synchronized (positionLock) {
if (direct)
Util.checkChannelPositionAligned(position(), alignment);
long n = 0;
int ti = -1;
try {
@ -217,7 +247,8 @@ public class FileChannelImpl
if (!isOpen())
return 0;
do {
n = IOUtil.read(fd, dsts, offset, length, nd);
n = IOUtil.read(fd, dsts, offset, length,
direct, alignment, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
@ -233,6 +264,8 @@ public class FileChannelImpl
if (!writable)
throw new NonWritableChannelException();
synchronized (positionLock) {
if (direct)
Util.checkChannelPositionAligned(position(), alignment);
int n = 0;
int ti = -1;
try {
@ -241,7 +274,7 @@ public class FileChannelImpl
if (!isOpen())
return 0;
do {
n = IOUtil.write(fd, src, -1, nd);
n = IOUtil.write(fd, src, -1, direct, alignment, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
@ -261,6 +294,8 @@ public class FileChannelImpl
if (!writable)
throw new NonWritableChannelException();
synchronized (positionLock) {
if (direct)
Util.checkChannelPositionAligned(position(), alignment);
long n = 0;
int ti = -1;
try {
@ -269,7 +304,8 @@ public class FileChannelImpl
if (!isOpen())
return 0;
do {
n = IOUtil.write(fd, srcs, offset, length, nd);
n = IOUtil.write(fd, srcs, offset, length,
direct, alignment, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
@ -752,6 +788,8 @@ public class FileChannelImpl
throw new IllegalArgumentException("Negative position");
if (!readable)
throw new NonReadableChannelException();
if (direct)
Util.checkChannelPositionAligned(position, alignment);
ensureOpen();
if (nd.needsPositionLock()) {
synchronized (positionLock) {
@ -774,7 +812,7 @@ public class FileChannelImpl
if (!isOpen())
return -1;
do {
n = IOUtil.read(fd, dst, position, nd);
n = IOUtil.read(fd, dst, position, direct, alignment, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
@ -791,6 +829,8 @@ public class FileChannelImpl
throw new IllegalArgumentException("Negative position");
if (!writable)
throw new NonWritableChannelException();
if (direct)
Util.checkChannelPositionAligned(position, alignment);
ensureOpen();
if (nd.needsPositionLock()) {
synchronized (positionLock) {
@ -811,7 +851,7 @@ public class FileChannelImpl
if (!isOpen())
return -1;
do {
n = IOUtil.write(fd, src, position, nd);
n = IOUtil.write(fd, src, position, direct, alignment, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -61,4 +61,6 @@ abstract class FileDispatcher extends NativeDispatcher {
abstract boolean canTransferToDirectly(SelectableChannel sc);
abstract boolean transferToDirectlyNeedsPositionLock();
abstract int setDirectIO(FileDescriptor fd, String path);
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -47,22 +47,38 @@ public class IOUtil {
NativeDispatcher nd)
throws IOException
{
if (src instanceof DirectBuffer)
return writeFromNativeBuffer(fd, src, position, nd);
return write(fd, src, position, false, -1, nd);
}
static int write(FileDescriptor fd, ByteBuffer src, long position,
boolean directIO, int alignment, NativeDispatcher nd)
throws IOException
{
if (src instanceof DirectBuffer) {
return writeFromNativeBuffer(fd, src, position,
directIO, alignment, nd);
}
// Substitute a native buffer
int pos = src.position();
int lim = src.limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
ByteBuffer bb;
if (directIO) {
Util.checkRemainingBufferSizeAligned(rem, alignment);
bb = Util.getTemporaryAlignedDirectBuffer(rem, alignment);
} else {
bb = Util.getTemporaryDirectBuffer(rem);
}
try {
bb.put(src);
bb.flip();
// Do not update src until we see how many bytes were written
src.position(pos);
int n = writeFromNativeBuffer(fd, bb, position, nd);
int n = writeFromNativeBuffer(fd, bb, position,
directIO, alignment, nd);
if (n > 0) {
// now update src
src.position(pos + n);
@ -74,7 +90,8 @@ public class IOUtil {
}
private static int writeFromNativeBuffer(FileDescriptor fd, ByteBuffer bb,
long position, NativeDispatcher nd)
long position, boolean directIO,
int alignment, NativeDispatcher nd)
throws IOException
{
int pos = bb.position();
@ -82,6 +99,11 @@ public class IOUtil {
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
if (directIO) {
Util.checkBufferPositionAligned(bb, pos, alignment);
Util.checkRemainingBufferSizeAligned(rem, alignment);
}
int written = 0;
if (rem == 0)
return 0;
@ -100,12 +122,19 @@ public class IOUtil {
static long write(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
throws IOException
{
return write(fd, bufs, 0, bufs.length, nd);
return write(fd, bufs, 0, bufs.length, false, -1, nd);
}
static long write(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
NativeDispatcher nd)
throws IOException
{
return write(fd, bufs, offset, length, false, -1, nd);
}
static long write(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
boolean directIO, int alignment, NativeDispatcher nd)
throws IOException
{
IOVecWrapper vec = IOVecWrapper.get(length);
@ -122,12 +151,20 @@ public class IOUtil {
int lim = buf.limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
if (directIO)
Util.checkRemainingBufferSizeAligned(rem, alignment);
if (rem > 0) {
vec.setBuffer(iov_len, buf, pos, rem);
// allocate shadow buffer to ensure I/O is done with direct buffer
if (!(buf instanceof DirectBuffer)) {
ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
ByteBuffer shadow;
if (directIO)
shadow = Util.getTemporaryAlignedDirectBuffer(rem,
alignment);
else
shadow = Util.getTemporaryDirectBuffer(rem);
shadow.put(buf);
shadow.flip();
vec.setShadow(iov_len, shadow);
@ -185,16 +222,33 @@ public class IOUtil {
static int read(FileDescriptor fd, ByteBuffer dst, long position,
NativeDispatcher nd)
throws IOException
{
return read(fd, dst, position, false, -1, nd);
}
static int read(FileDescriptor fd, ByteBuffer dst, long position,
boolean directIO, int alignment, NativeDispatcher nd)
throws IOException
{
if (dst.isReadOnly())
throw new IllegalArgumentException("Read-only buffer");
if (dst instanceof DirectBuffer)
return readIntoNativeBuffer(fd, dst, position, nd);
return readIntoNativeBuffer(fd, dst, position,
directIO, alignment, nd);
// Substitute a native buffer
ByteBuffer bb = Util.getTemporaryDirectBuffer(dst.remaining());
ByteBuffer bb;
int rem = dst.remaining();
if (directIO) {
Util.checkRemainingBufferSizeAligned(rem, alignment);
bb = Util.getTemporaryAlignedDirectBuffer(rem,
alignment);
} else {
bb = Util.getTemporaryDirectBuffer(rem);
}
try {
int n = readIntoNativeBuffer(fd, bb, position, nd);
int n = readIntoNativeBuffer(fd, bb, position,
directIO, alignment,nd);
bb.flip();
if (n > 0)
dst.put(bb);
@ -205,7 +259,8 @@ public class IOUtil {
}
private static int readIntoNativeBuffer(FileDescriptor fd, ByteBuffer bb,
long position, NativeDispatcher nd)
long position, boolean directIO,
int alignment, NativeDispatcher nd)
throws IOException
{
int pos = bb.position();
@ -213,6 +268,11 @@ public class IOUtil {
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
if (directIO) {
Util.checkBufferPositionAligned(bb, pos, alignment);
Util.checkRemainingBufferSizeAligned(rem, alignment);
}
if (rem == 0)
return 0;
int n = 0;
@ -230,12 +290,19 @@ public class IOUtil {
static long read(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
throws IOException
{
return read(fd, bufs, 0, bufs.length, nd);
return read(fd, bufs, 0, bufs.length, false, -1, nd);
}
static long read(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
NativeDispatcher nd)
throws IOException
{
return read(fd, bufs, offset, bufs.length, false, -1, nd);
}
static long read(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
boolean directIO, int alignment, NativeDispatcher nd)
throws IOException
{
IOVecWrapper vec = IOVecWrapper.get(length);
@ -255,12 +322,21 @@ public class IOUtil {
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
if (directIO)
Util.checkRemainingBufferSizeAligned(rem, alignment);
if (rem > 0) {
vec.setBuffer(iov_len, buf, pos, rem);
// allocate shadow buffer to ensure I/O is done with direct buffer
if (!(buf instanceof DirectBuffer)) {
ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
ByteBuffer shadow;
if (directIO) {
shadow = Util.getTemporaryAlignedDirectBuffer(rem,
alignment);
} else {
shadow = Util.getTemporaryDirectBuffer(rem);
}
vec.setShadow(iov_len, shadow);
buf = shadow;
pos = shadow.position();

@ -37,7 +37,7 @@ import java.util.Iterator;
import java.util.Set;
import jdk.internal.misc.Unsafe;
import sun.security.action.GetPropertyAction;
import java.io.IOException;
public class Util {
@ -236,6 +236,33 @@ public class Util {
}
}
/**
* Returns a temporary buffer of at least the given size and
* aligned to the alignment
*/
public static ByteBuffer getTemporaryAlignedDirectBuffer(int size,
int alignment) {
if (isBufferTooLarge(size)) {
return ByteBuffer.allocateDirect(size + alignment - 1)
.alignedSlice(alignment);
}
BufferCache cache = bufferCache.get();
ByteBuffer buf = cache.get(size);
if (buf != null) {
if (buf.alignmentOffset(0, alignment) == 0) {
return buf;
}
} else {
if (!cache.isEmpty()) {
buf = cache.removeFirst();
free(buf);
}
}
return ByteBuffer.allocateDirect(size + alignment - 1)
.alignedSlice(alignment);
}
/**
* Releases a temporary buffer by returning to the cache or freeing it.
*/
@ -459,4 +486,37 @@ public class Util {
}
return dbb;
}
static void checkBufferPositionAligned(ByteBuffer bb,
int pos, int alignment)
throws IOException
{
if (bb.alignmentOffset(pos, alignment) != 0) {
throw new IOException("Current location of the bytebuffer ("
+ pos + ") is not a multiple of the block size ("
+ alignment + ")");
}
}
static void checkRemainingBufferSizeAligned(int rem,
int alignment)
throws IOException
{
if (rem % alignment != 0) {
throw new IOException("Number of remaining bytes ("
+ rem + ") is not a multiple of the block size ("
+ alignment + ")");
}
}
static void checkChannelPositionAligned(long position,
int alignment)
throws IOException
{
if (position % alignment != 0) {
throw new IOException("Channel position (" + position
+ ") is not a multiple of the block size ("
+ alignment + ")");
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -137,6 +137,8 @@ public final class ExtendedOptions {
public static final InternalOption<Void> FILE_TREE = new InternalOption<>();
public static final InternalOption<Void> DIRECT = new InternalOption<>();
public static final InternalOption<Integer> SENSITIVITY_HIGH = new InternalOption<>();
public static final InternalOption<Integer> SENSITIVITY_MEDIUM = new InternalOption<>();
public static final InternalOption<Integer> SENSITIVITY_LOW = new InternalOption<>();

@ -57,21 +57,22 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable {
public Object invoke(Object proxy, Method method, Object[] args) {
String member = method.getName();
Class<?>[] paramTypes = method.getParameterTypes();
int parameterCount = method.getParameterCount();
// Handle Object and Annotation methods
if (member.equals("equals") && paramTypes.length == 1 &&
paramTypes[0] == Object.class)
if (parameterCount == 1 && member == "equals" &&
method.getParameterTypes()[0] == Object.class) {
return equalsImpl(proxy, args[0]);
if (paramTypes.length != 0)
}
if (parameterCount != 0) {
throw new AssertionError("Too many parameters for an annotation method");
}
switch(member) {
case "toString":
if (member == "toString") {
return toStringImpl();
case "hashCode":
} else if (member == "hashCode") {
return hashCodeImpl();
case "annotationType":
} else if (member == "annotationType") {
return type;
}

@ -122,6 +122,17 @@ class FileDispatcherImpl extends FileDispatcher {
return false;
}
int setDirectIO(FileDescriptor fd, String path) {
int result = -1;
try {
result = setDirect0(fd);
} catch (IOException e) {
throw new UnsupportedOperationException
("Error setting up DirectIO", e);
}
return result;
}
// -- Native methods --
static native int read0(FileDescriptor fd, long address, int len)
@ -167,6 +178,8 @@ class FileDispatcherImpl extends FileDispatcher {
static native void closeIntFD(int fd) throws IOException;
static native int setDirect0(FileDescriptor fd) throws IOException;
static native void init();
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -64,6 +64,7 @@ class UnixChannelFactory {
boolean deleteOnClose;
boolean sync;
boolean dsync;
boolean direct;
static Flags toFlags(Set<? extends OpenOption> options) {
Flags flags = new Flags();
@ -88,6 +89,12 @@ class UnixChannelFactory {
flags.noFollowLinks = true;
continue;
}
if (ExtendedOptions.DIRECT.matches(option)) {
flags.direct = true;
continue;
}
if (option == null)
throw new NullPointerException();
throw new UnsupportedOperationException(option + " not supported");
@ -134,7 +141,8 @@ class UnixChannelFactory {
throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
FileDescriptor fdObj = open(dfd, path, pathForPermissionCheck, flags, mode);
return FileChannelImpl.open(fdObj, path.toString(), flags.read, flags.write, null);
return FileChannelImpl.open(fdObj, path.toString(), flags.read,
flags.write, flags.direct, null);
}
/**
@ -235,6 +243,8 @@ class UnixChannelFactory {
oflags |= O_DSYNC;
if (flags.sync)
oflags |= O_SYNC;
if (flags.direct)
oflags |= O_DIRECT;
// permission check before we open the file
SecurityManager sm = System.getSecurityManager();

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -70,6 +70,12 @@ class UnixConstants {
static final int PREFIX_O_NOFOLLOW = 00;
#endif
#ifdef O_DIRECT
static final int PREFIX_O_DIRECT = O_DIRECT;
#else
// not supported (dummy values will not be used at runtime).
static final int PREFIX_O_DIRECT = 00;
#endif
static final int PREFIX_S_IAMB =
(S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH);

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -125,6 +125,12 @@ abstract class UnixFileStore
return attrs.blockSize() * attrs.availableBlocks();
}
@Override
public long getBlockSize() throws IOException {
UnixFileStoreAttributes attrs = readAttributes();
return attrs.blockSize();
}
@Override
public long getUnallocatedSpace() throws IOException {
UnixFileStoreAttributes attrs = readAttributes();

@ -50,7 +50,7 @@
#define mmap64 mmap
#endif
static jfieldID chan_fd; /* jobject 'fd' in sun.io.FileChannelImpl */
static jfieldID chan_fd; /* jobject 'fd' in sun.nio.ch.FileChannelImpl */
JNIEXPORT jlong JNICALL
Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)

@ -34,6 +34,7 @@
#include <fcntl.h>
#include <sys/uio.h>
#include <unistd.h>
#include <sys/statvfs.h>
#if defined(__linux__)
#include <linux/fs.h>
#include <sys/ioctl.h>
@ -323,3 +324,58 @@ Java_sun_nio_ch_FileDispatcherImpl_closeIntFD(JNIEnv *env, jclass clazz, jint fd
{
closeFileDescriptor(env, fd);
}
JNIEXPORT jint JNICALL
Java_sun_nio_ch_FileDispatcherImpl_setDirect0(JNIEnv *env, jclass clazz,
jobject fdo)
{
jint fd = fdval(env, fdo);
jint result;
#ifdef MACOSX
struct statvfs file_stat;
#else
struct statvfs64 file_stat;
#endif
#if defined(O_DIRECT) || defined(F_NOCACHE) || defined(DIRECTIO_ON)
#ifdef O_DIRECT
jint orig_flag;
orig_flag = fcntl(fd, F_GETFL);
if (orig_flag == -1) {
JNU_ThrowIOExceptionWithLastError(env, "DirectIO setup failed");
return -1;
}
result = fcntl(fd, F_SETFL, orig_flag | O_DIRECT);
if (result == -1) {
JNU_ThrowIOExceptionWithLastError(env, "DirectIO setup failed");
return result;
}
#elif F_NOCACHE
result = fcntl(fd, F_NOCACHE, 1);
if (result == -1) {
JNU_ThrowIOExceptionWithLastError(env, "DirectIO setup failed");
return result;
}
#elif DIRECTIO_ON
result = directio(fd, DIRECTIO_ON);
if (result == -1) {
JNU_ThrowIOExceptionWithLastError(env, "DirectIO setup failed");
return result;
}
#endif
#ifdef MACOSX
result = fstatvfs(fd, &file_stat);
#else
result = fstatvfs64(fd, &file_stat);
#endif
if(result == -1) {
JNU_ThrowIOExceptionWithLastError(env, "DirectIO setup failed");
return result;
} else {
result = (int)file_stat.f_frsize;
}
#else
result == -1;
#endif
return result;
}

@ -30,6 +30,8 @@ import java.io.IOException;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.JavaIOFileDescriptorAccess;
import sun.security.action.GetPropertyAction;
import java.io.File;
import java.nio.CharBuffer;
class FileDispatcherImpl extends FileDispatcher {
@ -123,6 +125,21 @@ class FileDispatcherImpl extends FileDispatcher {
return true;
}
int setDirectIO(FileDescriptor fd, String path)
{
int result = -1;
String filePath = path.substring(0, path.lastIndexOf(File.separator));
CharBuffer buffer = CharBuffer.allocate(filePath.length());
buffer.put(filePath);
try {
result = setDirect0(fd, buffer);
} catch (IOException e) {
throw new UnsupportedOperationException
("Error setting up DirectIO", e);
}
return result;
}
static boolean isFastFileTransferRequested() {
String fileTransferProp = GetPropertyAction
.privilegedGetProperty("jdk.nio.enableFastFileTransfer");
@ -177,4 +194,6 @@ class FileDispatcherImpl extends FileDispatcher {
static native void close0(FileDescriptor fd) throws IOException;
static native long duplicateHandle(long fd) throws IOException;
static native int setDirect0(FileDescriptor fd, CharBuffer buffer) throws IOException;
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -74,6 +74,7 @@ class WindowsChannelFactory {
boolean overlapped;
boolean sync;
boolean dsync;
boolean direct;
// non-standard
boolean shareRead = true;
@ -121,6 +122,10 @@ class WindowsChannelFactory {
flags.shareDelete = false;
continue;
}
if (ExtendedOptions.DIRECT.matches(option)) {
flags.direct = true;
continue;
}
if (option == null)
throw new NullPointerException();
throw new UnsupportedOperationException();
@ -161,7 +166,8 @@ class WindowsChannelFactory {
throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
FileDescriptor fdObj = open(pathForWindows, pathToCheck, flags, pSecurityDescriptor);
return FileChannelImpl.open(fdObj, pathForWindows, flags.read, flags.write, null);
return FileChannelImpl.open(fdObj, pathForWindows, flags.read,
flags.write, flags.direct, null);
}
/**

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -125,7 +125,7 @@ class WindowsFileStore
}
// read the free space info
private DiskFreeSpace readDiskFreeSpace() throws IOException {
private DiskFreeSpace readDiskFreeSpaceEx() throws IOException {
try {
return GetDiskFreeSpaceEx(root);
} catch (WindowsException x) {
@ -134,19 +134,32 @@ class WindowsFileStore
}
}
private DiskFreeSpace readDiskFreeSpace() throws IOException {
try {
return GetDiskFreeSpace(root);
} catch (WindowsException x) {
x.rethrowAsIOException(root);
return null;
}
}
@Override
public long getTotalSpace() throws IOException {
return readDiskFreeSpace().totalNumberOfBytes();
return readDiskFreeSpaceEx().totalNumberOfBytes();
}
@Override
public long getUsableSpace() throws IOException {
return readDiskFreeSpace().freeBytesAvailable();
return readDiskFreeSpaceEx().freeBytesAvailable();
}
public long getBlockSize() throws IOException {
return readDiskFreeSpace().bytesPerSector();
}
@Override
public long getUnallocatedSpace() throws IOException {
return readDiskFreeSpace().freeBytesAvailable();
return readDiskFreeSpaceEx().freeBytesAvailable();
}
@Override
@ -165,6 +178,8 @@ class WindowsFileStore
return getUsableSpace();
if (attribute.equals("unallocatedSpace"))
return getUnallocatedSpace();
if (attribute.equals("bytesPerSector"))
return getBlockSize();
// windows specific for testing purposes
if (attribute.equals("volume:vsn"))
return volInfo.volumeSerialNumber();

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -485,21 +485,50 @@ class WindowsNativeDispatcher {
buffer.release();
}
}
/**
* GetDiskFreeSpace(
* LPCTSTR lpRootPathName,
* LPDWORD lpSectorsPerCluster,
* LPDWORD lpBytesPerSector,
* LPDWORD lpNumberOfFreeClusters,
* LPDWORD lpTotalNumberOfClusters
* )
*/
static DiskFreeSpace GetDiskFreeSpace(String path)
throws WindowsException
{
NativeBuffer buffer = asNativeBuffer(path);
try {
DiskFreeSpace space = new DiskFreeSpace();
GetDiskFreeSpace0(buffer.address(), space);
return space;
} finally {
buffer.release();
}
}
static class DiskFreeSpace {
private long freeBytesAvailable;
private long totalNumberOfBytes;
private long totalNumberOfFreeBytes;
private long bytesPerSector;
private DiskFreeSpace() { }
public long freeBytesAvailable() { return freeBytesAvailable; }
public long totalNumberOfBytes() { return totalNumberOfBytes; }
public long totalNumberOfFreeBytes() { return totalNumberOfFreeBytes; }
public long bytesPerSector() { return bytesPerSector; }
}
private static native void GetDiskFreeSpaceEx0(long lpDirectoryName,
DiskFreeSpace obj)
throws WindowsException;
private static native void GetDiskFreeSpace0(long lpRootPathName,
DiskFreeSpace obj)
throws WindowsException;
/**
* GetVolumePathName(
* LPCTSTR lpszFileName,

@ -456,3 +456,33 @@ Java_sun_nio_ch_FileDispatcherImpl_duplicateHandle(JNIEnv *env, jclass this, jlo
JNU_ThrowIOExceptionWithLastError(env, "DuplicateHandle failed");
return ptr_to_jlong(hResult);
}
JNIEXPORT jint JNICALL
Java_sun_nio_ch_FileDispatcherImpl_setDirect0(JNIEnv *env, jclass this,
jobject fdObj, jobject buffer)
{
jint result = -1;
HANDLE orig = (HANDLE)(handleval(env, fdObj));
HANDLE modify = ReOpenFile(orig, 0, 0,
FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH);
if (modify != INVALID_HANDLE_VALUE) {
DWORD sectorsPerCluster;
DWORD bytesPerSector;
DWORD numberOfFreeClusters;
DWORD totalNumberOfClusters;
LPCWSTR lpRootPathName = (*env)->GetDirectBufferAddress(env, buffer);
BOOL res = GetDiskFreeSpaceW(lpRootPathName,
&sectorsPerCluster,
&bytesPerSector,
&numberOfFreeClusters,
&totalNumberOfClusters);
if (res == 0) {
JNU_ThrowIOExceptionWithLastError(env, "DirectIO setup failed");
}
result = bytesPerSector;
}
return result;
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -59,6 +59,8 @@ static jfieldID diskSpace_bytesAvailable;
static jfieldID diskSpace_totalBytes;
static jfieldID diskSpace_totalFree;
static jfieldID diskSpace_bytesPerSector;
static jfieldID account_domain;
static jfieldID account_name;
static jfieldID account_use;
@ -121,6 +123,8 @@ Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
CHECK_NULL(diskSpace_totalBytes);
diskSpace_totalFree = (*env)->GetFieldID(env, clazz, "totalNumberOfFreeBytes", "J");
CHECK_NULL(diskSpace_totalFree);
diskSpace_bytesPerSector = (*env)->GetFieldID(env, clazz, "bytesPerSector", "J");
CHECK_NULL(diskSpace_bytesPerSector);
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$Account");
CHECK_NULL(clazz);
@ -582,6 +586,30 @@ Java_sun_nio_fs_WindowsNativeDispatcher_GetDiskFreeSpaceEx0(JNIEnv* env, jclass
long_to_jlong(totalNumberOfFreeBytes.QuadPart));
}
JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetDiskFreeSpace0(JNIEnv* env, jclass this,
jlong address, jobject obj)
{
DWORD sectorsPerCluster;
DWORD bytesPerSector;
DWORD numberOfFreeClusters;
DWORD totalNumberOfClusters;
LPCWSTR lpRootPathName = jlong_to_ptr(address);
BOOL res = GetDiskFreeSpaceW(lpRootPathName,
&sectorsPerCluster,
&bytesPerSector,
&numberOfFreeClusters,
&totalNumberOfClusters);
if (res == 0) {
throwWindowsException(env, GetLastError());
return;
}
(*env)->SetLongField(env, obj, diskSpace_bytesPerSector,
long_to_jlong(bytesPerSector));
}
JNIEXPORT jstring JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetVolumePathName0(JNIEnv* env, jclass this,

@ -3584,7 +3584,7 @@ public class Check {
private boolean isCanonical(JCTree tree) {
while (tree.hasTag(SELECT)) {
JCFieldAccess s = (JCFieldAccess) tree;
if (s.sym.owner.name != TreeInfo.symbol(s.selected).name)
if (s.sym.owner.getQualifiedName() != TreeInfo.symbol(s.selected).getQualifiedName())
return false;
tree = s.selected;
}

@ -2136,7 +2136,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
// Similar to getProtoSwitchPoints method above, but used for additional prototype switchpoints of
// properties that are known not to exist, e.g. the original property name in a __noSuchProperty__ invocation.
private SwitchPoint getProtoSwitchPoint(final String name) {
final SwitchPoint getProtoSwitchPoint(final String name) {
if (getProto() == null) {
return null;
}

@ -138,9 +138,9 @@ public final class WithObject extends Scope {
find = expression.findProperty(fallBack, true);
if (find != null) {
if (NO_SUCH_METHOD_NAME.equals(fallBack)) {
link = expression.noSuchMethod(desc, request);
link = expression.noSuchMethod(desc, request).addSwitchPoint(getProtoSwitchPoint(name));
} else if (NO_SUCH_PROPERTY_NAME.equals(fallBack)) {
link = expression.noSuchProperty(desc, request);
link = expression.noSuchProperty(desc, request).addSwitchPoint(getProtoSwitchPoint(name));
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -47,7 +47,29 @@ public enum ExtendedOpenOption implements OpenOption {
/**
* Prevent operations on the file that request delete access.
*/
NOSHARE_DELETE(ExtendedOptions.NOSHARE_DELETE);
NOSHARE_DELETE(ExtendedOptions.NOSHARE_DELETE),
/**
* Requires that direct I/O be used for read or write access.
* Attempting to open a file with this option set will result in
* an {@code UnsupportedOperationException} if the operating system or
* file system does not support Direct I/O or a sufficient equivalent.
*
* @apiNote
* The DIRECT option enables performing file I/O directly between user
* buffers and the file thereby circumventing the operating system page
* cache and possibly avoiding the thrashing which could otherwise occur
* in I/O-intensive applications. This option may be of benefit to
* applications which do their own caching or do random I/O operations
* on large data sets. It is likely to provide the most benefit when
* the file is stored on a device which has high I/O throughput capacity.
* The option should be used with caution however as in general it is
* likely to degrade performance. The performance effects of using it
* should be evaluated in each particular circumstance.
*
* @since 10
*/
DIRECT(ExtendedOptions.DIRECT);
ExtendedOpenOption(ExtendedOptions.InternalOption<Void> option) {
option.register(this);

@ -176,16 +176,17 @@ endif
# Expect JPRT to set JPRT_ARCHIVE_BUNDLE (path to zip bundle for results)
ifdef JPRT_ARCHIVE_BUNDLE
ARCHIVE_BUNDLE = $(JPRT_ARCHIVE_BUNDLE)
else
ARCHIVE_BUNDLE = $(ABS_TEST_OUTPUT_DIR)/ARCHIVE_BUNDLE.zip
endif
# How to create the test bundle (pass or fail, we want to create this)
# Follow command with ";$(BUNDLE_UP_AND_EXIT)", so it always gets executed.
ZIP_UP_RESULTS = ( $(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)` \
ifneq ($(ARCHIVE_BUNDLE), )
ZIP_UP_RESULTS = ( $(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)` \
&& $(CD) $(ABS_TEST_OUTPUT_DIR) \
&& $(CHMOD) -R a+r . \
&& $(ZIPEXE) -q -r $(ARCHIVE_BUNDLE) . )
&& $(ZIPEXE) -q -r $(ARCHIVE_BUNDLE) . ) ;
CLEAN_ARCHIVE_BUNDLE = @$(RM) $(ARCHIVE_BUNDLE)
endif
# important results files
SUMMARY_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport/text/summary.txt")
@ -252,7 +253,7 @@ BUNDLE_UP_AND_EXIT = \
if [ -f $(STATS_TXT) ] ; then \
$(CAT) $(STATS_TXT); \
fi; \
$(ZIP_UP_RESULTS) ; \
$(ZIP_UP_RESULTS) \
$(TESTEXIT) \
)
@ -272,7 +273,6 @@ BUNDLE_UP_AND_EXIT = \
# service, you may need CYGWIN=ntsec for this to work.
prep:
@$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR)
@$(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)`
@if [ ! -d $(TEST_ROOT)/../../.hg ] && [ ! -d $(TEST_ROOT)/../../../.hg ]; then \
$(FIND) $(TEST_ROOT) \( -name \*.dll -o -name \*.DLL -o -name \*.so \) \
-exec $(CHMOD) a+rx {} \; ; \
@ -286,7 +286,7 @@ endif
# Cleanup
clean:
@$(RM) -r $(ABS_TEST_OUTPUT_DIR)
@$(RM) $(ARCHIVE_BUNDLE)
$(CLEAN_ARCHIVE_BUNDLE)
################################################################

@ -0,0 +1,128 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8164900
* @summary Test for ExtendedOpenOption.DIRECT flag
* @requires (os.family == "linux" | os.family == "solaris"
* | os.family == "aix")
* @library /test/lib
* @build jdk.test.lib.Platform
* @run main/native DirectIOTest
*/
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.*;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.Path;
import java.nio.file.Files;
import jdk.test.lib.Platform;
import java.nio.file.FileStore;
import java.nio.file.StandardOpenOption;
import com.sun.nio.file.ExtendedOpenOption;
public class DirectIOTest {
private static final int SIZE = 4096;
private static void testWrite(Path p) throws Exception {
try (FileChannel fc = FileChannel.open(p, StandardOpenOption.WRITE,
ExtendedOpenOption.DIRECT)) {
FileStore fs = Files.getFileStore(p);
int alignment = (int)fs.getBlockSize();
ByteBuffer src = ByteBuffer.allocateDirect(SIZE + alignment - 1)
.alignedSlice(alignment);
for (int j = 0; j < SIZE; j++) {
src.put((byte)0);
}
src.flip();
fc.write(src);
}
}
private static void testRead(Path p) throws Exception {
try (FileChannel fc = FileChannel.open(p, ExtendedOpenOption.DIRECT)) {
FileStore fs = Files.getFileStore(p);
int alignment = (int)fs.getBlockSize();
ByteBuffer dest = ByteBuffer.allocateDirect(SIZE + alignment - 1)
.alignedSlice(alignment);
fc.read(dest);
}
}
public static Path createTempFile() throws IOException {
return Files.createTempFile(
Paths.get(System.getProperty("test.dir", ".")), "test", null);
}
public static boolean isDirectIOSupportedByFS(Path p) throws Exception {
boolean supported = true;
if (Platform.isSolaris()) {
String fsType = Files.getFileStore(p).type();
if (!fsType.equals("nfs") && !fsType.equals("ufs")) {
// print a message and return without failing
System.out.format("Skipping test: file system type %s of "
+ "FileStore of %s is neither nfs nor ufs.%n", fsType, p);
supported = false;
}
}
return supported;
}
private static boolean isFileInCache(Path p) {
String path = p.toString();
return isFileInCache0(SIZE, path);
}
private static native boolean isFileInCache0(int size, String path);
public static void main(String[] args) throws Exception {
Path p = createTempFile();
if (!isDirectIOSupportedByFS(p)) {
Files.delete(p);
return;
}
System.loadLibrary("DirectIO");
try {
testWrite(p);
if (isFileInCache(p)) {
throw new RuntimeException("DirectIO is not working properly with "
+ "write. File still exists in cache!");
}
testRead(p);
if (isFileInCache(p)) {
throw new RuntimeException("DirectIO is not working properly with "
+ "read. File still exists in cache!");
}
} finally {
Files.delete(p);
}
}
}

@ -0,0 +1,188 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 8164900
* @summary Test positional read method of FileChannel with DirectIO
* (use -Dseed=X to set PRNG seed)
* @library .. /test/lib
* @build jdk.test.lib.RandomFactory
* DirectIOTest
* @run main/othervm PreadDirect
* @key randomness
*/
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.*;
import java.nio.file.Files;
import java.nio.file.FileStore;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Random;
import com.sun.nio.file.ExtendedOpenOption;
import jdk.test.lib.RandomFactory;
/**
* Testing FileChannel's positional read method.
*/
public class PreadDirect {
private static PrintStream err = System.err;
private static Random generator = RandomFactory.getRandom();
private static int charsPerGroup = -1;
private static int alignment = -1;
public static void main(String[] args) throws Exception {
if (initTests()) {
genericTest();
testNotAlignedChannelPosition();
testNegativeChannelPosition();
}
}
private static boolean initTests() throws Exception {
Path p = DirectIOTest.createTempFile();
if (!DirectIOTest.isDirectIOSupportedByFS(p)) {
Files.delete(p);
return false;
}
try {
FileStore fs = Files.getFileStore(p);
alignment = (int)fs.getBlockSize();
charsPerGroup = alignment;
} finally {
Files.delete(p);
}
return true;
}
private static void testNegativeChannelPosition() throws Exception {
Path p = DirectIOTest.createTempFile();
try (OutputStream fos = Files.newOutputStream(p)) {
fos.write(new byte[charsPerGroup]);
}
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.DELETE_ON_CLOSE, ExtendedOpenOption.DIRECT)) {
try {
fc.read(ByteBuffer.allocate(charsPerGroup), -1L);
throw new RuntimeException("Expected exception not thrown");
} catch(IllegalArgumentException e) {
// Correct result
}
}
}
private static void testNotAlignedChannelPosition() throws Exception {
Path p = DirectIOTest.createTempFile();
try (OutputStream fos = Files.newOutputStream(p)) {
fos.write(new byte[charsPerGroup]);
}
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.DELETE_ON_CLOSE, ExtendedOpenOption.DIRECT)) {
long pos = charsPerGroup - 1;
try {
fc.read(ByteBuffer.allocate(charsPerGroup), pos);
throw new RuntimeException("Expected exception not thrown");
} catch(IOException e) {
if (!e.getMessage().contains("Channel position (" + pos
+ ") is not a multiple of the block size (" + alignment + ")"))
throw new RuntimeException("Read test failed");
}
}
}
private static void genericTest() throws Exception {
StringBuffer sb = new StringBuffer();
sb.setLength(2);
Path p = DirectIOTest.createTempFile();
initTestFile(p);
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.DELETE_ON_CLOSE, ExtendedOpenOption.DIRECT)) {
ByteBuffer block =
ByteBuffer.allocateDirect(charsPerGroup + alignment - 1)
.alignedSlice(alignment);
for (int x = 0; x < 100; x++) {
block.clear();
long offset = generator.nextInt(100) * charsPerGroup;
long expectedResult = offset / charsPerGroup;
offset = expectedResult * charsPerGroup;
long originalPosition = fc.position();
int read = fc.read(block, offset);
if (read != charsPerGroup)
throw new Exception("Read failed");
long newPosition = fc.position();
for (int i = 0; i < 2; i++) {
byte aByte = block.get(i);
sb.setCharAt(i, (char)aByte);
}
int result = Integer.parseInt(sb.toString());
if (result != expectedResult) {
err.println("I expected "+ expectedResult);
err.println("I got "+ result);
throw new Exception("Read test failed");
}
// Ensure that file pointer position has not changed
if (originalPosition != newPosition)
throw new Exception("File position modified");
}
}
}
private static void initTestFile(Path p) throws Exception {
try (OutputStream fos = Files.newOutputStream(p)) {
try (BufferedWriter awriter
= new BufferedWriter(new OutputStreamWriter(fos, "8859_1"))) {
for (int i = 0; i < 100; i++) {
String number = new Integer(i).toString();
for (int h = 0; h < 2 - number.length(); h++)
awriter.write("0");
awriter.write(""+i);
for (int j = 0; j < (charsPerGroup - 2); j++)
awriter.write("0");
}
awriter.flush();
}
}
}
}

@ -0,0 +1,185 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 8164900
* @summary Test positional write method of FileChannel with DirectIO
* (use -Dseed=X to set PRNG seed)
* @library .. /test/lib
* @build jdk.test.lib.RandomFactory
* DirectIOTest
* @run main/othervm PwriteDirect
* @key randomness
*/
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.*;
import java.nio.file.Files;
import java.nio.file.FileStore;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Random;
import com.sun.nio.file.ExtendedOpenOption;
import jdk.test.lib.RandomFactory;
/**
* Testing FileChannel's positional write method.
*/
public class PwriteDirect {
private static Random generator = RandomFactory.getRandom();
private static int charsPerGroup = -1;
private static int alignment = -1;
private static boolean initTests() throws Exception {
Path p = DirectIOTest.createTempFile();
if (!DirectIOTest.isDirectIOSupportedByFS(p)) {
Files.delete(p);
return false;
}
try {
FileStore fs = Files.getFileStore(p);
alignment = (int)fs.getBlockSize();
charsPerGroup = alignment;
} finally {
Files.delete(p);
}
return true;
}
public static void main(String[] args) throws Exception {
if (initTests()) {
genericTest();
TestWithNotAlignedChannelPosition();
testUnwritableChannel();
}
}
private static void testUnwritableChannel() throws Exception {
Path p = DirectIOTest.createTempFile();
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.DELETE_ON_CLOSE, ExtendedOpenOption.DIRECT)) {
try {
fc.write(ByteBuffer.allocate(charsPerGroup), 0);
throw new RuntimeException("Expected exception not thrown");
} catch(NonWritableChannelException e) {
// Correct result
}
}
}
private static void TestWithNotAlignedChannelPosition() throws Exception {
Path p = DirectIOTest.createTempFile();
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.WRITE, StandardOpenOption.DELETE_ON_CLOSE, ExtendedOpenOption.DIRECT)) {
int bufferSize = charsPerGroup;
long position = charsPerGroup - 1;
try {
fc.write(ByteBuffer.allocate(bufferSize), position);
throw new RuntimeException("Expected exception not thrown");
} catch(IOException e) {
if (!e.getMessage().contains("Channel position (" + position + ")"
+ " is not a multiple of the block size (" + alignment + ")"))
throw new RuntimeException("Write test failed");
}
}
}
private static void genericTest() throws Exception {
Path p = DirectIOTest.createTempFile();
initTestFile(p);
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.READ, StandardOpenOption.WRITE,
StandardOpenOption.DELETE_ON_CLOSE, ExtendedOpenOption.DIRECT)) {
ByteBuffer block =
ByteBuffer.allocateDirect(charsPerGroup + alignment - 1)
.alignedSlice(alignment);
for (int x = 0; x < 100; x++) {
block.clear();
long offset = generator.nextInt(100) * charsPerGroup;
// Write known sequence out
for (int i = 0; i < charsPerGroup; i++) {
block.put(i, (byte)'a');
}
long originalPosition = fc.position();
int written = fc.write(block, offset);
if (written < 0)
throw new Exception("Write failed");
long newPosition = fc.position();
// Ensure that file pointer position has not changed
if (originalPosition != newPosition)
throw new Exception("File position modified");
// Attempt to read sequence back in
originalPosition = fc.position();
block.rewind();
int read = fc.read(block, offset);
if (read != charsPerGroup)
throw new Exception("Read failed");
newPosition = fc.position();
// Ensure that file pointer position has not changed
if (originalPosition != newPosition)
throw new Exception("File position modified");
for (int j = 0; j < charsPerGroup; j++) {
if (block.get(j) != (byte)'a')
throw new Exception("Write test failed");
}
}
}
}
private static void initTestFile(Path p) throws Exception {
try (OutputStream fos = Files.newOutputStream(p)) {
try (BufferedWriter awriter
= new BufferedWriter(new OutputStreamWriter(fos, "8859_1"))) {
for (int i = 0; i < 100; i++) {
String number = new Integer(i).toString();
for (int h = 0; h < 4 - number.length(); h++)
awriter.write("0");
awriter.write("" + i);
for (int j = 0; j < 4092; j++)
awriter.write("0");
}
awriter.flush();
}
}
}
}

@ -0,0 +1,266 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 8164900
* @summary Test read method of FileChannel with DirectIO
* (use -Dseed=X to set PRNG seed)
* @library .. /test/lib
* @build jdk.test.lib.RandomFactory
* DirectIOTest
* @run main/othervm ReadDirect
* @key randomness
*/
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.*;
import java.nio.file.Files;
import java.nio.file.FileStore;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Random;
import com.sun.nio.file.ExtendedOpenOption;
import jdk.test.lib.RandomFactory;
public class ReadDirect {
private static PrintStream err = System.err;
private static Random generator = RandomFactory.getRandom();
private static int charsPerGroup = -1;
private static int alignment = -1;
private static boolean initTests() throws Exception {
Path p = DirectIOTest.createTempFile();
if (!DirectIOTest.isDirectIOSupportedByFS(p)) {
Files.delete(p);
return false;
}
try {
FileStore fs = Files.getFileStore(p);
alignment = (int)fs.getBlockSize();
charsPerGroup = alignment;
} finally {
Files.delete(p);
}
return true;
}
private static void testWithSingleBuffer() throws Exception {
StringBuffer sb = new StringBuffer();
sb.setLength(2);
Path p = DirectIOTest.createTempFile();
initTestFile(p);
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE,
ExtendedOpenOption.DIRECT)) {
ByteBuffer block = ByteBuffer.allocateDirect(charsPerGroup
+ alignment - 1).alignedSlice(alignment);
for (int x = 0; x < 100; x++) {
block.clear();
long offset = x * charsPerGroup;
long expectedResult = offset / charsPerGroup;
fc.read(block);
for (int i = 0; i < 2; i++) {
byte aByte = block.get(i);
sb.setCharAt(i, (char)aByte);
}
int result = Integer.parseInt(sb.toString());
if (result != expectedResult) {
err.println("I expected " + expectedResult);
err.println("I got " + result);
throw new Exception("Read test failed");
}
}
}
}
private static void testWithNotAlignedBufferSize() throws Exception {
int bufferSize = charsPerGroup - 1;
Path p = DirectIOTest.createTempFile();
try (OutputStream fos = Files.newOutputStream(p)) {
fos.write(new byte[bufferSize]);
}
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE,
ExtendedOpenOption.DIRECT)) {
ByteBuffer block = ByteBuffer.allocate(bufferSize);
try {
fc.read(block);
throw new RuntimeException("Expected exception not thrown");
} catch (IOException e) {
if (!e.getMessage().contains("Number of remaining bytes ("
+ bufferSize + ") is not a multiple of the block size ("
+ alignment + ")"))
throw new Exception("Read test failed");
}
}
}
private static void testWithNotAlignedBufferOffset() throws Exception {
int bufferSize = charsPerGroup * 2;
int pos = alignment - 1;
Path p = DirectIOTest.createTempFile();
try (OutputStream fos = Files.newOutputStream(p)) {
fos.write(new byte[bufferSize]);
}
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE,
ExtendedOpenOption.DIRECT)) {
ByteBuffer block = ByteBuffer.allocateDirect(bufferSize);
block.position(pos);
block.limit(bufferSize - 1);
try {
fc.read(block);
throw new RuntimeException("Expected exception not thrown");
} catch (IOException e) {
if (!e.getMessage().contains("Current location of the bytebuffer "
+ "(" + pos + ") is not a multiple of the block size ("
+ alignment + ")"))
throw new Exception("Read test failed");
}
}
}
private static void testWithArrayOfBuffer() throws Exception {
StringBuffer sb = new StringBuffer();
sb.setLength(2);
ByteBuffer[] dests = new ByteBuffer[4];
Path p = DirectIOTest.createTempFile();
initTestFile(p);
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE,
ExtendedOpenOption.DIRECT)) {
int randomNumber = -1;
for (int i = 0; i < 4; i++) {
dests[i] = ByteBuffer.allocateDirect
(charsPerGroup + alignment - 1).alignedSlice(alignment);
for (int j = 0; j < charsPerGroup; j++) {
dests[i].put(j, (byte)'a');
}
}
randomNumber = generator.nextInt(100);
long offset = randomNumber * charsPerGroup;
fc.position(offset);
fc.read(dests, 1, 2);
for (int i = 0; i < 4; i++) {
if (i == 1 || i == 2) {
for (int j = 0; j < 2; j++) {
byte aByte = dests[i].get(j);
sb.setCharAt(j, (char)aByte);
}
int result = Integer.parseInt(sb.toString());
int expectedResult = randomNumber + i - 1;
if (result != expectedResult) {
err.println("I expected " + expectedResult);
err.println("I got " + result);
throw new Exception("Read test failed");
}
} else {
for (int k = 0; k < charsPerGroup; k++) {
if (dests[i].get(k) != (byte)'a')
throw new RuntimeException("Read test failed");
}
}
}
}
}
public static void testOnEOF() throws Exception {
int bufferSize = charsPerGroup / 2;
Path p = DirectIOTest.createTempFile();
try (OutputStream fos = Files.newOutputStream(p)) {
byte[] writeBlock = new byte[bufferSize];
for (int i = 0; i < bufferSize; i++) {
writeBlock[i] = ((byte)'a');
}
fos.write(writeBlock);
}
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE,
ExtendedOpenOption.DIRECT)) {
ByteBuffer block = ByteBuffer.allocateDirect(
(bufferSize / alignment + 1) * alignment + alignment - 1)
.alignedSlice(alignment);
int result = fc.read(block);
if (result != bufferSize) {
err.println("Number of bytes to read " + bufferSize);
err.println("I read " + result);
throw new Exception("Read test failed");
}
for (int j = 0; j < bufferSize; j++) {
if (block.get(j) != (byte)'a')
throw new RuntimeException("Read test failed");
}
}
}
public static void main(String[] args) throws Exception {
if (initTests()) {
testWithSingleBuffer();
testWithNotAlignedBufferSize();
testWithNotAlignedBufferOffset();
testWithArrayOfBuffer();
testOnEOF();
}
}
private static void initTestFile(Path p)
throws Exception {
try (OutputStream fos = Files.newOutputStream(p)) {
try (BufferedWriter awriter
= new BufferedWriter(new OutputStreamWriter(fos, "8859_1"))) {
for (int i = 0; i < 100; i++) {
String number = new Integer(i).toString();
for (int h = 0; h < 2 - number.length(); h++)
awriter.write("0");
awriter.write("" + i);
for (int j = 0; j < (charsPerGroup - 2); j++)
awriter.write("0");
}
awriter.flush();
}
}
}
}

@ -0,0 +1,154 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8164900
* @summary Test FileChannel write with DirectIO
* @library .. /test/lib
* @build DirectIOTest
* @run main/othervm WriteDirect
*/
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.Files;
import java.nio.file.FileStore;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import com.sun.nio.file.ExtendedOpenOption;
public class WriteDirect {
private static int charsPerGroup = -1;
private static int alignment = -1;
private static boolean initTests() throws Exception {
Path p = DirectIOTest.createTempFile();
if (!DirectIOTest.isDirectIOSupportedByFS(p)) {
Files.delete(p);
return false;
}
try {
FileStore fs = Files.getFileStore(p);
alignment = (int)fs.getBlockSize();
charsPerGroup = alignment;
} finally {
Files.delete(p);
}
return true;
}
public static void main(String[] args) throws Exception {
if (initTests()) {
testWithNotAlignedBuffer();
testWithNotAlignedBufferOffset();
testWithArrayOfBuffer();
}
}
static void testWithNotAlignedBuffer() throws Exception {
Path p = DirectIOTest.createTempFile();
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.WRITE, StandardOpenOption.DELETE_ON_CLOSE,
ExtendedOpenOption.DIRECT)) {
int bufferSize = charsPerGroup - 1;
ByteBuffer src = ByteBuffer.allocate(bufferSize);
try {
fc.write(src);
throw new RuntimeException("Expected exception not thrown");
} catch (IOException e) {
if (!e.getMessage().contains("Number of remaining bytes ("
+ bufferSize + ") is not a multiple of the block size ("
+ alignment + ")"))
throw new Exception("Write failure");
}
}
}
private static void testWithNotAlignedBufferOffset() throws Exception {
int bufferSize = charsPerGroup * 2;
int pos = alignment - 1;
Path p = DirectIOTest.createTempFile();
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.WRITE, StandardOpenOption.DELETE_ON_CLOSE,
ExtendedOpenOption.DIRECT)) {
ByteBuffer block = ByteBuffer.allocateDirect(bufferSize);
block.position(pos);
block.limit(bufferSize - 1);
try {
fc.write(block);
throw new RuntimeException("Expected exception not thrown");
} catch (IOException e) {
if (!e.getMessage().contains("Current location of the bytebuffer "
+ "(" + pos + ") is not a multiple of the block size ("
+ alignment + ")"))
throw new Exception("Write test failed");
}
}
}
static void testWithArrayOfBuffer() throws Exception {
Path p = DirectIOTest.createTempFile();
ByteBuffer[] srcs = new ByteBuffer[4];
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.WRITE, ExtendedOpenOption.DIRECT)) {
for (int i = 0; i < 4; i++) {
srcs[i] = ByteBuffer.allocateDirect(charsPerGroup + alignment - 1)
.alignedSlice(alignment);
for (int j = 0; j < charsPerGroup; j++) {
srcs[i].put((byte)i);
}
srcs[i].flip();
}
fc.write(srcs, 1, 2);
}
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE)) {
ByteBuffer bb = ByteBuffer.allocateDirect(charsPerGroup * 2);
fc.read(bb);
bb.flip();
for (int k = 0; k < charsPerGroup; k++) {
if (bb.get() != 1)
throw new RuntimeException("Write failure");
}
for (int m = 0; m < charsPerGroup; m++) {
if (bb.get() != 2)
throw new RuntimeException("Write failure");
}
try {
bb.get();
throw new RuntimeException("Write failure");
} catch (BufferUnderflowException bufe) {
// correct result
}
}
}
}

@ -0,0 +1,103 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Test if a file exists in the file system cache
*/
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/mman.h>
#include "jni.h"
/*
* Throws an exception with the given class name and detail message
*/
static void ThrowException(JNIEnv *env, const char *name, const char *msg) {
jclass cls = (*env)->FindClass(env, name);
if (cls != NULL) {
(*env)->ThrowNew(env, cls, msg);
}
}
/*
* Class: DirectIO
* Method: isFileInCache0
* Signature: (ILjava/lang/String;)Z
*/
JNIEXPORT jboolean Java_DirectIOTest_isFileInCache0(JNIEnv *env,
jclass cls,
jint file_size,
jstring file_path) {
void *f_mmap;
#ifdef __linux__
unsigned char *f_seg;
#else
char *f_seg;
#endif
#ifdef __APPLE__
size_t mask = MINCORE_INCORE;
#else
size_t mask = 0x1;
#endif
size_t page_size = getpagesize();
size_t index = (file_size + page_size - 1) /page_size;
jboolean result = JNI_FALSE;
const char* path = (*env)->GetStringUTFChars(env, file_path, JNI_FALSE);
int fd = open(path, O_RDWR);
(*env)->ReleaseStringUTFChars(env, file_path, path);
f_mmap = mmap(0, file_size, PROT_NONE, MAP_SHARED, fd, 0);
if (f_mmap == MAP_FAILED) {
close(fd);
ThrowException(env, "java/io/IOException",
"test of whether file exists in cache failed");
}
f_seg = malloc(index);
if (f_seg != NULL) {
if(mincore(f_mmap, file_size, f_seg) == 0) {
size_t i;
for (i = 0; i < index; i++) {
if (f_seg[i] & mask) {
result = JNI_TRUE;
break;
}
}
}
free(f_seg);
} else {
ThrowException(env, "java/io/IOException",
"test of whether file exists in cache failed");
}
close(fd);
munmap(f_mmap, file_size);
return result;
}

@ -0,0 +1,37 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8165198: Inconsistent values with JavaImporter after accessing undefined variable
*
* @test
* @run
*/
var NashornScriptEngineFactory = Java.type("jdk.nashorn.api.scripting.NashornScriptEngineFactory");
var e = new NashornScriptEngineFactory().getScriptEngine("-ot=false");
var output = e.eval("with(new JavaImporter(java.util)){x}");
print(output);
e.eval("with(new JavaImporter(java.util)){x=1}");
var output2 = e.eval("with(new JavaImporter(java.util)){x}");
print(output2);

@ -0,0 +1,2 @@
null
1

@ -0,0 +1,40 @@
/*
* Copyright (c) 2017, Google Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8187247
* @summary canonical import check compares classes by simple name
* @author cushon
*
* @compile p1/A.java p2/A.java
* @compile/fail/ref=ImportCanonicalSameName.out -XDrawDiagnostics ImportCanonicalSameName.java
*/
package p1;
import p1.A.I;
class T {
I i;
}

@ -0,0 +1,2 @@
ImportCanonicalSameName.java:36:12: compiler.err.import.requires.canonical: p2.A.I
1 error

@ -0,0 +1,25 @@
/*
* Copyright (c) 2017, Google Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package p1;
public class A extends p2.A {}

@ -0,0 +1,27 @@
/*
* Copyright (c) 2017, Google Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package p2;
public class A {
public static class I {}
}