Merge
This commit is contained in:
commit
315d4eb3d6
@ -4,6 +4,7 @@ nbproject/private/
|
||||
^webrev
|
||||
^.hgtip
|
||||
^.bridge2
|
||||
^.jib/
|
||||
.DS_Store
|
||||
.metadata/
|
||||
.recommenders/
|
||||
|
@ -338,3 +338,4 @@ cf1dc4c035fb84693d4ae5ad818785cb4d1465d1 jdk9-b90
|
||||
331fda57dfd323c61804ba0472776790de572937 jdk9-b93
|
||||
349488425abcaf3ff62f580007860b4b56875d10 jdk9-b94
|
||||
12a6fb4f070f8ca8fbca219ab9abf5da8908b317 jdk-9+95
|
||||
5582a79892596169ebddb3e2c2aa44939e4e3f40 jdk-9+96
|
||||
|
@ -99,7 +99,13 @@ AC_DEFUN([BASIC_FIXUP_PATH],
|
||||
AC_MSG_ERROR([The path of $1, which resolves as "$path", is not found.])
|
||||
fi
|
||||
|
||||
$1="`cd "$path"; $THEPWDCMD -L`"
|
||||
if test -d "$path"; then
|
||||
$1="`cd "$path"; $THEPWDCMD -L`"
|
||||
else
|
||||
dir="`$DIRNAME "$path"`"
|
||||
base="`$BASENAME "$path"`"
|
||||
$1="`cd "$dir"; $THEPWDCMD -L`/$base"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
])
|
||||
@ -237,12 +243,18 @@ AC_DEFUN([BASIC_DEPRECATED_ARG_WITH],
|
||||
# Register a --enable argument but mark it as deprecated
|
||||
# $1: The name of the with argument to deprecate, not including --enable-
|
||||
# $2: The name of the argument to deprecate, in shell variable style (i.e. with _ instead of -)
|
||||
# $3: Messages to user.
|
||||
AC_DEFUN([BASIC_DEPRECATED_ARG_ENABLE],
|
||||
[
|
||||
AC_ARG_ENABLE($1, [AS_HELP_STRING([--enable-$1],
|
||||
[Deprecated. Option is kept for backwards compatibility and is ignored])])
|
||||
if test "x$enable_$2" != x; then
|
||||
AC_MSG_WARN([Option --enable-$1 is deprecated and will be ignored.])
|
||||
|
||||
if test "x$3" != x; then
|
||||
AC_MSG_WARN([$3])
|
||||
fi
|
||||
|
||||
fi
|
||||
])
|
||||
|
||||
@ -1072,6 +1084,26 @@ AC_DEFUN_ONCE([BASIC_CHECK_BASH_OPTIONS],
|
||||
AC_SUBST(BASH_ARGS)
|
||||
])
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Default make target
|
||||
#
|
||||
AC_DEFUN_ONCE([BASIC_SETUP_DEFAULT_MAKE_TARGET],
|
||||
[
|
||||
AC_ARG_WITH(default-make-target, [AS_HELP_STRING([--with-default-make-target],
|
||||
[set the default make target @<:@exploded-image@:>@])])
|
||||
if test "x$with_default_make_target" = "x" \
|
||||
|| test "x$with_default_make_target" = "xyes"; then
|
||||
DEFAULT_MAKE_TARGET="exploded-image"
|
||||
elif test "x$with_default_make_target" = "xno"; then
|
||||
AC_MSG_ERROR([--without-default-make-target is not a valid option])
|
||||
else
|
||||
DEFAULT_MAKE_TARGET="$with_default_make_target"
|
||||
fi
|
||||
|
||||
AC_SUBST(DEFAULT_MAKE_TARGET)
|
||||
])
|
||||
|
||||
# Code to run after AC_OUTPUT
|
||||
AC_DEFUN_ONCE([BASIC_POST_CONFIG_OUTPUT],
|
||||
[
|
||||
|
8
common/autoconf/configure
vendored
8
common/autoconf/configure
vendored
@ -257,10 +257,14 @@ fi
|
||||
|
||||
# Now transfer control to the script generated by autoconf. This is where the
|
||||
# main work is done.
|
||||
RCDIR=`mktemp -dt jdk-build-configure.tmp.XXXXXX` || exit $?
|
||||
trap "rm -rf \"$RCDIR\"" EXIT
|
||||
conf_logfile=./configure.log
|
||||
(exec 3>&1 ; (. $conf_script_to_run "${conf_processed_arguments[@]}" 2>&1 1>&3 ) | tee -a $conf_logfile 1>&2 ; exec 3>&-) | tee -a $conf_logfile
|
||||
(exec 3>&1 ; ((. $conf_script_to_run "${conf_processed_arguments[@]}" 2>&1 1>&3 ) \
|
||||
; echo $? > "$RCDIR/rc" ) \
|
||||
| tee -a $conf_logfile 1>&2 ; exec 3>&-) | tee -a $conf_logfile
|
||||
|
||||
conf_result_code=$?
|
||||
conf_result_code=`cat "$RCDIR/rc"`
|
||||
###
|
||||
### Post-processing
|
||||
###
|
||||
|
@ -121,6 +121,9 @@ PKG_PROG_PKG_CONFIG
|
||||
# After basic tools have been setup, we can check build os specific details.
|
||||
PLATFORM_SETUP_OPENJDK_BUILD_OS_VERSION
|
||||
|
||||
# Misc basic settings
|
||||
BASIC_SETUP_DEFAULT_MAKE_TARGET
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Determine OpenJDK variants, options and version numbers.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -491,53 +491,74 @@ AC_DEFUN_ONCE([JDKOPT_DETECT_INTREE_EC],
|
||||
AC_DEFUN_ONCE([JDKOPT_SETUP_DEBUG_SYMBOLS],
|
||||
[
|
||||
#
|
||||
# ENABLE_DEBUG_SYMBOLS
|
||||
# NATIVE_DEBUG_SYMBOLS
|
||||
# This must be done after the toolchain is setup, since we're looking at objcopy.
|
||||
#
|
||||
AC_ARG_ENABLE([debug-symbols],
|
||||
[AS_HELP_STRING([--disable-debug-symbols],[disable generation of debug symbols @<:@enabled@:>@])])
|
||||
AC_MSG_CHECKING([what type of native debug symbols to use])
|
||||
AC_ARG_WITH([native-debug-symbols],
|
||||
[AS_HELP_STRING([--with-native-debug-symbols],
|
||||
[set the native debug symbol configuration (none, internal, external, zipped) @<:@zipped@:>@])],
|
||||
[],
|
||||
[with_native_debug_symbols="zipped"])
|
||||
NATIVE_DEBUG_SYMBOLS=$with_native_debug_symbols
|
||||
AC_MSG_RESULT([$NATIVE_DEBUG_SYMBOLS])
|
||||
|
||||
AC_MSG_CHECKING([if we should generate debug symbols])
|
||||
if test "x$NATIVE_DEBUG_SYMBOLS" = xzipped; then
|
||||
|
||||
if test "x$enable_debug_symbols" = "xyes" && test "x$OBJCOPY" = x; then
|
||||
# explicit enabling of enable-debug-symbols and can't find objcopy
|
||||
# this is an error
|
||||
AC_MSG_ERROR([Unable to find objcopy, cannot enable debug-symbols])
|
||||
fi
|
||||
|
||||
if test "x$enable_debug_symbols" = "xyes"; then
|
||||
ENABLE_DEBUG_SYMBOLS=true
|
||||
elif test "x$enable_debug_symbols" = "xno"; then
|
||||
ENABLE_DEBUG_SYMBOLS=false
|
||||
else
|
||||
# Default is on if objcopy is found
|
||||
if test "x$OBJCOPY" != x; then
|
||||
ENABLE_DEBUG_SYMBOLS=true
|
||||
# MacOS X and Windows don't use objcopy but default is on for those OSes
|
||||
elif test "x$OPENJDK_TARGET_OS" = xmacosx || test "x$OPENJDK_TARGET_OS" = xwindows; then
|
||||
ENABLE_DEBUG_SYMBOLS=true
|
||||
else
|
||||
ENABLE_DEBUG_SYMBOLS=false
|
||||
if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; then
|
||||
if test "x$OBJCOPY" = x; then
|
||||
# enabling of enable-debug-symbols and can't find objcopy
|
||||
# this is an error
|
||||
AC_MSG_ERROR([Unable to find objcopy, cannot enable native debug symbols])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$ENABLE_DEBUG_SYMBOLS])
|
||||
|
||||
#
|
||||
# ZIP_DEBUGINFO_FILES
|
||||
#
|
||||
AC_MSG_CHECKING([if we should zip debug-info files])
|
||||
AC_ARG_ENABLE([zip-debug-info],
|
||||
[AS_HELP_STRING([--disable-zip-debug-info],[disable zipping of debug-info files @<:@enabled@:>@])],
|
||||
[enable_zip_debug_info="${enableval}"], [enable_zip_debug_info="yes"])
|
||||
AC_MSG_RESULT([${enable_zip_debug_info}])
|
||||
|
||||
if test "x${enable_zip_debug_info}" = "xno"; then
|
||||
ZIP_DEBUGINFO_FILES=false
|
||||
else
|
||||
ENABLE_DEBUG_SYMBOLS=true
|
||||
ZIP_DEBUGINFO_FILES=true
|
||||
DEBUG_BINARIES=true
|
||||
STRIP_POLICY=min_strip
|
||||
elif test "x$NATIVE_DEBUG_SYMBOLS" = xnone; then
|
||||
ENABLE_DEBUG_SYMBOLS=false
|
||||
ZIP_DEBUGINFO_FILES=false
|
||||
DEBUG_BINARIES=false
|
||||
STRIP_POLICY=no_strip
|
||||
elif test "x$NATIVE_DEBUG_SYMBOLS" = xinternal; then
|
||||
ENABLE_DEBUG_SYMBOLS=false # -g option only
|
||||
ZIP_DEBUGINFO_FILES=false
|
||||
DEBUG_BINARIES=true
|
||||
STRIP_POLICY=no_strip
|
||||
STRIP=""
|
||||
elif test "x$NATIVE_DEBUG_SYMBOLS" = xexternal; then
|
||||
|
||||
if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; then
|
||||
if test "x$OBJCOPY" = x; then
|
||||
# enabling of enable-debug-symbols and can't find objcopy
|
||||
# this is an error
|
||||
AC_MSG_ERROR([Unable to find objcopy, cannot enable native debug symbols])
|
||||
fi
|
||||
fi
|
||||
|
||||
ENABLE_DEBUG_SYMBOLS=true
|
||||
ZIP_DEBUGINFO_FILES=false
|
||||
DEBUG_BINARIES=true
|
||||
STRIP_POLICY=min_strip
|
||||
else
|
||||
AC_MSG_ERROR([Allowed native debug symbols are: none, internal, external, zipped])
|
||||
fi
|
||||
|
||||
# --enable-debug-symbols is deprecated.
|
||||
# Please use --with-native-debug-symbols=[internal,external,zipped] .
|
||||
BASIC_DEPRECATED_ARG_ENABLE(debug-symbols, debug_symbols,
|
||||
[Please use --with-native-debug-symbols=[[internal,external,zipped]] .])
|
||||
|
||||
# --enable-zip-debug-info is deprecated.
|
||||
# Please use --with-native-debug-symbols=zipped .
|
||||
BASIC_DEPRECATED_ARG_ENABLE(zip-debug-info, zip_debug_info,
|
||||
[Please use --with-native-debug-symbols=zipped .])
|
||||
|
||||
AC_SUBST(NATIVE_DEBUG_SYMBOLS)
|
||||
AC_SUBST(DEBUG_BINARIES)
|
||||
AC_SUBST(STRIP_POLICY)
|
||||
AC_SUBST(ENABLE_DEBUG_SYMBOLS)
|
||||
AC_SUBST(ZIP_DEBUGINFO_FILES)
|
||||
])
|
||||
|
@ -271,6 +271,9 @@ SJAVAC_SERVER_DIR=$(MAKESUPPORT_OUTPUTDIR)/javacservers
|
||||
# Number of parallel jobs to use for compilation
|
||||
JOBS?=@JOBS@
|
||||
|
||||
# Default make target
|
||||
DEFAULT_MAKE_TARGET:=@DEFAULT_MAKE_TARGET@
|
||||
|
||||
FREETYPE_LIBS:=@FREETYPE_LIBS@
|
||||
FREETYPE_CFLAGS:=@FREETYPE_CFLAGS@
|
||||
FREETYPE_BUNDLE_LIB_PATH=@FREETYPE_BUNDLE_LIB_PATH@
|
||||
@ -418,6 +421,9 @@ ENABLE_DEBUG_SYMBOLS:=@ENABLE_DEBUG_SYMBOLS@
|
||||
CFLAGS_DEBUG_SYMBOLS:=@CFLAGS_DEBUG_SYMBOLS@
|
||||
CXXFLAGS_DEBUG_SYMBOLS:=@CXXFLAGS_DEBUG_SYMBOLS@
|
||||
ZIP_DEBUGINFO_FILES:=@ZIP_DEBUGINFO_FILES@
|
||||
NATIVE_DEBUG_SYMBOLS:=@NATIVE_DEBUG_SYMBOLS@
|
||||
DEBUG_BINARIES:=@DEBUG_BINARIES@
|
||||
STRIP_POLICY:=@STRIP_POLICY@
|
||||
|
||||
#
|
||||
# Compress (or not) jars
|
||||
|
127
common/bin/jib.sh
Normal file
127
common/bin/jib.sh
Normal file
@ -0,0 +1,127 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# This script installs the JIB tool into it's own local repository and
|
||||
# puts a wrapper scripts into <source-root>/.jib
|
||||
|
||||
mydir="$(dirname "${BASH_SOURCE[0]}")"
|
||||
myname="$(basename "${BASH_SOURCE[0]}")"
|
||||
|
||||
installed_jib_script=${mydir}/../../.jib/jib
|
||||
install_data=${mydir}/../../.jib/.data
|
||||
|
||||
setup_url() {
|
||||
if [ -f "~/.config/jib/jib.conf" ]; then
|
||||
source ~/.config/jib/jib.conf
|
||||
fi
|
||||
|
||||
jib_repository="jdk-virtual"
|
||||
jib_organization="jpg/infra/builddeps"
|
||||
jib_module="jib"
|
||||
jib_revision="2.0-SNAPSHOT"
|
||||
jib_ext="jib.sh.gz"
|
||||
|
||||
closed_script="${mydir}/../../closed/conf/jib-install.conf"
|
||||
if [ -f "${closed_script}" ]; then
|
||||
source "${closed_script}"
|
||||
fi
|
||||
|
||||
if [ -n "${JIB_SERVER}" ]; then
|
||||
jib_server="${JIB_SERVER}"
|
||||
fi
|
||||
if [ -n "${JIB_REPOSITORY}" ]; then
|
||||
jib_repository="${JIB_REPOSITORY}"
|
||||
fi
|
||||
if [ -n "${JIB_ORGANIZATION}" ]; then
|
||||
jib_organization="${JIB_ORGANIZATION}"
|
||||
fi
|
||||
if [ -n "${JIB_MODULE}" ]; then
|
||||
jib_module="${JIB_MODULE}"
|
||||
fi
|
||||
if [ -n "${JIB_REVISION}" ]; then
|
||||
jib_revision="${JIB_REVISION}"
|
||||
fi
|
||||
if [ -n "${JIB_EXTENSION}" ]; then
|
||||
jib_extension="${JIB_EXTENSION}"
|
||||
fi
|
||||
|
||||
if [ -n "${JIB_URL}" ]; then
|
||||
jib_url="${JIB_URL}"
|
||||
data_string="${jib_url}"
|
||||
else
|
||||
data_string="${jib_repository}/${jib_organization}/${jib_module}/${jib_revision}/${jib_module}-${jib_revision}.${jib_ext}"
|
||||
jib_url="${jib_server}/${data_string}"
|
||||
fi
|
||||
}
|
||||
|
||||
install_jib() {
|
||||
if [ -z "${jib_server}" -a -z "${JIB_URL}" ]; then
|
||||
echo "No jib server or URL provided, set either"
|
||||
echo "JIB_SERVER=<base server address>"
|
||||
echo "or"
|
||||
echo "JIB_URL=<full path to install script>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if command -v curl > /dev/null; then
|
||||
getcmd="curl -s"
|
||||
elif command -v wget > /dev/null; then
|
||||
getcmd="wget --quiet -O -"
|
||||
else
|
||||
echo "Could not find either curl or wget"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v gunzip > /dev/null; then
|
||||
echo "Could not find gunzip"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Downloading JIB bootstrap script"
|
||||
mkdir -p "${installed_jib_script%/*}"
|
||||
rm -f "${installed_jib_script}.gz"
|
||||
${getcmd} ${jib_url} > "${installed_jib_script}.gz"
|
||||
if [ ! -s "${installed_jib_script}.gz" ]; then
|
||||
echo "Failed to download ${jib_url}"
|
||||
exit 1
|
||||
fi
|
||||
echo "Extracting JIB bootstrap script"
|
||||
rm -f "${installed_jib_script}"
|
||||
gunzip "${installed_jib_script}.gz"
|
||||
chmod +x "${installed_jib_script}"
|
||||
echo "${data_string}" > "${install_data}"
|
||||
}
|
||||
|
||||
# Main body starts here
|
||||
|
||||
setup_url
|
||||
|
||||
if [ ! -x "${installed_jib_script}" ]; then
|
||||
install_jib
|
||||
elif [ ! -e "${install_data}" ] || [ "${data_string}" != "$(cat "${install_data}")" ]; then
|
||||
echo "Install url changed since last time, reinstalling"
|
||||
install_jib
|
||||
fi
|
||||
|
||||
${installed_jib_script} "$@"
|
@ -1293,10 +1293,7 @@ jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/j2secmod_md.h : jdk/src/win
|
||||
jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/p11_md.c : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.c
|
||||
jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/p11_md.h : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.h
|
||||
jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/package.html : jdk/src/macosx/classes/com/apple/concurrent/package.html
|
||||
jdk/src/jdk.deploy.osx/macosx/classes/apple/applescript : jdk/src/macosx/classes/apple/applescript
|
||||
jdk/src/jdk.deploy.osx/macosx/classes/apple/security : jdk/src/macosx/classes/apple/security
|
||||
jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent : jdk/src/macosx/classes/com/apple/concurrent
|
||||
jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine : jdk/src/macosx/native/apple/applescript
|
||||
jdk/src/jdk.deploy.osx/macosx/native/libosx/CFileManager.m : jdk/src/macosx/native/com/apple/eio/CFileManager.m
|
||||
jdk/src/jdk.deploy.osx/macosx/native/libosx/Dispatch.m : jdk/src/macosx/native/com/apple/concurrent/Dispatch.m
|
||||
jdk/src/jdk.deploy.osx/macosx/native/libosx/JavaAppLauncher.m : jdk/src/macosx/native/apple/launcher/JavaAppLauncher.m
|
||||
|
555
common/conf/jib-profiles.js
Normal file
555
common/conf/jib-profiles.js
Normal file
@ -0,0 +1,555 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file defines build profiles for the JIB tool and others.
|
||||
*
|
||||
* A build profile defines a set of configuration options and external
|
||||
* dependencies that we for some reason or other care about specifically.
|
||||
* Typically, build profiles are defined for the build configurations we
|
||||
* build regularly.
|
||||
*
|
||||
* Contract against this file from the tools that use it, is to provide
|
||||
* a function on the form:
|
||||
*
|
||||
* getJibProfiles(input)
|
||||
*
|
||||
* which returns an object graph describing the profiles and their
|
||||
* dependencies. The name of the function is based on the name of this
|
||||
* file, minus the extension and the '-', camel cased and prefixed with
|
||||
* 'get'.
|
||||
*
|
||||
*
|
||||
* The parameter 'input' is an object that optionally contains some data.
|
||||
* Optionally because a tool may read the configuration for different purposes.
|
||||
* To initially get a list of available profiles, the active profile may not
|
||||
* yet be known for instance.
|
||||
*
|
||||
* Data that may be set on the input object:
|
||||
*
|
||||
* input.profile = <name of active profile>
|
||||
*
|
||||
* If the active profile is set, the following data from it must also
|
||||
* be provided:
|
||||
*
|
||||
* input.profile
|
||||
* input.target_os
|
||||
* input.target_cpu
|
||||
* input.build_os
|
||||
* input.build_cpu
|
||||
* input.target_platform
|
||||
* input.build_platform
|
||||
* // The build_osenv_* variables describe the unix layer on Windows systems,
|
||||
* // i.e. Cygwin, which may also be 32 or 64 bit.
|
||||
* input.build_osenv
|
||||
* input.build_osenv_cpu
|
||||
* input.build_osenv_platform
|
||||
*
|
||||
* For more complex nested attributes, there is a method "get":
|
||||
*
|
||||
* input.get("<dependency>", "<attribute>")
|
||||
*
|
||||
* Valid attributes are:
|
||||
* install_path
|
||||
* download_path
|
||||
* download_dir
|
||||
*
|
||||
*
|
||||
* The output data generated by this configuration file has the following
|
||||
* format:
|
||||
*
|
||||
* data: {
|
||||
* // Identifies the version of this format to the tool reading it
|
||||
* format_version: "1.0",
|
||||
*
|
||||
* // Name of base outputdir. JIB assumes the actual output dir is formed
|
||||
* // by adding the configuration name: <output_basedir>/<config-name>
|
||||
* output_basedir: "build",
|
||||
* // Configure argument to use to specify configuration name
|
||||
* configuration_configure_arg:
|
||||
* // Make argument to use to specify configuration name
|
||||
* configuration_make_arg:
|
||||
*
|
||||
* profiles: {
|
||||
* <profile-name>: {
|
||||
* // Name of os the profile is built to run on
|
||||
* target_os; <string>
|
||||
* // Name of cpu the profile is built to run on
|
||||
* target_cpu; <string>
|
||||
* // Combination of target_os and target_cpu for convenience
|
||||
* target_platform; <string>
|
||||
* // Name of os the profile is built on
|
||||
* build_os; <string>
|
||||
* // Name of cpu the profile is built on
|
||||
* build_cpu; <string>
|
||||
* // Combination of build_os and build_cpu for convenience
|
||||
* build_platform; <string>
|
||||
*
|
||||
* // List of dependencies needed to build this profile
|
||||
* dependencies: <Array of strings>
|
||||
*
|
||||
* // List of configure args to use for this profile
|
||||
* configure_args: <Array of strings>
|
||||
*
|
||||
* // List of free form labels describing aspects of this profile
|
||||
* labels: <Array of strings>
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Dependencies use a Maven like deployment structure
|
||||
* dependencies: {
|
||||
* <dependency-name>: {
|
||||
* // Organization part of path defining this dependency
|
||||
* organization: <string>
|
||||
* // File extension for this dependency
|
||||
* ext: <string>
|
||||
* // Module part of path for defining this dependency,
|
||||
* // defaults to <dependency-name>
|
||||
* module: <string>
|
||||
* // Revision part of path for defining this dependency
|
||||
* revision: <string>
|
||||
*
|
||||
* // List of configure args to add when using this dependency,
|
||||
* // defaults to
|
||||
* // "--with-<dependency-name>=input.get("<dependency-name", "install_path")"
|
||||
* configure_args: <array of strings>
|
||||
*
|
||||
* // Name of environment variable to set when using this dependency
|
||||
* // when running make
|
||||
* environment_name: <string>
|
||||
* // Value of environment variable to set when using this dependency
|
||||
* // when running make
|
||||
* environment_value: <string>
|
||||
*
|
||||
* // Value to add to the PATH variable when using this dependency,
|
||||
* // applies to both make and configure
|
||||
* environment_path: <string>
|
||||
* }
|
||||
*
|
||||
* <dependency-name>: {
|
||||
* // For certain dependencies where a legacy distribution mechanism is
|
||||
* // already in place, the "javare" server layout is also supported
|
||||
* // Indicate that an alternate server source and layout should be used
|
||||
* server: "javare"
|
||||
*
|
||||
* // For "javare", a combination of module, revision,
|
||||
* // build number (optional), files and checksum file is possible for
|
||||
* // artifacts following the standard layout.
|
||||
* module: <string>
|
||||
* revision: <string>
|
||||
* build_number: <string>
|
||||
* checksum_file: <string>
|
||||
* file: <string>
|
||||
*
|
||||
* // For other files, use checksum path and path instead
|
||||
* checksum_path: <string>
|
||||
* path: <string>
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
/**
|
||||
* Main entry to generate the profile configuration
|
||||
*
|
||||
* @param input External data to use for generating the configuration
|
||||
* @returns {{}} Profile configuration
|
||||
*/
|
||||
var getJibProfiles = function (input) {
|
||||
|
||||
var data = {};
|
||||
|
||||
// Identifies the version of this format to the tool reading it
|
||||
data.format_version = "1.0";
|
||||
|
||||
// Organization is used when uploading/publishing build results
|
||||
data.organization = "com.oracle.jpg.jdk";
|
||||
|
||||
// The base directory for the build output. JIB will assume that the
|
||||
// actual build directory will be <output_basedir>/<configuration>
|
||||
data.output_basedir = "build";
|
||||
// The configure argument to use to specify the name of the configuration
|
||||
data.configuration_configure_arg = "--with-conf-name=";
|
||||
// The make argument to use to specify the name of the configuration
|
||||
data.configuration_make_arg = "CONF_NAME=";
|
||||
|
||||
// Define some common values
|
||||
var common = getJibProfilesCommon(input);
|
||||
// Generate the profiles part of the configuration
|
||||
data.profiles = getJibProfilesProfiles(input, common);
|
||||
// Generate the dependencies part of the configuration
|
||||
data.dependencies = getJibProfilesDependencies(input, common);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates some common values
|
||||
*
|
||||
* @param input External data to use for generating the configuration
|
||||
* @returns Common values
|
||||
*/
|
||||
var getJibProfilesCommon = function (input) {
|
||||
var common = {
|
||||
dependencies: ["boot_jdk", "gnumake", "jtreg"],
|
||||
configure_args: ["--with-default-make-target=all"],
|
||||
configure_args_32bit: ["--with-target-bits=32", "--with-jvm-variants=client,server"],
|
||||
configure_args_debug: ["--enable-debug"],
|
||||
organization: "jpg.infra.builddeps"
|
||||
};
|
||||
|
||||
return common;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates the profiles part of the configuration.
|
||||
*
|
||||
* @param input External data to use for generating the configuration
|
||||
* @param common The common values
|
||||
* @returns {{}} Profiles part of the configuration
|
||||
*/
|
||||
var getJibProfilesProfiles = function (input, common) {
|
||||
var profiles = {};
|
||||
|
||||
// Main SE profiles
|
||||
var mainProfiles = {
|
||||
|
||||
"linux-x64": {
|
||||
target_os: "linux",
|
||||
target_cpu: "x64",
|
||||
dependencies: concat(common.dependencies, "devkit"),
|
||||
configure_args: common.configure_args,
|
||||
make_args: common.make_args
|
||||
},
|
||||
|
||||
"linux-x86": {
|
||||
target_os: "linux",
|
||||
target_cpu: "x86",
|
||||
build_cpu: "x64",
|
||||
dependencies: concat(common.dependencies, "devkit"),
|
||||
configure_args: concat(common.configure_args, common.configure_args_32bit),
|
||||
make_args: common.make_args
|
||||
},
|
||||
|
||||
"macosx-x64": {
|
||||
target_os: "macosx",
|
||||
target_cpu: "x64",
|
||||
dependencies: concat(common.dependencies, "devkit"),
|
||||
configure_args: concat(common.configure_args, "--with-sdk-name=macosx10.9"),
|
||||
make_args: common.make_args
|
||||
},
|
||||
|
||||
"solaris-x64": {
|
||||
target_os: "solaris",
|
||||
target_cpu: "x64",
|
||||
dependencies: concat(common.dependencies, "devkit", "cups"),
|
||||
configure_args: common.configure_args,
|
||||
make_args: common.make_args
|
||||
},
|
||||
|
||||
"solaris-sparcv9": {
|
||||
target_os: "solaris",
|
||||
target_cpu: "sparcv9",
|
||||
dependencies: concat(common.dependencies, "devkit", "cups"),
|
||||
configure_args: common.configure_args,
|
||||
make_args: common.make_args
|
||||
},
|
||||
|
||||
"windows-x64": {
|
||||
target_os: "windows",
|
||||
target_cpu: "x64",
|
||||
dependencies: concat(common.dependencies, "devkit", "freetype"),
|
||||
configure_args: common.configure_args,
|
||||
make_args: common.make_args
|
||||
},
|
||||
|
||||
"windows-x86": {
|
||||
target_os: "windows",
|
||||
target_cpu: "x86",
|
||||
build_cpu: "x64",
|
||||
dependencies: concat(common.dependencies, "devkit", "freetype"),
|
||||
configure_args: concat(common.configure_args, common.configure_args_32bit),
|
||||
make_args: common.make_args
|
||||
}
|
||||
};
|
||||
profiles = concatObjects(profiles, mainProfiles);
|
||||
// Generate debug versions of all the main profiles
|
||||
profiles = concatObjects(profiles, generateDebugProfiles(common, mainProfiles));
|
||||
|
||||
// Specific open profiles needed for JPRT testing
|
||||
var jprtOpenProfiles = {
|
||||
|
||||
"linux-x64-open": {
|
||||
target_os: mainProfiles["linux-x64"].target_os,
|
||||
target_cpu: mainProfiles["linux-x64"].target_cpu,
|
||||
dependencies: mainProfiles["linux-x64"].dependencies,
|
||||
configure_args: concat(mainProfiles["linux-x64"].configure_args,
|
||||
"--enable-openjdk-only"),
|
||||
make_args: mainProfiles["linux-x64"].make_args,
|
||||
labels: [ "open" ]
|
||||
},
|
||||
|
||||
"solaris-x64-open": {
|
||||
target_os: mainProfiles["solaris-x64"].target_os,
|
||||
target_cpu: mainProfiles["solaris-x64"].target_cpu,
|
||||
dependencies: mainProfiles["solaris-x64"].dependencies,
|
||||
configure_args: concat(mainProfiles["solaris-x64"].configure_args,
|
||||
"--enable-openjdk-only"),
|
||||
make_args: mainProfiles["solaris-x64"].make_args,
|
||||
labels: [ "open" ]
|
||||
}
|
||||
};
|
||||
profiles = concatObjects(profiles, jprtOpenProfiles);
|
||||
// Generate debug profiles for the open jprt profiles
|
||||
profiles = concatObjects(profiles, generateDebugProfiles(common, jprtOpenProfiles));
|
||||
|
||||
// Profiles used to run tests. Used in JPRT.
|
||||
var testOnlyProfiles = {
|
||||
|
||||
"run-test": {
|
||||
target_os: input.build_os,
|
||||
target_cpu: input.build_cpu,
|
||||
dependencies: [ "jtreg", "gnumake" ],
|
||||
labels: "test"
|
||||
}
|
||||
};
|
||||
profiles = concatObjects(profiles, testOnlyProfiles);
|
||||
|
||||
// Generate the missing platform attributes
|
||||
profiles = generatePlatformAttributes(profiles);
|
||||
return profiles;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate the dependencies part of the configuration
|
||||
*
|
||||
* @param input External data to use for generating the configuration
|
||||
* @param common The common values
|
||||
* @returns {{}} Dependencies part of configuration
|
||||
*/
|
||||
var getJibProfilesDependencies = function (input, common) {
|
||||
|
||||
var boot_jdk_platform = input.build_os + "-"
|
||||
+ (input.build_cpu == "x86" ? "i586" : input.build_cpu);
|
||||
|
||||
var devkit_platform_revisions = {
|
||||
linux_x64: "gcc4.9.2-OEL6.4+1.0",
|
||||
macosx_x64: "Xcode6.3-MacOSX10.9+1.0",
|
||||
solaris_x64: "SS12u3-Solaris10u10+1.0",
|
||||
solaris_sparcv9: "SS12u3-Solaris10u10+1.0",
|
||||
windows_x64: "VS2013SP4+1.0"
|
||||
};
|
||||
|
||||
var devkit_platform = (input.target_cpu == "x86"
|
||||
? input.target_os + "_x64"
|
||||
: input.target_platform);
|
||||
|
||||
var dependencies = {
|
||||
|
||||
boot_jdk: {
|
||||
server: "javare",
|
||||
module: "jdk",
|
||||
revision: "8",
|
||||
checksum_file: boot_jdk_platform + "/MD5_VALUES",
|
||||
file: boot_jdk_platform + "/jdk-8-" + boot_jdk_platform + ".tar.gz",
|
||||
configure_args: (input.build_os == "macosx"
|
||||
? "--with-boot-jdk=" + input.get("boot_jdk", "install_path") + "/jdk1.8.0.jdk/Contents/Home"
|
||||
: "--with-boot-jdk=" + input.get("boot_jdk", "install_path") + "/jdk1.8.0")
|
||||
},
|
||||
|
||||
devkit: {
|
||||
organization: common.organization,
|
||||
ext: "tar.gz",
|
||||
module: "devkit-" + devkit_platform,
|
||||
revision: devkit_platform_revisions[devkit_platform]
|
||||
},
|
||||
|
||||
build_devkit: {
|
||||
organization: common.organization,
|
||||
ext: "tar.gz",
|
||||
module: "devkit-" + input.build_platform,
|
||||
revision: devkit_platform_revisions[input.build_platform]
|
||||
},
|
||||
|
||||
cups: {
|
||||
organization: common.organization,
|
||||
ext: "tar.gz",
|
||||
revision: "1.0118+1.0"
|
||||
},
|
||||
|
||||
jtreg: {
|
||||
server: "javare",
|
||||
revision: "4.1",
|
||||
build_number: "b12",
|
||||
checksum_file: "MD5_VALUES",
|
||||
file: "jtreg_bin-4.1.zip",
|
||||
environment_name: "JT_HOME"
|
||||
},
|
||||
|
||||
gnumake: {
|
||||
organization: common.organization,
|
||||
ext: "tar.gz",
|
||||
revision: "4.0+1.0",
|
||||
|
||||
module: (input.build_os == "windows"
|
||||
? "gnumake-" + input.build_osenv_platform
|
||||
: "gnumake-" + input.build_platform),
|
||||
|
||||
configure_args: (input.build_os == "windows"
|
||||
? "MAKE=" + input.get("gnumake", "install_path") + "/cygwin/bin/make"
|
||||
: "MAKE=" + input.get("gnumake", "install_path") + "/bin/make"),
|
||||
|
||||
environment_path: (input.build_os == "windows"
|
||||
? input.get("gnumake", "install_path") + "/cygwin/bin"
|
||||
: input.get("gnumake", "install_path") + "/bin")
|
||||
},
|
||||
|
||||
freetype: {
|
||||
organization: common.organization,
|
||||
ext: "tar.gz",
|
||||
revision: "2.3.4+1.0",
|
||||
module: "freetype-" + input.target_platform
|
||||
}
|
||||
};
|
||||
|
||||
return dependencies;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate the missing platform attributes for profiles
|
||||
*
|
||||
* @param profiles Profiles map to generate attributes on
|
||||
* @returns {{}} New profiles map with platform attributes fully filled in
|
||||
*/
|
||||
var generatePlatformAttributes = function (profiles) {
|
||||
var ret = concatObjects(profiles, {});
|
||||
for (var profile in profiles) {
|
||||
if (ret[profile].build_os == null) {
|
||||
ret[profile].build_os = ret[profile].target_os;
|
||||
}
|
||||
if (ret[profile].build_cpu == null) {
|
||||
ret[profile].build_cpu = ret[profile].target_cpu;
|
||||
}
|
||||
ret[profile].target_platform = ret[profile].target_os + "_" + ret[profile].target_cpu;
|
||||
ret[profile].build_platform = ret[profile].build_os + "_" + ret[profile].build_cpu;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates debug versions of profiles. Clones the given profiles and adds
|
||||
* debug metadata.
|
||||
*
|
||||
* @param common Common values
|
||||
* @param profiles Profiles map to generate debug profiles for
|
||||
* @returns {{}} New map of profiles containing debug profiles
|
||||
*/
|
||||
var generateDebugProfiles = function (common, profiles) {
|
||||
var newProfiles = {};
|
||||
for (var profile in profiles) {
|
||||
var debugProfile = profile + "-debug";
|
||||
newProfiles[debugProfile] = clone(profiles[profile]);
|
||||
newProfiles[debugProfile].debug_level = "fastdebug";
|
||||
newProfiles[debugProfile].labels
|
||||
= concat(newProfiles[debugProfile].labels || [], "debug"),
|
||||
newProfiles[debugProfile].configure_args
|
||||
= concat(newProfiles[debugProfile].configure_args,
|
||||
common.configure_args_debug);
|
||||
}
|
||||
return newProfiles;
|
||||
};
|
||||
|
||||
/**
|
||||
* Deep clones an object tree.
|
||||
*
|
||||
* @param o Object to clone
|
||||
* @returns {{}} Clone of o
|
||||
*/
|
||||
var clone = function (o) {
|
||||
return JSON.parse(JSON.stringify(o));
|
||||
};
|
||||
|
||||
/**
|
||||
* Concatenates all arguments into a new array
|
||||
*
|
||||
* @returns {Array.<T>} New array containing all arguments
|
||||
*/
|
||||
var concat = function () {
|
||||
return Array.prototype.concat.apply([], arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
* Copies all elements in an array into a new array but replacing all
|
||||
* occurrences of original with replacement.
|
||||
*
|
||||
* @param original Element to look for
|
||||
* @param replacement Element to replace with
|
||||
* @param a Array to copy
|
||||
* @returns {Array} New array with all occurrences of original replaced
|
||||
* with replacement
|
||||
*/
|
||||
var replace = function (original, replacement, a) {
|
||||
var newA = [];
|
||||
for (var i in a) {
|
||||
if (original == a[i]) {
|
||||
newA.push(replacement);
|
||||
} else {
|
||||
newA.push(a[i]);
|
||||
}
|
||||
}
|
||||
return newA;
|
||||
};
|
||||
|
||||
/**
|
||||
* Deep concatenation of two objects. For each node encountered, merge
|
||||
* the contents with the corresponding node in the other object tree,
|
||||
* treating all strings as array elements.
|
||||
*
|
||||
* @param o1 Object to concatenate
|
||||
* @param o2 Object to concatenate
|
||||
* @returns {{}} New object tree containing the concatenation of o1 and o2
|
||||
*/
|
||||
var concatObjects = function (o1, o2) {
|
||||
var ret = {};
|
||||
for (var a in o1) {
|
||||
if (o2[a] == null) {
|
||||
ret[a] = o1[a];
|
||||
}
|
||||
}
|
||||
for (var a in o2) {
|
||||
if (o1[a] == null) {
|
||||
ret[a] = o2[a];
|
||||
} else {
|
||||
if (typeof o1[a] == 'string') {
|
||||
ret[a] = [o1[a]].concat(o2[a]);
|
||||
} else if (Array.isArray(o1[a])) {
|
||||
ret[a] = o1[a].concat(o2[a]);
|
||||
} else if (typeof o1[a] == 'object') {
|
||||
ret[a] = concatObjects(o1[a], o2[a]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
@ -11,7 +11,12 @@
|
||||
^.hgtip
|
||||
.DS_Store
|
||||
\.class$
|
||||
^\.?mx.jvmci/
|
||||
^\.mx.jvmci/env
|
||||
^\.mx.jvmci/.*\.pyc
|
||||
^\.mx.jvmci/eclipse-launches/.*
|
||||
^\.mx.jvmci/hotspot/eclipse/.*
|
||||
^\.idea/
|
||||
^workingsets.xml
|
||||
^src/jdk.vm.ci/share/classes/\w[\w\.]*/.*\.xml
|
||||
^src/jdk.vm.ci/share/classes/\w[\w\.]*/.*\.iml
|
||||
^src/jdk.vm.ci/share/classes/\w[\w\.]*/nbproject
|
||||
|
@ -498,3 +498,4 @@ bc48b669bc6610fac97e16593050c0f559cf6945 jdk9-b88
|
||||
d8b24776484cc4dfd19f50b23eaa18a80a161371 jdk9-b93
|
||||
a22b7c80529f5f05c847e932e017456e83c46233 jdk9-b94
|
||||
0c79cf3cdf0904fc4a630b91b32904491e1ae430 jdk-9+95
|
||||
a94bb7203596dd632486f1e3655fa5f70541dc08 jdk-9+96
|
||||
|
18
hotspot/.mx.jvmci/.project
Normal file
18
hotspot/.mx.jvmci/.project
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>mx.jvmci</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
<project>mx</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.python.pydev.PyDevBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.python.pydev.pythonNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
14
hotspot/.mx.jvmci/.pydevproject
Normal file
14
hotspot/.mx.jvmci/.pydevproject
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?eclipse-pydev version="1.0"?>
|
||||
|
||||
<pydev_project>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
|
||||
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
||||
<path>/mx.jvmci</path>
|
||||
</pydev_pathproperty>
|
||||
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
||||
<path>/mx</path>
|
||||
</pydev_pathproperty>
|
||||
|
||||
</pydev_project>
|
@ -0,0 +1 @@
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=disabled
|
145
hotspot/.mx.jvmci/hotspot/templates/eclipse/cproject
Normal file
145
hotspot/.mx.jvmci/hotspot/templates/eclipse/cproject
Normal file
@ -0,0 +1,145 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="hotspot" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
|
||||
<folderInfo id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577" name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.base.1866612258" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.2075405295" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
|
||||
<builder autoBuildTarget="" buildPath="${workspace_loc:/hotspot}/.." cleanBuildTarget="clean" enableAutoBuild="true" enableCleanBuild="false" enabledIncrementalBuild="false" id="cdt.managedbuild.target.gnu.builder.base.81453037" incrementalBuildTarget="jvmg1" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base">
|
||||
<outputEntries>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name=""/>
|
||||
</outputEntries>
|
||||
</builder>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1094883386" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1342888057" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
|
||||
<option id="gnu.cpp.compiler.option.preprocessor.def.634868600" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="_LP64=1"/>
|
||||
<listOptionValue builtIn="false" value="COMPILER1=1"/>
|
||||
<listOptionValue builtIn="false" value="VM_LITTLE_ENDIAN=1"/>
|
||||
<listOptionValue builtIn="false" value="ASSERT=1"/>
|
||||
<listOptionValue builtIn="false" value="_REENTRANT=1"/>
|
||||
<listOptionValue builtIn="false" value="DEBUG=1"/>
|
||||
<listOptionValue builtIn="false" value="AMD64=1"/>
|
||||
<listOptionValue builtIn="false" value="LINUX=1"/>
|
||||
<listOptionValue builtIn="false" value="TARGET_ARCH_x86=1"/>
|
||||
<listOptionValue builtIn="false" value="TARGET_COMPILER_gcc=1"/>
|
||||
<listOptionValue builtIn="false" value="TARGET_OS_FAMILY_linux=1"/>
|
||||
<listOptionValue builtIn="false" value="TARGET_OS_ARCH_linux_x86=1"/>
|
||||
<listOptionValue builtIn="false" value="TARGET_ARCH_MODEL_x86_64=1"/>
|
||||
<listOptionValue builtIn="false" value="INCLUDE_JVMCI=1"/>
|
||||
<listOptionValue builtIn="false" value="COMPILER2=1"/>
|
||||
</option>
|
||||
<option id="gnu.cpp.compiler.option.preprocessor.undef.2137486146" name="Undefined symbols (-U)" superClass="gnu.cpp.compiler.option.preprocessor.undef"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.866181452" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1535888880" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
|
||||
<option id="gnu.c.compiler.option.preprocessor.def.symbols.825962493" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="_LP64=1"/>
|
||||
<listOptionValue builtIn="false" value="COMPILER1=1"/>
|
||||
<listOptionValue builtIn="false" value="VM_LITTLE_ENDIAN=1"/>
|
||||
<listOptionValue builtIn="false" value="ASSERT=1"/>
|
||||
<listOptionValue builtIn="false" value="_REENTRANT=1"/>
|
||||
<listOptionValue builtIn="false" value="DEBUG=1"/>
|
||||
<listOptionValue builtIn="false" value="AMD64=1"/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.906671119" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.base.1271041307" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.550499946" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.274517766" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.base.554053529" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1055083385" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="cpu/vm/templateTable_x86_32.cpp|cpu/vm/templateInterpreter_x86_32.cpp|cpu/vm/stubRoutines_x86_32.cpp|cpu/vm/stubGenerator_x86_32.cpp|cpu/vm/sharedRuntime_x86_32.cpp|cpu/vm/jniFastGetField_x86_32.cpp|cpu/vm/interpreterRT_x86_32.cpp|cpu/vm/interpreter_x86_32.cpp|cpu/vm/interp_masm_x86_32.cpp|cpu/vm/vtableStubs_x86_32.cpp" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="hotspot.null.1712822257" name="hotspot"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
<configuration configurationName="Default">
|
||||
<resource resourceType="PROJECT" workspacePath="/hotspot"/>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162.;cdt.managedbuild.tool.gnu.c.compiler.base.1862778408;cdt.managedbuild.tool.gnu.c.compiler.input.29080811">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004.;cdt.managedbuild.tool.gnu.cpp.compiler.base.501581878;cdt.managedbuild.tool.gnu.cpp.compiler.input.1552002453">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.388217325;cdt.managedbuild.tool.gnu.solaris.cpp.compiler.base.377383651;cdt.managedbuild.tool.gnu.cpp.compiler.input.103897085">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.solaris.c.compiler.base.351149667;cdt.managedbuild.tool.gnu.c.compiler.input.820447325">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.388217325;cdt.managedbuild.tool.gnu.solaris.c.compiler.base.212558466;cdt.managedbuild.tool.gnu.c.compiler.input.1115218695">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.c.compiler.base.1535888880;cdt.managedbuild.tool.gnu.c.compiler.input.906671119">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051.;cdt.managedbuild.tool.gnu.c.compiler.base.592469102;cdt.managedbuild.tool.gnu.c.compiler.input.1891927256">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.solaris.cpp.compiler.base.429326045;cdt.managedbuild.tool.gnu.cpp.compiler.input.1860785837">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004.;cdt.managedbuild.tool.gnu.c.compiler.base.647707969;cdt.managedbuild.tool.gnu.c.compiler.input.1613323394">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162.;cdt.managedbuild.tool.gnu.c.compiler.base.1536145259;cdt.managedbuild.tool.gnu.c.compiler.input.1935913022">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.cpp.compiler.base.1342888057;cdt.managedbuild.tool.gnu.cpp.compiler.input.866181452">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225.;cdt.managedbuild.tool.gnu.cpp.compiler.base.1404788740;cdt.managedbuild.tool.gnu.cpp.compiler.input.1175382997">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162.;cdt.managedbuild.tool.gnu.cpp.compiler.base.677873708;cdt.managedbuild.tool.gnu.cpp.compiler.input.429177901">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051.;cdt.managedbuild.tool.gnu.cpp.compiler.base.1920567990;cdt.managedbuild.tool.gnu.cpp.compiler.input.1463421641">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225.;cdt.managedbuild.tool.gnu.c.compiler.base.961579870;cdt.managedbuild.tool.gnu.c.compiler.input.1710196852">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162.;cdt.managedbuild.tool.gnu.cpp.compiler.base.1673917487;cdt.managedbuild.tool.gnu.cpp.compiler.input.931461388">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.pathentry"/>
|
||||
</cproject>
|
@ -0,0 +1,198 @@
|
||||
eclipse.preferences.version=1
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162/BUILDING_FROM_IDE/delimiter=\:
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162/BUILDING_FROM_IDE/operation=append
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162/BUILDING_FROM_IDE/value=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162/append=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162/appendContributed=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004.562670952/BUILDING_FROM_IDE/delimiter=\:
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004.562670952/BUILDING_FROM_IDE/operation=append
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004.562670952/BUILDING_FROM_IDE/value=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004.562670952/append=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004.562670952/appendContributed=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004/BUILDING_FROM_IDE/delimiter=\:
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004/BUILDING_FROM_IDE/operation=append
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004/BUILDING_FROM_IDE/value=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004/append=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004/appendContributed=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051/BUILDING_FROM_IDE/delimiter=\:
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051/BUILDING_FROM_IDE/operation=append
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051/BUILDING_FROM_IDE/value=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051/append=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051/appendContributed=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225/BUILDING_FROM_IDE/delimiter=\:
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225/BUILDING_FROM_IDE/operation=append
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225/BUILDING_FROM_IDE/value=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225/append=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225/appendContributed=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162/BUILDING_FROM_IDE/delimiter=\:
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162/BUILDING_FROM_IDE/operation=append
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162/BUILDING_FROM_IDE/value=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162/append=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162/appendContributed=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881/BUILDING_FROM_IDE/delimiter=\:
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881/BUILDING_FROM_IDE/operation=append
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881/BUILDING_FROM_IDE/value=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881/append=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881/appendContributed=true
|
||||
org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_assignment=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration=80
|
||||
org.eclipse.cdt.core.formatter.alignment_for_binary_expression=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_compact_if=0
|
||||
org.eclipse.cdt.core.formatter.alignment_for_conditional_expression=80
|
||||
org.eclipse.cdt.core.formatter.alignment_for_conditional_expression_chain=18
|
||||
org.eclipse.cdt.core.formatter.alignment_for_constructor_initializer_list=0
|
||||
org.eclipse.cdt.core.formatter.alignment_for_declarator_list=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_enumerator_list=48
|
||||
org.eclipse.cdt.core.formatter.alignment_for_expression_list=0
|
||||
org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_member_access=0
|
||||
org.eclipse.cdt.core.formatter.alignment_for_overloaded_left_shift_chain=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_block=end_of_line
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_method_declaration=end_of_line
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration=end_of_line
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_switch=end_of_line
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_type_declaration=end_of_line
|
||||
org.eclipse.cdt.core.formatter.comment.min_distance_between_code_and_line_comment=1
|
||||
org.eclipse.cdt.core.formatter.comment.never_indent_line_comments_on_first_column=true
|
||||
org.eclipse.cdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
|
||||
org.eclipse.cdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.cdt.core.formatter.continuation_indentation=2
|
||||
org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||
org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||
org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header=false
|
||||
org.eclipse.cdt.core.formatter.indent_access_specifier_extra_spaces=0
|
||||
org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier=true
|
||||
org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header=false
|
||||
org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header=false
|
||||
org.eclipse.cdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.cdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.cdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch=true
|
||||
org.eclipse.cdt.core.formatter.indentation.size=2
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_colon_in_constructor_initializer_list=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_exception_specification=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_binary_operator=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_exception_specification=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_exception_specification=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_exception_specification=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.cdt.core.formatter.join_wrapped_lines=true
|
||||
org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line=true
|
||||
org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.cdt.core.formatter.lineSplit=160
|
||||
org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.cdt.core.formatter.tabulation.char=space
|
||||
org.eclipse.cdt.core.formatter.tabulation.size=2
|
||||
org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
@ -0,0 +1,5 @@
|
||||
#Wed Sep 01 16:21:02 PDT 2010
|
||||
eclipse.preferences.version=1
|
||||
formatter_profile=_hotspotStyle
|
||||
formatter_settings_version=1
|
||||
|
@ -0,0 +1,6 @@
|
||||
#Wed Sep 01 16:13:40 PDT 2010
|
||||
content-types/enabled=true
|
||||
content-types/org.eclipse.cdt.core.cxxHeader/file-extensions=hpp,incl
|
||||
content-types/org.eclipse.cdt.core.cxxSource/file-extensions=cpp
|
||||
eclipse.preferences.version=1
|
||||
|
890
hotspot/.mx.jvmci/mx_jvmci.py
Normal file
890
hotspot/.mx.jvmci/mx_jvmci.py
Normal file
@ -0,0 +1,890 @@
|
||||
#
|
||||
# ----------------------------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
# ----------------------------------------------------------------------------------------------------
|
||||
|
||||
import os, shutil, zipfile, re, time, sys, datetime, platform
|
||||
from os.path import join, exists, dirname, isdir
|
||||
from argparse import ArgumentParser, REMAINDER
|
||||
import StringIO
|
||||
import xml.dom.minidom
|
||||
import subprocess
|
||||
|
||||
import mx
|
||||
import mx_gate
|
||||
import mx_unittest
|
||||
|
||||
from mx_gate import Task
|
||||
from mx_unittest import unittest
|
||||
|
||||
_suite = mx.suite('jvmci')
|
||||
|
||||
"""
|
||||
Top level directory of the JDK source workspace.
|
||||
"""
|
||||
_jdkSourceRoot = dirname(_suite.dir)
|
||||
|
||||
_JVMCI_JDK_TAG = 'jvmci'
|
||||
|
||||
_minVersion = mx.VersionSpec('1.9')
|
||||
|
||||
# max version (first _unsupported_ version)
|
||||
_untilVersion = None
|
||||
|
||||
_jvmciModes = {
|
||||
'hosted' : ['-XX:+UnlockExperimentalVMOptions', '-XX:+EnableJVMCI'],
|
||||
'jit' : ['-XX:+UnlockExperimentalVMOptions', '-XX:+EnableJVMCI', '-XX:+UseJVMCICompiler'],
|
||||
'disabled' : []
|
||||
}
|
||||
|
||||
# TODO: can optimized be built without overriding release build?
|
||||
_jdkDebugLevels = ['release', 'fastdebug', 'slowdebug']
|
||||
|
||||
# TODO: add client once/if it can be built on 64-bit platforms
|
||||
_jdkJvmVariants = ['server']
|
||||
|
||||
"""
|
||||
Translation table from mx_jvmci:8 --vmbuild values to mx_jvmci:9 --jdk-debug-level values.
|
||||
"""
|
||||
_legacyVmbuilds = {
|
||||
'product' : 'release',
|
||||
'debug' : 'slowdebug'
|
||||
}
|
||||
|
||||
"""
|
||||
Translates a mx_jvmci:8 --vmbuild value to a mx_jvmci:9 --jdk-debug-level value.
|
||||
"""
|
||||
def _translateLegacyDebugLevel(debugLevel):
|
||||
return _legacyVmbuilds.get(debugLevel, debugLevel)
|
||||
|
||||
"""
|
||||
Translation table from mx_jvmci:8 --vm values to mx_jvmci:9 (--jdk-jvm-variant, --jvmci-mode) tuples.
|
||||
"""
|
||||
_legacyVms = {
|
||||
'jvmci' : ('server', 'jit')
|
||||
}
|
||||
|
||||
"""
|
||||
A VM configuration composed of a JDK debug level, JVM variant and a JVMCI mode.
|
||||
This is also a context manager that can be used with the 'with' statement to set/change
|
||||
a VM configuration within a dynamic scope. For example:
|
||||
|
||||
with ConfiguredJDK(debugLevel='fastdebug'):
|
||||
dacapo(['pmd'])
|
||||
"""
|
||||
class VM:
|
||||
def __init__(self, jvmVariant=None, debugLevel=None, jvmciMode=None):
|
||||
self.update(jvmVariant, debugLevel, jvmciMode)
|
||||
|
||||
def update(self, jvmVariant=None, debugLevel=None, jvmciMode=None):
|
||||
if jvmVariant in _legacyVms:
|
||||
# Backwards compatibility for mx_jvmci:8 API
|
||||
jvmVariant, newJvmciMode = _legacyVms[jvmVariant]
|
||||
if jvmciMode is not None and jvmciMode != newJvmciMode:
|
||||
mx.abort('JVM variant "' + jvmVariant + '" implies JVMCI mode "' + newJvmciMode +
|
||||
'" which conflicts with explicitly specified JVMCI mode of "' + jvmciMode + '"')
|
||||
jvmciMode = newJvmciMode
|
||||
debugLevel = _translateLegacyDebugLevel(debugLevel)
|
||||
assert jvmVariant is None or jvmVariant in _jdkJvmVariants, jvmVariant
|
||||
assert debugLevel is None or debugLevel in _jdkDebugLevels, debugLevel
|
||||
assert jvmciMode is None or jvmciMode in _jvmciModes, jvmciMode
|
||||
self.jvmVariant = jvmVariant or _vm.jvmVariant
|
||||
self.debugLevel = debugLevel or _vm.debugLevel
|
||||
self.jvmciMode = jvmciMode or _vm.jvmciMode
|
||||
|
||||
def __enter__(self):
|
||||
global _vm
|
||||
self.previousVm = _vm
|
||||
_vm = self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
global _vm
|
||||
_vm = self.previousVm
|
||||
|
||||
_vm = VM(jvmVariant=_jdkJvmVariants[0], debugLevel=_jdkDebugLevels[0], jvmciMode='hosted')
|
||||
|
||||
def get_vm():
|
||||
"""
|
||||
Gets the configured VM.
|
||||
"""
|
||||
return _vm
|
||||
|
||||
def relativeVmLibDirInJdk():
|
||||
mxos = mx.get_os()
|
||||
if mxos == 'darwin':
|
||||
return join('lib')
|
||||
if mxos == 'windows' or mxos == 'cygwin':
|
||||
return join('bin')
|
||||
return join('lib', mx.get_arch())
|
||||
|
||||
def isJVMCIEnabled(vm):
|
||||
assert vm in _jdkJvmVariants
|
||||
return True
|
||||
|
||||
class JvmciJDKDeployedDist(object):
|
||||
def __init__(self, name, compilers=False):
|
||||
self._name = name
|
||||
self._compilers = compilers
|
||||
|
||||
def dist(self):
|
||||
return mx.distribution(self._name)
|
||||
|
||||
def deploy(self, jdkDir):
|
||||
mx.nyi('deploy', self)
|
||||
|
||||
class ExtJDKDeployedDist(JvmciJDKDeployedDist):
|
||||
def __init__(self, name):
|
||||
JvmciJDKDeployedDist.__init__(self, name)
|
||||
|
||||
|
||||
"""
|
||||
The monolithic JVMCI distribution is deployed through use of -Xbootclasspath/p
|
||||
so that it's not necessary to run JDK make after editing JVMCI sources.
|
||||
The latter causes all JDK Java sources to be rebuilt since JVMCI is
|
||||
(currently) in java.base.
|
||||
"""
|
||||
_monolithicJvmci = JvmciJDKDeployedDist('JVMCI')
|
||||
|
||||
"""
|
||||
List of distributions that are deployed on the boot class path.
|
||||
Note: In jvmci-8, they were deployed directly into the JDK directory.
|
||||
"""
|
||||
jdkDeployedDists = [_monolithicJvmci]
|
||||
|
||||
def _makehelp():
|
||||
return subprocess.check_output([mx.gmake_cmd(), 'help'], cwd=_jdkSourceRoot)
|
||||
|
||||
def _runmake(args):
|
||||
"""run the JDK make process
|
||||
|
||||
To build hotspot and import it into the JDK: "mx make hotspot import-hotspot"
|
||||
{0}"""
|
||||
|
||||
jdkBuildDir = _get_jdk_build_dir()
|
||||
if not exists(jdkBuildDir):
|
||||
# JDK9 must be bootstrapped with a JDK8
|
||||
compliance = mx.JavaCompliance('8')
|
||||
jdk8 = mx.get_jdk(compliance.exactMatch, versionDescription=compliance.value)
|
||||
cmd = ['sh', 'configure', '--with-debug-level=' + _vm.debugLevel, '--disable-debug-symbols', '--disable-precompiled-headers',
|
||||
'--with-jvm-variants=' + _vm.jvmVariant, '--disable-warnings-as-errors', '--with-boot-jdk=' + jdk8.home]
|
||||
mx.run(cmd, cwd=_jdkSourceRoot)
|
||||
cmd = [mx.gmake_cmd(), 'CONF=' + _vm.debugLevel]
|
||||
if mx.get_opts().verbose:
|
||||
cmd.append('LOG=debug')
|
||||
cmd.extend(args)
|
||||
if mx.get_opts().use_jdk_image and 'images' not in args:
|
||||
cmd.append('images')
|
||||
|
||||
if not mx.get_opts().verbose:
|
||||
mx.log('--------------- make execution ----------------------')
|
||||
mx.log('Working directory: ' + _jdkSourceRoot)
|
||||
mx.log('Command line: ' + ' '.join(cmd))
|
||||
mx.log('-----------------------------------------------------')
|
||||
|
||||
mx.run(cmd, cwd=_jdkSourceRoot)
|
||||
|
||||
if 'images' in cmd:
|
||||
_create_jdk_bundle(jdkBuildDir)
|
||||
|
||||
def _get_jdk_bundle_arches():
|
||||
"""
|
||||
Gets a list of names that will be the part of a JDK bundle's file name denoting the architecture.
|
||||
The first element in the list is the canonical name. Symlinks should be created for the
|
||||
remaining names.
|
||||
"""
|
||||
cpu = mx.get_arch()
|
||||
if cpu == 'amd64':
|
||||
return ['x64', 'x86_64', 'amd64']
|
||||
elif cpu == 'sparcv9':
|
||||
return ['sparcv9']
|
||||
mx.abort('Unsupported JDK bundle arch: ' + cpu)
|
||||
|
||||
def _create_jdk_bundle(jdkBuildDir):
|
||||
"""
|
||||
Creates a tar.gz JDK archive, an accompanying tar.gz.sha1 file with its
|
||||
SHA1 signature plus symlinks to the archive for non-canonical architecture names.
|
||||
"""
|
||||
jdkImageDir = join(jdkBuildDir, 'images', 'jdk')
|
||||
|
||||
arches = _get_jdk_bundle_arches()
|
||||
jdkTgzPath = join(_suite.get_output_root(), 'jdk-bundles', 'jdk9-{}-{}.tar.gz'.format(_get_openjdk_os(), arches[0]))
|
||||
with mx.Archiver(jdkTgzPath, kind='tgz') as arc:
|
||||
mx.log('Creating ' + jdkTgzPath)
|
||||
for root, _, filenames in os.walk(jdkImageDir):
|
||||
for name in filenames:
|
||||
f = join(root, name)
|
||||
arcname = 'jdk1.9.0/' + os.path.relpath(f, jdkImageDir)
|
||||
arc.zf.add(name=f, arcname=arcname, recursive=False)
|
||||
# The OpenJDK build creates an empty cacerts file so grab one from
|
||||
# the default JDK which is assumed to be an OracleJDK
|
||||
cacerts = join(mx.get_jdk(tag='default').home, 'jre', 'lib', 'security', 'cacerts')
|
||||
arc.zf.add(name=cacerts, arcname='jdk1.9.0/lib/security/cacerts')
|
||||
|
||||
with open(jdkTgzPath + '.sha1', 'w') as fp:
|
||||
mx.log('Creating ' + jdkTgzPath + '.sha1')
|
||||
fp.write(mx.sha1OfFile(jdkTgzPath))
|
||||
|
||||
def _create_link(source, link_name):
|
||||
if exists(link_name):
|
||||
os.remove(link_name)
|
||||
mx.log('Creating ' + link_name + ' -> ' + source)
|
||||
os.symlink(source, link_name)
|
||||
|
||||
for arch in arches[1:]:
|
||||
link_name = join(_suite.get_output_root(), 'jdk-bundles', 'jdk9-{}-{}.tar.gz'.format(_get_openjdk_os(), arch))
|
||||
jdkTgzName = os.path.basename(jdkTgzPath)
|
||||
_create_link(jdkTgzName, link_name)
|
||||
_create_link(jdkTgzName + '.sha1', link_name + '.sha1')
|
||||
|
||||
def _runmultimake(args):
|
||||
"""run the JDK make process for one or more configurations"""
|
||||
|
||||
jvmVariantsDefault = ','.join(_jdkJvmVariants)
|
||||
debugLevelsDefault = ','.join(_jdkDebugLevels)
|
||||
|
||||
parser = ArgumentParser(prog='mx multimake')
|
||||
parser.add_argument('--jdk-jvm-variants', '--vms', help='a comma separated list of VMs to build (default: ' + jvmVariantsDefault + ')', metavar='<args>', default=jvmVariantsDefault)
|
||||
parser.add_argument('--jdk-debug-levels', '--builds', help='a comma separated list of JDK debug levels (default: ' + debugLevelsDefault + ')', metavar='<args>', default=debugLevelsDefault)
|
||||
parser.add_argument('-n', '--no-check', action='store_true', help='omit running "java -version" after each build')
|
||||
select = parser.add_mutually_exclusive_group()
|
||||
select.add_argument('-c', '--console', action='store_true', help='send build output to console instead of log files')
|
||||
select.add_argument('-d', '--output-dir', help='directory for log files instead of current working directory', default=os.getcwd(), metavar='<dir>')
|
||||
|
||||
args = parser.parse_args(args)
|
||||
jvmVariants = args.jdk_jvm_variants.split(',')
|
||||
debugLevels = [_translateLegacyDebugLevel(dl) for dl in args.jdk_debug_levels.split(',')]
|
||||
|
||||
allStart = time.time()
|
||||
for jvmVariant in jvmVariants:
|
||||
for debugLevel in debugLevels:
|
||||
if not args.console:
|
||||
logFile = join(mx.ensure_dir_exists(args.output_dir), jvmVariant + '-' + debugLevel + '.log')
|
||||
log = open(logFile, 'wb')
|
||||
start = time.time()
|
||||
mx.log('BEGIN: ' + jvmVariant + '-' + debugLevel + '\t(see: ' + logFile + ')')
|
||||
verbose = ['-v'] if mx.get_opts().verbose else []
|
||||
# Run as subprocess so that output can be directed to a file
|
||||
cmd = [sys.executable, '-u', mx.__file__] + verbose + ['--jdk-jvm-variant=' + jvmVariant, '--jdk-debug-level=' + debugLevel, 'make']
|
||||
mx.logv("executing command: " + str(cmd))
|
||||
subprocess.check_call(cmd, cwd=_suite.dir, stdout=log, stderr=subprocess.STDOUT)
|
||||
duration = datetime.timedelta(seconds=time.time() - start)
|
||||
mx.log('END: ' + jvmVariant + '-' + debugLevel + '\t[' + str(duration) + ']')
|
||||
else:
|
||||
with VM(jvmVariant=jvmVariant, debugLevel=debugLevel):
|
||||
_runmake([])
|
||||
if not args.no_check:
|
||||
with VM(jvmciMode='jit'):
|
||||
run_vm(['-XX:-BootstrapJVMCI', '-version'])
|
||||
allDuration = datetime.timedelta(seconds=time.time() - allStart)
|
||||
mx.log('TOTAL TIME: ' + '[' + str(allDuration) + ']')
|
||||
|
||||
class HotSpotProject(mx.NativeProject):
|
||||
"""
|
||||
Defines a NativeProject representing the HotSpot binaries built via make.
|
||||
"""
|
||||
def __init__(self, suite, name, deps, workingSets, **args):
|
||||
assert name == 'hotspot'
|
||||
mx.NativeProject.__init__(self, suite, name, "", [], deps, workingSets, None, None, join(suite.mxDir, name))
|
||||
|
||||
def eclipse_config_up_to_date(self, configZip):
|
||||
# Assume that any change to this module might imply changes to the generated IDE files
|
||||
if configZip.isOlderThan(__file__):
|
||||
return False
|
||||
for _, source in self._get_eclipse_settings_sources().iteritems():
|
||||
if configZip.isOlderThan(source):
|
||||
return False
|
||||
return True
|
||||
|
||||
def _get_eclipse_settings_sources(self):
|
||||
"""
|
||||
Gets a dictionary from the name of an Eclipse settings file to
|
||||
the file providing its generated content.
|
||||
"""
|
||||
if not hasattr(self, '_eclipse_settings'):
|
||||
esdict = {}
|
||||
templateSettingsDir = join(self.dir, 'templates', 'eclipse', 'settings')
|
||||
if exists(templateSettingsDir):
|
||||
for name in os.listdir(templateSettingsDir):
|
||||
source = join(templateSettingsDir, name)
|
||||
esdict[name] = source
|
||||
self._eclipse_settings = esdict
|
||||
return self._eclipse_settings
|
||||
|
||||
def _eclipseinit(self, files=None, libFiles=None):
|
||||
"""
|
||||
Generates an Eclipse project for each HotSpot build configuration.
|
||||
"""
|
||||
|
||||
roots = [
|
||||
'ASSEMBLY_EXCEPTION',
|
||||
'LICENSE',
|
||||
'README',
|
||||
'THIRD_PARTY_README',
|
||||
'agent',
|
||||
'make',
|
||||
'src',
|
||||
'test'
|
||||
]
|
||||
|
||||
for jvmVariant in _jdkJvmVariants:
|
||||
for debugLevel in _jdkDebugLevels:
|
||||
name = jvmVariant + '-' + debugLevel
|
||||
eclProjectDir = join(self.dir, 'eclipse', name)
|
||||
mx.ensure_dir_exists(eclProjectDir)
|
||||
|
||||
out = mx.XMLDoc()
|
||||
out.open('projectDescription')
|
||||
out.element('name', data='hotspot:' + name)
|
||||
out.element('comment', data='')
|
||||
out.element('projects', data='')
|
||||
out.open('buildSpec')
|
||||
out.open('buildCommand')
|
||||
out.element('name', data='org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder')
|
||||
out.element('triggers', data='full,incremental')
|
||||
out.element('arguments', data='')
|
||||
out.close('buildCommand')
|
||||
|
||||
out.close('buildSpec')
|
||||
out.open('natures')
|
||||
out.element('nature', data='org.eclipse.cdt.core.cnature')
|
||||
out.element('nature', data='org.eclipse.cdt.core.ccnature')
|
||||
out.element('nature', data='org.eclipse.cdt.managedbuilder.core.managedBuildNature')
|
||||
out.element('nature', data='org.eclipse.cdt.managedbuilder.core.ScannerConfigNature')
|
||||
out.close('natures')
|
||||
|
||||
if roots:
|
||||
out.open('linkedResources')
|
||||
for r in roots:
|
||||
f = join(_suite.dir, r)
|
||||
out.open('link')
|
||||
out.element('name', data=r)
|
||||
out.element('type', data='2' if isdir(f) else '1')
|
||||
out.element('locationURI', data=mx.get_eclipse_project_rel_locationURI(f, eclProjectDir))
|
||||
out.close('link')
|
||||
|
||||
out.open('link')
|
||||
out.element('name', data='generated')
|
||||
out.element('type', data='2')
|
||||
generated = join(_get_hotspot_build_dir(jvmVariant, debugLevel), 'generated')
|
||||
out.element('locationURI', data=mx.get_eclipse_project_rel_locationURI(generated, eclProjectDir))
|
||||
out.close('link')
|
||||
|
||||
out.close('linkedResources')
|
||||
out.close('projectDescription')
|
||||
projectFile = join(eclProjectDir, '.project')
|
||||
mx.update_file(projectFile, out.xml(indent='\t', newl='\n'))
|
||||
if files:
|
||||
files.append(projectFile)
|
||||
|
||||
cprojectTemplate = join(self.dir, 'templates', 'eclipse', 'cproject')
|
||||
cprojectFile = join(eclProjectDir, '.cproject')
|
||||
with open(cprojectTemplate) as f:
|
||||
content = f.read()
|
||||
mx.update_file(cprojectFile, content)
|
||||
if files:
|
||||
files.append(cprojectFile)
|
||||
|
||||
settingsDir = join(eclProjectDir, ".settings")
|
||||
mx.ensure_dir_exists(settingsDir)
|
||||
for name, source in self._get_eclipse_settings_sources().iteritems():
|
||||
out = StringIO.StringIO()
|
||||
print >> out, '# GENERATED -- DO NOT EDIT'
|
||||
print >> out, '# Source:', source
|
||||
with open(source) as f:
|
||||
print >> out, f.read()
|
||||
content = out.getvalue()
|
||||
mx.update_file(join(settingsDir, name), content)
|
||||
if files:
|
||||
files.append(join(settingsDir, name))
|
||||
|
||||
def getBuildTask(self, args):
|
||||
return JDKBuildTask(self, args, _vm.debugLevel, _vm.jvmVariant)
|
||||
|
||||
|
||||
class JDKBuildTask(mx.NativeBuildTask):
|
||||
def __init__(self, project, args, debugLevel, jvmVariant):
|
||||
mx.NativeBuildTask.__init__(self, args, project)
|
||||
self.jvmVariant = jvmVariant
|
||||
self.debugLevel = debugLevel
|
||||
|
||||
def __str__(self):
|
||||
return 'Building JDK[{}, {}]'.format(self.debugLevel, self.jvmVariant)
|
||||
|
||||
def build(self):
|
||||
if mx.get_opts().use_jdk_image:
|
||||
_runmake(['images'])
|
||||
else:
|
||||
_runmake([])
|
||||
self._newestOutput = None
|
||||
|
||||
def clean(self, forBuild=False):
|
||||
if forBuild: # Let make handle incremental builds
|
||||
return
|
||||
if exists(_get_jdk_build_dir(self.debugLevel)):
|
||||
_runmake(['clean'])
|
||||
self._newestOutput = None
|
||||
|
||||
# Backwards compatibility for mx_jvmci:8 API
|
||||
def buildvms(args):
|
||||
_runmultimake(args)
|
||||
|
||||
def run_vm(args, vm=None, nonZeroIsFatal=True, out=None, err=None, cwd=None, timeout=None, debugLevel=None, vmbuild=None):
|
||||
"""run a Java program by executing the java executable in a JVMCI JDK"""
|
||||
jdkTag = mx.get_jdk_option().tag
|
||||
if jdkTag and jdkTag != _JVMCI_JDK_TAG:
|
||||
mx.abort('The "--jdk" option must have the tag "' + _JVMCI_JDK_TAG + '" when running a command requiring a JVMCI VM')
|
||||
jdk = get_jvmci_jdk(debugLevel=debugLevel or _translateLegacyDebugLevel(vmbuild))
|
||||
return jdk.run_java(args, nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd, timeout=timeout)
|
||||
|
||||
def _unittest_vm_launcher(vmArgs, mainClass, mainClassArgs):
|
||||
run_vm(vmArgs + [mainClass] + mainClassArgs)
|
||||
|
||||
mx_unittest.set_vm_launcher('JVMCI VM launcher', _unittest_vm_launcher)
|
||||
|
||||
def _jvmci_gate_runner(args, tasks):
|
||||
# Build release server VM now so we can run the unit tests
|
||||
with Task('BuildHotSpotJVMCIHosted: release', tasks) as t:
|
||||
if t: _runmultimake(['--jdk-jvm-variants', 'server', '--jdk-debug-levels', 'release'])
|
||||
|
||||
# Run unit tests in hosted mode
|
||||
with VM(jvmVariant='server', debugLevel='release', jvmciMode='hosted'):
|
||||
with Task('JVMCI UnitTests: hosted-release', tasks) as t:
|
||||
if t: unittest(['--suite', 'jvmci', '--enable-timing', '--verbose', '--fail-fast'])
|
||||
|
||||
# Build the other VM flavors
|
||||
with Task('BuildHotSpotJVMCIOthers: fastdebug', tasks) as t:
|
||||
if t: _runmultimake(['--jdk-jvm-variants', 'server', '--jdk-debug-levels', 'fastdebug'])
|
||||
|
||||
with Task('CleanAndBuildIdealGraphVisualizer', tasks, disableJacoco=True) as t:
|
||||
if t and platform.processor() != 'sparc':
|
||||
buildxml = mx._cygpathU2W(join(_suite.dir, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'build.xml'))
|
||||
mx.run(['ant', '-f', buildxml, '-q', 'clean', 'build'], env=_igvBuildEnv())
|
||||
|
||||
mx_gate.add_gate_runner(_suite, _jvmci_gate_runner)
|
||||
mx_gate.add_gate_argument('-g', '--only-build-jvmci', action='store_false', dest='buildNonJVMCI', help='only build the JVMCI VM')
|
||||
|
||||
def _igvJdk():
|
||||
v8u20 = mx.VersionSpec("1.8.0_20")
|
||||
v8u40 = mx.VersionSpec("1.8.0_40")
|
||||
v8 = mx.VersionSpec("1.8")
|
||||
def _igvJdkVersionCheck(version):
|
||||
return version >= v8 and (version < v8u20 or version >= v8u40)
|
||||
return mx.get_jdk(_igvJdkVersionCheck, versionDescription='>= 1.8 and < 1.8.0u20 or >= 1.8.0u40', purpose="building & running IGV").home
|
||||
|
||||
def _igvBuildEnv():
|
||||
# When the http_proxy environment variable is set, convert it to the proxy settings that ant needs
|
||||
env = dict(os.environ)
|
||||
proxy = os.environ.get('http_proxy')
|
||||
if not (proxy is None) and len(proxy) > 0:
|
||||
if '://' in proxy:
|
||||
# Remove the http:// prefix (or any other protocol prefix)
|
||||
proxy = proxy.split('://', 1)[1]
|
||||
# Separate proxy server name and port number
|
||||
proxyName, proxyPort = proxy.split(':', 1)
|
||||
proxyEnv = '-DproxyHost="' + proxyName + '" -DproxyPort=' + proxyPort
|
||||
env['ANT_OPTS'] = proxyEnv
|
||||
|
||||
env['JAVA_HOME'] = _igvJdk()
|
||||
return env
|
||||
|
||||
def igv(args):
|
||||
"""run the Ideal Graph Visualizer"""
|
||||
logFile = '.ideal_graph_visualizer.log'
|
||||
with open(join(_suite.dir, logFile), 'w') as fp:
|
||||
mx.logv('[Ideal Graph Visualizer log is in ' + fp.name + ']')
|
||||
nbplatform = join(_suite.dir, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'nbplatform')
|
||||
|
||||
# Remove NetBeans platform if it is earlier than the current supported version
|
||||
if exists(nbplatform):
|
||||
updateTrackingFile = join(nbplatform, 'platform', 'update_tracking', 'org-netbeans-core.xml')
|
||||
if not exists(updateTrackingFile):
|
||||
mx.log('Could not find \'' + updateTrackingFile + '\', removing NetBeans platform')
|
||||
shutil.rmtree(nbplatform)
|
||||
else:
|
||||
dom = xml.dom.minidom.parse(updateTrackingFile)
|
||||
currentVersion = mx.VersionSpec(dom.getElementsByTagName('module_version')[0].getAttribute('specification_version'))
|
||||
supportedVersion = mx.VersionSpec('3.43.1')
|
||||
if currentVersion < supportedVersion:
|
||||
mx.log('Replacing NetBeans platform version ' + str(currentVersion) + ' with version ' + str(supportedVersion))
|
||||
shutil.rmtree(nbplatform)
|
||||
elif supportedVersion < currentVersion:
|
||||
mx.log('Supported NetBeans version in igv command should be updated to ' + str(currentVersion))
|
||||
|
||||
if not exists(nbplatform):
|
||||
mx.logv('[This execution may take a while as the NetBeans platform needs to be downloaded]')
|
||||
|
||||
env = _igvBuildEnv()
|
||||
# make the jar for Batik 1.7 available.
|
||||
env['IGV_BATIK_JAR'] = mx.library('BATIK').get_path(True)
|
||||
if mx.run(['ant', '-f', mx._cygpathU2W(join(_suite.dir, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'build.xml')), '-l', mx._cygpathU2W(fp.name), 'run'], env=env, nonZeroIsFatal=False):
|
||||
mx.abort("IGV ant build & launch failed. Check '" + logFile + "'. You can also try to delete 'src/share/tools/IdealGraphVisualizer/nbplatform'.")
|
||||
|
||||
def c1visualizer(args):
|
||||
"""run the Cl Compiler Visualizer"""
|
||||
libpath = join(_suite.dir, 'lib')
|
||||
if mx.get_os() == 'windows':
|
||||
executable = join(libpath, 'c1visualizer', 'bin', 'c1visualizer.exe')
|
||||
else:
|
||||
executable = join(libpath, 'c1visualizer', 'bin', 'c1visualizer')
|
||||
|
||||
# Check whether the current C1Visualizer installation is the up-to-date
|
||||
if exists(executable) and not exists(mx.library('C1VISUALIZER_DIST').get_path(resolve=False)):
|
||||
mx.log('Updating C1Visualizer')
|
||||
shutil.rmtree(join(libpath, 'c1visualizer'))
|
||||
|
||||
archive = mx.library('C1VISUALIZER_DIST').get_path(resolve=True)
|
||||
|
||||
if not exists(executable):
|
||||
zf = zipfile.ZipFile(archive, 'r')
|
||||
zf.extractall(libpath)
|
||||
|
||||
if not exists(executable):
|
||||
mx.abort('C1Visualizer binary does not exist: ' + executable)
|
||||
|
||||
if mx.get_os() != 'windows':
|
||||
# Make sure that execution is allowed. The zip file does not always specfiy that correctly
|
||||
os.chmod(executable, 0777)
|
||||
|
||||
mx.run([executable])
|
||||
|
||||
def hsdis(args, copyToDir=None):
|
||||
"""download the hsdis library
|
||||
|
||||
This is needed to support HotSpot's assembly dumping features.
|
||||
By default it downloads the Intel syntax version, use the 'att' argument to install AT&T syntax."""
|
||||
flavor = 'intel'
|
||||
if 'att' in args:
|
||||
flavor = 'att'
|
||||
if mx.get_arch() == "sparcv9":
|
||||
flavor = "sparcv9"
|
||||
lib = mx.add_lib_suffix('hsdis-' + mx.get_arch())
|
||||
path = join(_suite.dir, 'lib', lib)
|
||||
|
||||
sha1s = {
|
||||
'att/hsdis-amd64.dll' : 'bcbd535a9568b5075ab41e96205e26a2bac64f72',
|
||||
'att/hsdis-amd64.so' : '58919ba085d4ef7a513f25bae75e7e54ee73c049',
|
||||
'intel/hsdis-amd64.dll' : '6a388372cdd5fe905c1a26ced614334e405d1f30',
|
||||
'intel/hsdis-amd64.so' : '844ed9ffed64fe9599638f29a8450c50140e3192',
|
||||
'intel/hsdis-amd64.dylib' : 'fdb13ef0d7d23d93dacaae9c98837bea0d4fc5a2',
|
||||
'sparcv9/hsdis-sparcv9.so': '970640a9af0bd63641f9063c11275b371a59ee60',
|
||||
}
|
||||
|
||||
flavoredLib = flavor + "/" + lib
|
||||
if flavoredLib not in sha1s:
|
||||
mx.logv("hsdis not supported on this plattform or architecture")
|
||||
return
|
||||
|
||||
if not exists(path):
|
||||
sha1 = sha1s[flavoredLib]
|
||||
sha1path = path + '.sha1'
|
||||
mx.download_file_with_sha1('hsdis', path, ['https://lafo.ssw.uni-linz.ac.at/pub/hsdis/' + flavoredLib], sha1, sha1path, True, True, sources=False)
|
||||
if copyToDir is not None and exists(copyToDir):
|
||||
shutil.copy(path, copyToDir)
|
||||
|
||||
def hcfdis(args):
|
||||
"""disassemble HexCodeFiles embedded in text files
|
||||
|
||||
Run a tool over the input files to convert all embedded HexCodeFiles
|
||||
to a disassembled format."""
|
||||
|
||||
parser = ArgumentParser(prog='mx hcfdis')
|
||||
parser.add_argument('-m', '--map', help='address to symbol map applied to disassembler output')
|
||||
parser.add_argument('files', nargs=REMAINDER, metavar='files...')
|
||||
|
||||
args = parser.parse_args(args)
|
||||
|
||||
path = mx.library('HCFDIS').get_path(resolve=True)
|
||||
mx.run_java(['-cp', path, 'com.oracle.max.hcfdis.HexCodeFileDis'] + args.files)
|
||||
|
||||
if args.map is not None:
|
||||
addressRE = re.compile(r'0[xX]([A-Fa-f0-9]+)')
|
||||
with open(args.map) as fp:
|
||||
lines = fp.read().splitlines()
|
||||
symbols = dict()
|
||||
for l in lines:
|
||||
addressAndSymbol = l.split(' ', 1)
|
||||
if len(addressAndSymbol) == 2:
|
||||
address, symbol = addressAndSymbol
|
||||
if address.startswith('0x'):
|
||||
address = long(address, 16)
|
||||
symbols[address] = symbol
|
||||
for f in args.files:
|
||||
with open(f) as fp:
|
||||
lines = fp.read().splitlines()
|
||||
updated = False
|
||||
for i in range(0, len(lines)):
|
||||
l = lines[i]
|
||||
for m in addressRE.finditer(l):
|
||||
sval = m.group(0)
|
||||
val = long(sval, 16)
|
||||
sym = symbols.get(val)
|
||||
if sym:
|
||||
l = l.replace(sval, sym)
|
||||
updated = True
|
||||
lines[i] = l
|
||||
if updated:
|
||||
mx.log('updating ' + f)
|
||||
with open('new_' + f, "w") as fp:
|
||||
for l in lines:
|
||||
print >> fp, l
|
||||
|
||||
def jol(args):
|
||||
"""Java Object Layout"""
|
||||
joljar = mx.library('JOL_INTERNALS').get_path(resolve=True)
|
||||
candidates = mx.findclass(args, logToConsole=False, matcher=lambda s, classname: s == classname or classname.endswith('.' + s) or classname.endswith('$' + s))
|
||||
|
||||
if len(candidates) > 0:
|
||||
candidates = mx.select_items(sorted(candidates))
|
||||
else:
|
||||
# mx.findclass can be mistaken, don't give up yet
|
||||
candidates = args
|
||||
|
||||
run_vm(['-javaagent:' + joljar, '-cp', os.pathsep.join([mx.classpath(), joljar]), "org.openjdk.jol.MainObjectInternals"] + candidates)
|
||||
|
||||
class JVMCIArchiveParticipant:
|
||||
def __init__(self, dist):
|
||||
self.dist = dist
|
||||
|
||||
def __opened__(self, arc, srcArc, services):
|
||||
self.services = services
|
||||
self.arc = arc
|
||||
|
||||
def __add__(self, arcname, contents):
|
||||
if arcname.startswith('META-INF/jvmci.providers/'):
|
||||
provider = arcname[len('META-INF/jvmci.providers/'):]
|
||||
for service in contents.strip().split(os.linesep):
|
||||
assert service
|
||||
self.services.setdefault(service, []).append(provider)
|
||||
return True
|
||||
elif arcname.endswith('_OptionDescriptors.class'):
|
||||
# Need to create service files for the providers of the
|
||||
# jdk.vm.ci.options.Options service created by
|
||||
# jdk.vm.ci.options.processor.OptionProcessor.
|
||||
provider = arcname[:-len('.class'):].replace('/', '.')
|
||||
self.services.setdefault('jdk.vm.ci.options.OptionDescriptors', []).append(provider)
|
||||
return False
|
||||
|
||||
def __addsrc__(self, arcname, contents):
|
||||
return False
|
||||
|
||||
def __closing__(self):
|
||||
pass
|
||||
|
||||
def _get_openjdk_os():
|
||||
# See: common/autoconf/platform.m4
|
||||
os = mx.get_os()
|
||||
if 'darwin' in os:
|
||||
os = 'macosx'
|
||||
elif 'linux' in os:
|
||||
os = 'linux'
|
||||
elif 'solaris' in os:
|
||||
os = 'solaris'
|
||||
elif 'cygwin' in os or 'mingw' in os:
|
||||
os = 'windows'
|
||||
return os
|
||||
|
||||
def _get_openjdk_cpu():
|
||||
cpu = mx.get_arch()
|
||||
if cpu == 'amd64':
|
||||
cpu = 'x86_64'
|
||||
elif cpu == 'sparcv9':
|
||||
cpu = 'sparcv9'
|
||||
return cpu
|
||||
|
||||
def _get_openjdk_os_cpu():
|
||||
return _get_openjdk_os() + '-' + _get_openjdk_cpu()
|
||||
|
||||
def _get_jdk_build_dir(debugLevel=None):
|
||||
"""
|
||||
Gets the directory into which the JDK is built. This directory contains
|
||||
the exploded JDK under jdk/ and the JDK image under images/jdk/.
|
||||
"""
|
||||
if debugLevel is None:
|
||||
debugLevel = _vm.debugLevel
|
||||
name = '{}-{}-{}-{}'.format(_get_openjdk_os_cpu(), 'normal', _vm.jvmVariant, debugLevel)
|
||||
return join(dirname(_suite.dir), 'build', name)
|
||||
|
||||
_jvmci_bootclasspath_prepends = []
|
||||
|
||||
def _get_hotspot_build_dir(jvmVariant=None, debugLevel=None):
|
||||
"""
|
||||
Gets the directory in which a particular HotSpot configuration is built
|
||||
(e.g., <JDK_REPO_ROOT>/build/macosx-x86_64-normal-server-release/hotspot/bsd_amd64_compiler2)
|
||||
"""
|
||||
if jvmVariant is None:
|
||||
jvmVariant = _vm.jvmVariant
|
||||
|
||||
os = mx.get_os()
|
||||
if os == 'darwin':
|
||||
os = 'bsd'
|
||||
arch = mx.get_arch()
|
||||
buildname = {'client': 'compiler1', 'server': 'compiler2'}.get(jvmVariant, jvmVariant)
|
||||
|
||||
name = '{}_{}_{}'.format(os, arch, buildname)
|
||||
return join(_get_jdk_build_dir(debugLevel=debugLevel), 'hotspot', name)
|
||||
|
||||
def add_bootclasspath_prepend(dep):
|
||||
assert isinstance(dep, mx.ClasspathDependency)
|
||||
_jvmci_bootclasspath_prepends.append(dep)
|
||||
|
||||
class JVMCI9JDKConfig(mx.JDKConfig):
|
||||
def __init__(self, debugLevel):
|
||||
self.debugLevel = debugLevel
|
||||
jdkBuildDir = _get_jdk_build_dir(debugLevel)
|
||||
jdkDir = join(jdkBuildDir, 'images', 'jdk') if mx.get_opts().use_jdk_image else join(jdkBuildDir, 'jdk')
|
||||
mx.JDKConfig.__init__(self, jdkDir, tag=_JVMCI_JDK_TAG)
|
||||
|
||||
def parseVmArgs(self, args, addDefaultArgs=True):
|
||||
args = mx.expand_project_in_args(args, insitu=False)
|
||||
jacocoArgs = mx_gate.get_jacoco_agent_args()
|
||||
if jacocoArgs:
|
||||
args = jacocoArgs + args
|
||||
|
||||
# Support for -G: options
|
||||
def translateGOption(arg):
|
||||
if arg.startswith('-G:+'):
|
||||
if '=' in arg:
|
||||
mx.abort('Mixing + and = in -G: option specification: ' + arg)
|
||||
arg = '-Djvmci.option.' + arg[len('-G:+'):] + '=true'
|
||||
elif arg.startswith('-G:-'):
|
||||
if '=' in arg:
|
||||
mx.abort('Mixing - and = in -G: option specification: ' + arg)
|
||||
arg = '-Djvmci.option.' + arg[len('-G:+'):] + '=false'
|
||||
elif arg.startswith('-G:'):
|
||||
arg = '-Djvmci.option.' + arg[len('-G:'):]
|
||||
return arg
|
||||
args = map(translateGOption, args)
|
||||
|
||||
args = ['-Xbootclasspath/p:' + dep.classpath_repr() for dep in _jvmci_bootclasspath_prepends] + args
|
||||
|
||||
jvmciModeArgs = _jvmciModes[_vm.jvmciMode]
|
||||
if jvmciModeArgs:
|
||||
bcpDeps = [jdkDist.dist() for jdkDist in jdkDeployedDists]
|
||||
if bcpDeps:
|
||||
args = ['-Xbootclasspath/p:' + os.pathsep.join([d.classpath_repr() for d in bcpDeps])] + args
|
||||
|
||||
# Set the default JVMCI compiler
|
||||
for jdkDist in reversed(jdkDeployedDists):
|
||||
assert isinstance(jdkDist, JvmciJDKDeployedDist), jdkDist
|
||||
if jdkDist._compilers:
|
||||
jvmciCompiler = jdkDist._compilers[-1]
|
||||
args = ['-Djvmci.compiler=' + jvmciCompiler] + args
|
||||
break
|
||||
|
||||
if '-version' in args:
|
||||
ignoredArgs = args[args.index('-version') + 1:]
|
||||
if len(ignoredArgs) > 0:
|
||||
mx.log("Warning: The following options will be ignored by the vm because they come after the '-version' argument: " + ' '.join(ignoredArgs))
|
||||
return self.processArgs(args, addDefaultArgs=addDefaultArgs)
|
||||
|
||||
# Overrides JDKConfig
|
||||
def run_java(self, args, vm=None, nonZeroIsFatal=True, out=None, err=None, cwd=None, timeout=None, env=None, addDefaultArgs=True):
|
||||
if vm is None:
|
||||
vm = 'server'
|
||||
|
||||
args = self.parseVmArgs(args, addDefaultArgs=addDefaultArgs)
|
||||
|
||||
jvmciModeArgs = _jvmciModes[_vm.jvmciMode]
|
||||
cmd = [self.java] + ['-' + vm] + jvmciModeArgs + args
|
||||
return mx.run(cmd, nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd)
|
||||
|
||||
"""
|
||||
The dict of JVMCI JDKs indexed by debug-level names.
|
||||
"""
|
||||
_jvmci_jdks = {}
|
||||
|
||||
def get_jvmci_jdk(debugLevel=None):
|
||||
"""
|
||||
Gets the JVMCI JDK corresponding to 'debugLevel'.
|
||||
"""
|
||||
if not debugLevel:
|
||||
debugLevel = _vm.debugLevel
|
||||
jdk = _jvmci_jdks.get(debugLevel)
|
||||
if jdk is None:
|
||||
try:
|
||||
jdk = JVMCI9JDKConfig(debugLevel)
|
||||
except mx.JDKConfigException as e:
|
||||
jdkBuildDir = _get_jdk_build_dir(debugLevel)
|
||||
msg = 'Error with the JDK built into {}:\n{}\nTry (re)building it with: mx --jdk-debug-level={} make'
|
||||
if mx.get_opts().use_jdk_image:
|
||||
msg += ' images'
|
||||
mx.abort(msg.format(jdkBuildDir, e.message, debugLevel))
|
||||
_jvmci_jdks[debugLevel] = jdk
|
||||
return jdk
|
||||
|
||||
class JVMCIJDKFactory(mx.JDKFactory):
|
||||
def getJDKConfig(self):
|
||||
jdk = get_jvmci_jdk(_vm.debugLevel)
|
||||
return jdk
|
||||
|
||||
def description(self):
|
||||
return "JVMCI JDK"
|
||||
|
||||
mx.update_commands(_suite, {
|
||||
'make': [_runmake, '[args...]', _makehelp],
|
||||
'multimake': [_runmultimake, '[options]'],
|
||||
'c1visualizer' : [c1visualizer, ''],
|
||||
'hsdis': [hsdis, '[att]'],
|
||||
'hcfdis': [hcfdis, ''],
|
||||
'igv' : [igv, ''],
|
||||
'jol' : [jol, ''],
|
||||
'vm': [run_vm, '[-options] class [args...]'],
|
||||
})
|
||||
|
||||
mx.add_argument('-M', '--jvmci-mode', action='store', choices=sorted(_jvmciModes.viewkeys()), help='the JVM variant type to build/run (default: ' + _vm.jvmciMode + ')')
|
||||
mx.add_argument('--jdk-jvm-variant', '--vm', action='store', choices=_jdkJvmVariants + sorted(_legacyVms.viewkeys()), help='the JVM variant type to build/run (default: ' + _vm.jvmVariant + ')')
|
||||
mx.add_argument('--jdk-debug-level', '--vmbuild', action='store', choices=_jdkDebugLevels + sorted(_legacyVmbuilds.viewkeys()), help='the JDK debug level to build/run (default: ' + _vm.debugLevel + ')')
|
||||
mx.add_argument('-I', '--use-jdk-image', action='store_true', help='build/run JDK image instead of exploded JDK')
|
||||
|
||||
def mx_post_parse_cmd_line(opts):
|
||||
mx.addJDKFactory(_JVMCI_JDK_TAG, mx.JavaCompliance('9'), JVMCIJDKFactory())
|
||||
mx.set_java_command_default_jdk_tag(_JVMCI_JDK_TAG)
|
||||
|
||||
jdkTag = mx.get_jdk_option().tag
|
||||
|
||||
jvmVariant = None
|
||||
debugLevel = None
|
||||
jvmciMode = None
|
||||
|
||||
if opts.jdk_jvm_variant is not None:
|
||||
jvmVariant = opts.jdk_jvm_variant
|
||||
if jdkTag and jdkTag != _JVMCI_JDK_TAG:
|
||||
mx.warn('Ignoring "--jdk-jvm-variant" option as "--jdk" tag is not "' + _JVMCI_JDK_TAG + '"')
|
||||
|
||||
if opts.jdk_debug_level is not None:
|
||||
debugLevel = _translateLegacyDebugLevel(opts.jdk_debug_level)
|
||||
if jdkTag and jdkTag != _JVMCI_JDK_TAG:
|
||||
mx.warn('Ignoring "--jdk-debug-level" option as "--jdk" tag is not "' + _JVMCI_JDK_TAG + '"')
|
||||
|
||||
if opts.jvmci_mode is not None:
|
||||
jvmciMode = opts.jvmci_mode
|
||||
if jdkTag and jdkTag != _JVMCI_JDK_TAG:
|
||||
mx.warn('Ignoring "--jvmci-mode" option as "--jdk" tag is not "' + _JVMCI_JDK_TAG + '"')
|
||||
|
||||
_vm.update(jvmVariant, debugLevel, jvmciMode)
|
||||
|
||||
for jdkDist in jdkDeployedDists:
|
||||
dist = jdkDist.dist()
|
||||
if isinstance(jdkDist, JvmciJDKDeployedDist):
|
||||
dist.set_archiveparticipant(JVMCIArchiveParticipant(dist))
|
358
hotspot/.mx.jvmci/suite.py
Normal file
358
hotspot/.mx.jvmci/suite.py
Normal file
@ -0,0 +1,358 @@
|
||||
suite = {
|
||||
"mxversion" : "5.5.12",
|
||||
"name" : "jvmci",
|
||||
"url" : "http://openjdk.java.net/projects/graal",
|
||||
"developer" : {
|
||||
"name" : "Truffle and Graal developers",
|
||||
"email" : "graal-dev@openjdk.java.net",
|
||||
"organization" : "Graal",
|
||||
"organizationUrl" : "http://openjdk.java.net/projects/graal",
|
||||
},
|
||||
"repositories" : {
|
||||
"lafo-snapshots" : {
|
||||
"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots",
|
||||
"licenses" : ["GPLv2-CPE", "UPL"]
|
||||
},
|
||||
},
|
||||
|
||||
"licenses" : {
|
||||
"UPL" : {
|
||||
"name" : "Universal Permissive License, Version 1.0",
|
||||
"url" : "http://opensource.org/licenses/UPL",
|
||||
}
|
||||
},
|
||||
|
||||
"defaultLicense" : "GPLv2-CPE",
|
||||
|
||||
# This puts mx/ as a sibiling of the JDK build configuration directories
|
||||
# (e.g., macosx-x86_64-normal-server-release).
|
||||
"outputRoot" : "../build/mx/hotspot",
|
||||
|
||||
# ------------- Libraries -------------
|
||||
|
||||
"libraries" : {
|
||||
|
||||
# ------------- 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"],
|
||||
},
|
||||
},
|
||||
|
||||
"projects" : {
|
||||
|
||||
# ------------- JVMCI:Service -------------
|
||||
|
||||
"jdk.vm.ci.service" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "API,JVMCI",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.service.processor" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : ["jdk.vm.ci.service"],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "JVMCI,Codegen,HotSpot",
|
||||
},
|
||||
|
||||
# ------------- JVMCI:API -------------
|
||||
|
||||
"jdk.vm.ci.common" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "API,JVMCI",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.meta" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "API,JVMCI",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.code" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : ["jdk.vm.ci.meta"],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "API,JVMCI",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.runtime" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.code",
|
||||
],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"annotationProcessors" : ["JVMCI_OPTIONS_PROCESSOR"],
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "API,JVMCI",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.runtime.test" : {
|
||||
"subDir" : "test/compiler/jvmci",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : [
|
||||
"mx:JUNIT",
|
||||
"jdk.vm.ci.common",
|
||||
"jdk.vm.ci.runtime",
|
||||
],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "API,JVMCI",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.inittimer" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "JVMCI",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.options" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"dependencies" : ["jdk.vm.ci.inittimer"],
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "JVMCI",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.options.processor" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.options",
|
||||
],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "JVMCI,Codegen",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.options.test" : {
|
||||
"subDir" : "test/compiler/jvmci",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.options",
|
||||
"mx:JUNIT",
|
||||
],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "JVMCI",
|
||||
},
|
||||
|
||||
# ------------- JVMCI:HotSpot -------------
|
||||
|
||||
"jdk.vm.ci.amd64" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : ["jdk.vm.ci.code"],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "JVMCI,AMD64",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.sparc" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : ["jdk.vm.ci.code"],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "JVMCI,SPARC",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.hotspot" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.options",
|
||||
"jdk.vm.ci.hotspotvmconfig",
|
||||
"jdk.vm.ci.common",
|
||||
"jdk.vm.ci.runtime",
|
||||
"jdk.vm.ci.service",
|
||||
],
|
||||
"annotationProcessors" : [
|
||||
"JVMCI_OPTIONS_PROCESSOR",
|
||||
],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "JVMCI",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.hotspotvmconfig" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "JVMCI,HotSpot",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.hotspot.amd64" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.amd64",
|
||||
"jdk.vm.ci.hotspot",
|
||||
],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"annotationProcessors" : [
|
||||
"JVMCI_SERVICE_PROCESSOR",
|
||||
],
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "JVMCI,HotSpot,AMD64",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.hotspot.sparc" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.sparc",
|
||||
"jdk.vm.ci.hotspot",
|
||||
],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"annotationProcessors" : [
|
||||
"JVMCI_SERVICE_PROCESSOR",
|
||||
],
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "JVMCI,HotSpot,SPARC",
|
||||
},
|
||||
|
||||
"hotspot" : {
|
||||
"native" : True,
|
||||
"class" : "HotSpotProject",
|
||||
}
|
||||
},
|
||||
|
||||
"distributions" : {
|
||||
|
||||
# ------------- Distributions -------------
|
||||
|
||||
"JVMCI_SERVICE" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"dependencies" : ["jdk.vm.ci.service"],
|
||||
},
|
||||
|
||||
"JVMCI_OPTIONS" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"dependencies" : ["jdk.vm.ci.options"],
|
||||
},
|
||||
|
||||
"JVMCI_API" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.inittimer",
|
||||
"jdk.vm.ci.runtime",
|
||||
"jdk.vm.ci.common",
|
||||
"jdk.vm.ci.amd64",
|
||||
"jdk.vm.ci.sparc",
|
||||
],
|
||||
"distDependencies" : [
|
||||
"JVMCI_OPTIONS",
|
||||
"JVMCI_SERVICE",
|
||||
],
|
||||
},
|
||||
|
||||
"JVMCI_HOTSPOTVMCONFIG" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.hotspotvmconfig",
|
||||
],
|
||||
},
|
||||
|
||||
"JVMCI_HOTSPOT" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.hotspot.amd64",
|
||||
"jdk.vm.ci.hotspot.sparc",
|
||||
],
|
||||
"distDependencies" : [
|
||||
"JVMCI_HOTSPOTVMCONFIG",
|
||||
"JVMCI_SERVICE",
|
||||
"JVMCI_API",
|
||||
],
|
||||
},
|
||||
|
||||
"JVMCI_TEST" : {
|
||||
"subDir" : "test/compiler/jvmci",
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.options.test",
|
||||
"jdk.vm.ci.runtime.test",
|
||||
],
|
||||
"distDependencies" : [
|
||||
"JVMCI_API",
|
||||
],
|
||||
"exclude" : ["mx:JUNIT"],
|
||||
},
|
||||
|
||||
"JVMCI_OPTIONS_PROCESSOR" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"dependencies" : ["jdk.vm.ci.options.processor"],
|
||||
"distDependencies" : [
|
||||
"JVMCI_OPTIONS",
|
||||
],
|
||||
},
|
||||
|
||||
"JVMCI_SERVICE_PROCESSOR" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"dependencies" : ["jdk.vm.ci.service.processor"],
|
||||
"distDependencies" : [
|
||||
"JVMCI_SERVICE",
|
||||
],
|
||||
},
|
||||
|
||||
# This exists to have a monolithic jvmci.jar file which simplifies
|
||||
# using the -Xoverride option in JDK9.
|
||||
"JVMCI" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"overlaps" : [
|
||||
"JVMCI_API",
|
||||
"JVMCI_OPTIONS",
|
||||
"JVMCI_SERVICE",
|
||||
"JVMCI_HOTSPOT",
|
||||
"JVMCI_HOTSPOTVMCONFIG",
|
||||
"JVMCI_SERVICE_PROCESSOR",
|
||||
"JVMCI_OPTIONS_PROCESSOR"
|
||||
],
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.options",
|
||||
"jdk.vm.ci.service",
|
||||
"jdk.vm.ci.inittimer",
|
||||
"jdk.vm.ci.runtime",
|
||||
"jdk.vm.ci.common",
|
||||
"jdk.vm.ci.amd64",
|
||||
"jdk.vm.ci.sparc",
|
||||
"jdk.vm.ci.hotspotvmconfig",
|
||||
"jdk.vm.ci.hotspot.amd64",
|
||||
"jdk.vm.ci.hotspot.sparc",
|
||||
"jdk.vm.ci.options.processor",
|
||||
"jdk.vm.ci.service.processor"
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
@ -129,7 +129,7 @@ esac
|
||||
|
||||
# Special handling of arch model.
|
||||
case "${Platform_arch_model}" in
|
||||
"x86_32") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} *x86_64*" ;;
|
||||
"x86_32") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} *x86_64* ${JVMCI_SPECIFIC_FILES}" ;;
|
||||
"x86_64") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} *x86_32*" ;;
|
||||
esac
|
||||
|
||||
|
@ -45,10 +45,16 @@ CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER1" /D INCLUDE_JVMCI=0
|
||||
|
||||
!if "$(Variant)" == "compiler2"
|
||||
CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER2"
|
||||
!if "$(BUILDARCH)" == "i486"
|
||||
CXX_FLAGS=$(CXX_FLAGS) /D INCLUDE_JVMCI=0
|
||||
!endif
|
||||
!endif
|
||||
|
||||
!if "$(Variant)" == "tiered"
|
||||
CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER1" /D "COMPILER2"
|
||||
!if "$(BUILDARCH)" == "i486"
|
||||
CXX_FLAGS=$(CXX_FLAGS) /D INCLUDE_JVMCI=0
|
||||
!endif
|
||||
!endif
|
||||
|
||||
!if "$(BUILDARCH)" == "i486"
|
||||
|
@ -4306,7 +4306,6 @@ encode %{
|
||||
int disp = $mem$$disp;
|
||||
if (index == -1) {
|
||||
__ prfm(Address(base, disp), PSTL1KEEP);
|
||||
__ nop();
|
||||
} else {
|
||||
Register index_reg = as_Register(index);
|
||||
if (disp == 0) {
|
||||
@ -13844,6 +13843,139 @@ instruct cmpP_narrowOop_imm0_branch(cmpOp cmp, iRegN oop, immP0 zero, label labl
|
||||
ins_pipe(pipe_cmp_branch);
|
||||
%}
|
||||
|
||||
// Test bit and Branch
|
||||
|
||||
instruct cmpL_branch_sign(cmpOp cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{
|
||||
match(If cmp (CmpL op1 op2));
|
||||
predicate(n->in(1)->as_Bool()->_test._test == BoolTest::lt
|
||||
|| n->in(1)->as_Bool()->_test._test == BoolTest::ge);
|
||||
effect(USE labl);
|
||||
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "cb$cmp $op1, $labl # long" %}
|
||||
ins_encode %{
|
||||
Label* L = $labl$$label;
|
||||
Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
|
||||
if (cond == Assembler::LT)
|
||||
__ tbnz($op1$$Register, 63, *L);
|
||||
else
|
||||
__ tbz($op1$$Register, 63, *L);
|
||||
%}
|
||||
ins_pipe(pipe_cmp_branch);
|
||||
%}
|
||||
|
||||
instruct cmpI_branch_sign(cmpOp cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{
|
||||
match(If cmp (CmpI op1 op2));
|
||||
predicate(n->in(1)->as_Bool()->_test._test == BoolTest::lt
|
||||
|| n->in(1)->as_Bool()->_test._test == BoolTest::ge);
|
||||
effect(USE labl);
|
||||
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "cb$cmp $op1, $labl # int" %}
|
||||
ins_encode %{
|
||||
Label* L = $labl$$label;
|
||||
Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
|
||||
if (cond == Assembler::LT)
|
||||
__ tbnz($op1$$Register, 31, *L);
|
||||
else
|
||||
__ tbz($op1$$Register, 31, *L);
|
||||
%}
|
||||
ins_pipe(pipe_cmp_branch);
|
||||
%}
|
||||
|
||||
instruct cmpL_branch_bit(cmpOp cmp, iRegL op1, immL op2, immL0 op3, label labl, rFlagsReg cr) %{
|
||||
match(If cmp (CmpL (AndL op1 op2) op3));
|
||||
predicate((n->in(1)->as_Bool()->_test._test == BoolTest::ne
|
||||
|| n->in(1)->as_Bool()->_test._test == BoolTest::eq)
|
||||
&& is_power_of_2(n->in(2)->in(1)->in(2)->get_long()));
|
||||
effect(USE labl);
|
||||
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "tb$cmp $op1, $op2, $labl" %}
|
||||
ins_encode %{
|
||||
Label* L = $labl$$label;
|
||||
Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
|
||||
int bit = exact_log2($op2$$constant);
|
||||
if (cond == Assembler::EQ)
|
||||
__ tbz($op1$$Register, bit, *L);
|
||||
else
|
||||
__ tbnz($op1$$Register, bit, *L);
|
||||
%}
|
||||
ins_pipe(pipe_cmp_branch);
|
||||
%}
|
||||
|
||||
instruct cmpI_branch_bit(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl, rFlagsReg cr) %{
|
||||
match(If cmp (CmpI (AndI op1 op2) op3));
|
||||
predicate((n->in(1)->as_Bool()->_test._test == BoolTest::ne
|
||||
|| n->in(1)->as_Bool()->_test._test == BoolTest::eq)
|
||||
&& is_power_of_2(n->in(2)->in(1)->in(2)->get_int()));
|
||||
effect(USE labl);
|
||||
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "tb$cmp $op1, $op2, $labl" %}
|
||||
ins_encode %{
|
||||
Label* L = $labl$$label;
|
||||
Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
|
||||
int bit = exact_log2($op2$$constant);
|
||||
if (cond == Assembler::EQ)
|
||||
__ tbz($op1$$Register, bit, *L);
|
||||
else
|
||||
__ tbnz($op1$$Register, bit, *L);
|
||||
%}
|
||||
ins_pipe(pipe_cmp_branch);
|
||||
%}
|
||||
|
||||
// Test bits
|
||||
|
||||
instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{
|
||||
match(Set cr (CmpL (AndL op1 op2) op3));
|
||||
predicate(Assembler::operand_valid_for_logical_immediate
|
||||
(/*is_32*/false, n->in(1)->in(2)->get_long()));
|
||||
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "tst $op1, $op2 # long" %}
|
||||
ins_encode %{
|
||||
__ tst($op1$$Register, $op2$$constant);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{
|
||||
match(Set cr (CmpI (AndI op1 op2) op3));
|
||||
predicate(Assembler::operand_valid_for_logical_immediate
|
||||
(/*is_32*/true, n->in(1)->in(2)->get_int()));
|
||||
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "tst $op1, $op2 # int" %}
|
||||
ins_encode %{
|
||||
__ tstw($op1$$Register, $op2$$constant);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{
|
||||
match(Set cr (CmpL (AndL op1 op2) op3));
|
||||
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "tst $op1, $op2 # long" %}
|
||||
ins_encode %{
|
||||
__ tst($op1$$Register, $op2$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{
|
||||
match(Set cr (CmpI (AndI op1 op2) op3));
|
||||
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "tstw $op1, $op2 # int" %}
|
||||
ins_encode %{
|
||||
__ tstw($op1$$Register, $op2$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
|
||||
// Conditional Far Branch
|
||||
// Conditional Far Branch Unsigned
|
||||
// TODO: fixme
|
||||
@ -14167,6 +14299,9 @@ instruct string_compare(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cn
|
||||
|
||||
format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %}
|
||||
ins_encode %{
|
||||
// Count is in 8-bit bytes; non-Compact chars are 16 bits.
|
||||
__ asrw($cnt1$$Register, $cnt1$$Register, 1);
|
||||
__ asrw($cnt2$$Register, $cnt2$$Register, 1);
|
||||
__ string_compare($str1$$Register, $str2$$Register,
|
||||
$cnt1$$Register, $cnt2$$Register, $result$$Register,
|
||||
$tmp1$$Register);
|
||||
@ -14223,6 +14358,8 @@ instruct string_equals(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
|
||||
|
||||
format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp" %}
|
||||
ins_encode %{
|
||||
// Count is in 8-bit bytes; non-Compact chars are 16 bits.
|
||||
__ asrw($cnt$$Register, $cnt$$Register, 1);
|
||||
__ string_equals($str1$$Register, $str2$$Register,
|
||||
$cnt$$Register, $result$$Register,
|
||||
$tmp$$Register);
|
||||
|
@ -215,8 +215,11 @@ class MacroAssembler: public Assembler {
|
||||
inline void moviw(Register Rd, unsigned imm) { orrw(Rd, zr, imm); }
|
||||
inline void movi(Register Rd, unsigned imm) { orr(Rd, zr, imm); }
|
||||
|
||||
inline void tstw(Register Rd, unsigned imm) { andsw(zr, Rd, imm); }
|
||||
inline void tst(Register Rd, unsigned imm) { ands(zr, Rd, imm); }
|
||||
inline void tstw(Register Rd, Register Rn) { andsw(zr, Rd, Rn); }
|
||||
inline void tst(Register Rd, Register Rn) { ands(zr, Rd, Rn); }
|
||||
|
||||
inline void tstw(Register Rd, uint64_t imm) { andsw(zr, Rd, imm); }
|
||||
inline void tst(Register Rd, uint64_t imm) { ands(zr, Rd, imm); }
|
||||
|
||||
inline void bfiw(Register Rd, Register Rn, unsigned lsb, unsigned width) {
|
||||
bfmw(Rd, Rn, ((32 - lsb) & 31), (width - 1));
|
||||
|
@ -386,7 +386,8 @@ void TemplateTable::ldc(bool wide)
|
||||
|
||||
// get type
|
||||
__ add(r3, r1, tags_offset);
|
||||
__ ldrb(r3, Address(r0, r3));
|
||||
__ lea(r3, Address(r0, r3));
|
||||
__ ldarb(r3, r3);
|
||||
|
||||
// unresolved class - get the resolved class
|
||||
__ cmp(r3, JVM_CONSTANT_UnresolvedClass);
|
||||
@ -3316,7 +3317,8 @@ void TemplateTable::_new() {
|
||||
// how Constant Pool is updated (see ConstantPool::klass_at_put)
|
||||
const int tags_offset = Array<u1>::base_offset_in_bytes();
|
||||
__ lea(rscratch1, Address(r0, r3, Address::lsl(0)));
|
||||
__ ldrb(rscratch1, Address(rscratch1, tags_offset));
|
||||
__ lea(rscratch1, Address(rscratch1, tags_offset));
|
||||
__ ldarb(rscratch1, rscratch1);
|
||||
__ cmp(rscratch1, JVM_CONSTANT_Class);
|
||||
__ br(Assembler::NE, slow_case);
|
||||
|
||||
@ -3460,7 +3462,8 @@ void TemplateTable::checkcast()
|
||||
__ get_unsigned_2_byte_index_at_bcp(r19, 1); // r19=index
|
||||
// See if bytecode has already been quicked
|
||||
__ add(rscratch1, r3, Array<u1>::base_offset_in_bytes());
|
||||
__ ldrb(r1, Address(rscratch1, r19));
|
||||
__ lea(r1, Address(rscratch1, r19));
|
||||
__ ldarb(r1, r1);
|
||||
__ cmp(r1, JVM_CONSTANT_Class);
|
||||
__ br(Assembler::EQ, quicked);
|
||||
|
||||
@ -3514,7 +3517,8 @@ void TemplateTable::instanceof() {
|
||||
__ get_unsigned_2_byte_index_at_bcp(r19, 1); // r19=index
|
||||
// See if bytecode has already been quicked
|
||||
__ add(rscratch1, r3, Array<u1>::base_offset_in_bytes());
|
||||
__ ldrb(r1, Address(rscratch1, r19));
|
||||
__ lea(r1, Address(rscratch1, r19));
|
||||
__ ldarb(r1, r1);
|
||||
__ cmp(r1, JVM_CONSTANT_Class);
|
||||
__ br(Assembler::EQ, quicked);
|
||||
|
||||
|
@ -552,6 +552,8 @@ public class CompilationResult {
|
||||
*/
|
||||
private final boolean isImmutablePIC;
|
||||
|
||||
private boolean closed;
|
||||
|
||||
private int entryBCI = -1;
|
||||
|
||||
private final DataSection dataSection = new DataSection();
|
||||
@ -666,6 +668,7 @@ public class CompilationResult {
|
||||
* @param entryBCI the entryBCI to set
|
||||
*/
|
||||
public void setEntryBCI(int entryBCI) {
|
||||
checkOpen();
|
||||
this.entryBCI = entryBCI;
|
||||
}
|
||||
|
||||
@ -673,11 +676,14 @@ public class CompilationResult {
|
||||
* Sets the assumptions made during compilation.
|
||||
*/
|
||||
public void setAssumptions(Assumption[] assumptions) {
|
||||
checkOpen();
|
||||
this.assumptions = assumptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the assumptions made during compilation.
|
||||
*
|
||||
* The caller must not modify the contents of the returned array.
|
||||
*/
|
||||
public Assumption[] getAssumptions() {
|
||||
return assumptions;
|
||||
@ -690,6 +696,7 @@ public class CompilationResult {
|
||||
* @param inlinedMethods the methods inlined during compilation
|
||||
*/
|
||||
public void setMethods(ResolvedJavaMethod rootMethod, Collection<ResolvedJavaMethod> inlinedMethods) {
|
||||
checkOpen();
|
||||
assert rootMethod != null;
|
||||
assert inlinedMethods != null;
|
||||
if (inlinedMethods.contains(rootMethod)) {
|
||||
@ -717,6 +724,8 @@ public class CompilationResult {
|
||||
/**
|
||||
* Gets the methods whose bytecodes were used as input to the compilation.
|
||||
*
|
||||
* The caller must not modify the contents of the returned array.
|
||||
*
|
||||
* @return {@code null} if the compilation did not record method dependencies otherwise the
|
||||
* methods whose bytecodes were used as input to the compilation with the first element
|
||||
* being the root method of the compilation
|
||||
@ -726,6 +735,7 @@ public class CompilationResult {
|
||||
}
|
||||
|
||||
public void setBytecodeSize(int bytecodeSize) {
|
||||
checkOpen();
|
||||
this.bytecodeSize = bytecodeSize;
|
||||
}
|
||||
|
||||
@ -755,6 +765,7 @@ public class CompilationResult {
|
||||
* @param size the size of the frame in bytes
|
||||
*/
|
||||
public void setTotalFrameSize(int size) {
|
||||
checkOpen();
|
||||
totalFrameSize = size;
|
||||
}
|
||||
|
||||
@ -765,6 +776,7 @@ public class CompilationResult {
|
||||
* @param size the size of the machine code
|
||||
*/
|
||||
public void setTargetCode(byte[] code, int size) {
|
||||
checkOpen();
|
||||
targetCode = code;
|
||||
targetCodeSize = size;
|
||||
}
|
||||
@ -778,6 +790,7 @@ public class CompilationResult {
|
||||
* @param ref The reference that should be inserted in the code.
|
||||
*/
|
||||
public void recordDataPatch(int codePos, Reference ref) {
|
||||
checkOpen();
|
||||
assert codePos >= 0 && ref != null;
|
||||
dataPatches.add(new DataPatch(codePos, ref));
|
||||
}
|
||||
@ -814,6 +827,7 @@ public class CompilationResult {
|
||||
* @param direct specifies if this is a {@linkplain Call#direct direct} call
|
||||
*/
|
||||
public void recordCall(int codePos, int size, InvokeTarget target, DebugInfo debugInfo, boolean direct) {
|
||||
checkOpen();
|
||||
final Call call = new Call(target, codePos, size, direct, debugInfo);
|
||||
addInfopoint(call);
|
||||
}
|
||||
@ -825,6 +839,7 @@ public class CompilationResult {
|
||||
* @param handlerPos the position of the handler
|
||||
*/
|
||||
public void recordExceptionHandler(int codePos, int handlerPos) {
|
||||
checkOpen();
|
||||
assert validateExceptionHandlerAdd(codePos, handlerPos) : String.format("Duplicate exception handler for pc 0x%x handlerPos 0x%x", codePos, handlerPos);
|
||||
exceptionHandlers.add(new ExceptionHandler(codePos, handlerPos));
|
||||
}
|
||||
@ -870,31 +885,12 @@ public class CompilationResult {
|
||||
* Records a custom infopoint in the code section.
|
||||
*
|
||||
* Compiler implementations can use this method to record non-standard infopoints, which are not
|
||||
* handled by the dedicated methods like {@link #recordCall}.
|
||||
* handled by dedicated methods like {@link #recordCall}.
|
||||
*
|
||||
* @param infopoint the infopoint to record, usually a derived class from {@link Infopoint}
|
||||
*/
|
||||
public void addInfopoint(Infopoint infopoint) {
|
||||
// The infopoints list must always be sorted
|
||||
if (!infopoints.isEmpty()) {
|
||||
Infopoint previousInfopoint = infopoints.get(infopoints.size() - 1);
|
||||
if (previousInfopoint.pcOffset > infopoint.pcOffset) {
|
||||
// This re-sorting should be very rare
|
||||
Collections.sort(infopoints);
|
||||
previousInfopoint = infopoints.get(infopoints.size() - 1);
|
||||
}
|
||||
if (previousInfopoint.pcOffset == infopoint.pcOffset) {
|
||||
if (infopoint.reason.canBeOmitted()) {
|
||||
return;
|
||||
}
|
||||
if (previousInfopoint.reason.canBeOmitted()) {
|
||||
Infopoint removed = infopoints.remove(infopoints.size() - 1);
|
||||
assert removed == previousInfopoint;
|
||||
} else {
|
||||
throw new RuntimeException("Infopoints that can not be omited should have distinct PCs");
|
||||
}
|
||||
}
|
||||
}
|
||||
checkOpen();
|
||||
infopoints.add(infopoint);
|
||||
}
|
||||
|
||||
@ -905,6 +901,7 @@ public class CompilationResult {
|
||||
* @param markId the identifier for this mark
|
||||
*/
|
||||
public Mark recordMark(int codePos, Object markId) {
|
||||
checkOpen();
|
||||
Mark mark = new Mark(codePos, markId);
|
||||
marks.add(mark);
|
||||
return mark;
|
||||
@ -924,6 +921,7 @@ public class CompilationResult {
|
||||
* @param offset
|
||||
*/
|
||||
public void setCustomStackAreaOffset(int offset) {
|
||||
checkOpen();
|
||||
customStackAreaOffset = offset;
|
||||
}
|
||||
|
||||
@ -952,6 +950,7 @@ public class CompilationResult {
|
||||
}
|
||||
|
||||
public void addAnnotation(CodeAnnotation annotation) {
|
||||
checkOpen();
|
||||
assert annotation != null;
|
||||
if (annotations == null) {
|
||||
annotations = new ArrayList<>();
|
||||
@ -1034,6 +1033,7 @@ public class CompilationResult {
|
||||
}
|
||||
|
||||
public void setHasUnsafeAccess(boolean hasUnsafeAccess) {
|
||||
checkOpen();
|
||||
this.hasUnsafeAccess = hasUnsafeAccess;
|
||||
}
|
||||
|
||||
@ -1041,8 +1041,14 @@ public class CompilationResult {
|
||||
return hasUnsafeAccess;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
hasUnsafeAccess = false;
|
||||
/**
|
||||
* Clears the information in this object pertaining to generating code. That is, the
|
||||
* {@linkplain #getMarks() marks}, {@linkplain #getInfopoints() infopoints},
|
||||
* {@linkplain #getExceptionHandlers() exception handlers}, {@linkplain #getDataPatches() data
|
||||
* patches} and {@linkplain #getAnnotations() annotations} recorded in this object are cleared.
|
||||
*/
|
||||
public void resetForEmittingCode() {
|
||||
checkOpen();
|
||||
infopoints.clear();
|
||||
dataPatches.clear();
|
||||
exceptionHandlers.clear();
|
||||
@ -1052,4 +1058,21 @@ public class CompilationResult {
|
||||
annotations.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkOpen() {
|
||||
if (closed) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this compilation result to future updates.
|
||||
*/
|
||||
public void close() {
|
||||
if (closed) {
|
||||
throw new IllegalStateException("Cannot re-close compilation result " + this);
|
||||
}
|
||||
dataSection.close();
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ public final class DataSection implements Iterable<Data> {
|
||||
|
||||
private final ArrayList<Data> dataItems = new ArrayList<>();
|
||||
|
||||
private boolean finalLayout;
|
||||
private boolean closed;
|
||||
private int sectionAlignment;
|
||||
private int sectionSize;
|
||||
|
||||
@ -163,7 +163,7 @@ public final class DataSection implements Iterable<Data> {
|
||||
}
|
||||
if (obj instanceof DataSection) {
|
||||
DataSection that = (DataSection) obj;
|
||||
if (this.finalLayout == that.finalLayout && this.sectionAlignment == that.sectionAlignment && this.sectionSize == that.sectionSize && Objects.equals(this.dataItems, that.dataItems)) {
|
||||
if (this.closed == that.closed && this.sectionAlignment == that.sectionAlignment && this.sectionSize == that.sectionSize && Objects.equals(this.dataItems, that.dataItems)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -171,14 +171,14 @@ public final class DataSection implements Iterable<Data> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a {@link Data} item into the data section. If the item is already in the data section,
|
||||
* the same {@link DataSectionReference} is returned.
|
||||
* Inserts a {@link Data} item into the data section. If the item is already in the data
|
||||
* section, the same {@link DataSectionReference} is returned.
|
||||
*
|
||||
* @param data the {@link Data} item to be inserted
|
||||
* @return a unique {@link DataSectionReference} identifying the {@link Data} item
|
||||
*/
|
||||
public DataSectionReference insertData(Data data) {
|
||||
assert !finalLayout;
|
||||
checkOpen();
|
||||
synchronized (data) {
|
||||
if (data.ref == null) {
|
||||
data.ref = new DataSectionReference();
|
||||
@ -193,7 +193,8 @@ public final class DataSection implements Iterable<Data> {
|
||||
* {@link DataSection}, and empties the other section.
|
||||
*/
|
||||
public void addAll(DataSection other) {
|
||||
assert !finalLayout && !other.finalLayout;
|
||||
checkOpen();
|
||||
other.checkOpen();
|
||||
|
||||
for (Data data : other.dataItems) {
|
||||
assert data.ref != null;
|
||||
@ -203,12 +204,20 @@ public final class DataSection implements Iterable<Data> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the layout of the data section. This can be called only once, and after it has been
|
||||
* called, the data section can no longer be modified.
|
||||
* Determines if this object has been {@link #close() closed}.
|
||||
*/
|
||||
public void finalizeLayout() {
|
||||
assert !finalLayout;
|
||||
finalLayout = true;
|
||||
public boolean closed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the layout of the data section and closes this object to further updates.
|
||||
*
|
||||
* This must be called exactly once.
|
||||
*/
|
||||
void close() {
|
||||
checkOpen();
|
||||
closed = true;
|
||||
|
||||
// simple heuristic: put items with larger alignment requirement first
|
||||
dataItems.sort((a, b) -> a.alignment - b.alignment);
|
||||
@ -227,37 +236,38 @@ public final class DataSection implements Iterable<Data> {
|
||||
sectionSize = position;
|
||||
}
|
||||
|
||||
public boolean isFinalized() {
|
||||
return finalLayout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of the data section. Can only be called after {@link #finalizeLayout}.
|
||||
* Gets the size of the data section.
|
||||
*
|
||||
* This must only be called once this object has been {@linkplain #closed() closed}.
|
||||
*/
|
||||
public int getSectionSize() {
|
||||
assert finalLayout;
|
||||
checkClosed();
|
||||
return sectionSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum alignment requirement of the data section. Can only be called after
|
||||
* {@link #finalizeLayout}.
|
||||
* Gets the minimum alignment requirement of the data section.
|
||||
*
|
||||
* This must only be called once this object has been {@linkplain #closed() closed}.
|
||||
*/
|
||||
public int getSectionAlignment() {
|
||||
assert finalLayout;
|
||||
checkClosed();
|
||||
return sectionAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the data section. Can only be called after {@link #finalizeLayout}.
|
||||
* Builds the data section into a given buffer.
|
||||
*
|
||||
* @param buffer The {@link ByteBuffer} where the data section should be built. The buffer must
|
||||
* This must only be called once this object has been {@linkplain #closed() closed}.
|
||||
*
|
||||
* @param buffer the {@link ByteBuffer} where the data section should be built. The buffer must
|
||||
* hold at least {@link #getSectionSize()} bytes.
|
||||
* @param patch A {@link Consumer} to receive {@link DataPatch data patches} for relocations in
|
||||
* the data section.
|
||||
* @param patch a {@link Consumer} to receive {@link DataPatch data patches} for relocations in
|
||||
* the data section
|
||||
*/
|
||||
public void buildDataSection(ByteBuffer buffer, Consumer<DataPatch> patch) {
|
||||
assert finalLayout;
|
||||
checkClosed();
|
||||
for (Data d : dataItems) {
|
||||
buffer.position(d.ref.getOffset());
|
||||
d.builder.emit(buffer, patch);
|
||||
@ -300,8 +310,20 @@ public final class DataSection implements Iterable<Data> {
|
||||
return ((position + alignment - 1) / alignment) * alignment;
|
||||
}
|
||||
|
||||
private void checkClosed() {
|
||||
if (!closed) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkOpen() {
|
||||
if (closed) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
assert !finalLayout;
|
||||
checkOpen();
|
||||
this.dataItems.clear();
|
||||
this.sectionAlignment = 0;
|
||||
this.sectionSize = 0;
|
||||
|
@ -26,22 +26,12 @@ package jdk.vm.ci.code;
|
||||
* A reason for infopoint insertion.
|
||||
*/
|
||||
public enum InfopointReason {
|
||||
UNKNOWN(false),
|
||||
SAFEPOINT(false),
|
||||
CALL(false),
|
||||
IMPLICIT_EXCEPTION(false),
|
||||
METHOD_START(true),
|
||||
METHOD_END(true),
|
||||
LINE_NUMBER(true),
|
||||
METASPACE_ACCESS(true);
|
||||
|
||||
private InfopointReason(boolean canBeOmitted) {
|
||||
this.canBeOmitted = canBeOmitted;
|
||||
}
|
||||
|
||||
private final boolean canBeOmitted;
|
||||
|
||||
public boolean canBeOmitted() {
|
||||
return canBeOmitted;
|
||||
}
|
||||
SAFEPOINT,
|
||||
CALL,
|
||||
IMPLICIT_EXCEPTION,
|
||||
METASPACE_ACCESS,
|
||||
METHOD_START,
|
||||
METHOD_END,
|
||||
BYTECODE_POSITION;
|
||||
}
|
||||
|
@ -24,9 +24,12 @@ package jdk.vm.ci.hotspot;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.Stream.Builder;
|
||||
|
||||
@ -41,6 +44,8 @@ import jdk.vm.ci.code.CompilationResult.JumpTable;
|
||||
import jdk.vm.ci.code.CompilationResult.Mark;
|
||||
import jdk.vm.ci.code.CompilationResult.Site;
|
||||
import jdk.vm.ci.code.DataSection;
|
||||
import jdk.vm.ci.code.InfopointReason;
|
||||
import jdk.vm.ci.common.JVMCIError;
|
||||
import jdk.vm.ci.meta.Assumptions.Assumption;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
|
||||
@ -118,7 +123,6 @@ public class HotSpotCompiledCode {
|
||||
targetCodeSize = compResult.getTargetCodeSize();
|
||||
|
||||
DataSection data = compResult.getDataSection();
|
||||
data.finalizeLayout();
|
||||
dataSection = new byte[data.getSectionSize()];
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.wrap(dataSection).order(ByteOrder.nativeOrder());
|
||||
@ -155,14 +159,75 @@ public class HotSpotCompiledCode {
|
||||
|
||||
static class SiteComparator implements Comparator<Site> {
|
||||
|
||||
/**
|
||||
* Defines an order for sorting {@link Infopoint}s based on their
|
||||
* {@linkplain Infopoint#reason reasons}. This is used to choose which infopoint to preserve
|
||||
* when multiple infopoints collide on the same PC offset. A negative order value implies a
|
||||
* non-optional infopoint (i.e., must be preserved). Non-optional infopoints must not
|
||||
* collide.
|
||||
*/
|
||||
static final Map<InfopointReason, Integer> HOTSPOT_INFOPOINT_SORT_ORDER = new EnumMap<>(InfopointReason.class);
|
||||
static {
|
||||
HOTSPOT_INFOPOINT_SORT_ORDER.put(InfopointReason.SAFEPOINT, -4);
|
||||
HOTSPOT_INFOPOINT_SORT_ORDER.put(InfopointReason.CALL, -3);
|
||||
HOTSPOT_INFOPOINT_SORT_ORDER.put(InfopointReason.IMPLICIT_EXCEPTION, -2);
|
||||
HOTSPOT_INFOPOINT_SORT_ORDER.put(InfopointReason.METASPACE_ACCESS, 1);
|
||||
HOTSPOT_INFOPOINT_SORT_ORDER.put(InfopointReason.METHOD_START, 2);
|
||||
HOTSPOT_INFOPOINT_SORT_ORDER.put(InfopointReason.METHOD_END, 3);
|
||||
HOTSPOT_INFOPOINT_SORT_ORDER.put(InfopointReason.BYTECODE_POSITION, 4);
|
||||
}
|
||||
|
||||
static int ord(Infopoint info) {
|
||||
return HOTSPOT_INFOPOINT_SORT_ORDER.get(info.reason);
|
||||
}
|
||||
|
||||
static int checkCollision(Infopoint i1, Infopoint i2) {
|
||||
int o1 = ord(i1);
|
||||
int o2 = ord(i2);
|
||||
if (o1 < 0 && o2 < 0) {
|
||||
throw new JVMCIError("Non-optional infopoints cannot collide: %s and %s", i1, i2);
|
||||
}
|
||||
return o1 - o2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records whether any two {@link Infopoint}s had the same {@link Infopoint#pcOffset}.
|
||||
*/
|
||||
boolean sawCollidingInfopoints;
|
||||
|
||||
public int compare(Site s1, Site s2) {
|
||||
if (s1.pcOffset == s2.pcOffset && (s1 instanceof Mark ^ s2 instanceof Mark)) {
|
||||
return s1 instanceof Mark ? -1 : 1;
|
||||
if (s1.pcOffset == s2.pcOffset) {
|
||||
// Marks must come first since patching a call site
|
||||
// may need to know the mark denoting the call type
|
||||
// (see uses of CodeInstaller::_next_call_type).
|
||||
boolean s1IsMark = s1 instanceof Mark;
|
||||
boolean s2IsMark = s2 instanceof Mark;
|
||||
if (s1IsMark != s2IsMark) {
|
||||
return s1IsMark ? -1 : 1;
|
||||
}
|
||||
|
||||
// Infopoints must group together so put them after
|
||||
// other Site types.
|
||||
boolean s1IsInfopoint = s1 instanceof Infopoint;
|
||||
boolean s2IsInfopoint = s2 instanceof Infopoint;
|
||||
if (s1IsInfopoint != s2IsInfopoint) {
|
||||
return s1IsInfopoint ? 1 : -1;
|
||||
}
|
||||
|
||||
if (s1IsInfopoint) {
|
||||
sawCollidingInfopoints = true;
|
||||
return checkCollision((Infopoint) s1, (Infopoint) s2);
|
||||
}
|
||||
}
|
||||
return s1.pcOffset - s2.pcOffset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HotSpot expects sites to be presented in ascending order of PC (see
|
||||
* {@code DebugInformationRecorder::add_new_pc_offset}). In addition, it expects
|
||||
* {@link Infopoint} PCs to be unique.
|
||||
*/
|
||||
private static Site[] getSortedSites(CompilationResult target) {
|
||||
List<?>[] lists = new List<?>[]{target.getInfopoints(), target.getDataPatches(), target.getMarks()};
|
||||
int count = 0;
|
||||
@ -176,7 +241,27 @@ public class HotSpotCompiledCode {
|
||||
result[pos++] = (Site) elem;
|
||||
}
|
||||
}
|
||||
Arrays.sort(result, new SiteComparator());
|
||||
SiteComparator c = new SiteComparator();
|
||||
Arrays.sort(result, c);
|
||||
if (c.sawCollidingInfopoints) {
|
||||
Infopoint lastInfopoint = null;
|
||||
List<Site> copy = new ArrayList<>(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (result[i] instanceof Infopoint) {
|
||||
Infopoint info = (Infopoint) result[i];
|
||||
if (lastInfopoint == null || lastInfopoint.pcOffset != info.pcOffset) {
|
||||
lastInfopoint = info;
|
||||
copy.add(info);
|
||||
} else {
|
||||
// Omit this colliding infopoint
|
||||
assert lastInfopoint.reason.compareTo(info.reason) <= 0;
|
||||
}
|
||||
} else {
|
||||
copy.add(result[i]);
|
||||
}
|
||||
}
|
||||
result = copy.toArray(new Site[copy.size()]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ void LIR_Assembler::patching_epilog(PatchingStub* patch, LIR_PatchCode patch_cod
|
||||
// We must have enough patching space so that call can be inserted.
|
||||
// We cannot use fat nops here, since the concurrent code rewrite may transiently
|
||||
// create the illegal instruction sequence.
|
||||
while ((intx) _masm->pc() - (intx) patch->pc_start() < NativeCall::instruction_size) {
|
||||
while ((intx) _masm->pc() - (intx) patch->pc_start() < NativeGeneralJump::instruction_size) {
|
||||
_masm->nop();
|
||||
}
|
||||
patch->install(_masm, patch_code, obj, info);
|
||||
|
@ -1163,7 +1163,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int i = NativeCall::instruction_size; i < *byte_count; i++) {
|
||||
for (int i = NativeGeneralJump::instruction_size; i < *byte_count; i++) {
|
||||
address ptr = copy_buff + i;
|
||||
int a_byte = (*ptr) & 0xFF;
|
||||
address dst = instr_pc + i;
|
||||
|
@ -33,7 +33,7 @@
|
||||
// We keep track of these chunks in order to detect
|
||||
// repetition and enable sharing.
|
||||
class DIR_Chunk {
|
||||
friend class DebugInformationRecorder;
|
||||
private:
|
||||
int _offset; // location in the stream of this scope
|
||||
int _length; // number of bytes in the stream
|
||||
int _hash; // hash of stream bytes (for quicker reuse)
|
||||
@ -41,6 +41,9 @@ class DIR_Chunk {
|
||||
DebugInformationRecorder* _DIR;
|
||||
#endif
|
||||
|
||||
public:
|
||||
int offset() { return _offset; }
|
||||
|
||||
void* operator new(size_t ignore, DebugInformationRecorder* dir) throw() {
|
||||
assert(ignore == sizeof(DIR_Chunk), "");
|
||||
if (dir->_next_chunk >= dir->_next_chunk_limit) {
|
||||
@ -284,7 +287,7 @@ int DebugInformationRecorder::find_sharable_decode_offset(int stream_offset) {
|
||||
NOT_PRODUCT(++dir_stats.chunks_shared);
|
||||
assert(ns+1 == _next_chunk, "");
|
||||
_next_chunk = ns;
|
||||
return match->_offset;
|
||||
return match->offset();
|
||||
} else {
|
||||
// Inserted this chunk, so nothing to do
|
||||
return serialized_null;
|
||||
@ -296,7 +299,7 @@ int DebugInformationRecorder::find_sharable_decode_offset(int stream_offset) {
|
||||
NOT_PRODUCT(++dir_stats.chunks_reshared);
|
||||
assert(ns+1 == _next_chunk, "");
|
||||
_next_chunk = ns;
|
||||
return ms->_offset;
|
||||
return ms->offset();
|
||||
}
|
||||
|
||||
// Look in recently encountered scopes next:
|
||||
@ -311,7 +314,7 @@ int DebugInformationRecorder::find_sharable_decode_offset(int stream_offset) {
|
||||
_shared_chunks->append(ms);
|
||||
assert(ns+1 == _next_chunk, "");
|
||||
_next_chunk = ns;
|
||||
return ms->_offset;
|
||||
return ms->offset();
|
||||
}
|
||||
|
||||
// No match. Add this guy to the list, in hopes of future shares.
|
||||
|
@ -727,10 +727,9 @@ JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer,
|
||||
if (InfopointReason::SAFEPOINT() == reason || InfopointReason::CALL() == reason || InfopointReason::IMPLICIT_EXCEPTION() == reason) {
|
||||
TRACE_jvmci_4("safepoint at %i", pc_offset);
|
||||
site_Safepoint(buffer, pc_offset, site, CHECK_OK);
|
||||
} else if (InfopointReason::METHOD_START() == reason || InfopointReason::METHOD_END() == reason || InfopointReason::LINE_NUMBER() == reason) {
|
||||
site_Infopoint(buffer, pc_offset, site, CHECK_OK);
|
||||
} else {
|
||||
JVMCI_ERROR_OK("unknown infopoint reason at %i", pc_offset);
|
||||
TRACE_jvmci_4("infopoint at %i", pc_offset);
|
||||
site_Infopoint(buffer, pc_offset, site, CHECK_OK);
|
||||
}
|
||||
} else if (site->is_a(CompilationResult_DataPatch::klass())) {
|
||||
TRACE_jvmci_4("datapatch at %i", pc_offset);
|
||||
@ -868,25 +867,33 @@ GrowableArray<ScopeValue*>* CodeInstaller::record_virtual_objects(Handle debug_i
|
||||
return objects;
|
||||
}
|
||||
|
||||
void CodeInstaller::record_scope(jint pc_offset, Handle debug_info, TRAPS) {
|
||||
void CodeInstaller::record_scope(jint pc_offset, Handle debug_info, ScopeMode scope_mode, TRAPS) {
|
||||
Handle position = DebugInfo::bytecodePosition(debug_info);
|
||||
if (position.is_null()) {
|
||||
// Stubs do not record scope info, just oop maps
|
||||
return;
|
||||
}
|
||||
|
||||
GrowableArray<ScopeValue*>* objectMapping = record_virtual_objects(debug_info, CHECK);
|
||||
record_scope(pc_offset, position, objectMapping, CHECK);
|
||||
GrowableArray<ScopeValue*>* objectMapping;
|
||||
if (scope_mode == CodeInstaller::FullFrame) {
|
||||
objectMapping = record_virtual_objects(debug_info, CHECK);
|
||||
} else {
|
||||
objectMapping = NULL;
|
||||
}
|
||||
record_scope(pc_offset, position, scope_mode, objectMapping, CHECK);
|
||||
}
|
||||
|
||||
void CodeInstaller::record_scope(jint pc_offset, Handle position, GrowableArray<ScopeValue*>* objects, TRAPS) {
|
||||
void CodeInstaller::record_scope(jint pc_offset, Handle position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, TRAPS) {
|
||||
Handle frame;
|
||||
if (position->is_a(BytecodeFrame::klass())) {
|
||||
if (scope_mode == CodeInstaller::FullFrame) {
|
||||
if (!position->is_a(BytecodeFrame::klass())) {
|
||||
JVMCI_ERROR("Full frame expected for debug info at %i", pc_offset);
|
||||
}
|
||||
frame = position;
|
||||
}
|
||||
Handle caller_frame = BytecodePosition::caller(position);
|
||||
if (caller_frame.not_null()) {
|
||||
record_scope(pc_offset, caller_frame, objects, CHECK);
|
||||
record_scope(pc_offset, caller_frame, scope_mode, objects, CHECK);
|
||||
}
|
||||
|
||||
Handle hotspot_method = BytecodePosition::method(position);
|
||||
@ -990,7 +997,7 @@ void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, Handle si
|
||||
// jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start();
|
||||
OopMap *map = create_oop_map(debug_info, CHECK);
|
||||
_debug_recorder->add_safepoint(pc_offset, map);
|
||||
record_scope(pc_offset, debug_info, CHECK);
|
||||
record_scope(pc_offset, debug_info, CodeInstaller::FullFrame, CHECK);
|
||||
_debug_recorder->end_safepoint(pc_offset);
|
||||
}
|
||||
|
||||
@ -1000,8 +1007,12 @@ void CodeInstaller::site_Infopoint(CodeBuffer& buffer, jint pc_offset, Handle si
|
||||
JVMCI_ERROR("debug info expected at infopoint at %i", pc_offset);
|
||||
}
|
||||
|
||||
// We'd like to check that pc_offset is greater than the
|
||||
// last pc recorded with _debug_recorder (raising an exception if not)
|
||||
// but DebugInformationRecorder doesn't have sufficient public API.
|
||||
|
||||
_debug_recorder->add_non_safepoint(pc_offset);
|
||||
record_scope(pc_offset, debug_info, CHECK);
|
||||
record_scope(pc_offset, debug_info, CodeInstaller::BytecodePosition, CHECK);
|
||||
_debug_recorder->end_non_safepoint(pc_offset);
|
||||
}
|
||||
|
||||
@ -1028,7 +1039,7 @@ void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, Handle site, T
|
||||
if (debug_info.not_null()) {
|
||||
OopMap *map = create_oop_map(debug_info, CHECK);
|
||||
_debug_recorder->add_safepoint(next_pc_offset, map);
|
||||
record_scope(next_pc_offset, debug_info, CHECK);
|
||||
record_scope(next_pc_offset, debug_info, CodeInstaller::FullFrame, CHECK);
|
||||
}
|
||||
|
||||
if (foreign_call.not_null()) {
|
||||
|
@ -219,8 +219,18 @@ protected:
|
||||
|
||||
OopMap* create_oop_map(Handle debug_info, TRAPS);
|
||||
|
||||
void record_scope(jint pc_offset, Handle debug_info, TRAPS);
|
||||
void record_scope(jint pc_offset, Handle code_pos, GrowableArray<ScopeValue*>* objects, TRAPS);
|
||||
/**
|
||||
* Specifies the level of detail to record for a scope.
|
||||
*/
|
||||
enum ScopeMode {
|
||||
// Only record a method and BCI
|
||||
BytecodePosition,
|
||||
// Record a method, bci and JVM frame state
|
||||
FullFrame
|
||||
};
|
||||
|
||||
void record_scope(jint pc_offset, Handle debug_info, ScopeMode scope_mode, TRAPS);
|
||||
void record_scope(jint pc_offset, Handle position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, TRAPS);
|
||||
void record_object_value(ObjectValue* sv, Handle value, GrowableArray<ScopeValue*>* objects, TRAPS);
|
||||
|
||||
GrowableArray<ScopeValue*>* record_virtual_objects(Handle debug_info, TRAPS);
|
||||
|
@ -148,14 +148,9 @@ class JVMCIJavaClasses : AllStatic {
|
||||
int_field(CompilationResult_DataSectionReference, offset) \
|
||||
end_class \
|
||||
start_class(InfopointReason) \
|
||||
static_oop_field(InfopointReason, UNKNOWN, "Ljdk/vm/ci/code/InfopointReason;") \
|
||||
static_oop_field(InfopointReason, SAFEPOINT, "Ljdk/vm/ci/code/InfopointReason;") \
|
||||
static_oop_field(InfopointReason, CALL, "Ljdk/vm/ci/code/InfopointReason;") \
|
||||
static_oop_field(InfopointReason, IMPLICIT_EXCEPTION, "Ljdk/vm/ci/code/InfopointReason;") \
|
||||
static_oop_field(InfopointReason, METHOD_START, "Ljdk/vm/ci/code/InfopointReason;") \
|
||||
static_oop_field(InfopointReason, METHOD_END, "Ljdk/vm/ci/code/InfopointReason;") \
|
||||
static_oop_field(InfopointReason, LINE_NUMBER, "Ljdk/vm/ci/code/InfopointReason;") \
|
||||
static_oop_field(InfopointReason, METASPACE_ACCESS, "Ljdk/vm/ci/code/InfopointReason;") \
|
||||
end_class \
|
||||
start_class(CompilationResult_Infopoint) \
|
||||
oop_field(CompilationResult_Infopoint, debugInfo, "Ljdk/vm/ci/code/DebugInfo;") \
|
||||
|
@ -744,7 +744,10 @@
|
||||
range(0, max_intx) \
|
||||
\
|
||||
develop(bool, StressArrayCopyMacroNode, false, \
|
||||
"Perform ArrayCopy load/store replacement during IGVN only")
|
||||
"Perform ArrayCopy load/store replacement during IGVN only") \
|
||||
\
|
||||
develop(bool, RenumberLiveNodes, true, \
|
||||
"Renumber live nodes") \
|
||||
|
||||
C2_FLAGS(DECLARE_DEVELOPER_FLAG, \
|
||||
DECLARE_PD_DEVELOPER_FLAG, \
|
||||
|
@ -2156,6 +2156,20 @@ void Compile::Optimize() {
|
||||
// so keep only the actual candidates for optimizations.
|
||||
cleanup_expensive_nodes(igvn);
|
||||
|
||||
if (!failing() && RenumberLiveNodes && live_nodes() + NodeLimitFudgeFactor < unique()) {
|
||||
Compile::TracePhase tp("", &timers[_t_renumberLive]);
|
||||
initial_gvn()->replace_with(&igvn);
|
||||
for_igvn()->clear();
|
||||
Unique_Node_List new_worklist(C->comp_arena());
|
||||
{
|
||||
ResourceMark rm;
|
||||
PhaseRenumberLive prl = PhaseRenumberLive(initial_gvn(), for_igvn(), &new_worklist);
|
||||
}
|
||||
set_for_igvn(&new_worklist);
|
||||
igvn = PhaseIterGVN(initial_gvn());
|
||||
igvn.optimize();
|
||||
}
|
||||
|
||||
// Perform escape analysis
|
||||
if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) {
|
||||
if (has_loops()) {
|
||||
|
@ -152,6 +152,8 @@ class LibraryCallKit : public GraphKit {
|
||||
Node* generate_limit_guard(Node* offset, Node* subseq_length,
|
||||
Node* array_length,
|
||||
RegionNode* region);
|
||||
void generate_string_range_check(Node* array, Node* offset,
|
||||
Node* length, bool char_count);
|
||||
Node* generate_current_thread(Node* &tls_output);
|
||||
Node* load_mirror_from_klass(Node* klass);
|
||||
Node* load_klass_from_mirror_common(Node* mirror, bool never_see_null,
|
||||
@ -204,6 +206,8 @@ class LibraryCallKit : public GraphKit {
|
||||
bool inline_string_compareTo(StrIntrinsicNode::ArgEnc ae);
|
||||
bool inline_string_indexOf(StrIntrinsicNode::ArgEnc ae);
|
||||
bool inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae);
|
||||
Node* make_indexOf_node(Node* src_start, Node* src_count, Node* tgt_start, Node* tgt_count,
|
||||
RegionNode* region, Node* phi, StrIntrinsicNode::ArgEnc ae);
|
||||
bool inline_string_indexOfChar();
|
||||
bool inline_string_equals(StrIntrinsicNode::ArgEnc ae);
|
||||
bool inline_string_toBytesU();
|
||||
@ -897,6 +901,31 @@ inline Node* LibraryCallKit::generate_limit_guard(Node* offset,
|
||||
return is_over;
|
||||
}
|
||||
|
||||
// Emit range checks for the given String.value byte array
|
||||
void LibraryCallKit::generate_string_range_check(Node* array, Node* offset, Node* count, bool char_count) {
|
||||
if (stopped()) {
|
||||
return; // already stopped
|
||||
}
|
||||
RegionNode* bailout = new RegionNode(1);
|
||||
record_for_igvn(bailout);
|
||||
if (char_count) {
|
||||
// Convert char count to byte count
|
||||
count = _gvn.transform(new LShiftINode(count, intcon(1)));
|
||||
}
|
||||
|
||||
// Offset and count must not be negative
|
||||
generate_negative_guard(offset, bailout);
|
||||
generate_negative_guard(count, bailout);
|
||||
// Offset + count must not exceed length of array
|
||||
generate_limit_guard(offset, count, load_array_length(array), bailout);
|
||||
|
||||
if (bailout->req() > 1) {
|
||||
PreserveJVMState pjvms(this);
|
||||
set_control(_gvn.transform(bailout));
|
||||
uncommon_trap(Deoptimization::Reason_intrinsic,
|
||||
Deoptimization::Action_maybe_recompile);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------generate_current_thread--------------------
|
||||
Node* LibraryCallKit::generate_current_thread(Node* &tls_output) {
|
||||
@ -1016,7 +1045,9 @@ bool LibraryCallKit::inline_array_equals(StrIntrinsicNode::ArgEnc ae) {
|
||||
|
||||
//------------------------------inline_hasNegatives------------------------------
|
||||
bool LibraryCallKit::inline_hasNegatives() {
|
||||
if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
|
||||
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(callee()->signature()->size() == 3, "hasNegatives has 3 parameters");
|
||||
// no receiver since it is static method
|
||||
@ -1024,26 +1055,14 @@ bool LibraryCallKit::inline_hasNegatives() {
|
||||
Node* offset = argument(1);
|
||||
Node* len = argument(2);
|
||||
|
||||
RegionNode* bailout = new RegionNode(1);
|
||||
record_for_igvn(bailout);
|
||||
|
||||
// offset must not be negative.
|
||||
generate_negative_guard(offset, bailout);
|
||||
|
||||
// offset + length must not exceed length of ba.
|
||||
generate_limit_guard(offset, len, load_array_length(ba), bailout);
|
||||
|
||||
if (bailout->req() > 1) {
|
||||
PreserveJVMState pjvms(this);
|
||||
set_control(_gvn.transform(bailout));
|
||||
uncommon_trap(Deoptimization::Reason_intrinsic,
|
||||
Deoptimization::Action_maybe_recompile);
|
||||
}
|
||||
if (!stopped()) {
|
||||
Node* ba_start = array_element_address(ba, offset, T_BYTE);
|
||||
Node* result = new HasNegativesNode(control(), memory(TypeAryPtr::BYTES), ba_start, len);
|
||||
set_result(_gvn.transform(result));
|
||||
// Range checks
|
||||
generate_string_range_check(ba, offset, len, false);
|
||||
if (stopped()) {
|
||||
return true;
|
||||
}
|
||||
Node* ba_start = array_element_address(ba, offset, T_BYTE);
|
||||
Node* result = new HasNegativesNode(control(), memory(TypeAryPtr::BYTES), ba_start, len);
|
||||
set_result(_gvn.transform(result));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1124,30 +1143,10 @@ bool LibraryCallKit::inline_string_indexOf(StrIntrinsicNode::ArgEnc ae) {
|
||||
tgt_count = _gvn.transform(new RShiftINode(tgt_count, intcon(1)));
|
||||
}
|
||||
|
||||
// Check for substr count > string count
|
||||
Node* cmp = _gvn.transform(new CmpINode(tgt_count, src_count));
|
||||
Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::gt));
|
||||
Node* if_gt = generate_slow_guard(bol, NULL);
|
||||
if (if_gt != NULL) {
|
||||
result_phi->init_req(2, intcon(-1));
|
||||
result_rgn->init_req(2, if_gt);
|
||||
}
|
||||
|
||||
if (!stopped()) {
|
||||
// Check for substr count == 0
|
||||
cmp = _gvn.transform(new CmpINode(tgt_count, intcon(0)));
|
||||
bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq));
|
||||
Node* if_zero = generate_slow_guard(bol, NULL);
|
||||
if (if_zero != NULL) {
|
||||
result_phi->init_req(3, intcon(0));
|
||||
result_rgn->init_req(3, if_zero);
|
||||
}
|
||||
}
|
||||
|
||||
if (!stopped()) {
|
||||
Node* result = make_string_method_node(Op_StrIndexOf, src_start, src_count, tgt_start, tgt_count, ae);
|
||||
result_phi->init_req(1, result);
|
||||
result_rgn->init_req(1, control());
|
||||
Node* result = make_indexOf_node(src_start, src_count, tgt_start, tgt_count, result_rgn, result_phi, ae);
|
||||
if (result != NULL) {
|
||||
result_phi->init_req(3, result);
|
||||
result_rgn->init_req(3, control());
|
||||
}
|
||||
set_control(_gvn.transform(result_rgn));
|
||||
record_for_igvn(result_rgn);
|
||||
@ -1158,44 +1157,53 @@ bool LibraryCallKit::inline_string_indexOf(StrIntrinsicNode::ArgEnc ae) {
|
||||
|
||||
//-----------------------------inline_string_indexOf-----------------------
|
||||
bool LibraryCallKit::inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae) {
|
||||
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
|
||||
return false;
|
||||
}
|
||||
if (!Matcher::has_match_rule(Op_StrIndexOf) || !UseSSE42Intrinsics) {
|
||||
return false;
|
||||
}
|
||||
assert(callee()->signature()->size() == 5, "String.indexOf() has 5 arguments");
|
||||
Node* src = argument(0); // byte[]
|
||||
Node* src_count = argument(1);
|
||||
Node* src_count = argument(1); // char count
|
||||
Node* tgt = argument(2); // byte[]
|
||||
Node* tgt_count = argument(3);
|
||||
Node* from_index = argument(4);
|
||||
|
||||
// Java code which calls this method has range checks for from_index value.
|
||||
src_count = _gvn.transform(new SubINode(src_count, from_index));
|
||||
Node* tgt_count = argument(3); // char count
|
||||
Node* from_index = argument(4); // char index
|
||||
|
||||
// Multiply byte array index by 2 if String is UTF16 encoded
|
||||
Node* src_offset = (ae == StrIntrinsicNode::LL) ? from_index : _gvn.transform(new LShiftINode(from_index, intcon(1)));
|
||||
src_count = _gvn.transform(new SubINode(src_count, from_index));
|
||||
Node* src_start = array_element_address(src, src_offset, T_BYTE);
|
||||
Node* tgt_start = array_element_address(tgt, intcon(0), T_BYTE);
|
||||
|
||||
Node* result = make_string_method_node(Op_StrIndexOf, src_start, src_count, tgt_start, tgt_count, ae);
|
||||
// Range checks
|
||||
generate_string_range_check(src, src_offset, src_count, ae != StrIntrinsicNode::LL);
|
||||
generate_string_range_check(tgt, intcon(0), tgt_count, ae == StrIntrinsicNode::UU);
|
||||
if (stopped()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The result is index relative to from_index if substring was found, -1 otherwise.
|
||||
// Generate code which will fold into cmove.
|
||||
RegionNode* region = new RegionNode(3);
|
||||
RegionNode* region = new RegionNode(5);
|
||||
Node* phi = new PhiNode(region, TypeInt::INT);
|
||||
|
||||
Node* cmp = _gvn.transform(new CmpINode(result, intcon(0)));
|
||||
Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::lt));
|
||||
Node* result = make_indexOf_node(src_start, src_count, tgt_start, tgt_count, region, phi, ae);
|
||||
if (result != NULL) {
|
||||
// The result is index relative to from_index if substring was found, -1 otherwise.
|
||||
// Generate code which will fold into cmove.
|
||||
Node* cmp = _gvn.transform(new CmpINode(result, intcon(0)));
|
||||
Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::lt));
|
||||
|
||||
Node* if_lt = generate_slow_guard(bol, NULL);
|
||||
if (if_lt != NULL) {
|
||||
// result == -1
|
||||
phi->init_req(2, result);
|
||||
region->init_req(2, if_lt);
|
||||
}
|
||||
if (!stopped()) {
|
||||
result = _gvn.transform(new AddINode(result, from_index));
|
||||
phi->init_req(1, result);
|
||||
region->init_req(1, control());
|
||||
Node* if_lt = generate_slow_guard(bol, NULL);
|
||||
if (if_lt != NULL) {
|
||||
// result == -1
|
||||
phi->init_req(3, result);
|
||||
region->init_req(3, if_lt);
|
||||
}
|
||||
if (!stopped()) {
|
||||
result = _gvn.transform(new AddINode(result, from_index));
|
||||
phi->init_req(4, result);
|
||||
region->init_req(4, control());
|
||||
}
|
||||
}
|
||||
|
||||
set_control(_gvn.transform(region));
|
||||
@ -1205,8 +1213,38 @@ bool LibraryCallKit::inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create StrIndexOfNode with fast path checks
|
||||
Node* LibraryCallKit::make_indexOf_node(Node* src_start, Node* src_count, Node* tgt_start, Node* tgt_count,
|
||||
RegionNode* region, Node* phi, StrIntrinsicNode::ArgEnc ae) {
|
||||
// Check for substr count > string count
|
||||
Node* cmp = _gvn.transform(new CmpINode(tgt_count, src_count));
|
||||
Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::gt));
|
||||
Node* if_gt = generate_slow_guard(bol, NULL);
|
||||
if (if_gt != NULL) {
|
||||
phi->init_req(1, intcon(-1));
|
||||
region->init_req(1, if_gt);
|
||||
}
|
||||
if (!stopped()) {
|
||||
// Check for substr count == 0
|
||||
cmp = _gvn.transform(new CmpINode(tgt_count, intcon(0)));
|
||||
bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq));
|
||||
Node* if_zero = generate_slow_guard(bol, NULL);
|
||||
if (if_zero != NULL) {
|
||||
phi->init_req(2, intcon(0));
|
||||
region->init_req(2, if_zero);
|
||||
}
|
||||
}
|
||||
if (!stopped()) {
|
||||
return make_string_method_node(Op_StrIndexOf, src_start, src_count, tgt_start, tgt_count, ae);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------inline_string_indexOfChar-----------------------
|
||||
bool LibraryCallKit::inline_string_indexOfChar() {
|
||||
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
|
||||
return false;
|
||||
}
|
||||
if (!Matcher::has_match_rule(Op_StrIndexOfChar) || !(UseSSE > 4)) {
|
||||
return false;
|
||||
}
|
||||
@ -1218,9 +1256,14 @@ bool LibraryCallKit::inline_string_indexOfChar() {
|
||||
|
||||
Node* src_offset = _gvn.transform(new LShiftINode(from_index, intcon(1)));
|
||||
Node* src_start = array_element_address(src, src_offset, T_BYTE);
|
||||
|
||||
Node* src_count = _gvn.transform(new SubINode(max, from_index));
|
||||
|
||||
// Range checks
|
||||
generate_string_range_check(src, src_offset, src_count, true);
|
||||
if (stopped()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
RegionNode* region = new RegionNode(3);
|
||||
Node* phi = new PhiNode(region, TypeInt::INT);
|
||||
|
||||
@ -1256,6 +1299,9 @@ bool LibraryCallKit::inline_string_indexOfChar() {
|
||||
// void StringLatin1.inflate(byte[] src, int srcOff, char[] dst, int dstOff, int len)
|
||||
// void StringLatin1.inflate(byte[] src, int srcOff, byte[] dst, int dstOff, int len)
|
||||
bool LibraryCallKit::inline_string_copy(bool compress) {
|
||||
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
|
||||
return false;
|
||||
}
|
||||
int nargs = 5; // 2 oops, 3 ints
|
||||
assert(callee()->signature()->size() == nargs, "string copy has 5 arguments");
|
||||
|
||||
@ -1278,6 +1324,13 @@ bool LibraryCallKit::inline_string_copy(bool compress) {
|
||||
(!compress && src_elem == T_BYTE && (dst_elem == T_BYTE || dst_elem == T_CHAR)),
|
||||
"Unsupported array types for inline_string_copy");
|
||||
|
||||
// Range checks
|
||||
generate_string_range_check(src, src_offset, length, compress && src_elem == T_BYTE);
|
||||
generate_string_range_check(dst, dst_offset, length, !compress && dst_elem == T_BYTE);
|
||||
if (stopped()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Convert char[] offsets to byte[] offsets
|
||||
if (compress && src_elem == T_BYTE) {
|
||||
src_offset = _gvn.transform(new LShiftINode(src_offset, intcon(1)));
|
||||
@ -1329,6 +1382,9 @@ bool LibraryCallKit::inline_string_copy(bool compress) {
|
||||
//------------------------inline_string_toBytesU--------------------------
|
||||
// public static byte[] StringUTF16.toBytes(char[] value, int off, int len)
|
||||
bool LibraryCallKit::inline_string_toBytesU() {
|
||||
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
|
||||
return false;
|
||||
}
|
||||
// Get the arguments.
|
||||
Node* value = argument(0);
|
||||
Node* offset = argument(1);
|
||||
@ -1347,8 +1403,11 @@ bool LibraryCallKit::inline_string_toBytesU() {
|
||||
RegionNode* bailout = new RegionNode(1);
|
||||
record_for_igvn(bailout);
|
||||
|
||||
// Make sure that resulting byte[] length does not overflow Integer.MAX_VALUE
|
||||
// Range checks
|
||||
generate_negative_guard(offset, bailout);
|
||||
generate_negative_guard(length, bailout);
|
||||
generate_limit_guard(offset, length, load_array_length(value), bailout);
|
||||
// Make sure that resulting byte[] length does not overflow Integer.MAX_VALUE
|
||||
generate_limit_guard(length, intcon(0), intcon(max_jint/2), bailout);
|
||||
|
||||
if (bailout->req() > 1) {
|
||||
@ -1357,9 +1416,9 @@ bool LibraryCallKit::inline_string_toBytesU() {
|
||||
uncommon_trap(Deoptimization::Reason_intrinsic,
|
||||
Deoptimization::Action_maybe_recompile);
|
||||
}
|
||||
if (stopped()) return true;
|
||||
|
||||
// Range checks are done by caller.
|
||||
if (stopped()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Node* size = _gvn.transform(new LShiftINode(length, intcon(1)));
|
||||
Node* klass_node = makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_BYTE)));
|
||||
@ -1412,12 +1471,14 @@ bool LibraryCallKit::inline_string_toBytesU() {
|
||||
}
|
||||
|
||||
//------------------------inline_string_getCharsU--------------------------
|
||||
// public void StringUTF16.getChars(byte[] value, int srcBegin, int srcEnd, char dst[], int dstBegin)
|
||||
// public void StringUTF16.getChars(byte[] src, int srcBegin, int srcEnd, char dst[], int dstBegin)
|
||||
bool LibraryCallKit::inline_string_getCharsU() {
|
||||
if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
|
||||
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the arguments.
|
||||
Node* value = argument(0);
|
||||
Node* src = argument(0);
|
||||
Node* src_begin = argument(1);
|
||||
Node* src_end = argument(2); // exclusive offset (i < src_end)
|
||||
Node* dst = argument(3);
|
||||
@ -1428,21 +1489,26 @@ bool LibraryCallKit::inline_string_getCharsU() {
|
||||
AllocateArrayNode* alloc = tightly_coupled_allocation(dst, NULL);
|
||||
|
||||
// Check if a null path was taken unconditionally.
|
||||
value = null_check(value);
|
||||
src = null_check(src);
|
||||
dst = null_check(dst);
|
||||
if (stopped()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Range checks are done by caller.
|
||||
|
||||
// Get length and convert char[] offset to byte[] offset
|
||||
Node* length = _gvn.transform(new SubINode(src_end, src_begin));
|
||||
src_begin = _gvn.transform(new LShiftINode(src_begin, intcon(1)));
|
||||
|
||||
// Range checks
|
||||
generate_string_range_check(src, src_begin, length, true);
|
||||
generate_string_range_check(dst, dst_begin, length, false);
|
||||
if (stopped()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!stopped()) {
|
||||
// Calculate starting addresses.
|
||||
Node* src_start = array_element_address(value, src_begin, T_BYTE);
|
||||
Node* src_start = array_element_address(src, src_begin, T_BYTE);
|
||||
Node* dst_start = array_element_address(dst, dst_begin, T_CHAR);
|
||||
|
||||
// Check if array addresses are aligned to HeapWordSize
|
||||
|
@ -316,6 +316,9 @@ inline int Node::Init(int req) {
|
||||
// Create a Node, with a given number of required edges.
|
||||
Node::Node(uint req)
|
||||
: _idx(Init(req))
|
||||
#ifdef ASSERT
|
||||
, _parse_idx(_idx)
|
||||
#endif
|
||||
{
|
||||
assert( req < Compile::current()->max_node_limit() - NodeLimitFudgeFactor, "Input limit exceeded" );
|
||||
debug_only( verify_construction() );
|
||||
@ -335,6 +338,9 @@ Node::Node(uint req)
|
||||
//------------------------------Node-------------------------------------------
|
||||
Node::Node(Node *n0)
|
||||
: _idx(Init(1))
|
||||
#ifdef ASSERT
|
||||
, _parse_idx(_idx)
|
||||
#endif
|
||||
{
|
||||
debug_only( verify_construction() );
|
||||
NOT_PRODUCT(nodes_created++);
|
||||
@ -347,6 +353,9 @@ Node::Node(Node *n0)
|
||||
//------------------------------Node-------------------------------------------
|
||||
Node::Node(Node *n0, Node *n1)
|
||||
: _idx(Init(2))
|
||||
#ifdef ASSERT
|
||||
, _parse_idx(_idx)
|
||||
#endif
|
||||
{
|
||||
debug_only( verify_construction() );
|
||||
NOT_PRODUCT(nodes_created++);
|
||||
@ -361,6 +370,9 @@ Node::Node(Node *n0, Node *n1)
|
||||
//------------------------------Node-------------------------------------------
|
||||
Node::Node(Node *n0, Node *n1, Node *n2)
|
||||
: _idx(Init(3))
|
||||
#ifdef ASSERT
|
||||
, _parse_idx(_idx)
|
||||
#endif
|
||||
{
|
||||
debug_only( verify_construction() );
|
||||
NOT_PRODUCT(nodes_created++);
|
||||
@ -377,6 +389,9 @@ Node::Node(Node *n0, Node *n1, Node *n2)
|
||||
//------------------------------Node-------------------------------------------
|
||||
Node::Node(Node *n0, Node *n1, Node *n2, Node *n3)
|
||||
: _idx(Init(4))
|
||||
#ifdef ASSERT
|
||||
, _parse_idx(_idx)
|
||||
#endif
|
||||
{
|
||||
debug_only( verify_construction() );
|
||||
NOT_PRODUCT(nodes_created++);
|
||||
@ -395,6 +410,9 @@ Node::Node(Node *n0, Node *n1, Node *n2, Node *n3)
|
||||
//------------------------------Node-------------------------------------------
|
||||
Node::Node(Node *n0, Node *n1, Node *n2, Node *n3, Node *n4)
|
||||
: _idx(Init(5))
|
||||
#ifdef ASSERT
|
||||
, _parse_idx(_idx)
|
||||
#endif
|
||||
{
|
||||
debug_only( verify_construction() );
|
||||
NOT_PRODUCT(nodes_created++);
|
||||
@ -416,6 +434,9 @@ Node::Node(Node *n0, Node *n1, Node *n2, Node *n3, Node *n4)
|
||||
Node::Node(Node *n0, Node *n1, Node *n2, Node *n3,
|
||||
Node *n4, Node *n5)
|
||||
: _idx(Init(6))
|
||||
#ifdef ASSERT
|
||||
, _parse_idx(_idx)
|
||||
#endif
|
||||
{
|
||||
debug_only( verify_construction() );
|
||||
NOT_PRODUCT(nodes_created++);
|
||||
@ -439,6 +460,9 @@ Node::Node(Node *n0, Node *n1, Node *n2, Node *n3,
|
||||
Node::Node(Node *n0, Node *n1, Node *n2, Node *n3,
|
||||
Node *n4, Node *n5, Node *n6)
|
||||
: _idx(Init(7))
|
||||
#ifdef ASSERT
|
||||
, _parse_idx(_idx)
|
||||
#endif
|
||||
{
|
||||
debug_only( verify_construction() );
|
||||
NOT_PRODUCT(nodes_created++);
|
||||
|
@ -293,10 +293,16 @@ protected:
|
||||
|
||||
public:
|
||||
// Each Node is assigned a unique small/dense number. This number is used
|
||||
// to index into auxiliary arrays of data and bitvectors.
|
||||
// It is declared const to defend against inadvertant assignment,
|
||||
// since it is used by clients as a naked field.
|
||||
// to index into auxiliary arrays of data and bit vectors.
|
||||
// The field _idx is declared constant to defend against inadvertent assignments,
|
||||
// since it is used by clients as a naked field. However, the field's value can be
|
||||
// changed using the set_idx() method.
|
||||
//
|
||||
// The PhaseRenumberLive phase renumbers nodes based on liveness information.
|
||||
// Therefore, it updates the value of the _idx field. The parse-time _idx is
|
||||
// preserved in _parse_idx.
|
||||
const node_idx_t _idx;
|
||||
DEBUG_ONLY(const node_idx_t _parse_idx;)
|
||||
|
||||
// Get the (read-only) number of input edges
|
||||
uint req() const { return _cnt; }
|
||||
|
@ -77,6 +77,7 @@ void Phase::print_timers() {
|
||||
tty->print_cr(" Other: %7.3f s", other);
|
||||
}
|
||||
}
|
||||
tty->print_cr (" Renumber Live: %7.3f s", timers[_t_renumberLive].seconds());
|
||||
tty->print_cr (" IdealLoop: %7.3f s", timers[_t_idealLoop].seconds());
|
||||
tty->print_cr (" IdealLoop Verify: %7.3f s", timers[_t_idealLoopVerify].seconds());
|
||||
tty->print_cr (" Cond Const Prop: %7.3f s", timers[_t_ccp].seconds());
|
||||
@ -88,6 +89,7 @@ void Phase::print_timers() {
|
||||
(timers[_t_escapeAnalysis].seconds() +
|
||||
timers[_t_iterGVN].seconds() +
|
||||
timers[_t_incrInline].seconds() +
|
||||
timers[_t_renumberLive].seconds() +
|
||||
timers[_t_idealLoop].seconds() +
|
||||
timers[_t_idealLoopVerify].seconds() +
|
||||
timers[_t_ccp].seconds() +
|
||||
|
@ -42,22 +42,23 @@ class PhaseGVN;
|
||||
class Phase : public StackObj {
|
||||
public:
|
||||
enum PhaseNumber {
|
||||
Compiler, // Top-level compiler phase
|
||||
Parser, // Parse bytecodes
|
||||
Remove_Useless, // Remove useless nodes
|
||||
Optimistic, // Optimistic analysis phase
|
||||
GVN, // Pessimistic global value numbering phase
|
||||
Ins_Select, // Instruction selection phase
|
||||
CFG, // Build a CFG
|
||||
BlockLayout, // Linear ordering of blocks
|
||||
Register_Allocation, // Register allocation, duh
|
||||
LIVE, // Dragon-book LIVE range problem
|
||||
StringOpts, // StringBuilder related optimizations
|
||||
Interference_Graph, // Building the IFG
|
||||
Coalesce, // Coalescing copies
|
||||
Ideal_Loop, // Find idealized trip-counted loops
|
||||
Macro_Expand, // Expand macro nodes
|
||||
Peephole, // Apply peephole optimizations
|
||||
Compiler, // Top-level compiler phase
|
||||
Parser, // Parse bytecodes
|
||||
Remove_Useless, // Remove useless nodes
|
||||
Remove_Useless_And_Renumber_Live, // First, remove useless nodes from the graph. Then, renumber live nodes.
|
||||
Optimistic, // Optimistic analysis phase
|
||||
GVN, // Pessimistic global value numbering phase
|
||||
Ins_Select, // Instruction selection phase
|
||||
CFG, // Build a CFG
|
||||
BlockLayout, // Linear ordering of blocks
|
||||
Register_Allocation, // Register allocation, duh
|
||||
LIVE, // Dragon-book LIVE range problem
|
||||
StringOpts, // StringBuilder related optimizations
|
||||
Interference_Graph, // Building the IFG
|
||||
Coalesce, // Coalescing copies
|
||||
Ideal_Loop, // Find idealized trip-counted loops
|
||||
Macro_Expand, // Expand macro nodes
|
||||
Peephole, // Apply peephole optimizations
|
||||
last_phase
|
||||
};
|
||||
|
||||
@ -73,6 +74,7 @@ public:
|
||||
_t_incrInline_igvn,
|
||||
_t_incrInline_pru,
|
||||
_t_incrInline_inline,
|
||||
_t_renumberLive,
|
||||
_t_idealLoop,
|
||||
_t_idealLoopVerify,
|
||||
_t_ccp,
|
||||
|
@ -406,7 +406,7 @@ void NodeHash::operator=(const NodeHash& nh) {
|
||||
//=============================================================================
|
||||
//------------------------------PhaseRemoveUseless-----------------------------
|
||||
// 1) Use a breadthfirst walk to collect useful nodes reachable from root.
|
||||
PhaseRemoveUseless::PhaseRemoveUseless( PhaseGVN *gvn, Unique_Node_List *worklist ) : Phase(Remove_Useless),
|
||||
PhaseRemoveUseless::PhaseRemoveUseless(PhaseGVN *gvn, Unique_Node_List *worklist, PhaseNumber phase_num) : Phase(phase_num),
|
||||
_useful(Thread::current()->resource_area()) {
|
||||
|
||||
// Implementation requires 'UseLoopSafepoints == true' and an edge from root
|
||||
@ -443,6 +443,82 @@ PhaseRemoveUseless::PhaseRemoveUseless( PhaseGVN *gvn, Unique_Node_List *worklis
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//------------------------------PhaseRenumberLive------------------------------
|
||||
// First, remove useless nodes (equivalent to identifying live nodes).
|
||||
// Then, renumber live nodes.
|
||||
//
|
||||
// The set of live nodes is returned by PhaseRemoveUseless in the _useful structure.
|
||||
// If the number of live nodes is 'x' (where 'x' == _useful.size()), then the
|
||||
// PhaseRenumberLive updates the node ID of each node (the _idx field) with a unique
|
||||
// value in the range [0, x).
|
||||
//
|
||||
// At the end of the PhaseRenumberLive phase, the compiler's count of unique nodes is
|
||||
// updated to 'x' and the list of dead nodes is reset (as there are no dead nodes).
|
||||
//
|
||||
// The PhaseRenumberLive phase updates two data structures with the new node IDs.
|
||||
// (1) The worklist is used by the PhaseIterGVN phase to identify nodes that must be
|
||||
// processed. A new worklist (with the updated node IDs) is returned in 'new_worklist'.
|
||||
// (2) Type information (the field PhaseGVN::_types) maps type information to each
|
||||
// node ID. The mapping is updated to use the new node IDs as well. Updated type
|
||||
// information is returned in PhaseGVN::_types.
|
||||
//
|
||||
// The PhaseRenumberLive phase does not preserve the order of elements in the worklist.
|
||||
//
|
||||
// Other data structures used by the compiler are not updated. The hash table for value
|
||||
// numbering (the field PhaseGVN::_table) is not updated because computing the hash
|
||||
// values is not based on node IDs. The field PhaseGVN::_nodes is not updated either
|
||||
// because it is empty wherever PhaseRenumberLive is used.
|
||||
PhaseRenumberLive::PhaseRenumberLive(PhaseGVN* gvn,
|
||||
Unique_Node_List* worklist, Unique_Node_List* new_worklist,
|
||||
PhaseNumber phase_num) :
|
||||
PhaseRemoveUseless(gvn, worklist, Remove_Useless_And_Renumber_Live) {
|
||||
|
||||
assert(RenumberLiveNodes, "RenumberLiveNodes must be set to true for node renumbering to take place");
|
||||
assert(C->live_nodes() == _useful.size(), "the number of live nodes must match the number of useful nodes");
|
||||
assert(gvn->nodes_size() == 0, "GVN must not contain any nodes at this point");
|
||||
|
||||
uint old_unique_count = C->unique();
|
||||
uint live_node_count = C->live_nodes();
|
||||
uint worklist_size = worklist->size();
|
||||
|
||||
// Storage for the updated type information.
|
||||
Type_Array new_type_array(C->comp_arena());
|
||||
|
||||
// Iterate over the set of live nodes.
|
||||
uint current_idx = 0; // The current new node ID. Incremented after every assignment.
|
||||
for (uint i = 0; i < _useful.size(); i++) {
|
||||
Node* n = _useful.at(i);
|
||||
const Type* type = gvn->type_or_null(n);
|
||||
new_type_array.map(current_idx, type);
|
||||
|
||||
bool in_worklist = false;
|
||||
if (worklist->member(n)) {
|
||||
in_worklist = true;
|
||||
}
|
||||
|
||||
n->set_idx(current_idx); // Update node ID.
|
||||
|
||||
if (in_worklist) {
|
||||
new_worklist->push(n);
|
||||
}
|
||||
|
||||
current_idx++;
|
||||
}
|
||||
|
||||
assert(worklist_size == new_worklist->size(), "the new worklist must have the same size as the original worklist");
|
||||
assert(live_node_count == current_idx, "all live nodes must be processed");
|
||||
|
||||
// Replace the compiler's type information with the updated type information.
|
||||
gvn->replace_types(new_type_array);
|
||||
|
||||
// Update the unique node count of the compilation to the number of currently live nodes.
|
||||
C->set_unique(live_node_count);
|
||||
|
||||
// Set the dead node count to 0 and reset dead node list.
|
||||
C->reset_dead_node_list();
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//------------------------------PhaseTransform---------------------------------
|
||||
|
@ -148,11 +148,21 @@ protected:
|
||||
Unique_Node_List _useful; // Nodes reachable from root
|
||||
// list is allocated from current resource area
|
||||
public:
|
||||
PhaseRemoveUseless( PhaseGVN *gvn, Unique_Node_List *worklist );
|
||||
PhaseRemoveUseless(PhaseGVN *gvn, Unique_Node_List *worklist, PhaseNumber phase_num = Remove_Useless);
|
||||
|
||||
Unique_Node_List *get_useful() { return &_useful; }
|
||||
};
|
||||
|
||||
//------------------------------PhaseRenumber----------------------------------
|
||||
// Phase that first performs a PhaseRemoveUseless, then it renumbers compiler
|
||||
// structures accordingly.
|
||||
class PhaseRenumberLive : public PhaseRemoveUseless {
|
||||
public:
|
||||
PhaseRenumberLive(PhaseGVN* gvn,
|
||||
Unique_Node_List* worklist, Unique_Node_List* new_worklist,
|
||||
PhaseNumber phase_num = Remove_Useless_And_Renumber_Live);
|
||||
};
|
||||
|
||||
|
||||
//------------------------------PhaseTransform---------------------------------
|
||||
// Phases that analyze, then transform. Constructing the Phase object does any
|
||||
@ -162,7 +172,7 @@ public:
|
||||
class PhaseTransform : public Phase {
|
||||
protected:
|
||||
Arena* _arena;
|
||||
Node_Array _nodes; // Map old node indices to new nodes.
|
||||
Node_List _nodes; // Map old node indices to new nodes.
|
||||
Type_Array _types; // Map old node indices to Types.
|
||||
|
||||
// ConNode caches:
|
||||
@ -187,7 +197,13 @@ public:
|
||||
|
||||
Arena* arena() { return _arena; }
|
||||
Type_Array& types() { return _types; }
|
||||
void replace_types(Type_Array new_types) {
|
||||
_types = new_types;
|
||||
}
|
||||
// _nodes is used in varying ways by subclasses, which define local accessors
|
||||
uint nodes_size() {
|
||||
return _nodes.size();
|
||||
}
|
||||
|
||||
public:
|
||||
// Get a previously recorded type for the node n.
|
||||
|
164
hotspot/test/compiler/codegen/8144028/BitTests.java
Normal file
164
hotspot/test/compiler/codegen/8144028/BitTests.java
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Red Hat, Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8144028
|
||||
* @summary Use AArch64 bit-test instructions in C2
|
||||
* @modules java.base
|
||||
* @run main/othervm -Xbatch -XX:CompileCommand=dontinline,BitTests::* -XX:-TieredCompilation BitTests
|
||||
* @run main/othervm -Xbatch -XX:+TieredCompilation -XX:TieredStopAtLevel=1 BitTests
|
||||
* @run main/othervm -Xbatch -XX:+TieredCompilation BitTests
|
||||
*
|
||||
*/
|
||||
|
||||
// Try to ensure that the bit test instructions TBZ/TBNZ, TST/TSTW
|
||||
// don't generate incorrect code. We can't guarantee that C2 will use
|
||||
// bit test instructions for this test and it's not a bug if it
|
||||
// doesn't. However, these test cases are ideal candidates for each
|
||||
// of the instruction forms.
|
||||
public class BitTests {
|
||||
|
||||
private final XorShift r = new XorShift();
|
||||
|
||||
private final long increment(long ctr) {
|
||||
return ctr + 1;
|
||||
}
|
||||
|
||||
private final int increment(int ctr) {
|
||||
return ctr + 1;
|
||||
}
|
||||
|
||||
private final long testIntSignedBranch(long counter) {
|
||||
if ((int)r.nextLong() < 0) {
|
||||
counter = increment(counter);
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
private final long testLongSignedBranch(long counter) {
|
||||
if (r.nextLong() < 0) {
|
||||
counter = increment(counter);
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
private final long testIntBitBranch(long counter) {
|
||||
if (((int)r.nextLong() & (1 << 27)) != 0) {
|
||||
counter = increment(counter);
|
||||
}
|
||||
if (((int)r.nextLong() & (1 << 27)) != 0) {
|
||||
counter = increment(counter);
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
private final long testLongBitBranch(long counter) {
|
||||
if ((r.nextLong() & (1l << 50)) != 0) {
|
||||
counter = increment(counter);
|
||||
}
|
||||
if ((r.nextLong() & (1l << 50)) != 0) {
|
||||
counter = increment(counter);
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
private final long testLongMaskBranch(long counter) {
|
||||
if (((r.nextLong() & 0x0800000000l) != 0)) {
|
||||
counter++;
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
private final long testIntMaskBranch(long counter) {
|
||||
if ((((int)r.nextLong() & 0x08) != 0)) {
|
||||
counter++;
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
private final long testLongMaskBranch(long counter, long mask) {
|
||||
if (((r.nextLong() & mask) != 0)) {
|
||||
counter++;
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
private final long testIntMaskBranch(long counter, int mask) {
|
||||
if ((((int)r.nextLong() & mask) != 0)) {
|
||||
counter++;
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
private final long step(long counter) {
|
||||
counter = testIntSignedBranch(counter);
|
||||
counter = testLongSignedBranch(counter);
|
||||
counter = testIntBitBranch(counter);
|
||||
counter = testLongBitBranch(counter);
|
||||
counter = testIntMaskBranch(counter);
|
||||
counter = testLongMaskBranch(counter);
|
||||
counter = testIntMaskBranch(counter, 0x8000);
|
||||
counter = testLongMaskBranch(counter, 0x800000000l);
|
||||
return counter;
|
||||
}
|
||||
|
||||
|
||||
private final long finalBits = 3;
|
||||
|
||||
private long bits = 7;
|
||||
|
||||
public static void main(String[] args) {
|
||||
BitTests t = new BitTests();
|
||||
|
||||
long counter = 0;
|
||||
for (int i = 0; i < 10000000; i++) {
|
||||
counter = t.step((int) counter);
|
||||
}
|
||||
if (counter != 50001495) {
|
||||
System.err.println("FAILED: counter = " + counter + ", should be 50001495.");
|
||||
System.exit(97);
|
||||
}
|
||||
System.out.println("PASSED");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Marsaglia's xor-shift generator, used here because it is
|
||||
// reproducible across all Java implementations. It is also very
|
||||
// fast.
|
||||
class XorShift {
|
||||
|
||||
private long y;
|
||||
|
||||
XorShift() {
|
||||
y = 2463534242l;
|
||||
}
|
||||
|
||||
public long nextLong() {
|
||||
y ^= (y << 13);
|
||||
y ^= (y >>> 17);
|
||||
return (y ^= (y << 5));
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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
|
||||
* @bug 8142303
|
||||
* @summary Tests handling of invalid array indices in C2 intrinsic if explicit range check in Java code is not inlined.
|
||||
* @run main/othervm -XX:CompileCommand=inline,java.lang.String::* -XX:CompileCommand=inline,java.lang.StringUTF16::* -XX:CompileCommand=exclude,java.lang.String::checkBoundsOffCount TestStringConstruction
|
||||
*/
|
||||
public class TestStringConstruction {
|
||||
|
||||
public static void main(String[] args) {
|
||||
char[] chars = new char[42];
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
test(chars);
|
||||
}
|
||||
}
|
||||
|
||||
private static String test(char[] chars) {
|
||||
try {
|
||||
// The constructor calls String::checkBoundsOffCount(-1, 42) to perform
|
||||
// range checks on offset and count. If this method is not inlined, C2
|
||||
// does not know about the explicit range checks and does not cut off the
|
||||
// dead code. As a result, -1 is fed as offset into the StringUTF16.compress
|
||||
// intrinsic which is replaced by TOP and causes a failure in the matcher.
|
||||
return new String(chars, -1 , 42);
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ public class CodeInstallerTest {
|
||||
}
|
||||
|
||||
protected void installCode(CompilationResult result) {
|
||||
result.close();
|
||||
codeCache.addCode(dummyMethod, result, null, null);
|
||||
}
|
||||
|
||||
|
@ -218,13 +218,6 @@ public class TestInvalidCompilationResult extends CodeInstallerTest {
|
||||
installCode(result);
|
||||
}
|
||||
|
||||
@Test(expected = JVMCIError.class)
|
||||
public void testUnknownInfopointReason() {
|
||||
CompilationResult result = createEmptyCompilationResult();
|
||||
result.addInfopoint(new Infopoint(0, null, InfopointReason.UNKNOWN));
|
||||
installCode(result);
|
||||
}
|
||||
|
||||
@Test(expected = JVMCIError.class)
|
||||
public void testInfopointMissingDebugInfo() {
|
||||
CompilationResult result = createEmptyCompilationResult();
|
||||
|
@ -106,13 +106,12 @@ public class JvmciNotifyInstallEventTest implements HotSpotVMEventListener {
|
||||
HotSpotCompilationRequest compRequest = new HotSpotCompilationRequest(method, -1, 0L);
|
||||
// to pass sanity check of default -1
|
||||
compResult.setTotalFrameSize(0);
|
||||
compResult.close();
|
||||
codeCache.installCode(compRequest, compResult, /* installedCode = */ null, /* speculationLog = */ null,
|
||||
/* isDefault = */ false);
|
||||
Asserts.assertEQ(gotInstallNotification, 1,
|
||||
"Got unexpected event count after 1st install attempt");
|
||||
// since "empty" compilation result is ok, a second attempt should be ok
|
||||
compResult = new CompilationResult(METHOD_NAME); // create another instance with fresh state
|
||||
compResult.setTotalFrameSize(0);
|
||||
codeCache.installCode(compRequest, compResult, /* installedCode = */ null, /* speculationLog = */ null,
|
||||
/* isDefault = */ false);
|
||||
Asserts.assertEQ(gotInstallNotification, 2,
|
||||
|
@ -338,3 +338,4 @@ b433e4dfb830fea60e5187e4580791b62cc362d2 jdk9-b90
|
||||
2f12392d0dde768150c83087cdbdd0d33a4d866c jdk9-b93
|
||||
559b626b01179420a94feb9c3d0f246970d2e3fa jdk9-b94
|
||||
8581faf0d474472e32f589bbc16db7eec912d83f jdk-9+95
|
||||
c021b855f51e572e63982654b17742cb1f814fb4 jdk-9+96
|
||||
|
@ -459,7 +459,7 @@ ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
# We can only compile native code after java has been compiled (since we
|
||||
# depend on generated .h files)
|
||||
$(SUPPORT_OUTPUTDIR)/demos/native/jni/Poller/Poller.o: \
|
||||
$(BUILD_DEMO_JAVA_POLLER_COMPILE_TARGETS)
|
||||
$(BUILD_DEMO_JAVA_Poller)
|
||||
|
||||
# Copy to image
|
||||
$(SUPPORT_OUTPUTDIR)/demos/image/jni/Poller/README.txt: \
|
||||
|
@ -29,32 +29,6 @@ ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
|
||||
################################################################################
|
||||
|
||||
LIBAPPLESCRIPTENGINE_SRC := $(JDK_TOPDIR)/src/jdk.deploy.osx/macosx/native/libapplescriptengine
|
||||
|
||||
$(eval $(call SetupNativeCompilation,BUILD_LIBAPPLESCRIPTENGINE, \
|
||||
LIBRARY := AppleScriptEngine, \
|
||||
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
|
||||
SRC := $(LIBAPPLESCRIPTENGINE_SRC), \
|
||||
OPTIMIZATION := LOW, \
|
||||
CFLAGS := $(CFLAGS_JDKLIB) \
|
||||
-I$(LIBAPPLESCRIPTENGINE_SRC) \
|
||||
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.deploy.osx, \
|
||||
DISABLED_WARNINGS_clang := implicit-function-declaration format, \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
LIBS := -framework Cocoa \
|
||||
-framework Carbon \
|
||||
-framework JavaNativeFoundation \
|
||||
$(JDKLIB_LIBS), \
|
||||
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libAppleScriptEngine, \
|
||||
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
|
||||
|
||||
$(BUILD_LIBAPPLESCRIPTENGINE): $(call FindLib, java.base, java)
|
||||
|
||||
TARGETS += $(BUILD_LIBAPPLESCRIPTENGINE)
|
||||
|
||||
################################################################################
|
||||
|
||||
LIBOSX_DIRS := $(JDK_TOPDIR)/src/jdk.deploy.osx/macosx/native/libosx
|
||||
LIBOSX_CFLAGS := -I$(LIBOSX_DIRS) \
|
||||
-I$(JDK_TOPDIR)/src/java.desktop/macosx/native/libosxapp \
|
||||
|
@ -173,7 +173,7 @@ SUNWprivate_1.1 {
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_futimes;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_open0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_openat0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_close;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_close0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_read;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_write;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_fopen0;
|
||||
|
@ -150,7 +150,7 @@ SUNWprivate_1.1 {
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_futimes;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_open0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_openat0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_close;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_close0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_read;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_write;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_fopen0;
|
||||
|
@ -150,7 +150,7 @@ SUNWprivate_1.1 {
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_futimes;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_open0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_openat0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_close;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_close0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_read;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_write;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_fopen0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2012, 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
|
||||
@ -104,6 +104,7 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
// errors
|
||||
DEF(ENOENT);
|
||||
DEF(ENXIO);
|
||||
DEF(EACCES);
|
||||
DEF(EEXIST);
|
||||
DEF(ENOTDIR);
|
||||
|
@ -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
|
||||
@ -117,8 +117,9 @@ class LinuxDosFileAttributeView
|
||||
public DosFileAttributes readAttributes() throws IOException {
|
||||
file.checkRead();
|
||||
|
||||
int fd = file.openForAttributeAccess(followLinks);
|
||||
int fd = -1;
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
final UnixFileAttributes attrs = UnixFileAttributes.get(fd);
|
||||
final int dosAttribute = getDosAttribute(fd);
|
||||
|
||||
@ -253,8 +254,9 @@ class LinuxDosFileAttributeView
|
||||
private void updateDosAttribute(int flag, boolean enable) throws IOException {
|
||||
file.checkWrite();
|
||||
|
||||
int fd = file.openForAttributeAccess(followLinks);
|
||||
int fd = -1;
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
int oldValue = getDosAttribute(fd);
|
||||
int newValue = oldValue;
|
||||
if (enable) {
|
||||
|
@ -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
|
||||
@ -94,22 +94,20 @@ class LinuxFileStore
|
||||
// returns true if extended attributes enabled on file system where given
|
||||
// file resides, returns false if disabled or unable to determine.
|
||||
private boolean isExtendedAttributesEnabled(UnixPath path) {
|
||||
int fd = -1;
|
||||
try {
|
||||
int fd = path.openForAttributeAccess(false);
|
||||
try {
|
||||
// fgetxattr returns size if called with size==0
|
||||
byte[] name = Util.toBytes("user.java");
|
||||
LinuxNativeDispatcher.fgetxattr(fd, name, 0L, 0);
|
||||
fd = path.openForAttributeAccess(false);
|
||||
|
||||
// fgetxattr returns size if called with size==0
|
||||
byte[] name = Util.toBytes("user.java");
|
||||
LinuxNativeDispatcher.fgetxattr(fd, name, 0L, 0);
|
||||
return true;
|
||||
} catch (UnixException e) {
|
||||
// attribute does not exist
|
||||
if (e.errno() == UnixConstants.ENODATA)
|
||||
return true;
|
||||
} catch (UnixException e) {
|
||||
// attribute does not exist
|
||||
if (e.errno() == UnixConstants.ENODATA)
|
||||
return true;
|
||||
} finally {
|
||||
UnixNativeDispatcher.close(fd);
|
||||
}
|
||||
} catch (IOException ignore) {
|
||||
// nothing we can do
|
||||
} finally {
|
||||
UnixNativeDispatcher.close(fd);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -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
|
||||
@ -97,7 +97,12 @@ class LinuxUserDefinedFileAttributeView
|
||||
if (System.getSecurityManager() != null)
|
||||
checkAccess(file.getPathForPermissionCheck(), true, false);
|
||||
|
||||
int fd = file.openForAttributeAccess(followLinks);
|
||||
int fd = -1;
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(file);
|
||||
}
|
||||
NativeBuffer buffer = null;
|
||||
try {
|
||||
int size = 1024;
|
||||
@ -133,7 +138,12 @@ class LinuxUserDefinedFileAttributeView
|
||||
if (System.getSecurityManager() != null)
|
||||
checkAccess(file.getPathForPermissionCheck(), true, false);
|
||||
|
||||
int fd = file.openForAttributeAccess(followLinks);
|
||||
int fd = -1;
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(file);
|
||||
}
|
||||
try {
|
||||
// fgetxattr returns size if called with size==0
|
||||
return fgetxattr(fd, nameAsBytes(file,name), 0L, 0);
|
||||
@ -169,7 +179,12 @@ class LinuxUserDefinedFileAttributeView
|
||||
address = nb.address();
|
||||
}
|
||||
|
||||
int fd = file.openForAttributeAccess(followLinks);
|
||||
int fd = -1;
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(file);
|
||||
}
|
||||
try {
|
||||
try {
|
||||
int n = fgetxattr(fd, nameAsBytes(file,name), address, rem);
|
||||
@ -236,7 +251,12 @@ class LinuxUserDefinedFileAttributeView
|
||||
}
|
||||
}
|
||||
|
||||
int fd = file.openForAttributeAccess(followLinks);
|
||||
int fd = -1;
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(file);
|
||||
}
|
||||
try {
|
||||
try {
|
||||
fsetxattr(fd, nameAsBytes(file,name), address, rem);
|
||||
@ -260,7 +280,12 @@ class LinuxUserDefinedFileAttributeView
|
||||
if (System.getSecurityManager() != null)
|
||||
checkAccess(file.getPathForPermissionCheck(), false, true);
|
||||
|
||||
int fd = file.openForAttributeAccess(followLinks);
|
||||
int fd = -1;
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(file);
|
||||
}
|
||||
try {
|
||||
fremovexattr(fd, nameAsBytes(file,name));
|
||||
} catch (UnixException x) {
|
||||
|
@ -177,7 +177,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
return;
|
||||
}
|
||||
byte[] buf = StringUTF16.newBytesFor(value.length);
|
||||
StringLatin1.inflateSB(value, buf, 0, count);
|
||||
StringLatin1.inflate(value, 0, buf, 0, count);
|
||||
this.value = buf;
|
||||
this.coder = UTF16;
|
||||
}
|
||||
@ -414,9 +414,9 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
int n = srcEnd - srcBegin;
|
||||
checkRange(dstBegin, dstBegin + n, dst.length);
|
||||
if (isLatin1()) {
|
||||
StringLatin1.getCharsSB(value, srcBegin, srcEnd, dst, dstBegin);
|
||||
StringLatin1.getChars(value, srcBegin, srcEnd, dst, dstBegin);
|
||||
} else {
|
||||
StringUTF16.getCharsSB(value, srcBegin, srcEnd, dst, dstBegin);
|
||||
StringUTF16.getChars(value, srcBegin, srcEnd, dst, dstBegin);
|
||||
}
|
||||
}
|
||||
|
||||
@ -980,7 +980,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
if (isLatin1()) {
|
||||
return StringLatin1.newString(value, start, end - start);
|
||||
}
|
||||
return StringUTF16.newStringSB(value, start, end - start);
|
||||
return StringUTF16.newString(value, start, end - start);
|
||||
}
|
||||
|
||||
private void shift(int offset, int n) {
|
||||
@ -1576,7 +1576,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
if (this.coder == coder) {
|
||||
System.arraycopy(value, 0, dst, dstBegin << coder, count << coder);
|
||||
} else { // this.coder == LATIN && coder == UTF16
|
||||
StringLatin1.inflateSB(value, dst, dstBegin, count);
|
||||
StringLatin1.inflate(value, 0, dst, dstBegin, count);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1641,10 +1641,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
if (getCoder() != str.coder()) {
|
||||
inflate();
|
||||
}
|
||||
byte[] val = this.value;
|
||||
byte coder = this.coder;
|
||||
checkOffset(index + str.length(), val.length >> coder);
|
||||
str.getBytes(val, index, coder);
|
||||
str.getBytes(value, index, coder);
|
||||
}
|
||||
|
||||
private final void appendChars(char[] s, int off, int end) {
|
||||
|
@ -1720,7 +1720,6 @@ public final class String
|
||||
*/
|
||||
static int indexOf(byte[] src, byte srcCoder, int srcCount,
|
||||
String tgtStr, int fromIndex) {
|
||||
|
||||
byte[] tgt = tgtStr.value;
|
||||
byte tgtCoder = tgtStr.coder();
|
||||
int tgtCount = tgtStr.length();
|
||||
@ -3103,7 +3102,7 @@ public final class String
|
||||
* If {@code offset} is negative, {@code count} is negative,
|
||||
* or {@code offset} is greater than {@code length - count}
|
||||
*/
|
||||
private static void checkBoundsOffCount(int offset, int count, int length) {
|
||||
static void checkBoundsOffCount(int offset, int count, int length) {
|
||||
if (offset < 0 || count < 0 || offset > length - count) {
|
||||
throw new StringIndexOutOfBoundsException(
|
||||
"offset " + offset + ", count " + count + ", length " + length);
|
||||
|
@ -413,7 +413,7 @@ public final class StringBuilder
|
||||
public String toString() {
|
||||
// Create a copy, don't share the array
|
||||
return isLatin1() ? StringLatin1.newString(value, 0, count)
|
||||
: StringUTF16.newStringSB(value, 0, count);
|
||||
: StringUTF16.newString(value, 0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,6 +36,7 @@ import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import static java.lang.String.LATIN1;
|
||||
import static java.lang.String.UTF16;
|
||||
import static java.lang.String.checkOffset;
|
||||
import static java.lang.String.checkBoundsOffCount;
|
||||
|
||||
final class StringLatin1 {
|
||||
|
||||
@ -523,6 +524,8 @@ final class StringLatin1 {
|
||||
// inflatedCopy byte[] -> byte[]
|
||||
@HotSpotIntrinsicCandidate
|
||||
public static void inflate(byte[] src, int srcOff, byte[] dst, int dstOff, int len) {
|
||||
// We need a range check here because 'putChar' has no checks
|
||||
checkBoundsOffCount(dstOff, len, dst.length);
|
||||
for (int i = 0; i < len; i++) {
|
||||
StringUTF16.putChar(dst, dstOff++, src[srcOff++] & 0xff);
|
||||
}
|
||||
@ -584,17 +587,4 @@ final class StringLatin1 {
|
||||
return cs;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
public static void getCharsSB(byte[] val, int srcBegin, int srcEnd, char dst[], int dstBegin) {
|
||||
checkOffset(srcEnd, val.length);
|
||||
getChars(val, srcBegin, srcEnd, dst, dstBegin);
|
||||
}
|
||||
|
||||
public static void inflateSB(byte[] val, byte[] dst, int dstOff, int count) {
|
||||
checkOffset(count, val.length);
|
||||
checkOffset(dstOff + count, dst.length >> 1); // dst is utf16
|
||||
inflate(val, 0, dst, dstOff, count);
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import static java.lang.String.UTF16;
|
||||
import static java.lang.String.LATIN1;
|
||||
import static java.lang.String.checkIndex;
|
||||
import static java.lang.String.checkOffset;
|
||||
import static java.lang.String.checkBoundsOffCount;
|
||||
|
||||
final class StringUTF16 {
|
||||
|
||||
@ -156,6 +157,8 @@ final class StringUTF16 {
|
||||
// compressedCopy byte[] -> byte[]
|
||||
@HotSpotIntrinsicCandidate
|
||||
public static int compress(byte[] src, int srcOff, byte[] dst, int dstOff, int len) {
|
||||
// We need a range check here because 'getChar' has no checks
|
||||
checkBoundsOffCount(srcOff, len, src.length);
|
||||
for (int i = 0; i < len; i++) {
|
||||
int c = getChar(src, srcOff++);
|
||||
if (c >>> 8 != 0) {
|
||||
@ -200,6 +203,8 @@ final class StringUTF16 {
|
||||
|
||||
@HotSpotIntrinsicCandidate
|
||||
public static void getChars(byte[] value, int srcBegin, int srcEnd, char dst[], int dstBegin) {
|
||||
// We need a range check here because 'getChar' has no checks
|
||||
checkBoundsOffCount(srcBegin, srcEnd - srcBegin, value.length);
|
||||
for (int i = srcBegin; i < srcEnd; i++) {
|
||||
dst[dstBegin++] = getChar(value, i);
|
||||
}
|
||||
@ -909,11 +914,6 @@ final class StringUTF16 {
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
public static void getCharsSB(byte[] val, int srcBegin, int srcEnd, char dst[], int dstBegin) {
|
||||
checkOffset(srcEnd, val.length >> 1);
|
||||
getChars(val, srcBegin, srcEnd, dst, dstBegin);
|
||||
}
|
||||
|
||||
public static void putCharSB(byte[] val, int index, int c) {
|
||||
checkIndex(index, val.length >> 1);
|
||||
putChar(val, index, c);
|
||||
@ -946,11 +946,6 @@ final class StringUTF16 {
|
||||
return codePointCount(val, beginIndex, endIndex);
|
||||
}
|
||||
|
||||
public static String newStringSB(byte[] val, int index, int len) {
|
||||
checkOffset(index + len, val.length >> 1);
|
||||
return newString(val, index, len);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
private static native boolean isBigEndian();
|
||||
|
@ -324,27 +324,54 @@ class InvokerBytecodeGenerator {
|
||||
emitIconstInsn((int) con);
|
||||
return;
|
||||
}
|
||||
if (con instanceof Byte) {
|
||||
emitIconstInsn((byte)con);
|
||||
return;
|
||||
}
|
||||
if (con instanceof Short) {
|
||||
emitIconstInsn((short)con);
|
||||
return;
|
||||
}
|
||||
if (con instanceof Character) {
|
||||
emitIconstInsn((char)con);
|
||||
return;
|
||||
}
|
||||
if (con instanceof Long) {
|
||||
long x = (long) con;
|
||||
if (x == (short) x) {
|
||||
emitIconstInsn((int) x);
|
||||
mv.visitInsn(Opcodes.I2L);
|
||||
short sx = (short)x;
|
||||
if (x == sx) {
|
||||
if (sx >= 0 && sx <= 1) {
|
||||
mv.visitInsn(Opcodes.LCONST_0 + (int) sx);
|
||||
} else {
|
||||
emitIconstInsn((int) x);
|
||||
mv.visitInsn(Opcodes.I2L);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (con instanceof Float) {
|
||||
float x = (float) con;
|
||||
if (x == (short) x) {
|
||||
emitIconstInsn((int) x);
|
||||
mv.visitInsn(Opcodes.I2F);
|
||||
short sx = (short)x;
|
||||
if (x == sx) {
|
||||
if (sx >= 0 && sx <= 2) {
|
||||
mv.visitInsn(Opcodes.FCONST_0 + (int) sx);
|
||||
} else {
|
||||
emitIconstInsn((int) x);
|
||||
mv.visitInsn(Opcodes.I2F);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (con instanceof Double) {
|
||||
double x = (double) con;
|
||||
if (x == (short) x) {
|
||||
emitIconstInsn((int) x);
|
||||
mv.visitInsn(Opcodes.I2D);
|
||||
short sx = (short)x;
|
||||
if (x == sx) {
|
||||
if (sx >= 0 && sx <= 1) {
|
||||
mv.visitInsn(Opcodes.DCONST_0 + (int) sx);
|
||||
} else {
|
||||
emitIconstInsn((int) x);
|
||||
mv.visitInsn(Opcodes.I2D);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -356,26 +383,16 @@ class InvokerBytecodeGenerator {
|
||||
mv.visitLdcInsn(con);
|
||||
}
|
||||
|
||||
private void emitIconstInsn(int i) {
|
||||
int opcode;
|
||||
switch (i) {
|
||||
case 0: opcode = Opcodes.ICONST_0; break;
|
||||
case 1: opcode = Opcodes.ICONST_1; break;
|
||||
case 2: opcode = Opcodes.ICONST_2; break;
|
||||
case 3: opcode = Opcodes.ICONST_3; break;
|
||||
case 4: opcode = Opcodes.ICONST_4; break;
|
||||
case 5: opcode = Opcodes.ICONST_5; break;
|
||||
default:
|
||||
if (i == (byte) i) {
|
||||
mv.visitIntInsn(Opcodes.BIPUSH, i & 0xFF);
|
||||
} else if (i == (short) i) {
|
||||
mv.visitIntInsn(Opcodes.SIPUSH, (char) i);
|
||||
} else {
|
||||
mv.visitLdcInsn(i);
|
||||
}
|
||||
return;
|
||||
private void emitIconstInsn(final int cst) {
|
||||
if (cst >= -1 && cst <= 5) {
|
||||
mv.visitInsn(Opcodes.ICONST_0 + cst);
|
||||
} else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
|
||||
mv.visitIntInsn(Opcodes.BIPUSH, cst);
|
||||
} else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
|
||||
mv.visitIntInsn(Opcodes.SIPUSH, cst);
|
||||
} else {
|
||||
mv.visitLdcInsn(cst);
|
||||
}
|
||||
mv.visitInsn(opcode);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2014, 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
|
||||
@ -2409,6 +2409,53 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the integer square root of this BigInteger. The integer square
|
||||
* root of the corresponding mathematical integer {@code n} is the largest
|
||||
* mathematical integer {@code s} such that {@code s*s <= n}. It is equal
|
||||
* to the value of {@code floor(sqrt(n))}, where {@code sqrt(n)} denotes the
|
||||
* real square root of {@code n} treated as a real. Note that the integer
|
||||
* square root will be less than the real square root if the latter is not
|
||||
* representable as an integral value.
|
||||
*
|
||||
* @return the integer square root of {@code this}
|
||||
* @throws ArithmeticException if {@code this} is negative. (The square
|
||||
* root of a negative integer {@code val} is
|
||||
* {@code (i * sqrt(-val))} where <i>i</i> is the
|
||||
* <i>imaginary unit</i> and is equal to
|
||||
* {@code sqrt(-1)}.)
|
||||
* @since 1.9
|
||||
*/
|
||||
public BigInteger sqrt() {
|
||||
if (this.signum < 0) {
|
||||
throw new ArithmeticException("Negative BigInteger");
|
||||
}
|
||||
|
||||
return new MutableBigInteger(this.mag).sqrt().toBigInteger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of two BigIntegers containing the integer square root
|
||||
* {@code s} of {@code this} and its remainder {@code this - s*s},
|
||||
* respectively.
|
||||
*
|
||||
* @return an array of two BigIntegers with the integer square root at
|
||||
* offset 0 and the remainder at offset 1
|
||||
* @throws ArithmeticException if {@code this} is negative. (The square
|
||||
* root of a negative integer {@code val} is
|
||||
* {@code (i * sqrt(-val))} where <i>i</i> is the
|
||||
* <i>imaginary unit</i> and is equal to
|
||||
* {@code sqrt(-1)}.)
|
||||
* @see #sqrt()
|
||||
* @since 1.9
|
||||
*/
|
||||
public BigInteger[] sqrtAndRemainder() {
|
||||
BigInteger s = sqrt();
|
||||
BigInteger r = this.subtract(s.square());
|
||||
assert r.compareTo(BigInteger.ZERO) >= 0;
|
||||
return new BigInteger[] {s, r};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigInteger whose value is the greatest common divisor of
|
||||
* {@code abs(this)} and {@code abs(val)}. Returns 0 if
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -1866,6 +1866,96 @@ class MutableBigInteger {
|
||||
return (r << 32) | (q & LONG_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the integer square root {@code floor(sqrt(this))} where
|
||||
* {@code sqrt(.)} denotes the mathematical square root. The contents of
|
||||
* {@code this} are <b>not</b> changed. The value of {@code this} is assumed
|
||||
* to be non-negative.
|
||||
*
|
||||
* @implNote The implementation is based on the material in Henry S. Warren,
|
||||
* Jr., <i>Hacker's Delight (2nd ed.)</i> (Addison Wesley, 2013), 279-282.
|
||||
*
|
||||
* @throws ArithmeticException if the value returned by {@code bitLength()}
|
||||
* overflows the range of {@code int}.
|
||||
* @return the integer square root of {@code this}
|
||||
* @since 1.9
|
||||
*/
|
||||
MutableBigInteger sqrt() {
|
||||
// Special cases.
|
||||
if (this.isZero()) {
|
||||
return new MutableBigInteger(0);
|
||||
} else if (this.value.length == 1
|
||||
&& (this.value[0] & LONG_MASK) < 4) { // result is unity
|
||||
return ONE;
|
||||
}
|
||||
|
||||
if (bitLength() <= 63) {
|
||||
// Initial estimate is the square root of the positive long value.
|
||||
long v = new BigInteger(this.value, 1).longValueExact();
|
||||
long xk = (long)Math.floor(Math.sqrt(v));
|
||||
|
||||
// Refine the estimate.
|
||||
do {
|
||||
long xk1 = (xk + v/xk)/2;
|
||||
|
||||
// Terminate when non-decreasing.
|
||||
if (xk1 >= xk) {
|
||||
return new MutableBigInteger(new int[] {
|
||||
(int)(xk >>> 32), (int)(xk & LONG_MASK)
|
||||
});
|
||||
}
|
||||
|
||||
xk = xk1;
|
||||
} while (true);
|
||||
} else {
|
||||
// Set up the initial estimate of the iteration.
|
||||
|
||||
// Obtain the bitLength > 63.
|
||||
int bitLength = (int) this.bitLength();
|
||||
if (bitLength != this.bitLength()) {
|
||||
throw new ArithmeticException("bitLength() integer overflow");
|
||||
}
|
||||
|
||||
// Determine an even valued right shift into positive long range.
|
||||
int shift = bitLength - 63;
|
||||
if (shift % 2 == 1) {
|
||||
shift++;
|
||||
}
|
||||
|
||||
// Shift the value into positive long range.
|
||||
MutableBigInteger xk = new MutableBigInteger(this);
|
||||
xk.rightShift(shift);
|
||||
xk.normalize();
|
||||
|
||||
// Use the square root of the shifted value as an approximation.
|
||||
double d = new BigInteger(xk.value, 1).doubleValue();
|
||||
BigInteger bi = BigInteger.valueOf((long)Math.ceil(Math.sqrt(d)));
|
||||
xk = new MutableBigInteger(bi.mag);
|
||||
|
||||
// Shift the approximate square root back into the original range.
|
||||
xk.leftShift(shift / 2);
|
||||
|
||||
// Refine the estimate.
|
||||
MutableBigInteger xk1 = new MutableBigInteger();
|
||||
do {
|
||||
// xk1 = (xk + n/xk)/2
|
||||
this.divide(xk, xk1, false);
|
||||
xk1.add(xk);
|
||||
xk1.rightShift(1);
|
||||
|
||||
// Terminate when non-decreasing.
|
||||
if (xk1.compare(xk) >= 0) {
|
||||
return xk;
|
||||
}
|
||||
|
||||
// xk = xk1
|
||||
xk.copyValue(xk1);
|
||||
|
||||
xk1.reset();
|
||||
} while (true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate GCD of this and b. This and b are changed by the computation.
|
||||
*/
|
||||
|
@ -24,12 +24,11 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* The classes and interfaces in this package have been deprecated.
|
||||
* The {@code java.security} package contains suitable replacements.
|
||||
* See that package and, for example, {@code java.security.Permission}
|
||||
* for details.
|
||||
* The classes and interfaces in this package have been deprecated. New
|
||||
* classes should not be added to this package. The {@code java.security}
|
||||
* package contains suitable replacements. See {@link java.security.Policy}
|
||||
* and related classes for details.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
@Deprecated
|
||||
package java.security.acl;
|
||||
|
@ -61,6 +61,7 @@
|
||||
*/
|
||||
package java.time;
|
||||
|
||||
import static java.time.LocalTime.MINUTES_PER_HOUR;
|
||||
import static java.time.LocalTime.NANOS_PER_SECOND;
|
||||
import static java.time.LocalTime.SECONDS_PER_DAY;
|
||||
import static java.time.LocalTime.SECONDS_PER_HOUR;
|
||||
@ -973,7 +974,7 @@ public final class Duration
|
||||
if (multiplicand == 1) {
|
||||
return this;
|
||||
}
|
||||
return create(toSeconds().multiply(BigDecimal.valueOf(multiplicand)));
|
||||
return create(toBigDecimalSeconds().multiply(BigDecimal.valueOf(multiplicand)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -992,7 +993,7 @@ public final class Duration
|
||||
if (divisor == 1) {
|
||||
return this;
|
||||
}
|
||||
return create(toSeconds().divide(BigDecimal.valueOf(divisor), RoundingMode.DOWN));
|
||||
return create(toBigDecimalSeconds().divide(BigDecimal.valueOf(divisor), RoundingMode.DOWN));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1001,7 +1002,7 @@ public final class Duration
|
||||
*
|
||||
* @return the total length of the duration in seconds, with a scale of 9, not null
|
||||
*/
|
||||
private BigDecimal toSeconds() {
|
||||
private BigDecimal toBigDecimalSeconds() {
|
||||
return BigDecimal.valueOf(seconds).add(BigDecimal.valueOf(nanos, 9));
|
||||
}
|
||||
|
||||
@ -1167,6 +1168,19 @@ public final class Duration
|
||||
return seconds / SECONDS_PER_MINUTE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of seconds in this duration.
|
||||
* <p>
|
||||
* This returns the total number of whole seconds in the duration.
|
||||
* <p>
|
||||
* This instance is immutable and unaffected by this method call.
|
||||
*
|
||||
* @return the whole seconds part of the length of the duration, positive or negative
|
||||
*/
|
||||
public long toSeconds() {
|
||||
return seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this duration to the total length in milliseconds.
|
||||
* <p>
|
||||
@ -1201,6 +1215,100 @@ public final class Duration
|
||||
return totalNanos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the number of days in the duration.
|
||||
* <p>
|
||||
* This returns the total number of days in the duration by dividing the
|
||||
* number of seconds by 86400.
|
||||
* This is based on the standard definition of a day as 24 hours.
|
||||
* <p>
|
||||
* This instance is immutable and unaffected by this method call.
|
||||
*
|
||||
* @return the number of days in the duration, may be negative
|
||||
*/
|
||||
public long toDaysPart(){
|
||||
return seconds / SECONDS_PER_DAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the number of hours part in the duration.
|
||||
* <p>
|
||||
* This returns the number of remaining hours when dividing {@link #toHours}
|
||||
* by hours in a day.
|
||||
* This is based on the standard definition of a day as 24 hours.
|
||||
* <p>
|
||||
* This instance is immutable and unaffected by this method call.
|
||||
*
|
||||
* @return the number of hours part in the duration, may be negative
|
||||
*/
|
||||
public int toHoursPart(){
|
||||
return (int) (toHours() % 24);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the number of minutes part in the duration.
|
||||
* <p>
|
||||
* This returns the number of remaining minutes when dividing {@link #toMinutes}
|
||||
* by minutes in an hour.
|
||||
* This is based on the standard definition of an hour as 60 minutes.
|
||||
* <p>
|
||||
* This instance is immutable and unaffected by this method call.
|
||||
*
|
||||
* @return the number of minutes parts in the duration, may be negative
|
||||
* may be negative
|
||||
*/
|
||||
public int toMinutesPart(){
|
||||
return (int) (toMinutes() % MINUTES_PER_HOUR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the number of seconds part in the duration.
|
||||
* <p>
|
||||
* This returns the remaining seconds when dividing {@link #toSeconds}
|
||||
* by seconds in a minute.
|
||||
* This is based on the standard definition of a minute as 60 seconds.
|
||||
* <p>
|
||||
* This instance is immutable and unaffected by this method call.
|
||||
*
|
||||
* @return the number of seconds parts in the duration, may be negative
|
||||
*/
|
||||
public int toSecondsPart(){
|
||||
return (int) (seconds % SECONDS_PER_MINUTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the number of milliseconds part of the duration.
|
||||
* <p>
|
||||
* This returns the milliseconds part by dividing the number of nanoseconds by 1,000,000.
|
||||
* The length of the duration is stored using two fields - seconds and nanoseconds.
|
||||
* The nanoseconds part is a value from 0 to 999,999,999 that is an adjustment to
|
||||
* the length in seconds.
|
||||
* The total duration is defined by calling {@link #getNano()} and {@link #getSeconds()}.
|
||||
* <p>
|
||||
* This instance is immutable and unaffected by this method call.
|
||||
*
|
||||
* @return the number of milliseconds part of the duration.
|
||||
*/
|
||||
public int toMillisPart(){
|
||||
return nanos / 1000_000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the nanoseconds part within seconds of the duration.
|
||||
* <p>
|
||||
* The length of the duration is stored using two fields - seconds and nanoseconds.
|
||||
* The nanoseconds part is a value from 0 to 999,999,999 that is an adjustment to
|
||||
* the length in seconds.
|
||||
* The total duration is defined by calling {@link #getNano()} and {@link #getSeconds()}.
|
||||
* <p>
|
||||
* This instance is immutable and unaffected by this method call.
|
||||
*
|
||||
* @return the nanoseconds within the second part of the length of the duration, from 0 to 999,999,999
|
||||
*/
|
||||
public int toNanosPart(){
|
||||
return nanos;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Compares this duration to the specified {@code Duration}.
|
||||
@ -1208,7 +1316,7 @@ public final class Duration
|
||||
* The comparison is based on the total length of the durations.
|
||||
* It is "consistent with equals", as defined by {@link Comparable}.
|
||||
*
|
||||
* @param otherDuration the other duration to compare to, not null
|
||||
* @param otherDuration the other duration to compare to, not null
|
||||
* @return the comparator value, negative if less, positive if greater
|
||||
*/
|
||||
@Override
|
||||
@ -1226,7 +1334,7 @@ public final class Duration
|
||||
* <p>
|
||||
* The comparison is based on the total length of the durations.
|
||||
*
|
||||
* @param otherDuration the other duration, null returns false
|
||||
* @param otherDuration the other duration, null returns false
|
||||
* @return true if the other duration is equal to this one
|
||||
*/
|
||||
@Override
|
||||
|
126
jdk/src/java.base/share/classes/java/util/KeyValueHolder.java
Normal file
126
jdk/src/java.base/share/classes/java/util/KeyValueHolder.java
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
/**
|
||||
* An immutable container for a key and a value, suitable for use
|
||||
* in creating and populating {@code Map} instances.
|
||||
*
|
||||
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
|
||||
* class; use of identity-sensitive operations (including reference equality
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code KeyValueHolder} may have unpredictable results and should be avoided.
|
||||
*
|
||||
* @apiNote
|
||||
* This class is not public. Instances can be created using the
|
||||
* {@link Map#entry Map.entry(k, v)} factory method, which is public.
|
||||
*
|
||||
* <p>This class differs from AbstractMap.SimpleImmutableEntry in the following ways:
|
||||
* it is not serializable, it is final, and its key and value must be non-null.
|
||||
*
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
*
|
||||
* @see Map#ofEntries Map.ofEntries()
|
||||
* @since 9
|
||||
*/
|
||||
final class KeyValueHolder<K,V> implements Map.Entry<K,V> {
|
||||
final K key;
|
||||
final V value;
|
||||
|
||||
KeyValueHolder(K k, V v) {
|
||||
key = Objects.requireNonNull(k);
|
||||
value = Objects.requireNonNull(v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key from this holder.
|
||||
*
|
||||
* @return the key
|
||||
*/
|
||||
@Override
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value from this holder.
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
@Override
|
||||
public V getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws {@link UnsupportedOperationException}.
|
||||
*
|
||||
* @param value ignored
|
||||
* @return never returns normally
|
||||
*/
|
||||
@Override
|
||||
public V setValue(V value) {
|
||||
throw new UnsupportedOperationException("not supported");
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified object with this entry for equality.
|
||||
* Returns {@code true} if the given object is also a map entry and
|
||||
* the two entries' keys and values are equal. Note that key and
|
||||
* value are non-null, so equals() can be called safely on them.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
|
||||
return key.equals(e.getKey()) && value.equals(e.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this map entry. The hash code
|
||||
* is {@code key.hashCode() ^ value.hashCode()}. Note that key and
|
||||
* value are non-null, so hashCode() can be called safely on them.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return key.hashCode() ^ value.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String representation of this map entry. This
|
||||
* implementation returns the string representation of this
|
||||
* entry's key followed by the equals character ("{@code =}")
|
||||
* followed by the string representation of this entry's value.
|
||||
*
|
||||
* @return a String representation of this map entry
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return key + "=" + value;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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,6 +87,28 @@ import java.util.function.UnaryOperator;
|
||||
* Such exceptions are marked as "optional" in the specification for this
|
||||
* interface.
|
||||
*
|
||||
* <h2><a name="immutable">Immutable List Static Factory Methods</a></h2>
|
||||
* <p>The {@link List#of(Object...) List.of()} static factory methods
|
||||
* provide a convenient way to create immutable lists. The {@code List}
|
||||
* instances created by these methods have the following characteristics:
|
||||
*
|
||||
* <ul>
|
||||
* <li>They are <em>structurally immutable</em>. Elements cannot be added, removed,
|
||||
* or replaced. Attempts to do so result in {@code UnsupportedOperationException}.
|
||||
* However, if the contained elements are themselves mutable,
|
||||
* this may cause the List's contents to appear to change.
|
||||
* <li>They disallow {@code null} elements. Attempts to create them with
|
||||
* {@code null} elements result in {@code NullPointerException}.
|
||||
* <li>They are serializable if all elements are serializable.
|
||||
* <li>The order of elements in the list is the same as the order of the
|
||||
* provided arguments, or of the elements in the provided array.
|
||||
* <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
|
||||
* Callers should make no assumptions about the identity of the returned instances.
|
||||
* Factories are free to create new instances or reuse existing ones. Therefore,
|
||||
* identity-sensitive operations on these instances (reference equality ({@code ==}),
|
||||
* identity hash code, and synchronization) are unreliable and should be avoided.
|
||||
* </ul>
|
||||
*
|
||||
* <p>This interface is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
@ -731,4 +753,312 @@ public interface List<E> extends Collection<E> {
|
||||
default Spliterator<E> spliterator() {
|
||||
return Spliterators.spliterator(this, Spliterator.ORDERED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable list containing zero elements.
|
||||
*
|
||||
* See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code List}'s element type
|
||||
* @return an empty {@code List}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> List<E> of() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable list containing one element.
|
||||
*
|
||||
* See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code List}'s element type
|
||||
* @param e1 the single element
|
||||
* @return a {@code List} containing the specified element
|
||||
* @throws NullPointerException if the element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> List<E> of(E e1) {
|
||||
return Collections.singletonList(Objects.requireNonNull(e1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable list containing two elements.
|
||||
*
|
||||
* See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code List}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @return a {@code List} containing the specified elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> List<E> of(E e1, E e2) {
|
||||
return Collections.unmodifiableList(
|
||||
Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable list containing three elements.
|
||||
*
|
||||
* See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code List}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @return a {@code List} containing the specified elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> List<E> of(E e1, E e2, E e3) {
|
||||
return Collections.unmodifiableList(
|
||||
Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable list containing four elements.
|
||||
*
|
||||
* See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code List}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @param e4 the fourth element
|
||||
* @return a {@code List} containing the specified elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> List<E> of(E e1, E e2, E e3, E e4) {
|
||||
return Collections.unmodifiableList(
|
||||
Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3),
|
||||
Objects.requireNonNull(e4)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable list containing five elements.
|
||||
*
|
||||
* See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code List}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @param e4 the fourth element
|
||||
* @param e5 the fifth element
|
||||
* @return a {@code List} containing the specified elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5) {
|
||||
return Collections.unmodifiableList(
|
||||
Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3),
|
||||
Objects.requireNonNull(e4),
|
||||
Objects.requireNonNull(e5)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable list containing six elements.
|
||||
*
|
||||
* See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code List}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @param e4 the fourth element
|
||||
* @param e5 the fifth element
|
||||
* @param e6 the sixth element
|
||||
* @return a {@code List} containing the specified elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
|
||||
return Collections.unmodifiableList(
|
||||
Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3),
|
||||
Objects.requireNonNull(e4),
|
||||
Objects.requireNonNull(e5),
|
||||
Objects.requireNonNull(e6)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable list containing seven elements.
|
||||
*
|
||||
* See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code List}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @param e4 the fourth element
|
||||
* @param e5 the fifth element
|
||||
* @param e6 the sixth element
|
||||
* @param e7 the seventh element
|
||||
* @return a {@code List} containing the specified elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
|
||||
return Collections.unmodifiableList(
|
||||
Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3),
|
||||
Objects.requireNonNull(e4),
|
||||
Objects.requireNonNull(e5),
|
||||
Objects.requireNonNull(e6),
|
||||
Objects.requireNonNull(e7)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable list containing eight elements.
|
||||
*
|
||||
* See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code List}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @param e4 the fourth element
|
||||
* @param e5 the fifth element
|
||||
* @param e6 the sixth element
|
||||
* @param e7 the seventh element
|
||||
* @param e8 the eighth element
|
||||
* @return a {@code List} containing the specified elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
|
||||
return Collections.unmodifiableList(
|
||||
Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3),
|
||||
Objects.requireNonNull(e4),
|
||||
Objects.requireNonNull(e5),
|
||||
Objects.requireNonNull(e6),
|
||||
Objects.requireNonNull(e7),
|
||||
Objects.requireNonNull(e8)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable list containing nine elements.
|
||||
*
|
||||
* See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code List}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @param e4 the fourth element
|
||||
* @param e5 the fifth element
|
||||
* @param e6 the sixth element
|
||||
* @param e7 the seventh element
|
||||
* @param e8 the eighth element
|
||||
* @param e9 the ninth element
|
||||
* @return a {@code List} containing the specified elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
|
||||
return Collections.unmodifiableList(
|
||||
Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3),
|
||||
Objects.requireNonNull(e4),
|
||||
Objects.requireNonNull(e5),
|
||||
Objects.requireNonNull(e6),
|
||||
Objects.requireNonNull(e7),
|
||||
Objects.requireNonNull(e8),
|
||||
Objects.requireNonNull(e9)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable list containing ten elements.
|
||||
*
|
||||
* See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code List}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @param e4 the fourth element
|
||||
* @param e5 the fifth element
|
||||
* @param e6 the sixth element
|
||||
* @param e7 the seventh element
|
||||
* @param e8 the eighth element
|
||||
* @param e9 the ninth element
|
||||
* @param e10 the tenth element
|
||||
* @return a {@code List} containing the specified elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
|
||||
return Collections.unmodifiableList(
|
||||
Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3),
|
||||
Objects.requireNonNull(e4),
|
||||
Objects.requireNonNull(e5),
|
||||
Objects.requireNonNull(e6),
|
||||
Objects.requireNonNull(e7),
|
||||
Objects.requireNonNull(e8),
|
||||
Objects.requireNonNull(e9),
|
||||
Objects.requireNonNull(e10)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable list containing an arbitrary number of elements.
|
||||
* See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
|
||||
*
|
||||
* @apiNote
|
||||
* This method also accepts a single array as an argument. The element type of
|
||||
* the resulting list will be the component type of the array, and the size of
|
||||
* the list will be equal to the length of the array. To create a list with
|
||||
* a single element that is an array, do the following:
|
||||
*
|
||||
* <pre>{@code
|
||||
* String[] array = ... ;
|
||||
* List<String[]> list = List.<String[]>of(array);
|
||||
* }</pre>
|
||||
*
|
||||
* This will cause the {@link List#of(Object) List.of(E)} method
|
||||
* to be invoked instead.
|
||||
*
|
||||
* @param <E> the {@code List}'s element type
|
||||
* @param elements the elements to be contained in the list
|
||||
* @return a {@code List} containing the specified elements
|
||||
* @throws NullPointerException if an element is {@code null} or if the array is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
@SafeVarargs
|
||||
@SuppressWarnings("varargs")
|
||||
static <E> List<E> of(E... elements) {
|
||||
elements = elements.clone(); // throws NPE if es is null
|
||||
for (E e : elements) {
|
||||
Objects.requireNonNull(e);
|
||||
}
|
||||
return Collections.unmodifiableList(Arrays.asList(elements));
|
||||
}
|
||||
}
|
||||
|
@ -1248,7 +1248,7 @@ public final class Locale implements Cloneable, Serializable {
|
||||
* object, consisting of language, country, variant, script,
|
||||
* and extensions as below:
|
||||
* <blockquote>
|
||||
* language + "_" + country + "_" + (variant + "_#" | "#") + script + "-" + extensions
|
||||
* language + "_" + country + "_" + (variant + "_#" | "#") + script + "_" + extensions
|
||||
* </blockquote>
|
||||
*
|
||||
* Language is always lower case, country is always upper case, script is always title
|
||||
@ -1278,7 +1278,7 @@ public final class Locale implements Cloneable, Serializable {
|
||||
* <li>{@code en_US_WIN}</li>
|
||||
* <li>{@code de__POSIX}</li>
|
||||
* <li>{@code zh_CN_#Hans}</li>
|
||||
* <li>{@code zh_TW_#Hant-x-java}</li>
|
||||
* <li>{@code zh_TW_#Hant_x-java}</li>
|
||||
* <li>{@code th_TH_TH_#u-nu-thai}</li></ul>
|
||||
*
|
||||
* @return A string representation of the Locale, for debugging.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -110,6 +110,31 @@ import java.io.Serializable;
|
||||
* Implementations may optionally handle the self-referential scenario, however
|
||||
* most current implementations do not do so.
|
||||
*
|
||||
* <h2><a name="immutable">Immutable Map Static Factory Methods</a></h2>
|
||||
* <p>The {@link Map#of() Map.of()} and
|
||||
* {@link Map#ofEntries(Map.Entry...) Map.ofEntries()}
|
||||
* static factory methods provide a convenient way to create immutable maps.
|
||||
* The {@code Map}
|
||||
* instances created by these methods have the following characteristics:
|
||||
*
|
||||
* <ul>
|
||||
* <li>They are <em>structurally immutable</em>. Keys and values cannot be added,
|
||||
* removed, or updated. Attempts to do so result in {@code UnsupportedOperationException}.
|
||||
* However, if the contained keys or values are themselves mutable, this may cause the
|
||||
* Map to behave inconsistently or its contents to appear to change.
|
||||
* <li>They disallow {@code null} keys and values. Attempts to create them with
|
||||
* {@code null} keys or values result in {@code NullPointerException}.
|
||||
* <li>They are serializable if all keys and values are serializable.
|
||||
* <li>They reject duplicate keys at creation time. Duplicate keys
|
||||
* passed to a static factory method result in {@code IllegalArgumentException}.
|
||||
* <li>The iteration order of mappings is unspecified and is subject to change.
|
||||
* <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
|
||||
* Callers should make no assumptions about the identity of the returned instances.
|
||||
* Factories are free to create new instances or reuse existing ones. Therefore,
|
||||
* identity-sensitive operations on these instances (reference equality ({@code ==}),
|
||||
* identity hash code, and synchronization) are unreliable and should be avoided.
|
||||
* </ul>
|
||||
*
|
||||
* <p>This interface is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
@ -126,7 +151,7 @@ import java.io.Serializable;
|
||||
* @see Set
|
||||
* @since 1.2
|
||||
*/
|
||||
public interface Map<K,V> {
|
||||
public interface Map<K, V> {
|
||||
// Query Operations
|
||||
|
||||
/**
|
||||
@ -373,7 +398,7 @@ public interface Map<K,V> {
|
||||
* @see Map#entrySet()
|
||||
* @since 1.2
|
||||
*/
|
||||
interface Entry<K,V> {
|
||||
interface Entry<K, V> {
|
||||
/**
|
||||
* Returns the key corresponding to this entry.
|
||||
*
|
||||
@ -468,7 +493,7 @@ public interface Map<K,V> {
|
||||
* @see Comparable
|
||||
* @since 1.8
|
||||
*/
|
||||
public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
|
||||
public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> comparingByKey() {
|
||||
return (Comparator<Map.Entry<K, V>> & Serializable)
|
||||
(c1, c2) -> c1.getKey().compareTo(c2.getKey());
|
||||
}
|
||||
@ -485,7 +510,7 @@ public interface Map<K,V> {
|
||||
* @see Comparable
|
||||
* @since 1.8
|
||||
*/
|
||||
public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() {
|
||||
public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue() {
|
||||
return (Comparator<Map.Entry<K, V>> & Serializable)
|
||||
(c1, c2) -> c1.getValue().compareTo(c2.getValue());
|
||||
}
|
||||
@ -1233,4 +1258,465 @@ public interface Map<K,V> {
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable map containing zero mappings.
|
||||
* See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <K> the {@code Map}'s key type
|
||||
* @param <V> the {@code Map}'s value type
|
||||
* @return an empty {@code Map}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <K, V> Map<K, V> of() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable map containing a single mapping.
|
||||
* See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <K> the {@code Map}'s key type
|
||||
* @param <V> the {@code Map}'s value type
|
||||
* @param k1 the mapping's key
|
||||
* @param v1 the mapping's value
|
||||
* @return a {@code Map} containing the specified mapping
|
||||
* @throws NullPointerException if the key or the value is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <K, V> Map<K, V> of(K k1, V v1) {
|
||||
return Collections.singletonMap(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable map containing two mappings.
|
||||
* See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <K> the {@code Map}'s key type
|
||||
* @param <V> the {@code Map}'s value type
|
||||
* @param k1 the first mapping's key
|
||||
* @param v1 the first mapping's value
|
||||
* @param k2 the second mapping's key
|
||||
* @param v2 the second mapping's value
|
||||
* @return a {@code Map} containing the specified mappings
|
||||
* @throws IllegalArgumentException if the keys are duplicates
|
||||
* @throws NullPointerException if any key or value is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2) {
|
||||
Map<K, V> map = new HashMap<>(3); // specify number of buckets to avoid resizing
|
||||
map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
|
||||
map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
|
||||
if (map.size() != 2) {
|
||||
throw new IllegalArgumentException("duplicate keys");
|
||||
}
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable map containing three mappings.
|
||||
* See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <K> the {@code Map}'s key type
|
||||
* @param <V> the {@code Map}'s value type
|
||||
* @param k1 the first mapping's key
|
||||
* @param v1 the first mapping's value
|
||||
* @param k2 the second mapping's key
|
||||
* @param v2 the second mapping's value
|
||||
* @param k3 the third mapping's key
|
||||
* @param v3 the third mapping's value
|
||||
* @return a {@code Map} containing the specified mappings
|
||||
* @throws IllegalArgumentException if there are any duplicate keys
|
||||
* @throws NullPointerException if any key or value is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3) {
|
||||
Map<K, V> map = new HashMap<>(5); // specify number of buckets to avoid resizing
|
||||
map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
|
||||
map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
|
||||
map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
|
||||
if (map.size() != 3) {
|
||||
throw new IllegalArgumentException("duplicate keys");
|
||||
}
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable map containing four mappings.
|
||||
* See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <K> the {@code Map}'s key type
|
||||
* @param <V> the {@code Map}'s value type
|
||||
* @param k1 the first mapping's key
|
||||
* @param v1 the first mapping's value
|
||||
* @param k2 the second mapping's key
|
||||
* @param v2 the second mapping's value
|
||||
* @param k3 the third mapping's key
|
||||
* @param v3 the third mapping's value
|
||||
* @param k4 the fourth mapping's key
|
||||
* @param v4 the fourth mapping's value
|
||||
* @return a {@code Map} containing the specified mappings
|
||||
* @throws IllegalArgumentException if there are any duplicate keys
|
||||
* @throws NullPointerException if any key or value is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
|
||||
Map<K, V> map = new HashMap<>(6); // specify number of buckets to avoid resizing
|
||||
map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
|
||||
map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
|
||||
map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
|
||||
map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
|
||||
if (map.size() != 4) {
|
||||
throw new IllegalArgumentException("duplicate keys");
|
||||
}
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable map containing five mappings.
|
||||
* See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <K> the {@code Map}'s key type
|
||||
* @param <V> the {@code Map}'s value type
|
||||
* @param k1 the first mapping's key
|
||||
* @param v1 the first mapping's value
|
||||
* @param k2 the second mapping's key
|
||||
* @param v2 the second mapping's value
|
||||
* @param k3 the third mapping's key
|
||||
* @param v3 the third mapping's value
|
||||
* @param k4 the fourth mapping's key
|
||||
* @param v4 the fourth mapping's value
|
||||
* @param k5 the fifth mapping's key
|
||||
* @param v5 the fifth mapping's value
|
||||
* @return a {@code Map} containing the specified mappings
|
||||
* @throws IllegalArgumentException if there are any duplicate keys
|
||||
* @throws NullPointerException if any key or value is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
|
||||
Map<K, V> map = new HashMap<>(7); // specify number of buckets to avoid resizing
|
||||
map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
|
||||
map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
|
||||
map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
|
||||
map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
|
||||
map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
|
||||
if (map.size() != 5) {
|
||||
throw new IllegalArgumentException("duplicate keys");
|
||||
}
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable map containing six mappings.
|
||||
* See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <K> the {@code Map}'s key type
|
||||
* @param <V> the {@code Map}'s value type
|
||||
* @param k1 the first mapping's key
|
||||
* @param v1 the first mapping's value
|
||||
* @param k2 the second mapping's key
|
||||
* @param v2 the second mapping's value
|
||||
* @param k3 the third mapping's key
|
||||
* @param v3 the third mapping's value
|
||||
* @param k4 the fourth mapping's key
|
||||
* @param v4 the fourth mapping's value
|
||||
* @param k5 the fifth mapping's key
|
||||
* @param v5 the fifth mapping's value
|
||||
* @param k6 the sixth mapping's key
|
||||
* @param v6 the sixth mapping's value
|
||||
* @return a {@code Map} containing the specified mappings
|
||||
* @throws IllegalArgumentException if there are any duplicate keys
|
||||
* @throws NullPointerException if any key or value is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
|
||||
K k6, V v6) {
|
||||
Map<K, V> map = new HashMap<>(9); // specify number of buckets to avoid resizing
|
||||
map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
|
||||
map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
|
||||
map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
|
||||
map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
|
||||
map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
|
||||
map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
|
||||
if (map.size() != 6) {
|
||||
throw new IllegalArgumentException("duplicate keys");
|
||||
}
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable map containing seven mappings.
|
||||
* See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <K> the {@code Map}'s key type
|
||||
* @param <V> the {@code Map}'s value type
|
||||
* @param k1 the first mapping's key
|
||||
* @param v1 the first mapping's value
|
||||
* @param k2 the second mapping's key
|
||||
* @param v2 the second mapping's value
|
||||
* @param k3 the third mapping's key
|
||||
* @param v3 the third mapping's value
|
||||
* @param k4 the fourth mapping's key
|
||||
* @param v4 the fourth mapping's value
|
||||
* @param k5 the fifth mapping's key
|
||||
* @param v5 the fifth mapping's value
|
||||
* @param k6 the sixth mapping's key
|
||||
* @param v6 the sixth mapping's value
|
||||
* @param k7 the seventh mapping's key
|
||||
* @param v7 the seventh mapping's value
|
||||
* @return a {@code Map} containing the specified mappings
|
||||
* @throws IllegalArgumentException if there are any duplicate keys
|
||||
* @throws NullPointerException if any key or value is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
|
||||
K k6, V v6, K k7, V v7) {
|
||||
Map<K, V> map = new HashMap<>(10); // specify number of buckets to avoid resizing
|
||||
map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
|
||||
map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
|
||||
map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
|
||||
map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
|
||||
map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
|
||||
map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
|
||||
map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
|
||||
if (map.size() != 7) {
|
||||
throw new IllegalArgumentException("duplicate keys");
|
||||
}
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable map containing eight mappings.
|
||||
* See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <K> the {@code Map}'s key type
|
||||
* @param <V> the {@code Map}'s value type
|
||||
* @param k1 the first mapping's key
|
||||
* @param v1 the first mapping's value
|
||||
* @param k2 the second mapping's key
|
||||
* @param v2 the second mapping's value
|
||||
* @param k3 the third mapping's key
|
||||
* @param v3 the third mapping's value
|
||||
* @param k4 the fourth mapping's key
|
||||
* @param v4 the fourth mapping's value
|
||||
* @param k5 the fifth mapping's key
|
||||
* @param v5 the fifth mapping's value
|
||||
* @param k6 the sixth mapping's key
|
||||
* @param v6 the sixth mapping's value
|
||||
* @param k7 the seventh mapping's key
|
||||
* @param v7 the seventh mapping's value
|
||||
* @param k8 the eighth mapping's key
|
||||
* @param v8 the eighth mapping's value
|
||||
* @return a {@code Map} containing the specified mappings
|
||||
* @throws IllegalArgumentException if there are any duplicate keys
|
||||
* @throws NullPointerException if any key or value is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
|
||||
K k6, V v6, K k7, V v7, K k8, V v8) {
|
||||
Map<K, V> map = new HashMap<>(11); // specify number of buckets to avoid resizing
|
||||
map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
|
||||
map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
|
||||
map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
|
||||
map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
|
||||
map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
|
||||
map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
|
||||
map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
|
||||
map.put(Objects.requireNonNull(k8), Objects.requireNonNull(v8));
|
||||
if (map.size() != 8) {
|
||||
throw new IllegalArgumentException("duplicate keys");
|
||||
}
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable map containing nine mappings.
|
||||
* See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <K> the {@code Map}'s key type
|
||||
* @param <V> the {@code Map}'s value type
|
||||
* @param k1 the first mapping's key
|
||||
* @param v1 the first mapping's value
|
||||
* @param k2 the second mapping's key
|
||||
* @param v2 the second mapping's value
|
||||
* @param k3 the third mapping's key
|
||||
* @param v3 the third mapping's value
|
||||
* @param k4 the fourth mapping's key
|
||||
* @param v4 the fourth mapping's value
|
||||
* @param k5 the fifth mapping's key
|
||||
* @param v5 the fifth mapping's value
|
||||
* @param k6 the sixth mapping's key
|
||||
* @param v6 the sixth mapping's value
|
||||
* @param k7 the seventh mapping's key
|
||||
* @param v7 the seventh mapping's value
|
||||
* @param k8 the eighth mapping's key
|
||||
* @param v8 the eighth mapping's value
|
||||
* @param k9 the ninth mapping's key
|
||||
* @param v9 the ninth mapping's value
|
||||
* @return a {@code Map} containing the specified mappings
|
||||
* @throws IllegalArgumentException if there are any duplicate keys
|
||||
* @throws NullPointerException if any key or value is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
|
||||
K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) {
|
||||
Map<K, V> map = new HashMap<>(13); // specify number of buckets to avoid resizing
|
||||
map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
|
||||
map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
|
||||
map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
|
||||
map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
|
||||
map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
|
||||
map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
|
||||
map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
|
||||
map.put(Objects.requireNonNull(k8), Objects.requireNonNull(v8));
|
||||
map.put(Objects.requireNonNull(k9), Objects.requireNonNull(v9));
|
||||
if (map.size() != 9) {
|
||||
throw new IllegalArgumentException("duplicate keys");
|
||||
}
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable map containing ten mappings.
|
||||
* See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <K> the {@code Map}'s key type
|
||||
* @param <V> the {@code Map}'s value type
|
||||
* @param k1 the first mapping's key
|
||||
* @param v1 the first mapping's value
|
||||
* @param k2 the second mapping's key
|
||||
* @param v2 the second mapping's value
|
||||
* @param k3 the third mapping's key
|
||||
* @param v3 the third mapping's value
|
||||
* @param k4 the fourth mapping's key
|
||||
* @param v4 the fourth mapping's value
|
||||
* @param k5 the fifth mapping's key
|
||||
* @param v5 the fifth mapping's value
|
||||
* @param k6 the sixth mapping's key
|
||||
* @param v6 the sixth mapping's value
|
||||
* @param k7 the seventh mapping's key
|
||||
* @param v7 the seventh mapping's value
|
||||
* @param k8 the eighth mapping's key
|
||||
* @param v8 the eighth mapping's value
|
||||
* @param k9 the ninth mapping's key
|
||||
* @param v9 the ninth mapping's value
|
||||
* @param k10 the tenth mapping's key
|
||||
* @param v10 the tenth mapping's value
|
||||
* @return a {@code Map} containing the specified mappings
|
||||
* @throws IllegalArgumentException if there are any duplicate keys
|
||||
* @throws NullPointerException if any key or value is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
|
||||
K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) {
|
||||
Map<K, V> map = new HashMap<>(14); // specify number of buckets to avoid resizing
|
||||
map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
|
||||
map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
|
||||
map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
|
||||
map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
|
||||
map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
|
||||
map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
|
||||
map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
|
||||
map.put(Objects.requireNonNull(k8), Objects.requireNonNull(v8));
|
||||
map.put(Objects.requireNonNull(k9), Objects.requireNonNull(v9));
|
||||
map.put(Objects.requireNonNull(k10), Objects.requireNonNull(v10));
|
||||
if (map.size() != 10) {
|
||||
throw new IllegalArgumentException("duplicate keys");
|
||||
}
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable map containing keys and values extracted from the given entries.
|
||||
* The entries themselves are not stored in the map.
|
||||
* See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
|
||||
*
|
||||
* @apiNote
|
||||
* It is convenient to create the map entries using the {@link Map#entry Map.entry()} method.
|
||||
* For example,
|
||||
*
|
||||
* <pre>{@code
|
||||
* import static java.util.Map.entry;
|
||||
*
|
||||
* Map<Integer,String> map = Map.ofEntries(
|
||||
* entry(1, "a"),
|
||||
* entry(2, "b"),
|
||||
* entry(3, "c"),
|
||||
* ...
|
||||
* entry(26, "z"));
|
||||
* }</pre>
|
||||
*
|
||||
* @param <K> the {@code Map}'s key type
|
||||
* @param <V> the {@code Map}'s value type
|
||||
* @param entries {@code Map.Entry}s containing the keys and values from which the map is populated
|
||||
* @return a {@code Map} containing the specified mappings
|
||||
* @throws IllegalArgumentException if there are any duplicate keys
|
||||
* @throws NullPointerException if any entry, key, or value is {@code null}, or if
|
||||
* the {@code entries} array is {@code null}
|
||||
*
|
||||
* @see Map#entry Map.entry()
|
||||
* @since 9
|
||||
*/
|
||||
@SafeVarargs
|
||||
@SuppressWarnings("varargs")
|
||||
static <K, V> Map<K, V> ofEntries(Entry<K, V>... entries) {
|
||||
Map<K, V> map = new HashMap<>(entries.length * 4 / 3 + 1); // throws NPE if entries is null
|
||||
for (Entry<K, V> e : entries) {
|
||||
// next line throws NPE if e is null
|
||||
map.put(Objects.requireNonNull(e.getKey()), Objects.requireNonNull(e.getValue()));
|
||||
}
|
||||
if (map.size() != entries.length) {
|
||||
throw new IllegalArgumentException("duplicate keys");
|
||||
}
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable {@link Entry} containing the given key and value.
|
||||
* These entries are suitable for populating {@code Map} instances using the
|
||||
* {@link Map#ofEntries Map.ofEntries()} method.
|
||||
* The {@code Entry} instances created by this method have the following characteristics:
|
||||
*
|
||||
* <ul>
|
||||
* <li>They disallow {@code null} keys and values. Attempts to create them using a {@code null}
|
||||
* key or value result in {@code NullPointerException}.
|
||||
* <li>They are immutable. Calls to {@link Entry#setValue Entry.setValue()}
|
||||
* on a returned {@code Entry} result in {@code UnsupportedOperationException}.
|
||||
* <li>They are not serializable.
|
||||
* <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
|
||||
* Callers should make no assumptions about the identity of the returned instances.
|
||||
* This method is free to create new instances or reuse existing ones. Therefore,
|
||||
* identity-sensitive operations on these instances (reference equality ({@code ==}),
|
||||
* identity hash code, and synchronization) are unreliable and should be avoided.
|
||||
* </ul>
|
||||
*
|
||||
* @apiNote
|
||||
* For a serializable {@code Entry}, see {@link AbstractMap.SimpleEntry} or
|
||||
* {@link AbstractMap.SimpleImmutableEntry}.
|
||||
*
|
||||
* @param <K> the key's type
|
||||
* @param <V> the value's type
|
||||
* @param k the key
|
||||
* @param v the value
|
||||
* @return an {@code Entry} containing the specified key and value
|
||||
* @throws NullPointerException if the key or value is {@code null}
|
||||
*
|
||||
* @see Map#ofEntries Map.ofEntries()
|
||||
* @since 9
|
||||
*/
|
||||
static <K, V> Entry<K, V> entry(K k, V v) {
|
||||
// KeyValueHolder checks for nulls
|
||||
return new KeyValueHolder<>(k, v);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -63,6 +63,29 @@ package java.util;
|
||||
* Such exceptions are marked as "optional" in the specification for this
|
||||
* interface.
|
||||
*
|
||||
* <h2><a name="immutable">Immutable Set Static Factory Methods</a></h2>
|
||||
* <p>The {@link Set#of(Object...) Set.of()} static factory methods
|
||||
* provide a convenient way to create immutable sets. The {@code Set}
|
||||
* instances created by these methods have the following characteristics:
|
||||
*
|
||||
* <ul>
|
||||
* <li>They are <em>structurally immutable</em>. Elements cannot be added or
|
||||
* removed. Attempts to do so result in {@code UnsupportedOperationException}.
|
||||
* However, if the contained elements are themselves mutable, this may cause the
|
||||
* Set to behave inconsistently or its contents to appear to change.
|
||||
* <li>They disallow {@code null} elements. Attempts to create them with
|
||||
* {@code null} elements result in {@code NullPointerException}.
|
||||
* <li>They are serializable if all elements are serializable.
|
||||
* <li>They reject duplicate elements at creation time. Duplicate elements
|
||||
* passed to a static factory method result in {@code IllegalArgumentException}.
|
||||
* <li>The iteration order of set elements is unspecified and is subject to change.
|
||||
* <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
|
||||
* Callers should make no assumptions about the identity of the returned instances.
|
||||
* Factories are free to create new instances or reuse existing ones. Therefore,
|
||||
* identity-sensitive operations on these instances (reference equality ({@code ==}),
|
||||
* identity hash code, and synchronization) are unreliable and should be avoided.
|
||||
* </ul>
|
||||
*
|
||||
* <p>This interface is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
@ -410,4 +433,341 @@ public interface Set<E> extends Collection<E> {
|
||||
default Spliterator<E> spliterator() {
|
||||
return Spliterators.spliterator(this, Spliterator.DISTINCT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable set containing zero elements.
|
||||
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code Set}'s element type
|
||||
* @return an empty {@code Set}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> Set<E> of() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable set containing one element.
|
||||
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code Set}'s element type
|
||||
* @param e1 the single element
|
||||
* @return a {@code Set} containing the specified element
|
||||
* @throws NullPointerException if the element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> Set<E> of(E e1) {
|
||||
return Collections.singleton(Objects.requireNonNull(e1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable set containing two elements.
|
||||
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code Set}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @return a {@code Set} containing the specified elements
|
||||
* @throws IllegalArgumentException if the elements are duplicates
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> Set<E> of(E e1, E e2) {
|
||||
Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2)));
|
||||
if (set.size() != 2) {
|
||||
throw new IllegalArgumentException("duplicate elements");
|
||||
}
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable set containing three elements.
|
||||
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code Set}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @return a {@code Set} containing the specified elements
|
||||
* @throws IllegalArgumentException if there are any duplicate elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> Set<E> of(E e1, E e2, E e3) {
|
||||
Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3)));
|
||||
if (set.size() != 3) {
|
||||
throw new IllegalArgumentException("duplicate elements");
|
||||
}
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable set containing four elements.
|
||||
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code Set}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @param e4 the fourth element
|
||||
* @return a {@code Set} containing the specified elements
|
||||
* @throws IllegalArgumentException if there are any duplicate elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> Set<E> of(E e1, E e2, E e3, E e4) {
|
||||
Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3),
|
||||
Objects.requireNonNull(e4)));
|
||||
if (set.size() != 4) {
|
||||
throw new IllegalArgumentException("duplicate elements");
|
||||
}
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable set containing five elements.
|
||||
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code Set}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @param e4 the fourth element
|
||||
* @param e5 the fifth element
|
||||
* @return a {@code Set} containing the specified elements
|
||||
* @throws IllegalArgumentException if there are any duplicate elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5) {
|
||||
Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3),
|
||||
Objects.requireNonNull(e4),
|
||||
Objects.requireNonNull(e5)));
|
||||
if (set.size() != 5) {
|
||||
throw new IllegalArgumentException("duplicate elements");
|
||||
}
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable set containing six elements.
|
||||
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code Set}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @param e4 the fourth element
|
||||
* @param e5 the fifth element
|
||||
* @param e6 the sixth element
|
||||
* @return a {@code Set} containing the specified elements
|
||||
* @throws IllegalArgumentException if there are any duplicate elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
|
||||
Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3),
|
||||
Objects.requireNonNull(e4),
|
||||
Objects.requireNonNull(e5),
|
||||
Objects.requireNonNull(e6)));
|
||||
if (set.size() != 6) {
|
||||
throw new IllegalArgumentException("duplicate elements");
|
||||
}
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable set containing seven elements.
|
||||
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code Set}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @param e4 the fourth element
|
||||
* @param e5 the fifth element
|
||||
* @param e6 the sixth element
|
||||
* @param e7 the seventh element
|
||||
* @return a {@code Set} containing the specified elements
|
||||
* @throws IllegalArgumentException if there are any duplicate elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
|
||||
Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3),
|
||||
Objects.requireNonNull(e4),
|
||||
Objects.requireNonNull(e5),
|
||||
Objects.requireNonNull(e6),
|
||||
Objects.requireNonNull(e7)));
|
||||
if (set.size() != 7) {
|
||||
throw new IllegalArgumentException("duplicate elements");
|
||||
}
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable set containing eight elements.
|
||||
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code Set}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @param e4 the fourth element
|
||||
* @param e5 the fifth element
|
||||
* @param e6 the sixth element
|
||||
* @param e7 the seventh element
|
||||
* @param e8 the eighth element
|
||||
* @return a {@code Set} containing the specified elements
|
||||
* @throws IllegalArgumentException if there are any duplicate elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
|
||||
Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3),
|
||||
Objects.requireNonNull(e4),
|
||||
Objects.requireNonNull(e5),
|
||||
Objects.requireNonNull(e6),
|
||||
Objects.requireNonNull(e7),
|
||||
Objects.requireNonNull(e8)));
|
||||
if (set.size() != 8) {
|
||||
throw new IllegalArgumentException("duplicate elements");
|
||||
}
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable set containing nine elements.
|
||||
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code Set}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @param e4 the fourth element
|
||||
* @param e5 the fifth element
|
||||
* @param e6 the sixth element
|
||||
* @param e7 the seventh element
|
||||
* @param e8 the eighth element
|
||||
* @param e9 the ninth element
|
||||
* @return a {@code Set} containing the specified elements
|
||||
* @throws IllegalArgumentException if there are any duplicate elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
|
||||
Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3),
|
||||
Objects.requireNonNull(e4),
|
||||
Objects.requireNonNull(e5),
|
||||
Objects.requireNonNull(e6),
|
||||
Objects.requireNonNull(e7),
|
||||
Objects.requireNonNull(e8),
|
||||
Objects.requireNonNull(e9)));
|
||||
if (set.size() != 9) {
|
||||
throw new IllegalArgumentException("duplicate elements");
|
||||
}
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable set containing ten elements.
|
||||
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
|
||||
*
|
||||
* @param <E> the {@code Set}'s element type
|
||||
* @param e1 the first element
|
||||
* @param e2 the second element
|
||||
* @param e3 the third element
|
||||
* @param e4 the fourth element
|
||||
* @param e5 the fifth element
|
||||
* @param e6 the sixth element
|
||||
* @param e7 the seventh element
|
||||
* @param e8 the eighth element
|
||||
* @param e9 the ninth element
|
||||
* @param e10 the tenth element
|
||||
* @return a {@code Set} containing the specified elements
|
||||
* @throws IllegalArgumentException if there are any duplicate elements
|
||||
* @throws NullPointerException if an element is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
|
||||
Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
|
||||
Objects.requireNonNull(e2),
|
||||
Objects.requireNonNull(e3),
|
||||
Objects.requireNonNull(e4),
|
||||
Objects.requireNonNull(e5),
|
||||
Objects.requireNonNull(e6),
|
||||
Objects.requireNonNull(e7),
|
||||
Objects.requireNonNull(e8),
|
||||
Objects.requireNonNull(e9),
|
||||
Objects.requireNonNull(e10)));
|
||||
if (set.size() != 10) {
|
||||
throw new IllegalArgumentException("duplicate elements");
|
||||
}
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable set containing an arbitrary number of elements.
|
||||
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
|
||||
*
|
||||
* @apiNote
|
||||
* This method also accepts a single array as an argument. The element type of
|
||||
* the resulting set will be the component type of the array, and the size of
|
||||
* the set will be equal to the length of the array. To create a set with
|
||||
* a single element that is an array, do the following:
|
||||
*
|
||||
* <pre>{@code
|
||||
* String[] array = ... ;
|
||||
* Set<String[]> list = Set.<String[]>of(array);
|
||||
* }</pre>
|
||||
*
|
||||
* This will cause the {@link Set#of(Object) Set.of(E)} method
|
||||
* to be invoked instead.
|
||||
*
|
||||
* @param <E> the {@code Set}'s element type
|
||||
* @param elements the elements to be contained in the set
|
||||
* @return a {@code Set} containing the specified elements
|
||||
* @throws IllegalArgumentException if there are any duplicate elements
|
||||
* @throws NullPointerException if an element is {@code null} or if the array is {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
@SafeVarargs
|
||||
static <E> Set<E> of(E... elements) {
|
||||
for (E e : elements) { // throws NPE if es is null
|
||||
Objects.requireNonNull(e);
|
||||
}
|
||||
@SuppressWarnings("varargs")
|
||||
Set<E> set = new HashSet<>(Arrays.asList(elements));
|
||||
if (set.size() != elements.length) {
|
||||
throw new IllegalArgumentException("duplicate elements");
|
||||
}
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
}
|
||||
|
@ -26,16 +26,16 @@
|
||||
/**
|
||||
* Provides classes for public key certificates.
|
||||
*
|
||||
* This package has been deprecated. These classes include a simplified
|
||||
* version of the {@code java.security.cert} package. These classes were
|
||||
* developed as part of the Java Secure Socket
|
||||
* Extension (JSSE). When JSSE was added to the J2SE version 1.4, this
|
||||
* package was added for backward-compatibility reasons only.
|
||||
* The classes in this package have been deprecated. New classes should not
|
||||
* be added to this package. These classes include a simplified version of
|
||||
* the {@code java.security.cert} package. These classes were developed as
|
||||
* part of the Java Secure Socket Extension (JSSE). When JSSE was added to
|
||||
* the J2SE version 1.4, this package was added for backward-compatibility
|
||||
* reasons only.
|
||||
*
|
||||
* New applications should not use this package, but rather
|
||||
* {@code java.security.cert}.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
@Deprecated
|
||||
package javax.security.cert;
|
||||
|
@ -25,8 +25,8 @@
|
||||
|
||||
package sun.nio.cs;
|
||||
|
||||
import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
|
||||
import static sun.misc.Unsafe.ARRAY_BYTE_INDEX_SCALE;
|
||||
import static jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
|
||||
import static jdk.internal.misc.Unsafe.ARRAY_BYTE_INDEX_SCALE;
|
||||
|
||||
class StringUTF16 {
|
||||
|
||||
@ -35,5 +35,5 @@ class StringUTF16 {
|
||||
ARRAY_BYTE_BASE_OFFSET + ARRAY_BYTE_INDEX_SCALE * index * 2L);
|
||||
}
|
||||
|
||||
private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
|
||||
private static final jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
|
||||
}
|
||||
|
@ -766,17 +766,27 @@ public final class SSLSocketImpl extends BaseSSLSocketImpl {
|
||||
// records, so this also increases robustness.
|
||||
//
|
||||
if (length > 0) {
|
||||
IOException ioe = null;
|
||||
byte description = 0; // 0: never used, make the compiler happy
|
||||
writeLock.lock();
|
||||
try {
|
||||
outputRecord.deliver(source, offset, length);
|
||||
} catch (SSLHandshakeException she) {
|
||||
// may be record sequence number overflow
|
||||
fatal(Alerts.alert_handshake_failure, she);
|
||||
description = Alerts.alert_handshake_failure;
|
||||
ioe = she;
|
||||
} catch (IOException e) {
|
||||
fatal(Alerts.alert_unexpected_message, e);
|
||||
description = Alerts.alert_unexpected_message;
|
||||
ioe = e;
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
|
||||
// Be care of deadlock. Please don't place the call to fatal()
|
||||
// into the writeLock locked block.
|
||||
if (ioe != null) {
|
||||
fatal(description, ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -35,8 +35,10 @@ import java.util.regex.Pattern;
|
||||
public class AlgorithmDecomposer {
|
||||
|
||||
private static final Pattern transPattern = Pattern.compile("/");
|
||||
|
||||
// '(?<!padd)in': match 'in' but not preceded with 'padd'.
|
||||
private static final Pattern pattern =
|
||||
Pattern.compile("with|and|in", Pattern.CASE_INSENSITIVE);
|
||||
Pattern.compile("with|and|(?<!padd)in", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
/**
|
||||
* Decompose the standard algorithm name into sub-elements.
|
||||
|
@ -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
|
||||
@ -309,7 +309,12 @@ class SolarisAclFileAttributeView
|
||||
checkAccess(file, true, false);
|
||||
|
||||
// open file (will fail if file is a link and not following links)
|
||||
int fd = file.openForAttributeAccess(followLinks);
|
||||
int fd = -1;
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(file);
|
||||
}
|
||||
try {
|
||||
long address = unsafe.allocateMemory(SIZEOF_ACE_T * MAX_ACL_ENTRIES);
|
||||
try {
|
||||
@ -338,7 +343,12 @@ class SolarisAclFileAttributeView
|
||||
checkAccess(file, false, true);
|
||||
|
||||
// open file (will fail if file is a link and not following links)
|
||||
int fd = file.openForAttributeAccess(followLinks);
|
||||
int fd = -1;
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(file);
|
||||
}
|
||||
try {
|
||||
// SECURITY: need to copy list as can change during processing
|
||||
acl = new ArrayList<AclEntry>(acl);
|
||||
|
@ -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
|
||||
@ -71,9 +71,11 @@ class SolarisUserDefinedFileAttributeView
|
||||
if (System.getSecurityManager() != null)
|
||||
checkAccess(file.getPathForPermissionCheck(), true, false);
|
||||
|
||||
int fd = file.openForAttributeAccess(followLinks);
|
||||
int fd = -1;
|
||||
try {
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
|
||||
// open extended attribute directory
|
||||
int dfd = openat(fd, HERE, (O_RDONLY|O_XATTR), 0);
|
||||
long dp;
|
||||
@ -112,9 +114,11 @@ class SolarisUserDefinedFileAttributeView
|
||||
if (System.getSecurityManager() != null)
|
||||
checkAccess(file.getPathForPermissionCheck(), true, false);
|
||||
|
||||
int fd = file.openForAttributeAccess(followLinks);
|
||||
int fd = -1;
|
||||
try {
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
|
||||
// open attribute file
|
||||
int afd = openat(fd, nameAsBytes(file,name), (O_RDONLY|O_XATTR), 0);
|
||||
try {
|
||||
@ -142,9 +146,11 @@ class SolarisUserDefinedFileAttributeView
|
||||
if (System.getSecurityManager() != null)
|
||||
checkAccess(file.getPathForPermissionCheck(), true, false);
|
||||
|
||||
int fd = file.openForAttributeAccess(followLinks);
|
||||
int fd = -1;
|
||||
try {
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
|
||||
// open attribute file
|
||||
int afd = openat(fd, nameAsBytes(file,name), (O_RDONLY|O_XATTR), 0);
|
||||
|
||||
@ -181,9 +187,11 @@ class SolarisUserDefinedFileAttributeView
|
||||
if (System.getSecurityManager() != null)
|
||||
checkAccess(file.getPathForPermissionCheck(), false, true);
|
||||
|
||||
int fd = file.openForAttributeAccess(followLinks);
|
||||
int fd = -1;
|
||||
try {
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
|
||||
// open/create attribute file
|
||||
int afd = openat(fd, nameAsBytes(file,name),
|
||||
(O_CREAT|O_WRONLY|O_TRUNC|O_XATTR),
|
||||
@ -217,8 +225,10 @@ class SolarisUserDefinedFileAttributeView
|
||||
if (System.getSecurityManager() != null)
|
||||
checkAccess(file.getPathForPermissionCheck(), false, true);
|
||||
|
||||
int fd = file.openForAttributeAccess(followLinks);
|
||||
int fd = -1;
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
|
||||
int dfd = openat(fd, HERE, (O_RDONLY|O_XATTR), 0);
|
||||
try {
|
||||
unlinkat(dfd, nameAsBytes(file,name), 0);
|
||||
|
@ -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
|
||||
@ -86,6 +86,9 @@ class UnixException extends Exception {
|
||||
return new NoSuchFileException(file, other, null);
|
||||
if (errno() == UnixConstants.EEXIST)
|
||||
return new FileAlreadyExistsException(file, other, null);
|
||||
if (errno() == UnixConstants.ELOOP)
|
||||
return new FileSystemException(file, other, errorString()
|
||||
+ " or unable to access attributes of symbolic link");
|
||||
|
||||
// fallback to the more general exception
|
||||
return new FileSystemException(file, other, errorString());
|
||||
|
@ -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
|
||||
@ -71,14 +71,30 @@ class UnixFileAttributeViews {
|
||||
// permission check
|
||||
file.checkWrite();
|
||||
|
||||
int fd = file.openForAttributeAccess(followLinks);
|
||||
boolean haveFd = false;
|
||||
boolean useFutimes = false;
|
||||
int fd = -1;
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
if (fd != -1) {
|
||||
haveFd = true;
|
||||
useFutimes = futimesSupported();
|
||||
}
|
||||
} catch (UnixException x) {
|
||||
if (x.errno() != UnixConstants.ENXIO) {
|
||||
x.rethrowAsIOException(file);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// assert followLinks || !UnixFileAttributes.get(fd).isSymbolicLink();
|
||||
|
||||
// if not changing both attributes then need existing attributes
|
||||
if (lastModifiedTime == null || lastAccessTime == null) {
|
||||
try {
|
||||
UnixFileAttributes attrs = UnixFileAttributes.get(fd);
|
||||
UnixFileAttributes attrs = haveFd ?
|
||||
UnixFileAttributes.get(fd) :
|
||||
UnixFileAttributes.get(file, followLinks);
|
||||
if (lastModifiedTime == null)
|
||||
lastModifiedTime = attrs.lastModifiedTime();
|
||||
if (lastAccessTime == null)
|
||||
@ -94,7 +110,7 @@ class UnixFileAttributeViews {
|
||||
|
||||
boolean retry = false;
|
||||
try {
|
||||
if (futimesSupported()) {
|
||||
if (useFutimes) {
|
||||
futimes(fd, accessValue, modValue);
|
||||
} else {
|
||||
utimes(file, accessValue, modValue);
|
||||
@ -113,7 +129,7 @@ class UnixFileAttributeViews {
|
||||
if (modValue < 0L) modValue = 0L;
|
||||
if (accessValue < 0L) accessValue= 0L;
|
||||
try {
|
||||
if (futimesSupported()) {
|
||||
if (useFutimes) {
|
||||
futimes(fd, accessValue, modValue);
|
||||
} else {
|
||||
utimes(file, accessValue, modValue);
|
||||
|
@ -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
|
||||
@ -91,9 +91,14 @@ class UnixNativeDispatcher {
|
||||
throws UnixException;
|
||||
|
||||
/**
|
||||
* close(int filedes)
|
||||
* close(int filedes). If fd is -1 this is a no-op.
|
||||
*/
|
||||
static native void close(int fd);
|
||||
static void close(int fd) {
|
||||
if (fd != -1) {
|
||||
close0(fd);
|
||||
}
|
||||
}
|
||||
private static native void close0(int fd);
|
||||
|
||||
/**
|
||||
* FILE* fopen(const char *filename, const char* mode);
|
||||
|
@ -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
|
||||
@ -764,11 +764,12 @@ class UnixPath implements Path {
|
||||
// -- file operations --
|
||||
|
||||
// package-private
|
||||
int openForAttributeAccess(boolean followLinks) throws IOException {
|
||||
int openForAttributeAccess(boolean followLinks) throws UnixException {
|
||||
int flags = O_RDONLY;
|
||||
if (!followLinks) {
|
||||
if (O_NOFOLLOW == 0)
|
||||
throw new IOException("NOFOLLOW_LINKS is not supported on this platform");
|
||||
throw new UnixException
|
||||
("NOFOLLOW_LINKS is not supported on this platform");
|
||||
flags |= O_NOFOLLOW;
|
||||
}
|
||||
try {
|
||||
@ -778,12 +779,7 @@ class UnixPath implements Path {
|
||||
if (getFileSystem().isSolaris() && x.errno() == EINVAL)
|
||||
x.setError(ELOOP);
|
||||
|
||||
if (x.errno() == ELOOP)
|
||||
throw new FileSystemException(getPathForExceptionMessage(), null,
|
||||
x.getMessage() + " or unable to access attributes of symbolic link");
|
||||
|
||||
x.rethrowAsIOException(this);
|
||||
return -1; // keep compile happy
|
||||
throw x;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
@ -408,7 +408,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_openat0(JNIEnv* env, jclass this, jint dfd,
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_close(JNIEnv* env, jclass this, jint fd) {
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_close0(JNIEnv* env, jclass this, jint fd) {
|
||||
int err;
|
||||
/* TDB - need to decide if EIO and other errors should cause exception */
|
||||
RESTARTABLE(close((int)fd), err);
|
||||
|
@ -295,6 +295,7 @@ ping4(JNIEnv *env,
|
||||
char SendData[32] = {0};
|
||||
LPVOID ReplyBuffer = NULL;
|
||||
DWORD ReplySize = 0;
|
||||
jboolean ret = JNI_FALSE;
|
||||
|
||||
hIcmpFile = IcmpCreateFile();
|
||||
if (hIcmpFile == INVALID_HANDLE_VALUE) {
|
||||
@ -318,7 +319,11 @@ ping4(JNIEnv *env,
|
||||
NULL, // PIP_OPTION_INFORMATION RequestOptions,
|
||||
ReplyBuffer,// LPVOID ReplyBuffer,
|
||||
ReplySize, // DWORD ReplySize,
|
||||
timeout); // DWORD Timeout
|
||||
// Note: IcmpSendEcho and its derivatives
|
||||
// seem to have an undocumented minimum
|
||||
// timeout of 1000ms below which the
|
||||
// api behaves inconsistently.
|
||||
(timeout < 1000) ? 1000 : timeout); // DWORD Timeout
|
||||
} else {
|
||||
dwRetVal = IcmpSendEcho2Ex(hIcmpFile, // HANDLE IcmpHandle,
|
||||
NULL, // HANDLE Event
|
||||
@ -331,17 +336,19 @@ ping4(JNIEnv *env,
|
||||
NULL, // PIP_OPTION_INFORMATION RequestOptions,
|
||||
ReplyBuffer,// LPVOID ReplyBuffer,
|
||||
ReplySize, // DWORD ReplySize,
|
||||
timeout); // DWORD Timeout
|
||||
(timeout < 1000) ? 1000 : timeout); // DWORD Timeout
|
||||
}
|
||||
|
||||
if (dwRetVal != 0) {
|
||||
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
|
||||
if ((int)pEchoReply->RoundTripTime <= timeout)
|
||||
ret = JNI_TRUE;
|
||||
}
|
||||
|
||||
free(ReplyBuffer);
|
||||
IcmpCloseHandle(hIcmpFile);
|
||||
|
||||
if (dwRetVal != 0) {
|
||||
return JNI_TRUE;
|
||||
} else {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -119,6 +119,31 @@ typedef unsigned int hb_atomic_int_impl_t;
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false)
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(_AIX) && defined(__IBMCPP__)
|
||||
|
||||
#include <builtins.h>
|
||||
|
||||
|
||||
static inline int hb_fetch_and_add(volatile int* AI, unsigned int V) {
|
||||
__lwsync();
|
||||
int result = __fetch_and_add(AI, V);
|
||||
__isync();
|
||||
return result;
|
||||
}
|
||||
static inline int hb_compare_and_swaplp(volatile long* P, long O, long N) {
|
||||
__sync();
|
||||
int result = __compare_and_swaplp (P, &O, N);
|
||||
__sync();
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef int hb_atomic_int_impl_t;
|
||||
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
|
||||
#define hb_atomic_int_impl_add(AI, V) hb_fetch_and_add (&(AI), (V))
|
||||
|
||||
#define hb_atomic_ptr_impl_get(P) (__sync(), (void *) *(P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) hb_compare_and_swaplp ((long*)(P), (long)(O), (long)(N))
|
||||
|
||||
#elif !defined(HB_NO_MT)
|
||||
|
||||
#define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */
|
||||
|
@ -37,9 +37,13 @@ import java.net.InetAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.Properties;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import javax.management.remote.JMXConnectorServer;
|
||||
import javax.management.remote.JMXServiceURL;
|
||||
@ -60,6 +64,30 @@ public class Agent {
|
||||
* Agent status collector strategy class
|
||||
*/
|
||||
private static abstract class StatusCollector {
|
||||
protected static final Map<String, String> DEFAULT_PROPS = new HashMap<>();
|
||||
|
||||
static {
|
||||
DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.PORT,
|
||||
ConnectorBootstrap.DefaultValues.PORT);
|
||||
DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.USE_LOCAL_ONLY,
|
||||
ConnectorBootstrap.DefaultValues.USE_LOCAL_ONLY);
|
||||
DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.USE_AUTHENTICATION,
|
||||
ConnectorBootstrap.DefaultValues.USE_AUTHENTICATION);
|
||||
DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.USE_SSL,
|
||||
ConnectorBootstrap.DefaultValues.USE_SSL);
|
||||
DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.USE_REGISTRY_SSL,
|
||||
ConnectorBootstrap.DefaultValues.USE_REGISTRY_SSL);
|
||||
DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.SSL_NEED_CLIENT_AUTH,
|
||||
ConnectorBootstrap.DefaultValues.SSL_NEED_CLIENT_AUTH);
|
||||
DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.CONFIG_FILE_NAME,
|
||||
ConnectorBootstrap.DefaultValues.CONFIG_FILE_NAME);
|
||||
DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.PASSWORD_FILE_NAME,
|
||||
ConnectorBootstrap.DefaultValues.PASSWORD_FILE_NAME);
|
||||
DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.ACCESS_FILE_NAME,
|
||||
ConnectorBootstrap.DefaultValues.ACCESS_FILE_NAME);
|
||||
|
||||
}
|
||||
|
||||
final protected StringBuilder sb = new StringBuilder();
|
||||
final public String collect() {
|
||||
Properties agentProps = VMSupport.getAgentProperties();
|
||||
@ -93,28 +121,49 @@ public class Agent {
|
||||
private void addConnection(boolean remote, JMXServiceURL u) {
|
||||
appendConnectionHeader(remote);
|
||||
addConnectionDetails(u);
|
||||
if (remote) {
|
||||
addConfigProperties();
|
||||
}
|
||||
addConfigProperties();
|
||||
appendConnectionFooter(remote);
|
||||
}
|
||||
|
||||
private void addConfigProperties() {
|
||||
appendConfigPropsHeader();
|
||||
boolean[] first = new boolean[] {true};
|
||||
Properties props = configProps != null ?
|
||||
configProps : getManagementProperties();
|
||||
|
||||
props.entrySet().stream().forEach((e) -> {
|
||||
String key = (String)e.getKey();
|
||||
if (key.startsWith("com.sun.management.")) {
|
||||
addConfigProp(key, e.getValue(), first[0]);
|
||||
first[0] = false;
|
||||
Properties remoteProps = configProps != null ?
|
||||
configProps : getManagementProperties();
|
||||
Map<Object, Object> props = new HashMap<>(DEFAULT_PROPS);
|
||||
|
||||
if (remoteProps == null) {
|
||||
// local connector only
|
||||
String loc_only = System.getProperty(
|
||||
ConnectorBootstrap.PropertyNames.USE_LOCAL_ONLY
|
||||
);
|
||||
|
||||
if (loc_only != null &&
|
||||
!ConnectorBootstrap.DefaultValues.USE_LOCAL_ONLY.equals(loc_only)) {
|
||||
props.put(
|
||||
ConnectorBootstrap.PropertyNames.USE_LOCAL_ONLY,
|
||||
loc_only
|
||||
);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
props.putAll(remoteProps);
|
||||
}
|
||||
|
||||
props.entrySet().stream()
|
||||
.filter(preprocess(Map.Entry::getKey, StatusCollector::isManagementProp))
|
||||
.forEach(this::addConfigProp);
|
||||
|
||||
appendConfigPropsFooter();
|
||||
}
|
||||
|
||||
private static boolean isManagementProp(Object pName) {
|
||||
return pName != null && pName.toString().startsWith("com.sun.management.");
|
||||
}
|
||||
|
||||
private static <T, V> Predicate<T> preprocess(Function<T, V> f, Predicate<V> p) {
|
||||
return (T t) -> p.test(f.apply(t));
|
||||
}
|
||||
|
||||
abstract protected void addAgentStatus(boolean enabled);
|
||||
abstract protected void appendConnectionsHeader();
|
||||
abstract protected void appendConnectionsFooter();
|
||||
@ -123,7 +172,7 @@ public class Agent {
|
||||
abstract protected void appendConnectionFooter(boolean remote);
|
||||
abstract protected void appendConfigPropsHeader();
|
||||
abstract protected void appendConfigPropsFooter();
|
||||
abstract protected void addConfigProp(String key, Object value, boolean first);
|
||||
abstract protected void addConfigProp(Map.Entry<?, ?> prop);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -159,11 +208,14 @@ public class Agent {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addConfigProp(String key, Object value, boolean first) {
|
||||
if (!first) {
|
||||
sb.append('\n');
|
||||
protected void addConfigProp(Map.Entry<?, ?> prop) {
|
||||
sb.append(" ").append(prop.getKey()).append(" = ")
|
||||
.append(prop.getValue());
|
||||
Object defVal = DEFAULT_PROPS.get(prop.getKey());
|
||||
if (defVal != null && defVal.equals(prop.getValue())) {
|
||||
sb.append(" [default]");
|
||||
}
|
||||
sb.append(" ").append(key).append(" = ").append(value);
|
||||
sb.append("\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,389 +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 apple.applescript;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.script.*;
|
||||
|
||||
/**
|
||||
* AppleScriptEngine implements JSR 223 for AppleScript on Mac OS X
|
||||
*/
|
||||
public class AppleScriptEngine implements ScriptEngine {
|
||||
private static native void initNative();
|
||||
|
||||
private static native long createContextFrom(final Object object);
|
||||
private static native Object createObjectFrom(final long context);
|
||||
private static native void disposeContext(final long context);
|
||||
|
||||
private static native long evalScript(final String script, long contextptr);
|
||||
private static native long evalScriptFromURL(final String filename, long contextptr);
|
||||
|
||||
static {
|
||||
System.loadLibrary("AppleScriptEngine");
|
||||
initNative();
|
||||
TRACE("<static-init>");
|
||||
}
|
||||
|
||||
static void checkSecurity() {
|
||||
final SecurityManager securityManager = System.getSecurityManager();
|
||||
if (securityManager != null) securityManager.checkExec("/usr/bin/osascript");
|
||||
}
|
||||
|
||||
static void TRACE(final String str) {
|
||||
// System.out.println(AppleScriptEngine.class.getName() + "." + str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the ScriptEngine's long name variable
|
||||
* @return the long name of the ScriptEngine
|
||||
*/
|
||||
protected static String getEngine() {
|
||||
TRACE("getEngine()");
|
||||
return AppleScriptEngineFactory.ENGINE_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the ScriptEngine's version
|
||||
* @return the version of the ScriptEngine
|
||||
*/
|
||||
protected static String getEngineVersion() {
|
||||
TRACE("getEngineVersion()");
|
||||
return AppleScriptEngineFactory.ENGINE_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the ScriptEngine's short name
|
||||
* @return the short name of the ScriptEngine
|
||||
*/
|
||||
protected static String getName() {
|
||||
TRACE("getName()");
|
||||
return AppleScriptEngineFactory.ENGINE_SHORT_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the ScriptEngine's supported language name
|
||||
* @return the language the ScriptEngine supports
|
||||
*/
|
||||
protected static String getLanguage() {
|
||||
TRACE("getLanguage()");
|
||||
return AppleScriptEngineFactory.LANGUAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* The no argument constructor sets up the object with default members,
|
||||
* a factory for the engine and a fresh context.
|
||||
* @see com.apple.applescript.AppleScriptEngine#init()
|
||||
*/
|
||||
public AppleScriptEngine() {
|
||||
TRACE("<ctor>()");
|
||||
// set our parent factory to be a new factory
|
||||
factory = AppleScriptEngineFactory.getFactory();
|
||||
|
||||
// set up our noarg bindings
|
||||
setContext(new SimpleScriptContext());
|
||||
put(ARGV, "");
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* All AppleScriptEngines share the same ScriptEngineFactory
|
||||
*/
|
||||
private final ScriptEngineFactory factory;
|
||||
|
||||
/**
|
||||
* The local context for the AppleScriptEngine
|
||||
*/
|
||||
private ScriptContext context;
|
||||
|
||||
/**
|
||||
* The constructor taking a factory as an argument sets the parent factory for
|
||||
* this engine to be the passed factory, and sets up the engine with a fresh context
|
||||
* @param factory
|
||||
* @see com.apple.applescript.AppleScriptEngine#init()
|
||||
*/
|
||||
public AppleScriptEngine(final ScriptEngineFactory factory) {
|
||||
// inherit the factory passed to us
|
||||
this.factory = factory;
|
||||
|
||||
// set up our noarg bindings
|
||||
setContext(new SimpleScriptContext());
|
||||
put(ARGV, "");
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* The initializer populates the local context with some useful predefined variables:
|
||||
* <ul><li><code>javax_script_language_version</code> - the version of AppleScript that the AppleScriptEngine supports.</li>
|
||||
* <li><code>javax_script_language</code> - "AppleScript" -- the language supported by the AppleScriptEngine.</li>
|
||||
* <li><code>javax_script_engine</code> - "AppleScriptEngine" -- the name of the ScriptEngine.</li>
|
||||
* <li><code>javax_script_engine_version</code> - the version of the AppleScriptEngine</li>
|
||||
* <li><code>javax_script_argv</code> - "" -- AppleScript does not take arguments from the command line</li>
|
||||
* <li><code>javax_script_filename</code> - "" -- the currently executing filename</li>
|
||||
* <li><code>javax_script_name</code> - "AppleScriptEngine" -- the short name of the AppleScriptEngine</li>
|
||||
* <li><code>THREADING</code> - null -- the AppleScriptEngine does not support concurrency, you will have to implement thread-safeness yourself.</li></ul>
|
||||
*/
|
||||
private void init() {
|
||||
TRACE("init()");
|
||||
// set up our context
|
||||
/* TODO -- name of current executable? bad java documentation at:
|
||||
* http://docs.oracle.com/javase/6/docs/api/javax/script/ScriptEngine.html#FILENAME */
|
||||
put(ScriptEngine.FILENAME, "");
|
||||
put(ScriptEngine.ENGINE, getEngine());
|
||||
put(ScriptEngine.ENGINE_VERSION, getEngineVersion());
|
||||
put(ScriptEngine.NAME, getName());
|
||||
put(ScriptEngine.LANGUAGE, getLanguage());
|
||||
put(ScriptEngine.LANGUAGE_VERSION, getLanguageVersion());
|
||||
|
||||
// TODO -- for now, err on the side of caution and say that we are NOT thread-safe
|
||||
put("THREADING", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the AppleScriptEngine to get the local AppleScript version
|
||||
* @return the version of AppleScript running on the system
|
||||
*/
|
||||
protected String getLanguageVersion() {
|
||||
TRACE("AppleScriptEngine.getLanguageVersion()");
|
||||
try {
|
||||
final Object result = eval("get the version of AppleScript");
|
||||
if (result instanceof String) return (String)result;
|
||||
} catch (final ScriptException e) { e.printStackTrace(); }
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation required by ScriptEngine parent<br />
|
||||
* Returns the factory parent of this AppleScriptEngine
|
||||
*/
|
||||
public ScriptEngineFactory getFactory() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation required by ScriptEngine parent<br />
|
||||
* Return the engine's context
|
||||
* @return this ScriptEngine's context
|
||||
*/
|
||||
public ScriptContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation required by ScriptEngine parent<br />
|
||||
* Set a new context for the engine
|
||||
* @param context the new context to install in the engine
|
||||
*/
|
||||
public void setContext(final ScriptContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation required by ScriptEngine parent<br />
|
||||
* Create and return a new set of simple bindings.
|
||||
* @return a new and empty set of bindings
|
||||
*/
|
||||
public Bindings createBindings() {
|
||||
return new SimpleBindings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation required by ScriptEngine parent<br />
|
||||
* Return the engines bindings for the context indicated by the argument.
|
||||
* @param scope contextual scope to return.
|
||||
* @return the bindings in the engine for the scope indicated by the parameter
|
||||
*/
|
||||
public Bindings getBindings(final int scope) {
|
||||
return context.getBindings(scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation required by ScriptEngine parent<br />
|
||||
* Sets the bindings for the indicated scope
|
||||
* @param bindings a set of bindings to assign to the engine
|
||||
* @param scope the scope that the passed bindings should be assigned to
|
||||
*/
|
||||
public void setBindings(final Bindings bindings, final int scope) {
|
||||
context.setBindings(bindings, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation required by ScriptEngine parent<br />
|
||||
* Insert a key and value into the engine's bindings (scope: engine)
|
||||
* @param key the key of the pair
|
||||
* @param value the value of the pair
|
||||
*/
|
||||
public void put(final String key, final Object value) {
|
||||
getBindings(ScriptContext.ENGINE_SCOPE).put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation required by ScriptEngine parent<br />
|
||||
* Get a value from the engine's bindings using a key (scope: engine)
|
||||
* @param key the key of the pair
|
||||
* @return the value of the pair
|
||||
*/
|
||||
public Object get(final String key) {
|
||||
return getBindings(ScriptContext.ENGINE_SCOPE).get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation required by ScriptEngine parent<br />
|
||||
* Passes the Reader argument, as well as the engine's context to a lower evaluation function.<br />
|
||||
* Prefers FileReader or BufferedReader wrapping FileReader as argument.
|
||||
* @param reader a Reader to AppleScript source or compiled AppleScript
|
||||
* @return an Object corresponding to the return value of the script
|
||||
* @see com.apple.applescript.AppleScriptEngine#eval(Reader, ScriptContext)
|
||||
*/
|
||||
public Object eval(final Reader reader) throws ScriptException {
|
||||
return eval(reader, getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation required by ScriptEngine parent<br />
|
||||
* Uses the passed bindings as the context for executing the passed script.
|
||||
* @param reader a stream to AppleScript source or compiled AppleScript
|
||||
* @param bindings a Bindings object representing the contexts to execute inside
|
||||
* @return the return value of the script
|
||||
* @see com.apple.applescript.AppleScriptEngine#eval(Reader, ScriptContext)
|
||||
*/
|
||||
public Object eval(final Reader reader, final Bindings bindings) throws ScriptException {
|
||||
final Bindings tmp = getContext().getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
getContext().setBindings(bindings, ScriptContext.ENGINE_SCOPE);
|
||||
final Object retval = eval(reader);
|
||||
getContext().setBindings(tmp, ScriptContext.ENGINE_SCOPE);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation required by ScriptEngine parent<br />
|
||||
* This function can execute either AppleScript source or compiled AppleScript and functions by writing the
|
||||
* contents of the Reader to a temporary file and then executing it with the engine's context.
|
||||
* @param reader
|
||||
* @param scriptContext
|
||||
* @return an Object corresponding to the return value of the script
|
||||
*/
|
||||
public Object eval(final Reader reader, final ScriptContext context) throws ScriptException {
|
||||
checkSecurity();
|
||||
|
||||
// write our passed reader to a temporary file
|
||||
File tmpfile;
|
||||
FileWriter tmpwrite;
|
||||
try {
|
||||
tmpfile = Files.createTempFile("AppleScriptEngine.", ".scpt").toFile();
|
||||
tmpwrite = new FileWriter(tmpfile);
|
||||
|
||||
// read in our input and write directly to tmpfile
|
||||
/* TODO -- this may or may not be avoidable for certain Readers,
|
||||
* if a filename can be grabbed, it would be faster to get that and
|
||||
* use the underlying file than writing a temp file.
|
||||
*/
|
||||
int data;
|
||||
while ((data = reader.read()) != -1) {
|
||||
tmpwrite.write(data);
|
||||
}
|
||||
tmpwrite.close();
|
||||
|
||||
// set up our context business
|
||||
final long contextptr = scriptContextToNSDictionary(context);
|
||||
try {
|
||||
final long retCtx = evalScriptFromURL("file://" + tmpfile.getCanonicalPath(), contextptr);
|
||||
Object retVal = (retCtx == 0) ? null : createObjectFrom(retCtx);
|
||||
disposeContext(retCtx);
|
||||
return retVal;
|
||||
} finally {
|
||||
disposeContext(contextptr);
|
||||
tmpfile.delete();
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
throw new ScriptException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation required by ScriptEngine parent<br />
|
||||
* Evaluate an AppleScript script passed as a source string. Using the engine's built in context.
|
||||
* @param script the string to execute.
|
||||
* @return an Object representing the return value of the script
|
||||
* @see com.apple.applescript.AppleScriptEngine#eval(String, ScriptContext)
|
||||
*/
|
||||
public Object eval(final String script) throws ScriptException {
|
||||
return eval(script, getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation required by ScriptEngine parent<br />
|
||||
* Evaluate an AppleScript script passed as a source string with a custom ScriptContext.
|
||||
* @param script the AppleScript source to compile and execute.
|
||||
* @param scriptContext the context to execute the script under
|
||||
* @see com.apple.applescript.AppleScriptEngine#eval(String, ScriptContext)
|
||||
*/
|
||||
public Object eval(final String script, final Bindings bindings) throws ScriptException {
|
||||
final Bindings tmp = getContext().getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
getContext().setBindings(bindings, ScriptContext.ENGINE_SCOPE);
|
||||
|
||||
final Object retval = eval(script);
|
||||
getContext().setBindings(tmp, ScriptContext.ENGINE_SCOPE);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation required by ScriptEngine parent
|
||||
* @param script
|
||||
* @param scriptContext
|
||||
*/
|
||||
public Object eval(final String script, final ScriptContext context) throws ScriptException {
|
||||
checkSecurity();
|
||||
final long ctxPtr = scriptContextToNSDictionary(context);
|
||||
try {
|
||||
final long retCtx = evalScript(script, ctxPtr);
|
||||
Object retVal = (retCtx == 0) ? null : createObjectFrom(retCtx);
|
||||
disposeContext(retCtx);
|
||||
return retVal;
|
||||
} finally {
|
||||
disposeContext(ctxPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a ScriptContext into an NSDictionary
|
||||
* @param context ScriptContext for the engine
|
||||
* @return a pointer to an NSDictionary
|
||||
*/
|
||||
private long scriptContextToNSDictionary(final ScriptContext context) throws ScriptException {
|
||||
final Map<String, Object> contextAsMap = new HashMap<String, Object>();
|
||||
for (final Entry<String, Object> e : context.getBindings(ScriptContext.ENGINE_SCOPE).entrySet()) {
|
||||
contextAsMap.put(e.getKey().replaceAll("\\.", "_"), e.getValue());
|
||||
}
|
||||
return createContextFrom(contextAsMap);
|
||||
}
|
||||
}
|
@ -1,244 +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 apple.applescript;
|
||||
|
||||
import java.security.*;
|
||||
import java.util.*;
|
||||
import javax.script.*;
|
||||
|
||||
public class AppleScriptEngineFactory implements ScriptEngineFactory {
|
||||
private static volatile boolean initialized = false;
|
||||
|
||||
private static native void initNative();
|
||||
|
||||
static void TRACE(final String str) {
|
||||
// System.out.println(AppleScriptEngineFactory.class.getName() + "." + str);
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of this ScriptEngine
|
||||
*/
|
||||
static final String ENGINE_NAME = "AppleScriptEngine";
|
||||
|
||||
/**
|
||||
* The version of this ScriptEngine
|
||||
*/
|
||||
static final String ENGINE_VERSION = "1.1";
|
||||
|
||||
/**
|
||||
* The name of this ScriptEngine (yes, again)
|
||||
*/
|
||||
static final String ENGINE_SHORT_NAME = ENGINE_NAME;
|
||||
|
||||
/**
|
||||
* The name of the language supported by this ScriptEngine
|
||||
*/
|
||||
static final String LANGUAGE = "AppleScript";
|
||||
|
||||
static ScriptEngineFactory getFactory() {
|
||||
TRACE("getFactory()");
|
||||
return new AppleScriptEngineFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a new AppleScriptEngineFactory, replete with a member AppleScriptEngine
|
||||
*/
|
||||
public AppleScriptEngineFactory() {
|
||||
TRACE("<ctor>()");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full name of the ScriptEngine.
|
||||
*
|
||||
* @return full name of the ScriptEngine
|
||||
*/
|
||||
@Override
|
||||
public String getEngineName() {
|
||||
TRACE("getEngineName()");
|
||||
return ENGINE_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version of the ScriptEngine.
|
||||
*
|
||||
* @return version of the ScriptEngine
|
||||
*/
|
||||
@Override
|
||||
public String getEngineVersion() {
|
||||
TRACE("getEngineVersion()");
|
||||
return ENGINE_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the scripting language supported by this ScriptEngine.
|
||||
*
|
||||
* @return name of the language supported by the ScriptEngine(Factory)
|
||||
*/
|
||||
@Override
|
||||
public String getLanguageName() {
|
||||
TRACE("getLanguageName()");
|
||||
return LANGUAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version of the scripting language supported by this ScriptEngine(Factory).
|
||||
*
|
||||
* @return language version supported by the ScriptEngine(Factory)
|
||||
*/
|
||||
@Override
|
||||
public String getLanguageVersion() {
|
||||
TRACE("getLanguageVersion()");
|
||||
return AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
final AppleScriptEngine engine = getScriptEngine();
|
||||
return engine.getLanguageVersion();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable list of filename extensions, which generally identify
|
||||
* scripts written in the language supported by this ScriptEngine.
|
||||
*
|
||||
* @return ArrayList of file extensions AppleScript associates with
|
||||
*/
|
||||
@Override
|
||||
public List<String> getExtensions() {
|
||||
TRACE("getExtensions()");
|
||||
return Arrays.asList("scpt", "applescript", "app");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable list of mimetypes, associated with scripts
|
||||
* that can be executed by the engine.
|
||||
*
|
||||
* @return ArrayList of mimetypes that AppleScript associates with
|
||||
*/
|
||||
@Override
|
||||
public List<String> getMimeTypes() {
|
||||
TRACE("getMimeTypes()");
|
||||
return Arrays.asList("application/x-applescript", "text/plain", "text/applescript");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable list of short names for the ScriptEngine,
|
||||
* which may be used to identify the ScriptEngine by the ScriptEngineManager.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<String> getNames() {
|
||||
TRACE("getNames()");
|
||||
return Arrays.asList("AppleScriptEngine", "AppleScript", "OSA");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String which can be used to invoke a method of a Java
|
||||
* object using the syntax of the supported scripting language.
|
||||
*
|
||||
* @param obj
|
||||
* unused -- AppleScript does not support objects
|
||||
* @param m
|
||||
* function name
|
||||
* @param args
|
||||
* arguments to the function
|
||||
* @return the AppleScript string calling the method
|
||||
*/
|
||||
@Override
|
||||
public String getMethodCallSyntax(final String obj, final String fname, final String ... args) {
|
||||
// StringBuilder builder = new StringBuilder();
|
||||
// builder.append("my " + fname + "(");
|
||||
// // TODO -- do
|
||||
// builder.append(")\n");
|
||||
// return builder.toString();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String that can be used as a statement to display the specified String using the syntax of the supported scripting language.
|
||||
*
|
||||
* @param toDisplay
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getOutputStatement(final String toDisplay) {
|
||||
// TODO -- this might even be good enough? XD
|
||||
return getMethodCallSyntax(null, "print", toDisplay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of an attribute whose meaning may be implementation-specific.
|
||||
*
|
||||
* @param key
|
||||
* the key to look up
|
||||
* @return the static preseeded value for the key in the ScriptEngine, if it exists, otherwise <code>null</code>
|
||||
*/
|
||||
@Override
|
||||
public Object getParameter(final String key) {
|
||||
final AppleScriptEngine engine = getScriptEngine();
|
||||
if (!engine.getBindings(ScriptContext.ENGINE_SCOPE).containsKey(key)) return null;
|
||||
return engine.getBindings(ScriptContext.ENGINE_SCOPE).get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns A valid scripting language executable program with given statements.
|
||||
*
|
||||
* @param statements
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getProgram(final String ... statements) {
|
||||
final StringBuilder program = new StringBuilder();
|
||||
for (final String statement : statements) {
|
||||
program.append(statement + "\n");
|
||||
}
|
||||
return program.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the ScriptEngine associated with this ScriptEngineFactory.
|
||||
*
|
||||
* @return new AppleScriptEngine with this factory as it's parent
|
||||
*/
|
||||
@Override
|
||||
public AppleScriptEngine getScriptEngine() {
|
||||
AppleScriptEngine.checkSecurity();
|
||||
ensureInitialized();
|
||||
|
||||
return new AppleScriptEngine(this);
|
||||
}
|
||||
|
||||
private static synchronized void ensureInitialized() {
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
|
||||
java.awt.Toolkit.getDefaultToolkit();
|
||||
System.loadLibrary("AppleScriptEngine");
|
||||
initNative();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,38 +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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
// A 'collection' (responds to -objectEnumerator) is translated to an AS list.
|
||||
// For any other object obj, this returns [[obj description] aeDescriptorValue], mainly
|
||||
// intended for debugging purposes.
|
||||
@interface NSObject (JavaAppleScriptEngineAdditions)
|
||||
- (NSAppleEventDescriptor *) aeDescriptorValue;
|
||||
@end
|
||||
|
||||
@interface NSAppleEventDescriptor (JavaAppleScriptEngineAdditions)
|
||||
- (id) objCObjectValue;
|
||||
@end
|
@ -1,793 +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.
|
||||
*/
|
||||
|
||||
//
|
||||
// Most of this is adapted from Ken Ferry's KFAppleScript Additions, contributed with permission
|
||||
// http://homepage.mac.com/kenferry/software.html
|
||||
//
|
||||
|
||||
#import "AS_NS_ConversionUtils.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
|
||||
@interface NSAppleEventDescriptor (JavaAppleScriptEngineAdditionsPrivate)
|
||||
|
||||
// just returns self. This means that you can pass custom descriptors
|
||||
// to -[NSAppleScript executeHandler:error:withParameters:].
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue;
|
||||
|
||||
// working with primitive descriptor types
|
||||
+ (id)descriptorWithInt16:(SInt16)val;
|
||||
- (SInt16)int16Value;
|
||||
+ (id)descriptorWithUnsignedInt32:(UInt32)val;
|
||||
- (UInt32)unsignedInt32Value;
|
||||
+ (id)descriptorWithFloat32:(Float32)val;
|
||||
- (Float32)float32Value;
|
||||
+ (id)descriptorWithFloat64:(Float64)val;
|
||||
- (Float64)float64Value;
|
||||
+ (id)descriptorWithLongDateTime:(LongDateTime)val;
|
||||
- (LongDateTime)longDateTimeValue;
|
||||
|
||||
|
||||
// These are the methods for converting AS objects to objective-C objects.
|
||||
// -[NSAppleEventDescriptor objCObjectValue] is the general method for converting
|
||||
// AS objects to ObjC objects, and is called by -[NSAppleScript executeHandler:error:withParameters:].
|
||||
// It does no work itself. It finds a handler based on the type of the descriptor and lets that
|
||||
// handler object do the work. If there is no handler type registered for a the type of a descriptor,
|
||||
// the raw descriptor is returned.
|
||||
//
|
||||
// You can designate a handlers for descriptor types with
|
||||
// +[NSAppleEventDescriptor registerConversionHandler:selector:forDescriptorTypes:]. Please note
|
||||
// that this method does _not_ retain the handler object (for now anyway). The selector should
|
||||
// take a single argument, a descriptor to translate, and should return an object. An example such
|
||||
// selector is @selector(dictionaryWithAEDesc:), for which the handler object would be [NSDictionary class].
|
||||
//
|
||||
// A number of handlers are designated by default. The methods and objects can be easily inferred (or check
|
||||
// the implementation), but the automatically handled types are
|
||||
// typeUnicodeText,
|
||||
// typeText,
|
||||
// typeUTF8Text,
|
||||
// typeCString,
|
||||
// typeChar,
|
||||
// typeBoolean,
|
||||
// typeTrue,
|
||||
// typeFalse,
|
||||
// typeSInt16,
|
||||
// typeSInt32,
|
||||
// typeUInt32,
|
||||
// typeSInt64,
|
||||
// typeIEEE32BitFloatingPoint,
|
||||
// typeIEEE64BitFloatingPoint,
|
||||
// type128BitFloatingPoint,
|
||||
// typeAEList,
|
||||
// typeAERecord,
|
||||
// typeLongDateTime,
|
||||
// typeNull.
|
||||
+ (void)registerConversionHandler:(id)anObject selector:(SEL)aSelector forDescriptorTypes:(DescType)firstType, ...;
|
||||
+ (void) jaseSetUpHandlerDict;
|
||||
@end
|
||||
|
||||
// wrap the NSAppleEventDescriptor string methods
|
||||
@interface NSString (JavaAppleScriptEngineAdditions)
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue;
|
||||
+ (NSString *)stringWithAEDesc:(NSAppleEventDescriptor *)desc;
|
||||
@end
|
||||
|
||||
// wrap the NSAppleEventDescriptor longDateTime methods
|
||||
@interface NSDate (JavaAppleScriptEngineAdditions)
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue;
|
||||
+ (NSDate *)dateWithAEDesc:(NSAppleEventDescriptor *)desc;
|
||||
@end
|
||||
|
||||
// these are fairly complicated methods, due to having to try to match up the various
|
||||
// AS number types (see NSAppleEventDescriptor for the primitive number methods)
|
||||
// with NSNumber variants. For complete behavior it's best to look at the implementation.
|
||||
// Some notes:
|
||||
// NSNumbers created with numberWithBool should be correctly translated to AS booleans and vice versa.
|
||||
// NSNumbers created with large integer types may have to be translated to AS doubles,
|
||||
// so be careful if checking equality (you may have to check equality within epsilon).
|
||||
// Since NSNumbers can't remember if they were created with an unsigned value,
|
||||
// [[NSNumber numberWithUnsignedChar:255] aeDescriptorValue] is going to get you an AS integer
|
||||
// with value -1. If you really need a descriptor with an unsigned value, you'll need to do it
|
||||
// manually using the primitive methods on NSAppleEventDescriptor. The resulting descriptor
|
||||
// can still be passed to AS with -[NSAppleScript executeHandler:error:withParameters:].
|
||||
@interface NSNumber (JavaAppleScriptEngineAdditions)
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue;
|
||||
+ (id)numberWithAEDesc:(NSAppleEventDescriptor *)desc;
|
||||
@end
|
||||
|
||||
// Here we're following the behavior described in the CocoaScripting release note.
|
||||
//
|
||||
// NSPoint -> list of two numbers: {x, y}
|
||||
// NSRange -> list of two numbers: {begin offset, end offset}
|
||||
// NSRect -> list of four numbers: {left, bottom, right, top}
|
||||
// NSSize -> list of two numbers: {width, height}
|
||||
@interface NSValue (JavaAppleScriptEngineAdditions)
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue;
|
||||
@end
|
||||
|
||||
// No need for ObjC -> AS conversion here, we fall through to NSObject as a collection.
|
||||
// For AS -> ObjC conversion, we build an array using the primitive list methods on
|
||||
// NSAppleEventDescriptor.
|
||||
@interface NSArray (JavaAppleScriptEngineAdditions)
|
||||
+ (NSArray *)arrayWithAEDesc:(NSAppleEventDescriptor *)desc;
|
||||
@end
|
||||
|
||||
|
||||
// Please see the CocoaScripting release note for behavior. It's kind of complicated.
|
||||
//
|
||||
// methods wrap the primitive record methods on NSAppleEventDescriptor.
|
||||
@interface NSDictionary (JavaAppleScriptEngineAdditions)
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue;
|
||||
+ (NSDictionary *)dictionaryWithAEDesc:(NSAppleEventDescriptor *)desc;
|
||||
@end
|
||||
|
||||
// be aware that a null descriptor does not correspond to the 'null' keyword in
|
||||
// AppleScript - it's more like nothing at all. For example, the return
|
||||
// from an empty handler.
|
||||
@interface NSNull (JavaAppleScriptEngineAdditions)
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue;
|
||||
+ (NSNull *)nullWithAEDesc:(NSAppleEventDescriptor *)desc;
|
||||
@end
|
||||
|
||||
|
||||
@interface NSNumber (JavaAppleScriptEngineAdditionsPrivate)
|
||||
+ (id) jaseNumberWithSignedIntP:(void *)int_p byteCount:(int)bytes;
|
||||
+ (id) jaseNumberWithUnsignedIntP:(void *)int_p byteCount:(int)bytes;
|
||||
+ (id) jaseNumberWithFloatP:(void *)float_p byteCount:(int)bytes;
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSObject (JavaAppleScriptEngineAdditions)
|
||||
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue {
|
||||
// collections go to lists
|
||||
if (![self respondsToSelector:@selector(objectEnumerator)]) {
|
||||
// encode the description as a fallback - this is pretty useless, only helpful for debugging
|
||||
return [[self description] aeDescriptorValue];
|
||||
}
|
||||
|
||||
NSAppleEventDescriptor *resultDesc = [NSAppleEventDescriptor listDescriptor];
|
||||
NSEnumerator *objectEnumerator = [(id)self objectEnumerator];
|
||||
|
||||
unsigned int i = 1; // apple event descriptors are 1-indexed
|
||||
id currentObject;
|
||||
while((currentObject = [objectEnumerator nextObject]) != nil) {
|
||||
[resultDesc insertDescriptor:[currentObject aeDescriptorValue] atIndex:i++];
|
||||
}
|
||||
|
||||
return resultDesc;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSArray (JavaAppleScriptEngineAdditions)
|
||||
|
||||
// don't need to override aeDescriptorValue, the NSObject will treat the array as a collection
|
||||
+ (NSArray *)arrayWithAEDesc:(NSAppleEventDescriptor *)desc {
|
||||
NSAppleEventDescriptor *listDesc = [desc coerceToDescriptorType:typeAEList];
|
||||
NSMutableArray *resultArray = [NSMutableArray array];
|
||||
|
||||
// apple event descriptors are 1-indexed
|
||||
unsigned int listCount = [listDesc numberOfItems];
|
||||
unsigned int i;
|
||||
for (i = 1; i <= listCount; i++) {
|
||||
[resultArray addObject:[[listDesc descriptorAtIndex:i] objCObjectValue]];
|
||||
}
|
||||
|
||||
return resultArray;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSDictionary (JavaAppleScriptEngineAdditions)
|
||||
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue {
|
||||
NSAppleEventDescriptor *resultDesc = [NSAppleEventDescriptor recordDescriptor];
|
||||
NSMutableArray *userFields = [NSMutableArray array];
|
||||
NSArray *keys = [self allKeys];
|
||||
|
||||
unsigned int keyCount = [keys count];
|
||||
unsigned int i;
|
||||
for (i = 0; i < keyCount; i++) {
|
||||
id key = [keys objectAtIndex:i];
|
||||
|
||||
if ([key isKindOfClass:[NSNumber class]]) {
|
||||
[resultDesc setDescriptor:[[self objectForKey:key] aeDescriptorValue] forKeyword:[(NSNumber *)key intValue]];
|
||||
} else if ([key isKindOfClass:[NSString class]]) {
|
||||
[userFields addObject:key];
|
||||
[userFields addObject:[self objectForKey:key]];
|
||||
}
|
||||
}
|
||||
|
||||
if ([userFields count] > 0) {
|
||||
[resultDesc setDescriptor:[userFields aeDescriptorValue] forKeyword:keyASUserRecordFields];
|
||||
}
|
||||
|
||||
return resultDesc;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)dictionaryWithAEDesc:(NSAppleEventDescriptor *)desc {
|
||||
NSAppleEventDescriptor *recDescriptor = [desc coerceToDescriptorType:typeAERecord];
|
||||
NSMutableDictionary *resultDict = [NSMutableDictionary dictionary];
|
||||
|
||||
// NSAppleEventDescriptor uses 1 indexing
|
||||
unsigned int recordCount = [recDescriptor numberOfItems];
|
||||
unsigned int recordIndex;
|
||||
for (recordIndex = 1; recordIndex <= recordCount; recordIndex++) {
|
||||
AEKeyword keyword = [recDescriptor keywordForDescriptorAtIndex:recordIndex];
|
||||
|
||||
if(keyword == keyASUserRecordFields) {
|
||||
NSAppleEventDescriptor *listDescriptor = [recDescriptor descriptorAtIndex:recordIndex];
|
||||
|
||||
// NSAppleEventDescriptor uses 1 indexing
|
||||
unsigned int listCount = [listDescriptor numberOfItems];
|
||||
unsigned int listIndex;
|
||||
for (listIndex = 1; listIndex <= listCount; listIndex += 2) {
|
||||
id keyObj = [[listDescriptor descriptorAtIndex:listIndex] objCObjectValue];
|
||||
id valObj = [[listDescriptor descriptorAtIndex:listIndex+1] objCObjectValue];
|
||||
|
||||
[resultDict setObject:valObj forKey:keyObj];
|
||||
}
|
||||
} else {
|
||||
id keyObj = [NSNumber numberWithInt:keyword];
|
||||
id valObj = [[recDescriptor descriptorAtIndex:recordIndex] objCObjectValue];
|
||||
|
||||
[resultDict setObject:valObj forKey:keyObj];
|
||||
}
|
||||
}
|
||||
|
||||
return resultDict;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSString (JavaAppleScriptEngineAdditions)
|
||||
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue {
|
||||
return [NSAppleEventDescriptor descriptorWithString:self];
|
||||
}
|
||||
|
||||
+ (NSString *)stringWithAEDesc:(NSAppleEventDescriptor *)desc {
|
||||
return [desc stringValue];
|
||||
}
|
||||
|
||||
+ (NSString *)versionWithAEDesc:(NSAppleEventDescriptor *)desc {
|
||||
const AEDesc *aeDesc = [desc aeDesc];
|
||||
VersRec v;
|
||||
AEGetDescData(aeDesc, &v, sizeof(v));
|
||||
return [[[NSString alloc] initWithBytes:&v.shortVersion[1] length:StrLength(v.shortVersion) encoding:NSUTF8StringEncoding] autorelease];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSNull (JavaAppleScriptEngineAdditions)
|
||||
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue {
|
||||
return [NSAppleEventDescriptor nullDescriptor];
|
||||
}
|
||||
|
||||
+ (NSNull *)nullWithAEDesc:(NSAppleEventDescriptor *)desc {
|
||||
return [NSNull null];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSDate (JavaAppleScriptEngineAdditions)
|
||||
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue {
|
||||
LongDateTime ldt;
|
||||
UCConvertCFAbsoluteTimeToLongDateTime(CFDateGetAbsoluteTime((CFDateRef)self), &ldt);
|
||||
return [NSAppleEventDescriptor descriptorWithLongDateTime:ldt];
|
||||
}
|
||||
|
||||
+ (NSDate *)dateWithAEDesc:(NSAppleEventDescriptor *)desc {
|
||||
CFAbsoluteTime absTime;
|
||||
UCConvertLongDateTimeToCFAbsoluteTime([desc longDateTimeValue], &absTime);
|
||||
NSDate *resultDate = (NSDate *)CFDateCreate(NULL, absTime);
|
||||
return [resultDate autorelease];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
static inline int areEqualEncodings(const char *enc1, const char *enc2) {
|
||||
return (strcmp(enc1, enc2) == 0);
|
||||
}
|
||||
|
||||
@implementation NSNumber (JavaAppleScriptEngineAdditions)
|
||||
|
||||
-(id)jaseDescriptorValueWithFloatP:(void *)float_p byteCount:(int)bytes {
|
||||
float floatVal;
|
||||
if (bytes < sizeof(Float32)) {
|
||||
floatVal = [self floatValue];
|
||||
float_p = &floatVal;
|
||||
bytes = sizeof(floatVal);
|
||||
}
|
||||
|
||||
double doubleVal;
|
||||
if (bytes > sizeof(Float64)) {
|
||||
doubleVal = [self doubleValue];
|
||||
float_p = &doubleVal;
|
||||
bytes = sizeof(doubleVal);
|
||||
}
|
||||
|
||||
if (bytes == sizeof(Float32)) {
|
||||
return [NSAppleEventDescriptor descriptorWithFloat32:*(Float32 *)float_p];
|
||||
}
|
||||
|
||||
if (bytes == sizeof(Float64)) {
|
||||
return [NSAppleEventDescriptor descriptorWithFloat64:*(Float64 *)float_p];
|
||||
}
|
||||
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"Cannot create an NSAppleEventDescriptor for float with %d bytes of data.", bytes];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
-(id)jaseDescriptorValueWithSignedIntP:(void *)int_p byteCount:(int)bytes {
|
||||
int intVal;
|
||||
|
||||
if (bytes < sizeof(SInt16)) {
|
||||
intVal = [self intValue];
|
||||
int_p = &intVal;
|
||||
bytes = sizeof(intVal);
|
||||
}
|
||||
|
||||
if (bytes == sizeof(SInt16)) {
|
||||
return [NSAppleEventDescriptor descriptorWithInt16:*(SInt16 *)int_p];
|
||||
}
|
||||
|
||||
if (bytes == sizeof(SInt32)) {
|
||||
return [NSAppleEventDescriptor descriptorWithInt32:*(SInt32 *)int_p];
|
||||
}
|
||||
|
||||
double val = [self doubleValue];
|
||||
return [self jaseDescriptorValueWithFloatP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
-(id)jaseDescriptorValueWithUnsignedIntP:(void *)int_p byteCount:(int)bytes {
|
||||
unsigned int uIntVal;
|
||||
|
||||
if (bytes < sizeof(UInt32)) {
|
||||
uIntVal = [self unsignedIntValue];
|
||||
int_p = &uIntVal;
|
||||
bytes = sizeof(uIntVal);
|
||||
}
|
||||
|
||||
if (bytes == sizeof(UInt32)) {
|
||||
return [NSAppleEventDescriptor descriptorWithUnsignedInt32:*(UInt32 *)int_p];
|
||||
}
|
||||
|
||||
double val = (double)[self unsignedLongLongValue];
|
||||
return [self jaseDescriptorValueWithFloatP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue {
|
||||
// NSNumber is unfortunately complicated, because the applescript
|
||||
// type we should use depends on the c type that our NSNumber corresponds to
|
||||
|
||||
const char *type = [self objCType];
|
||||
|
||||
// convert
|
||||
if (areEqualEncodings(type, @encode(BOOL))) {
|
||||
return [NSAppleEventDescriptor descriptorWithBoolean:[self boolValue]];
|
||||
}
|
||||
|
||||
if (areEqualEncodings(type, @encode(char))) {
|
||||
char val = [self charValue];
|
||||
return [self jaseDescriptorValueWithSignedIntP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
if (areEqualEncodings(type, @encode(short))) {
|
||||
short val = [self shortValue];
|
||||
return [self jaseDescriptorValueWithSignedIntP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
if (areEqualEncodings(type, @encode(int))) {
|
||||
int val = [self intValue];
|
||||
return [self jaseDescriptorValueWithSignedIntP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
if (areEqualEncodings(type, @encode(long))) {
|
||||
long val = [self longValue];
|
||||
return [self jaseDescriptorValueWithSignedIntP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
if (areEqualEncodings(type, @encode(long long))) {
|
||||
long long val = [self longLongValue];
|
||||
return [self jaseDescriptorValueWithSignedIntP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
if (areEqualEncodings(type, @encode(unsigned char))) {
|
||||
unsigned char val = [self unsignedCharValue];
|
||||
return [self jaseDescriptorValueWithUnsignedIntP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
if (areEqualEncodings(type, @encode(unsigned short))) {
|
||||
unsigned short val = [self unsignedShortValue];
|
||||
return [self jaseDescriptorValueWithUnsignedIntP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
if (areEqualEncodings(type, @encode(unsigned int))) {
|
||||
unsigned int val = [self unsignedIntValue];
|
||||
return [self jaseDescriptorValueWithUnsignedIntP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
if (areEqualEncodings(type, @encode(unsigned long))) {
|
||||
unsigned long val = [self unsignedLongValue];
|
||||
return [self jaseDescriptorValueWithUnsignedIntP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
if (areEqualEncodings(type, @encode(unsigned long long))) {
|
||||
unsigned long long val = [self unsignedLongLongValue];
|
||||
return [self jaseDescriptorValueWithUnsignedIntP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
if (areEqualEncodings(type, @encode(float))) {
|
||||
float val = [self floatValue];
|
||||
return [self jaseDescriptorValueWithFloatP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
if (areEqualEncodings(type, @encode(double))) {
|
||||
double val = [self doubleValue];
|
||||
return [self jaseDescriptorValueWithFloatP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
[NSException raise:@"jaseUnsupportedAEDescriptorConversion"
|
||||
format:@"JavaAppleScriptEngineAdditions: conversion of an NSNumber with objCType '%s' to an aeDescriptor is not supported.", type];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (id)numberWithAEDesc:(NSAppleEventDescriptor *)desc {
|
||||
DescType type = [desc descriptorType];
|
||||
|
||||
if ((type == typeTrue) || (type == typeFalse) || (type == typeBoolean)) {
|
||||
return [NSNumber numberWithBool:[desc booleanValue]];
|
||||
}
|
||||
|
||||
if (type == typeSInt16) {
|
||||
SInt16 val = [desc int16Value];
|
||||
return [NSNumber jaseNumberWithSignedIntP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
if (type == typeSInt32) {
|
||||
SInt32 val = [desc int32Value];
|
||||
return [NSNumber jaseNumberWithSignedIntP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
if (type == typeUInt32) {
|
||||
UInt32 val = [desc unsignedInt32Value];
|
||||
return [NSNumber jaseNumberWithUnsignedIntP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
if (type == typeIEEE32BitFloatingPoint) {
|
||||
Float32 val = [desc float32Value];
|
||||
return [NSNumber jaseNumberWithFloatP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
if (type == typeIEEE64BitFloatingPoint) {
|
||||
Float64 val = [desc float64Value];
|
||||
return [NSNumber jaseNumberWithFloatP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
// try to coerce to 64bit floating point
|
||||
desc = [desc coerceToDescriptorType:typeIEEE64BitFloatingPoint];
|
||||
if (desc != nil) {
|
||||
Float64 val = [desc float64Value];
|
||||
return [NSNumber jaseNumberWithFloatP:&val byteCount:sizeof(val)];
|
||||
}
|
||||
|
||||
[NSException raise:@"jaseUnsupportedAEDescriptorConversion"
|
||||
format:@"JavaAppleScriptEngineAdditions: conversion of an NSAppleEventDescriptor with objCType '%s' to an aeDescriptor is not supported.", type];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (id) jaseNumberWithSignedIntP:(void *)int_p byteCount:(int)bytes {
|
||||
if (bytes == sizeof(char)) {
|
||||
return [NSNumber numberWithChar:*(char *)int_p];
|
||||
}
|
||||
|
||||
if (bytes == sizeof(short)) {
|
||||
return [NSNumber numberWithShort:*(short *)int_p];
|
||||
}
|
||||
|
||||
if (bytes == sizeof(int)) {
|
||||
return [NSNumber numberWithInt:*(int *)int_p];
|
||||
}
|
||||
|
||||
if (bytes == sizeof(long)) {
|
||||
return [NSNumber numberWithLong:*(long *)int_p];
|
||||
}
|
||||
|
||||
if (bytes == sizeof(long long)) {
|
||||
return [NSNumber numberWithLongLong:*(long long *)int_p];
|
||||
}
|
||||
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"NSNumber jaseNumberWithSignedIntP:byteCount: number with %i bytes not supported.", bytes];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (id) jaseNumberWithUnsignedIntP:(void *)int_p byteCount:(int)bytes {
|
||||
if (bytes == sizeof(unsigned char)) {
|
||||
return [NSNumber numberWithUnsignedChar:*(unsigned char *)int_p];
|
||||
}
|
||||
|
||||
if (bytes == sizeof(unsigned short)) {
|
||||
return [NSNumber numberWithUnsignedShort:*(unsigned short *)int_p];
|
||||
}
|
||||
|
||||
if (bytes == sizeof(unsigned int)) {
|
||||
return [NSNumber numberWithUnsignedInt:*(unsigned int *)int_p];
|
||||
}
|
||||
|
||||
if (bytes == sizeof(unsigned long)) {
|
||||
return [NSNumber numberWithUnsignedLong:*(unsigned long *)int_p];
|
||||
}
|
||||
|
||||
if (bytes == sizeof(unsigned long long)) {
|
||||
return [NSNumber numberWithUnsignedLongLong:*(unsigned long long *)int_p];
|
||||
}
|
||||
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"NSNumber numberWithUnsignedInt:byteCount: number with %i bytes not supported.", bytes];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (id) jaseNumberWithFloatP:(void *)float_p byteCount:(int)bytes {
|
||||
if (bytes == sizeof(float)) {
|
||||
return [NSNumber numberWithFloat:*(float *)float_p];
|
||||
}
|
||||
|
||||
if (bytes == sizeof(double)) {
|
||||
return [NSNumber numberWithFloat:*(double *)float_p];
|
||||
}
|
||||
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"NSNumber numberWithFloat:byteCount: floating point number with %i bytes not supported.", bytes];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSValue (JavaAppleScriptEngineAdditions)
|
||||
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue {
|
||||
const char *type = [self objCType];
|
||||
|
||||
if (areEqualEncodings(type, @encode(NSSize))) {
|
||||
NSSize size = [self sizeValue];
|
||||
return [[NSArray arrayWithObjects:
|
||||
[NSNumber numberWithFloat:size.width],
|
||||
[NSNumber numberWithFloat:size.height], nil] aeDescriptorValue];
|
||||
}
|
||||
|
||||
if (areEqualEncodings(type, @encode(NSPoint))) {
|
||||
NSPoint point = [self pointValue];
|
||||
return [[NSArray arrayWithObjects:
|
||||
[NSNumber numberWithFloat:point.x],
|
||||
[NSNumber numberWithFloat:point.y], nil] aeDescriptorValue];
|
||||
}
|
||||
|
||||
if (areEqualEncodings(type, @encode(NSRange))) {
|
||||
NSRange range = [self rangeValue];
|
||||
return [[NSArray arrayWithObjects:
|
||||
[NSNumber numberWithUnsignedInt:range.location],
|
||||
[NSNumber numberWithUnsignedInt:range.location + range.length], nil] aeDescriptorValue];
|
||||
}
|
||||
|
||||
if (areEqualEncodings(type, @encode(NSRect))) {
|
||||
NSRect rect = [self rectValue];
|
||||
return [[NSArray arrayWithObjects:
|
||||
[NSNumber numberWithFloat:rect.origin.x],
|
||||
[NSNumber numberWithFloat:rect.origin.y],
|
||||
[NSNumber numberWithFloat:rect.origin.x + rect.size.width],
|
||||
[NSNumber numberWithFloat:rect.origin.y + rect.size.height], nil] aeDescriptorValue];
|
||||
}
|
||||
|
||||
[NSException raise:@"jaseUnsupportedAEDescriptorConversion"
|
||||
format:@"JavaAppleScriptEngineAdditions: conversion of an NSNumber with objCType '%s' to an aeDescriptor is not supported.", type];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSImage (JavaAppleScriptEngineAdditions)
|
||||
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue {
|
||||
NSData *data = [self TIFFRepresentation];
|
||||
return [NSAppleEventDescriptor descriptorWithDescriptorType:typeTIFF data:data];
|
||||
}
|
||||
|
||||
+ (NSImage *)imageWithAEDesc:(NSAppleEventDescriptor *)desc {
|
||||
const AEDesc *d = [desc aeDesc];
|
||||
NSMutableData *data = [NSMutableData dataWithLength:AEGetDescDataSize(d)];
|
||||
AEGetDescData(d, [data mutableBytes], [data length]);
|
||||
return [[[NSImage alloc] initWithData:data] autorelease];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@implementation NSAppleEventDescriptor (JavaAppleScriptEngineAdditions)
|
||||
|
||||
// we're going to leak this. It doesn't matter much for running apps, but
|
||||
// for developers it might be nice to try to dispose of it (so it would not clutter the
|
||||
// output when testing for leaks)
|
||||
static NSMutableDictionary *handlerDict = nil;
|
||||
|
||||
- (id)objCObjectValue {
|
||||
if (handlerDict == nil) [NSAppleEventDescriptor jaseSetUpHandlerDict];
|
||||
|
||||
id returnObj;
|
||||
DescType type = [self descriptorType];
|
||||
NSInvocation *handlerInvocation = [handlerDict objectForKey:[NSValue valueWithBytes:&type objCType:@encode(DescType)]];
|
||||
if (handlerInvocation == nil) {
|
||||
if (type == typeType) {
|
||||
DescType subType;
|
||||
AEGetDescData([self aeDesc], &subType, sizeof(subType));
|
||||
if (subType == typeNull) return [NSNull null];
|
||||
}
|
||||
// return raw apple event descriptor if no handler is registered
|
||||
returnObj = self;
|
||||
} else {
|
||||
[handlerInvocation setArgument:&self atIndex:2];
|
||||
[handlerInvocation invoke];
|
||||
[handlerInvocation getReturnValue:&returnObj];
|
||||
}
|
||||
|
||||
return returnObj;
|
||||
}
|
||||
|
||||
// FIXME - error checking, non nil handler
|
||||
+ (void)registerConversionHandler:(id)anObject selector:(SEL)aSelector forDescriptorTypes:(DescType)firstType, ... {
|
||||
if (handlerDict == nil) [NSAppleEventDescriptor jaseSetUpHandlerDict];
|
||||
|
||||
NSInvocation *handlerInvocation = [NSInvocation invocationWithMethodSignature:[anObject methodSignatureForSelector:aSelector]];
|
||||
[handlerInvocation setTarget:anObject];
|
||||
[handlerInvocation setSelector:aSelector];
|
||||
|
||||
DescType aType = firstType;
|
||||
va_list typesList;
|
||||
va_start(typesList, firstType);
|
||||
do {
|
||||
NSValue *type = [NSValue valueWithBytes:&aType objCType:@encode(DescType)];
|
||||
[handlerDict setObject:handlerInvocation forKey:type];
|
||||
} while((aType = va_arg(typesList, DescType)) != 0);
|
||||
va_end(typesList);
|
||||
}
|
||||
|
||||
|
||||
- (NSAppleEventDescriptor *)aeDescriptorValue {
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (id)descriptorWithInt16:(SInt16)val {
|
||||
return [NSAppleEventDescriptor descriptorWithDescriptorType:typeSInt16 bytes:&val length:sizeof(val)];
|
||||
}
|
||||
|
||||
- (SInt16)int16Value {
|
||||
SInt16 retValue;
|
||||
[[[self coerceToDescriptorType:typeSInt16] data] getBytes:&retValue];
|
||||
return retValue;
|
||||
}
|
||||
|
||||
+ (id)descriptorWithUnsignedInt32:(UInt32)val {
|
||||
return [NSAppleEventDescriptor descriptorWithDescriptorType:typeUInt32 bytes:&val length:sizeof(val)];
|
||||
}
|
||||
|
||||
- (UInt32)unsignedInt32Value {
|
||||
UInt32 retValue;
|
||||
[[[self coerceToDescriptorType:typeUInt32] data] getBytes:&retValue];
|
||||
return retValue;
|
||||
}
|
||||
|
||||
|
||||
+ (id)descriptorWithFloat32:(Float32)val {
|
||||
return [NSAppleEventDescriptor descriptorWithDescriptorType:typeIEEE32BitFloatingPoint bytes:&val length:sizeof(val)];
|
||||
}
|
||||
|
||||
- (Float32)float32Value {
|
||||
Float32 retValue;
|
||||
[[[self coerceToDescriptorType:typeIEEE32BitFloatingPoint] data] getBytes:&retValue];
|
||||
return retValue;
|
||||
}
|
||||
|
||||
|
||||
+ (id)descriptorWithFloat64:(Float64)val {
|
||||
return [NSAppleEventDescriptor descriptorWithDescriptorType:typeIEEE64BitFloatingPoint bytes:&val length:sizeof(val)];
|
||||
}
|
||||
|
||||
- (Float64)float64Value {
|
||||
Float64 retValue;
|
||||
[[[self coerceToDescriptorType:typeIEEE64BitFloatingPoint] data] getBytes:&retValue];
|
||||
return retValue;
|
||||
}
|
||||
|
||||
+ (id)descriptorWithLongDateTime:(LongDateTime)val {
|
||||
return [NSAppleEventDescriptor descriptorWithDescriptorType:typeLongDateTime bytes:&val length:sizeof(val)];
|
||||
}
|
||||
|
||||
- (LongDateTime)longDateTimeValue {
|
||||
LongDateTime retValue;
|
||||
[[[self coerceToDescriptorType:typeLongDateTime] data] getBytes:&retValue];
|
||||
return retValue;
|
||||
}
|
||||
|
||||
+ (void)jaseSetUpHandlerDict {
|
||||
handlerDict = [[NSMutableDictionary alloc] init];
|
||||
|
||||
// register default handlers
|
||||
// types are culled from AEDataModel.h and AERegistry.h
|
||||
|
||||
// string -> NSStrings
|
||||
[NSAppleEventDescriptor registerConversionHandler:[NSString class] selector:@selector(stringWithAEDesc:) forDescriptorTypes:
|
||||
typeUnicodeText, typeText, typeUTF8Text, typeCString, typeChar, nil];
|
||||
|
||||
// number/bool -> NSNumber
|
||||
[NSAppleEventDescriptor registerConversionHandler:[NSNumber class] selector:@selector(numberWithAEDesc:) forDescriptorTypes:
|
||||
typeBoolean, typeTrue, typeFalse,
|
||||
typeSInt16, typeSInt32, typeUInt32, typeSInt64,
|
||||
typeIEEE32BitFloatingPoint, typeIEEE64BitFloatingPoint, type128BitFloatingPoint, nil];
|
||||
|
||||
// list -> NSArray
|
||||
[NSAppleEventDescriptor registerConversionHandler:[NSArray class] selector:@selector(arrayWithAEDesc:) forDescriptorTypes:typeAEList, nil];
|
||||
|
||||
// record -> NSDictionary
|
||||
[NSAppleEventDescriptor registerConversionHandler:[NSDictionary class] selector:@selector(dictionaryWithAEDesc:) forDescriptorTypes:typeAERecord, nil];
|
||||
|
||||
// date -> NSDate
|
||||
[NSAppleEventDescriptor registerConversionHandler:[NSDate class] selector:@selector(dateWithAEDesc:) forDescriptorTypes:typeLongDateTime, nil];
|
||||
|
||||
// images -> NSImage
|
||||
[NSAppleEventDescriptor registerConversionHandler:[NSImage class] selector:@selector(imageWithAEDesc:) forDescriptorTypes:
|
||||
typeTIFF, typeJPEG, typeGIF, typePict, typeIconFamily, typeIconAndMask, nil];
|
||||
|
||||
// vers -> NSString
|
||||
[NSAppleEventDescriptor registerConversionHandler:[NSString class] selector:@selector(versionWithAEDesc:) forDescriptorTypes:typeVersion, nil];
|
||||
|
||||
// null -> NSNull
|
||||
[NSAppleEventDescriptor registerConversionHandler:[NSNull class] selector:@selector(nullWithAEDesc:) forDescriptorTypes:typeNull, nil];
|
||||
}
|
||||
|
||||
@end
|
@ -1,199 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 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.
|
||||
*/
|
||||
|
||||
#import "apple_applescript_AppleScriptEngine.h"
|
||||
#import "apple_applescript_AppleScriptEngineFactory.h"
|
||||
|
||||
// Must include this before JavaNativeFoundation.h to get jni.h from build
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
|
||||
#import "NS_Java_ConversionUtils.h"
|
||||
#import "AppleScriptExecutionContext.h"
|
||||
|
||||
//#define DEBUG 1
|
||||
|
||||
/*
|
||||
* Declare library specific JNI_Onload entry if static build
|
||||
*/
|
||||
DEF_STATIC_JNI_OnLoad
|
||||
|
||||
/*
|
||||
* Class: apple_applescript_AppleScriptEngineFactory
|
||||
* Method: initNative
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_apple_applescript_AppleScriptEngineFactory_initNative
|
||||
(JNIEnv *env, jclass clazz)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: apple_applescript_AppleScriptEngine
|
||||
* Method: initNative
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_apple_applescript_AppleScriptEngine_initNative
|
||||
(JNIEnv *env, jclass clazz)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: apple_applescript_AppleScriptEngine
|
||||
* Method: createContextFrom
|
||||
* Signature: (Ljava/lang/Object;)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_apple_applescript_AppleScriptEngine_createContextFrom
|
||||
(JNIEnv *env, jclass clazz, jobject javaContext)
|
||||
{
|
||||
NSObject *obj = nil;
|
||||
|
||||
JNF_COCOA_ENTER(env);
|
||||
|
||||
obj = [[JavaAppleScriptEngineCoercion coercer] coerceJavaObject:javaContext withEnv:env];
|
||||
|
||||
#ifdef DEBUG
|
||||
NSLog(@"converted context: %@", obj);
|
||||
#endif
|
||||
|
||||
CFRetain(obj);
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
|
||||
return ptr_to_jlong(obj);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: apple_applescript_AppleScriptEngine
|
||||
* Method: createObjectFrom
|
||||
* Signature: (J)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_apple_applescript_AppleScriptEngine_createObjectFrom
|
||||
(JNIEnv *env, jclass clazz, jlong nativeContext)
|
||||
{
|
||||
jobject obj = NULL;
|
||||
|
||||
JNF_COCOA_ENTER(env);
|
||||
|
||||
obj = [[JavaAppleScriptEngineCoercion coercer] coerceNSObject:(id)jlong_to_ptr(nativeContext) withEnv:env];
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: apple_applescript_AppleScriptEngine
|
||||
* Method: disposeContext
|
||||
* Signature: (J)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_apple_applescript_AppleScriptEngine_disposeContext
|
||||
(JNIEnv *env, jclass clazz, jlong nativeContext)
|
||||
{
|
||||
|
||||
JNF_COCOA_ENTER(env);
|
||||
|
||||
id obj = (id)jlong_to_ptr(nativeContext);
|
||||
if (obj != nil) CFRelease(obj);
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: apple_applescript_AppleScriptEngine
|
||||
* Method: evalScript
|
||||
* Signature: (Ljava/lang/String;J)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_apple_applescript_AppleScriptEngine_evalScript
|
||||
(JNIEnv *env, jclass clazz, jstring ascript, jlong contextptr)
|
||||
{
|
||||
id retval = nil;
|
||||
|
||||
JNF_COCOA_ENTER(env);
|
||||
|
||||
NSDictionary *ncontext = jlong_to_ptr(contextptr);
|
||||
NSString *source = JNFJavaToNSString(env, ascript);
|
||||
|
||||
#ifdef DEBUG
|
||||
NSLog(@"evalScript(source:\"%@\" context: %@)", source, ncontext);
|
||||
#endif
|
||||
|
||||
AppleScriptExecutionContext *scriptInvocationCtx = [[[AppleScriptExecutionContext alloc] initWithSource:source context:ncontext] autorelease];
|
||||
retval = [scriptInvocationCtx invokeWithEnv:env];
|
||||
|
||||
#ifdef DEBUG
|
||||
NSLog(@"returning: %@", retval);
|
||||
#endif
|
||||
|
||||
if (retval) CFRetain(retval);
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
|
||||
return ptr_to_jlong(retval);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: apple_applescript_AppleScriptEngine
|
||||
* Method: evalScriptFromURL
|
||||
* Signature: (Ljava/lang/String;J)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_apple_applescript_AppleScriptEngine_evalScriptFromURL
|
||||
(JNIEnv *env, jclass clazz, jstring afilename, jlong contextptr)
|
||||
{
|
||||
id retval = nil;
|
||||
|
||||
JNF_COCOA_ENTER(env);
|
||||
|
||||
NSDictionary *ncontext = jlong_to_ptr(contextptr);
|
||||
NSString *filename = JNFJavaToNSString(env, afilename);
|
||||
|
||||
#ifdef DEBUG
|
||||
NSLog(@"evalScript(filename:\"%@\" context: %@)", filename, ncontext);
|
||||
#endif
|
||||
|
||||
AppleScriptExecutionContext *scriptInvocationCtx = [[[AppleScriptExecutionContext alloc] initWithFile:filename context:ncontext] autorelease];
|
||||
retval = [scriptInvocationCtx invokeWithEnv:env];
|
||||
|
||||
#ifdef DEBUG
|
||||
NSLog(@"returning: %@", retval);
|
||||
#endif
|
||||
|
||||
if (retval) CFRetain(retval);
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
|
||||
return ptr_to_jlong(retval);
|
||||
}
|
@ -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.
|
||||
*/
|
||||
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
|
||||
|
||||
@interface AppleScriptExecutionContext : NSObject {
|
||||
NSString *source;
|
||||
BOOL isFile;
|
||||
NSDictionary *context;
|
||||
NSDictionary *error;
|
||||
id returnValue;
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) NSString *source;
|
||||
@property (nonatomic, retain) NSDictionary *context;
|
||||
@property (nonatomic, retain) NSDictionary *error;
|
||||
@property (nonatomic, retain) id returnValue;
|
||||
|
||||
- (id) initWithSource:(NSString *)source context:(NSDictionary *)context;
|
||||
- (id) initWithFile:(NSString *)filename context:(NSDictionary *)context;
|
||||
- (id) invokeWithEnv:(JNIEnv *)env;
|
||||
|
||||
@end
|
@ -1,165 +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.
|
||||
*/
|
||||
|
||||
#import "AppleScriptExecutionContext.h"
|
||||
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
#import "AS_NS_ConversionUtils.h"
|
||||
|
||||
|
||||
@implementation AppleScriptExecutionContext
|
||||
|
||||
@synthesize source;
|
||||
@synthesize context;
|
||||
@synthesize error;
|
||||
@synthesize returnValue;
|
||||
|
||||
- (id) init:(NSString *)sourceIn context:(id)contextIn {
|
||||
self = [super init];
|
||||
if (!self) return self;
|
||||
|
||||
self.source = sourceIn;
|
||||
self.context = contextIn;
|
||||
self.returnValue = nil;
|
||||
self.error = nil;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithSource:(NSString *)sourceIn context:(NSDictionary *)contextIn {
|
||||
self = [self init:sourceIn context:contextIn];
|
||||
isFile = NO;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithFile:(NSString *)filenameIn context:(NSDictionary *)contextIn {
|
||||
self = [self init:filenameIn context:contextIn];
|
||||
isFile = YES;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc {
|
||||
self.source = nil;
|
||||
self.context = nil;
|
||||
self.returnValue = nil;
|
||||
self.error = nil;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSAppleScript *) scriptFromURL {
|
||||
NSURL *url = [NSURL URLWithString:source];
|
||||
NSDictionary *err = nil;
|
||||
NSAppleScript *script = [[[NSAppleScript alloc] initWithContentsOfURL:url error:(&err)] autorelease];
|
||||
if (err != nil) self.error = err;
|
||||
return script;
|
||||
}
|
||||
|
||||
- (NSAppleScript *) scriptFromSource {
|
||||
return [[[NSAppleScript alloc] initWithSource:source] autorelease];
|
||||
}
|
||||
|
||||
- (NSAppleEventDescriptor *) functionInvocationEvent {
|
||||
NSString *function = [[context objectForKey:@"javax_script_function"] description];
|
||||
if (function == nil) return nil;
|
||||
|
||||
// wrap the arg in an array if it is not already a list
|
||||
id args = [context objectForKey:@"javax_script_argv"];
|
||||
if (![args isKindOfClass:[NSArray class]]) {
|
||||
args = [NSArray arrayWithObjects:args, nil];
|
||||
}
|
||||
|
||||
// triangulate our target
|
||||
int pid = [[NSProcessInfo processInfo] processIdentifier];
|
||||
NSAppleEventDescriptor* targetAddress = [NSAppleEventDescriptor descriptorWithDescriptorType:typeKernelProcessID
|
||||
bytes:&pid
|
||||
length:sizeof(pid)];
|
||||
|
||||
// create the event to call a subroutine in the script
|
||||
NSAppleEventDescriptor* event = [[NSAppleEventDescriptor alloc] initWithEventClass:kASAppleScriptSuite
|
||||
eventID:kASSubroutineEvent
|
||||
targetDescriptor:targetAddress
|
||||
returnID:kAutoGenerateReturnID
|
||||
transactionID:kAnyTransactionID];
|
||||
|
||||
// set up the handler
|
||||
NSAppleEventDescriptor* subroutineDescriptor = [NSAppleEventDescriptor descriptorWithString:[function lowercaseString]];
|
||||
[event setParamDescriptor:subroutineDescriptor forKeyword:keyASSubroutineName];
|
||||
|
||||
// set up the arguments
|
||||
[event setParamDescriptor:[args aeDescriptorValue] forKeyword:keyDirectObject];
|
||||
|
||||
return [event autorelease];
|
||||
}
|
||||
|
||||
- (void) invoke {
|
||||
// create our script
|
||||
NSAppleScript *script = isFile ? [self scriptFromURL] : [self scriptFromSource];
|
||||
if (self.error != nil) return;
|
||||
|
||||
// find out if we have a subroutine to call
|
||||
NSAppleEventDescriptor *fxnInvkEvt = [self functionInvocationEvent];
|
||||
|
||||
// exec!
|
||||
NSAppleEventDescriptor *desc = nil;
|
||||
NSDictionary *err = nil;
|
||||
if (fxnInvkEvt == nil) {
|
||||
desc = [script executeAndReturnError:(&err)];
|
||||
} else {
|
||||
desc = [script executeAppleEvent:fxnInvkEvt error:(&err)];
|
||||
}
|
||||
|
||||
// if we encountered an exception, stash and bail
|
||||
if (err != nil) {
|
||||
self.error = err;
|
||||
return;
|
||||
}
|
||||
|
||||
// convert to NSObjects, and return in ivar
|
||||
self.returnValue = [desc objCObjectValue];
|
||||
}
|
||||
|
||||
- (id) invokeWithEnv:(JNIEnv *)env {
|
||||
BOOL useAnyThread = [@"any-thread" isEqual:[context valueForKey:@"javax_script_threading"]];
|
||||
|
||||
// check if we are already on the AppKit thread, if desired
|
||||
if(pthread_main_np() || useAnyThread) {
|
||||
[self invoke];
|
||||
} else {
|
||||
[JNFRunLoop performOnMainThread:@selector(invoke) on:self withObject:nil waitUntilDone:YES];
|
||||
}
|
||||
|
||||
// if we have an exception parked in our ivar, snarf the message (if there is one), and toss a ScriptException
|
||||
if (self.error != nil) {
|
||||
NSString *asErrString = [self.error objectForKey:NSAppleScriptErrorMessage];
|
||||
if (!asErrString) asErrString = @"AppleScriptEngine failed to execute script."; // usually when we fail to load a file
|
||||
[JNFException raise:env as:"javax/script/ScriptException" reason:[asErrString UTF8String]];
|
||||
}
|
||||
|
||||
return self.returnValue;
|
||||
}
|
||||
|
||||
@end
|
@ -1,33 +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.
|
||||
*/
|
||||
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
|
||||
|
||||
@interface JavaAppleScriptEngineCoercion : NSObject
|
||||
|
||||
+ (JNFTypeCoercer *) coercer;
|
||||
|
||||
@end
|
@ -1,145 +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.
|
||||
*/
|
||||
|
||||
#import "NS_Java_ConversionUtils.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface JavaAppleScriptBaseConverter : NSObject <JNFTypeCoercion>
|
||||
@end
|
||||
|
||||
@interface JavaAppleScriptImageConverter : NSObject <JNFTypeCoercion>
|
||||
@end
|
||||
|
||||
@interface JavaAppleScriptVersionConverter : NSObject <JNFTypeCoercion>
|
||||
@end
|
||||
|
||||
@interface JavaAppleScriptNullConverter : NSObject <JNFTypeCoercion>
|
||||
@end
|
||||
|
||||
|
||||
@implementation JavaAppleScriptEngineCoercion
|
||||
|
||||
static JNFTypeCoercer *appleScriptCoercer = nil;
|
||||
|
||||
+ (JNFTypeCoercer *) coercer {
|
||||
if (appleScriptCoercer) return appleScriptCoercer;
|
||||
|
||||
id asSpecificCoercions = [[JNFDefaultCoercions defaultCoercer] deriveCoercer];
|
||||
[asSpecificCoercions addCoercion:[[[JavaAppleScriptImageConverter alloc] init] autorelease] forNSClass:[NSImage class] javaClass:@"java/awt/Image"];
|
||||
[asSpecificCoercions addCoercion:[[[JavaAppleScriptVersionConverter alloc] init] autorelease] forNSClass:[NSAppleEventDescriptor class] javaClass:nil];
|
||||
[asSpecificCoercions addCoercion:[[[JavaAppleScriptNullConverter alloc] init] autorelease] forNSClass:[NSNull class] javaClass:nil];
|
||||
|
||||
return appleScriptCoercer = [asSpecificCoercions retain];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// [NSObject description] <-> java.lang.Object.toString()
|
||||
@implementation JavaAppleScriptBaseConverter
|
||||
|
||||
// by default, bizzare NSObjects will have -description called on them, and passed back to Java like that
|
||||
- (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
|
||||
return JNFNSToJavaString(env, [obj description]);
|
||||
}
|
||||
|
||||
// by default, bizzare Java objects will be toString()'d and passed to AppleScript like that
|
||||
- (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
|
||||
return JNFObjectToString(env, obj);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// NSImage <-> apple.awt.CImage
|
||||
@implementation JavaAppleScriptImageConverter
|
||||
|
||||
static JNF_CLASS_CACHE(jc_CImage, "apple/awt/CImage");
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_CImage_getCreator, jc_CImage, "getCreator", "()Lapple/awt/CImage$Creator;");
|
||||
static JNF_MEMBER_CACHE(jm_CImage_getNSImage, jc_CImage, "getNSImage", "()J");
|
||||
|
||||
static JNF_CLASS_CACHE(jc_CImage_Generator, "apple/awt/CImage$Creator");
|
||||
static JNF_MEMBER_CACHE(jm_CImage_Generator_createImageFromPtr, jc_CImage_Generator, "createImage", "(J)Ljava/awt/image/BufferedImage;");
|
||||
static JNF_MEMBER_CACHE(jm_CImage_Generator_createImageFromImg, jc_CImage_Generator, "createImage", "(Ljava/awt/Image;)Lapple/awt/CImage;");
|
||||
|
||||
- (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
|
||||
NSImage *img = (NSImage *)obj;
|
||||
CFRetain(img);
|
||||
jobject creator = JNFCallStaticObjectMethod(env, jm_CImage_getCreator);
|
||||
jobject jobj = JNFCallObjectMethod(env, creator, jm_CImage_Generator_createImageFromPtr, ptr_to_jlong(img));
|
||||
return jobj;
|
||||
}
|
||||
|
||||
- (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
|
||||
jobject cimage = obj;
|
||||
if (!JNFIsInstanceOf(env, obj, &jc_CImage)) {
|
||||
jobject creator = JNFCallStaticObjectMethod(env, jm_CImage_getCreator);
|
||||
cimage = JNFCallObjectMethod(env, creator, jm_CImage_Generator_createImageFromImg, obj);
|
||||
}
|
||||
|
||||
jlong nsImagePtr = JNFCallLongMethod(env, cimage, jm_CImage_getNSImage);
|
||||
|
||||
NSImage *img = (NSImage *)jlong_to_ptr(nsImagePtr);
|
||||
return [[img retain] autorelease];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// NSAppleEventDescriptor('vers') -> java.lang.String
|
||||
@implementation JavaAppleScriptVersionConverter
|
||||
|
||||
- (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
|
||||
NSAppleEventDescriptor *desc = (NSAppleEventDescriptor *)obj;
|
||||
|
||||
const AEDesc *aeDesc = [desc aeDesc];
|
||||
if (aeDesc->descriptorType == typeNull) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return JNFNSToJavaString(env, [obj description]);
|
||||
}
|
||||
|
||||
- (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
|
||||
return nil; // there is no Java object that represents a "version"
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// NSNull <-> null
|
||||
@implementation JavaAppleScriptNullConverter
|
||||
|
||||
- (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
@ -35,7 +35,7 @@ import java.security.cert.CertificateException;
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Vincent Ryan
|
||||
* @deprecated This package has been deprecated.
|
||||
* @deprecated This class has been deprecated.
|
||||
*/
|
||||
|
||||
@jdk.Exported
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user