This commit is contained in:
J. Duke 2017-07-05 21:07:16 +02:00
commit 315d4eb3d6
125 changed files with 7652 additions and 2704 deletions

View File

@ -4,6 +4,7 @@ nbproject/private/
^webrev
^.hgtip
^.bridge2
^.jib/
.DS_Store
.metadata/
.recommenders/

View File

@ -338,3 +338,4 @@ cf1dc4c035fb84693d4ae5ad818785cb4d1465d1 jdk9-b90
331fda57dfd323c61804ba0472776790de572937 jdk9-b93
349488425abcaf3ff62f580007860b4b56875d10 jdk9-b94
12a6fb4f070f8ca8fbca219ab9abf5da8908b317 jdk-9+95
5582a79892596169ebddb3e2c2aa44939e4e3f40 jdk-9+96

View File

@ -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],
[

View File

@ -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
###

View File

@ -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

View File

@ -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)
])

View File

@ -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
View 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} "$@"

View File

@ -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
View 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;
};

View File

@ -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

View File

@ -498,3 +498,4 @@ bc48b669bc6610fac97e16593050c0f559cf6945 jdk9-b88
d8b24776484cc4dfd19f50b23eaa18a80a161371 jdk9-b93
a22b7c80529f5f05c847e932e017456e83c46233 jdk9-b94
0c79cf3cdf0904fc4a630b91b32904491e1ae430 jdk-9+95
a94bb7203596dd632486f1e3655fa5f70541dc08 jdk-9+96

View 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>

View 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>

View File

@ -0,0 +1 @@
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=disabled

View 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>

View File

@ -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

View File

@ -0,0 +1,5 @@
#Wed Sep 01 16:21:02 PDT 2010
eclipse.preferences.version=1
formatter_profile=_hotspotStyle
formatter_settings_version=1

View File

@ -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

View 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
View 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"
],
},
},
}

View File

@ -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

View File

@ -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"

View File

@ -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);

View File

@ -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));

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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.

View File

@ -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()) {

View File

@ -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);

View File

@ -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;") \

View File

@ -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, \

View File

@ -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()) {

View File

@ -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

View File

@ -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++);

View File

@ -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; }

View File

@ -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() +

View File

@ -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,

View File

@ -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---------------------------------

View File

@ -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.

View 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));
}
}

View File

@ -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 "";
}
}
}

View File

@ -68,6 +68,7 @@ public class CodeInstallerTest {
}
protected void installCode(CompilationResult result) {
result.close();
codeCache.addCode(dummyMethod, result, null, null);
}

View File

@ -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();

View File

@ -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,

View File

@ -338,3 +338,4 @@ b433e4dfb830fea60e5187e4580791b62cc362d2 jdk9-b90
2f12392d0dde768150c83087cdbdd0d33a4d866c jdk9-b93
559b626b01179420a94feb9c3d0f246970d2e3fa jdk9-b94
8581faf0d474472e32f589bbc16db7eec912d83f jdk-9+95
c021b855f51e572e63982654b17742cb1f814fb4 jdk-9+96

View File

@ -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: \

View File

@ -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 \

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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) {

View File

@ -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;
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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);

View File

@ -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);
}
/**

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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);
}
/*

View File

@ -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

View File

@ -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.
*/

View File

@ -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;

View File

@ -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

View 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;
}
}

View File

@ -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));
}
}

View File

@ -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.

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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);
}
}
/*

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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());

View File

@ -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);

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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;
}
/*

View File

@ -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. */

View File

@ -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

View File

@ -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);
}
}

View File

@ -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();
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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