Merge
This commit is contained in:
commit
843a74d204
@ -392,3 +392,4 @@ a22e2671d88f6b22a4aa82e3966986542ed2a381 jdk-9+146
|
||||
5f6920274c48eb00d31afee6c034826a754c13d9 jdk-9+147
|
||||
3ffc3e886c74736e387f3685e86b557cdea706c8 jdk-9+148
|
||||
b119012d1c2ab2570fe8718633840d0c1f1f441d jdk-9+149
|
||||
6234069ff9789f7582e1faa32cb6283cbd1a5a2d jdk-9+150
|
||||
|
@ -305,9 +305,8 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK],
|
||||
BOOT_JDK_SOURCETARGET="-source 8 -target 8"
|
||||
AC_SUBST(BOOT_JDK_SOURCETARGET)
|
||||
|
||||
ADD_JVM_ARG_IF_OK([--patch-module foo=bar], dummy, [$JAVA])
|
||||
AC_MSG_CHECKING([if Boot JDK supports modules])
|
||||
if test "x$JVM_ARG_OK" = "xtrue"; then
|
||||
if "$JAVA" --list-modules > /dev/null 2>&1; then
|
||||
AC_MSG_RESULT([yes])
|
||||
BOOT_JDK_MODULAR="true"
|
||||
else
|
||||
|
@ -5170,7 +5170,7 @@ VS_SDK_PLATFORM_NAME_2013=
|
||||
#CUSTOM_AUTOCONF_INCLUDE
|
||||
|
||||
# Do not change or remove the following line, it is needed for consistency checks:
|
||||
DATE_WHEN_GENERATED=1482168759
|
||||
DATE_WHEN_GENERATED=1482828098
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
@ -24677,7 +24677,7 @@ $as_echo "$as_me: WARNING: Value for VERSION_MINOR has been sanitized from '$wit
|
||||
else
|
||||
if test "x$NO_DEFAULT_VERSION_PARTS" != xtrue; then
|
||||
# Default is 0, if unspecified
|
||||
VERSION_MINOR=0
|
||||
VERSION_MINOR=$DEFAULT_VERSION_MINOR
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -24724,7 +24724,7 @@ $as_echo "$as_me: WARNING: Value for VERSION_SECURITY has been sanitized from '$
|
||||
else
|
||||
if test "x$NO_DEFAULT_VERSION_PARTS" != xtrue; then
|
||||
# Default is 0, if unspecified
|
||||
VERSION_SECURITY=0
|
||||
VERSION_SECURITY=$DEFAULT_VERSION_SECURITY
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -24771,7 +24771,7 @@ $as_echo "$as_me: WARNING: Value for VERSION_PATCH has been sanitized from '$wit
|
||||
else
|
||||
if test "x$NO_DEFAULT_VERSION_PARTS" != xtrue; then
|
||||
# Default is 0, if unspecified
|
||||
VERSION_PATCH=0
|
||||
VERSION_PATCH=$DEFAULT_VERSION_PATCH
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -30665,24 +30665,9 @@ $as_echo "$tool_specified" >&6; }
|
||||
BOOT_JDK_SOURCETARGET="-source 8 -target 8"
|
||||
|
||||
|
||||
|
||||
$ECHO "Check if jvm arg is ok: --patch-module foo=bar" >&5
|
||||
$ECHO "Command: $JAVA --patch-module foo=bar -version" >&5
|
||||
OUTPUT=`$JAVA --patch-module foo=bar -version 2>&1`
|
||||
FOUND_WARN=`$ECHO "$OUTPUT" | $GREP -i warn`
|
||||
FOUND_VERSION=`$ECHO $OUTPUT | $GREP " version \""`
|
||||
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
|
||||
dummy="$dummy --patch-module foo=bar"
|
||||
JVM_ARG_OK=true
|
||||
else
|
||||
$ECHO "Arg failed:" >&5
|
||||
$ECHO "$OUTPUT" >&5
|
||||
JVM_ARG_OK=false
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if Boot JDK supports modules" >&5
|
||||
$as_echo_n "checking if Boot JDK supports modules... " >&6; }
|
||||
if test "x$JVM_ARG_OK" = "xtrue"; then
|
||||
if "$JAVA" --list-modules > /dev/null 2>&1; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
BOOT_JDK_MODULAR="true"
|
||||
|
@ -481,7 +481,7 @@ AC_DEFUN_ONCE([HOTSPOT_ENABLE_DISABLE_GTEST],
|
||||
AC_MSG_RESULT([no, forced])
|
||||
BUILD_GTEST="false"
|
||||
elif test "x$enable_hotspot_gtest" = "x"; then
|
||||
if test "x$GTEST_DIR_EXISTS" = "xtrue" && test "x$OPENJDK_TARGET_OS" != "xaix"; then
|
||||
if test "x$GTEST_DIR_EXISTS" = "xtrue"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
BUILD_GTEST="true"
|
||||
else
|
||||
|
@ -226,7 +226,7 @@ AC_DEFUN_ONCE([JDKVER_SETUP_JDK_VERSION_NUMBERS],
|
||||
else
|
||||
if test "x$NO_DEFAULT_VERSION_PARTS" != xtrue; then
|
||||
# Default is 0, if unspecified
|
||||
VERSION_MINOR=0
|
||||
VERSION_MINOR=$DEFAULT_VERSION_MINOR
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -248,7 +248,7 @@ AC_DEFUN_ONCE([JDKVER_SETUP_JDK_VERSION_NUMBERS],
|
||||
else
|
||||
if test "x$NO_DEFAULT_VERSION_PARTS" != xtrue; then
|
||||
# Default is 0, if unspecified
|
||||
VERSION_SECURITY=0
|
||||
VERSION_SECURITY=$DEFAULT_VERSION_SECURITY
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -270,7 +270,7 @@ AC_DEFUN_ONCE([JDKVER_SETUP_JDK_VERSION_NUMBERS],
|
||||
else
|
||||
if test "x$NO_DEFAULT_VERSION_PARTS" != xtrue; then
|
||||
# Default is 0, if unspecified
|
||||
VERSION_PATCH=0
|
||||
VERSION_PATCH=$DEFAULT_VERSION_PATCH
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -26,6 +26,9 @@
|
||||
# Default version numbers to use unless overridden by configure
|
||||
|
||||
DEFAULT_VERSION_MAJOR=9
|
||||
DEFAULT_VERSION_MINOR=0
|
||||
DEFAULT_VERSION_SECURITY=0
|
||||
DEFAULT_VERSION_PATCH=0
|
||||
|
||||
LAUNCHER_NAME=openjdk
|
||||
PRODUCT_NAME=OpenJDK
|
||||
|
45
common/bin/print-config.js
Normal file
45
common/bin/print-config.js
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This little utility can be used to expand the jib-profiles configuration
|
||||
* files into plain json.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* jjs -scripting print-config.js -- [<jib-profiles.js>]
|
||||
*
|
||||
*/
|
||||
|
||||
var file = $ARG[0];
|
||||
if (file == null) {
|
||||
file = new java.io.File(__DIR__, "../conf/jib-profiles.js").getCanonicalPath();
|
||||
}
|
||||
load(file);
|
||||
var input = {};
|
||||
input.get = function(dependencyName, attribute) {
|
||||
return "\${" + dependencyName + "." + attribute + "}";
|
||||
};
|
||||
print(JSON.stringify(getJibProfiles(input), null, 2));
|
@ -55,6 +55,7 @@
|
||||
* be provided:
|
||||
*
|
||||
* input.profile
|
||||
* input.build_id
|
||||
* input.target_os
|
||||
* input.target_cpu
|
||||
* input.build_os
|
||||
@ -181,11 +182,14 @@ var getJibProfiles = function (input) {
|
||||
|
||||
var data = {};
|
||||
|
||||
// Identifies the version of this format to the tool reading it
|
||||
data.format_version = "1.0";
|
||||
// Identifies the version of this format to the tool reading it.
|
||||
// 1.1 signifies that the publish, publish-src and get-src features are usable.
|
||||
data.format_version = "1.1";
|
||||
|
||||
// Organization is used when uploading/publishing build results
|
||||
data.organization = "com.oracle.jpg.jdk";
|
||||
// Organization, product and version are used when uploading/publishing build results
|
||||
data.organization = "";
|
||||
data.product = "jdk";
|
||||
data.version = getVersion();
|
||||
|
||||
// The base directory for the build output. JIB will assume that the
|
||||
// actual build directory will be <output_basedir>/<configuration>
|
||||
@ -195,12 +199,18 @@ var getJibProfiles = function (input) {
|
||||
// The make argument to use to specify the name of the configuration
|
||||
data.configuration_make_arg = "CONF_NAME=";
|
||||
|
||||
// Exclude list to use when Jib creates a source bundle
|
||||
data.src_bundle_excludes = "./build webrev .hg */.hg */*/.hg */*/*/.hg";
|
||||
// Include list to use when creating a minimal jib source bundle which
|
||||
// contains just the jib configuration files.
|
||||
data.conf_bundle_includes = "*/conf/jib-profiles.* common/autoconf/version-numbers"
|
||||
|
||||
// Define some common values
|
||||
var common = getJibProfilesCommon(input);
|
||||
var common = getJibProfilesCommon(input, data);
|
||||
// Generate the profiles part of the configuration
|
||||
data.profiles = getJibProfilesProfiles(input, common);
|
||||
data.profiles = getJibProfilesProfiles(input, common, data);
|
||||
// Generate the dependencies part of the configuration
|
||||
data.dependencies = getJibProfilesDependencies(input, common);
|
||||
data.dependencies = getJibProfilesDependencies(input, common, data);
|
||||
|
||||
return data;
|
||||
};
|
||||
@ -211,18 +221,168 @@ var getJibProfiles = function (input) {
|
||||
* @param input External data to use for generating the configuration
|
||||
* @returns Common values
|
||||
*/
|
||||
var getJibProfilesCommon = function (input) {
|
||||
var getJibProfilesCommon = function (input, data) {
|
||||
var common = {};
|
||||
|
||||
common.dependencies = ["boot_jdk", "gnumake", "jtreg"],
|
||||
common.default_make_targets = ["product-bundles", "test-bundles"],
|
||||
common.default_make_targets_debug = common.default_make_targets;
|
||||
common.default_make_targets_slowdebug = common.default_make_targets;
|
||||
common.configure_args = ["--enable-jtreg-failure-handler"],
|
||||
common.configure_args_32bit = ["--with-target-bits=32"],
|
||||
common.configure_args_debug = ["--enable-debug"],
|
||||
common.configure_args_slowdebug = ["--with-debug-level=slowdebug"],
|
||||
common.organization = "jpg.infra.builddeps"
|
||||
common.organization = "jpg.infra.builddeps";
|
||||
common.build_id = getBuildId(input);
|
||||
common.build_number = input.build_number != null ? input.build_number : "0";
|
||||
|
||||
// List of the main profile names used for iteration
|
||||
common.main_profile_names = [
|
||||
"linux-x64", "linux-x86", "macosx-x64", "solaris-x64",
|
||||
"solaris-sparcv9", "windows-x64", "windows-x86"
|
||||
];
|
||||
|
||||
// These are the base setttings for all the main build profiles.
|
||||
common.main_profile_base = {
|
||||
dependencies: ["boot_jdk", "gnumake", "jtreg"],
|
||||
default_make_targets: ["product-bundles", "test-bundles"],
|
||||
configure_args: [
|
||||
"--with-version-opt=" + common.build_id,
|
||||
"--enable-jtreg-failure-handler",
|
||||
"--with-version-build=" + common.build_number
|
||||
]
|
||||
};
|
||||
// Extra settings for debug profiles
|
||||
common.debug_suffix = "-debug";
|
||||
common.debug_profile_base = {
|
||||
configure_args: ["--enable-debug"],
|
||||
labels: "debug"
|
||||
};
|
||||
// Extra settings for slowdebug profiles
|
||||
common.slowdebug_suffix = "-slowdebug";
|
||||
common.slowdebug_profile_base = {
|
||||
configure_args: ["--with-debug-level=slowdebug"],
|
||||
labels: "slowdebug"
|
||||
};
|
||||
// Extra settings for openjdk only profiles
|
||||
common.open_suffix = "-open";
|
||||
common.open_profile_base = {
|
||||
configure_args: ["--enable-openjdk-only"],
|
||||
labels: "open"
|
||||
};
|
||||
|
||||
common.configure_args_32bit = ["--with-target-bits=32"];
|
||||
|
||||
/**
|
||||
* Define common artifacts template for all main profiles
|
||||
* @param pf - Name of platform in bundle names
|
||||
* @param demo_ext - Type of extension for demo bundle
|
||||
*/
|
||||
common.main_profile_artifacts = function (pf, demo_ext) {
|
||||
return {
|
||||
artifacts: {
|
||||
jdk: {
|
||||
local: "bundles/\\(jdk.*bin.tar.gz\\)",
|
||||
remote: [
|
||||
"bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin.tar.gz",
|
||||
"bundles/" + pf + "/\\1"
|
||||
],
|
||||
subdir: "jdk-" + data.version,
|
||||
exploded: "images/jdk"
|
||||
},
|
||||
jre: {
|
||||
local: "bundles/\\(jre.*bin.tar.gz\\)",
|
||||
remote: [
|
||||
"bundles/" + pf + "/jre-" + data.version + "_" + pf + "_bin.tar.gz",
|
||||
"bundles/" + pf + "/\\1"
|
||||
],
|
||||
subdir: "jre-" + data.version,
|
||||
exploded: "images/jre"
|
||||
},
|
||||
test: {
|
||||
local: "bundles/\\(jdk.*bin-tests.tar.gz\\)",
|
||||
remote: [
|
||||
"bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin-tests.tar.gz",
|
||||
"bundles/" + pf + "/\\1"
|
||||
],
|
||||
exploded: "images/test"
|
||||
},
|
||||
jdk_symbols: {
|
||||
local: "bundles/\\(jdk.*bin-symbols.tar.gz\\)",
|
||||
remote: [
|
||||
"bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin-symbols.tar.gz",
|
||||
"bundles/" + pf + "/\\1"
|
||||
],
|
||||
subdir: "jdk-" + data.version,
|
||||
exploded: "images/jdk"
|
||||
},
|
||||
jre_symbols: {
|
||||
local: "bundles/\\(jre.*bin-symbols.tar.gz\\)",
|
||||
remote: [
|
||||
"bundles/" + pf + "/jre-" + data.version + "_" + pf + "_bin-symbols.tar.gz",
|
||||
"bundles/" + pf + "/\\1"
|
||||
],
|
||||
subdir: "jre-" + data.version,
|
||||
exploded: "images/jre"
|
||||
},
|
||||
demo: {
|
||||
local: "bundles/\\(jdk.*demo." + demo_ext + "\\)",
|
||||
remote: [
|
||||
"bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_demo." + demo_ext,
|
||||
"bundles/" + pf + "/\\1"
|
||||
],
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Define common artifacts template for all debug profiles
|
||||
* @param pf - Name of platform in bundle names
|
||||
*/
|
||||
common.debug_profile_artifacts = function (pf) {
|
||||
return {
|
||||
artifacts: {
|
||||
jdk: {
|
||||
local: "bundles/\\(jdk.*bin-debug.tar.gz\\)",
|
||||
remote: [
|
||||
"bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin-debug.tar.gz",
|
||||
"bundles/" + pf + "/\\1"
|
||||
],
|
||||
subdir: "jdk-" + data.version,
|
||||
exploded: "images/jdk"
|
||||
},
|
||||
jre: {
|
||||
local: "bundles/\\(jre.*bin-debug.tar.gz\\)",
|
||||
remote: [
|
||||
"bundles/" + pf + "/jre-" + data.version + "_" + pf + "_bin-debug.tar.gz",
|
||||
"bundles/" + pf + "/\\1"
|
||||
],
|
||||
subdir: "jre-" + data.version,
|
||||
exploded: "images/jre"
|
||||
},
|
||||
test: {
|
||||
local: "bundles/\\(jdk.*bin-tests-debug.tar.gz\\)",
|
||||
remote: [
|
||||
"bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin-tests-debug.tar.gz",
|
||||
"bundles/" + pf + "/\\1"
|
||||
],
|
||||
exploded: "images/test"
|
||||
},
|
||||
jdk_symbols: {
|
||||
local: "bundles/\\(jdk.*bin-debug-symbols.tar.gz\\)",
|
||||
remote: [
|
||||
"bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin-debug-symbols.tar.gz",
|
||||
"bundles/" + pf + "/\\1"
|
||||
],
|
||||
subdir: "jdk-" + data.version,
|
||||
exploded: "images/jdk"
|
||||
},
|
||||
jre_symbols: {
|
||||
local: "bundles/\\(jre.*bin-debug-symbols.tar.gz\\)",
|
||||
remote: [
|
||||
"bundles/" + pf + "/jre-" + data.version + "_" + pf + "_bin-debug-symbols.tar.gz",
|
||||
"bundles/" + pf + "/\\1"
|
||||
],
|
||||
subdir: "jre-" + data.version,
|
||||
exploded: "images/jre"
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var boot_jdk_revision = "8";
|
||||
var boot_jdk_subdirpart = "1.8.0";
|
||||
@ -251,100 +411,105 @@ var getJibProfilesCommon = function (input) {
|
||||
* @param common The common values
|
||||
* @returns {{}} Profiles part of the configuration
|
||||
*/
|
||||
var getJibProfilesProfiles = function (input, common) {
|
||||
var profiles = {};
|
||||
|
||||
var getJibProfilesProfiles = function (input, common, data) {
|
||||
// Main SE profiles
|
||||
var mainProfiles = {
|
||||
var profiles = {
|
||||
|
||||
"linux-x64": {
|
||||
target_os: "linux",
|
||||
target_cpu: "x64",
|
||||
dependencies: concat(common.dependencies, "devkit"),
|
||||
configure_args: concat(common.configure_args, "--with-zlib=system"),
|
||||
default_make_targets: concat(common.default_make_targets, "docs-bundles")
|
||||
dependencies: ["devkit"],
|
||||
configure_args: ["--with-zlib=system"],
|
||||
default_make_targets: ["docs-bundles"],
|
||||
},
|
||||
|
||||
"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,
|
||||
dependencies: ["devkit"],
|
||||
configure_args: concat(common.configure_args_32bit,
|
||||
"--with-jvm-variants=minimal,server", "--with-zlib=system"),
|
||||
default_make_targets: common.default_make_targets
|
||||
},
|
||||
|
||||
"macosx-x64": {
|
||||
target_os: "macosx",
|
||||
target_cpu: "x64",
|
||||
dependencies: concat(common.dependencies, "devkit"),
|
||||
dependencies: ["devkit"],
|
||||
configure_args: concat(common.configure_args, "--with-zlib=system"),
|
||||
default_make_targets: common.default_make_targets
|
||||
},
|
||||
|
||||
"solaris-x64": {
|
||||
target_os: "solaris",
|
||||
target_cpu: "x64",
|
||||
dependencies: concat(common.dependencies, "devkit", "cups"),
|
||||
configure_args: concat(common.configure_args, "--with-zlib=system",
|
||||
"--enable-dtrace"),
|
||||
default_make_targets: common.default_make_targets
|
||||
dependencies: ["devkit", "cups"],
|
||||
configure_args: ["--with-zlib=system", "--enable-dtrace"],
|
||||
},
|
||||
|
||||
"solaris-sparcv9": {
|
||||
target_os: "solaris",
|
||||
target_cpu: "sparcv9",
|
||||
dependencies: concat(common.dependencies, "devkit", "cups"),
|
||||
configure_args: concat(common.configure_args, "--with-zlib=system",
|
||||
"--enable-dtrace"),
|
||||
default_make_targets: common.default_make_targets
|
||||
dependencies: ["devkit", "cups"],
|
||||
configure_args: ["--with-zlib=system", "--enable-dtrace"],
|
||||
},
|
||||
|
||||
"windows-x64": {
|
||||
target_os: "windows",
|
||||
target_cpu: "x64",
|
||||
dependencies: concat(common.dependencies, "devkit", "freetype"),
|
||||
configure_args: concat(common.configure_args),
|
||||
default_make_targets: common.default_make_targets
|
||||
dependencies: ["devkit", "freetype"],
|
||||
},
|
||||
|
||||
"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),
|
||||
default_make_targets: common.default_make_targets
|
||||
dependencies: ["devkit", "freetype"],
|
||||
configure_args: concat(common.configure_args_32bit),
|
||||
}
|
||||
};
|
||||
profiles = concatObjects(profiles, mainProfiles);
|
||||
// Add the base settings to all the main profiles
|
||||
common.main_profile_names.forEach(function (name) {
|
||||
profiles[name] = concatObjects(common.main_profile_base, profiles[name]);
|
||||
});
|
||||
|
||||
// Generate debug versions of all the main profiles
|
||||
profiles = concatObjects(profiles, generateDebugProfiles(common, mainProfiles));
|
||||
common.main_profile_names.forEach(function (name) {
|
||||
var debugName = name + common.debug_suffix;
|
||||
profiles[debugName] = concatObjects(profiles[name],
|
||||
common.debug_profile_base);
|
||||
});
|
||||
// Generate slowdebug versions of all the main profiles
|
||||
profiles = concatObjects(profiles, generateSlowdebugProfiles(common, mainProfiles));
|
||||
common.main_profile_names.forEach(function (name) {
|
||||
var debugName = name + common.slowdebug_suffix;
|
||||
profiles[debugName] = concatObjects(profiles[name],
|
||||
common.slowdebug_profile_base);
|
||||
});
|
||||
|
||||
// Generate open only profiles for all the main profiles for JPRT and reference
|
||||
// implementation builds.
|
||||
var openOnlyProfiles = generateOpenOnlyProfiles(common, mainProfiles);
|
||||
common.main_profile_names.forEach(function (name) {
|
||||
var openName = name + common.open_suffix;
|
||||
profiles[openName] = concatObjects(profiles[name],
|
||||
common.open_profile_base);
|
||||
});
|
||||
// The open only profiles on linux are used for reference builds and should
|
||||
// produce the compact profile images by default. This adds "profiles" as an
|
||||
// extra default target.
|
||||
var openOnlyProfilesExtra = {
|
||||
"linux-x64-open": {
|
||||
default_make_targets: "profiles"
|
||||
},
|
||||
|
||||
"linux-x86-open": {
|
||||
default_make_targets: "profiles",
|
||||
configure_args: "--with-jvm-variants=client,server"
|
||||
}
|
||||
};
|
||||
var openOnlyProfiles = concatObjects(openOnlyProfiles, openOnlyProfilesExtra);
|
||||
profiles = concatObjects(profiles, openOnlyProfilesExtra);
|
||||
|
||||
profiles = concatObjects(profiles, openOnlyProfiles);
|
||||
// Generate debug profiles for the open jprt profiles
|
||||
profiles = concatObjects(profiles, generateDebugProfiles(common, openOnlyProfiles));
|
||||
// Generate debug profiles for the open only profiles
|
||||
common.main_profile_names.forEach(function (name) {
|
||||
var openName = name + common.open_suffix;
|
||||
var openDebugName = openName + common.debug_suffix;
|
||||
profiles[openDebugName] = concatObjects(profiles[openName],
|
||||
common.debug_profile_base);
|
||||
});
|
||||
|
||||
// Profiles for building the zero jvm variant. These are used for verification
|
||||
// in JPRT.
|
||||
@ -352,31 +517,46 @@ var getJibProfilesProfiles = function (input, common) {
|
||||
"linux-x64-zero": {
|
||||
target_os: "linux",
|
||||
target_cpu: "x64",
|
||||
dependencies: concat(common.dependencies, "devkit"),
|
||||
configure_args: concat(common.configure_args,
|
||||
dependencies: ["devkit"],
|
||||
configure_args: [
|
||||
"--with-zlib=system",
|
||||
"--with-jvm-variants=zero",
|
||||
"--enable-libffi-bundling"),
|
||||
default_make_targets: common.default_make_targets
|
||||
"--enable-libffi-bundling"
|
||||
]
|
||||
},
|
||||
|
||||
"linux-x86-zero": {
|
||||
target_os: "linux",
|
||||
target_cpu: "x86",
|
||||
build_cpu: "x64",
|
||||
dependencies: concat(common.dependencies, "devkit"),
|
||||
configure_args: concat(common.configure_args, common.configure_args_32bit,
|
||||
dependencies: ["devkit"],
|
||||
configure_args: concat(common.configure_args_32bit, [
|
||||
"--with-zlib=system",
|
||||
"--with-jvm-variants=zero",
|
||||
"--enable-libffi-bundling"),
|
||||
default_make_targets: common.default_make_targets
|
||||
},
|
||||
"--enable-libffi-bundling"
|
||||
])
|
||||
}
|
||||
}
|
||||
profiles = concatObjects(profiles, zeroProfiles);
|
||||
profiles = concatObjects(profiles, generateDebugProfiles(common, zeroProfiles));
|
||||
|
||||
// Profiles used to run tests. Used in JPRT.
|
||||
// Add the base settings to the zero profiles and generate debug profiles
|
||||
Object.keys(zeroProfiles).forEach(function (name) {
|
||||
var debugName = name + common.debug_suffix;
|
||||
profiles[name] = concatObjects(common.main_profile_base, profiles[name]);
|
||||
profiles[debugName] = concatObjects(profiles[name], common.debug_profile_base);
|
||||
});
|
||||
|
||||
// Profiles used to run tests. Used in JPRT and Mach 5.
|
||||
var testOnlyProfiles = {
|
||||
"run-test-jprt": {
|
||||
target_os: input.build_os,
|
||||
target_cpu: input.build_cpu,
|
||||
dependencies: [ "jtreg", "gnumake", "boot_jdk" ],
|
||||
labels: "test",
|
||||
environment: {
|
||||
"JT_JAVA": common.boot_jdk_home
|
||||
}
|
||||
},
|
||||
|
||||
"run-test": {
|
||||
target_os: input.build_os,
|
||||
@ -390,6 +570,230 @@ var getJibProfilesProfiles = function (input, common) {
|
||||
};
|
||||
profiles = concatObjects(profiles, testOnlyProfiles);
|
||||
|
||||
// Profiles used to run tests using Jib for internal dependencies.
|
||||
var testedProfile = input.testedProfile;
|
||||
if (testedProfile == null) {
|
||||
testedProfile = input.build_os + "-" + input.build_cpu;
|
||||
}
|
||||
var testOnlyProfilesPrebuilt = {
|
||||
"run-test-prebuilt": {
|
||||
src: "src.conf",
|
||||
dependencies: [ "jtreg", "gnumake", testedProfile + ".jdk",
|
||||
testedProfile + ".test", "src.full"
|
||||
],
|
||||
work_dir: input.get("src.full", "install_path") + "/test",
|
||||
environment: {
|
||||
"PRODUCT_HOME": input.get(testedProfile + ".jdk", "home_path"),
|
||||
"TEST_IMAGE_DIR": input.get(testedProfile + ".test", "home_path"),
|
||||
"TEST_OUTPUT_DIR": input.src_top_dir
|
||||
},
|
||||
labels: "test"
|
||||
}
|
||||
};
|
||||
// If actually running the run-test-prebuilt profile, verify that the input
|
||||
// variable is valid and if so, add the appropriate target_* values from
|
||||
// the tested profile.
|
||||
if (input.profile == "run-test-prebuilt") {
|
||||
if (profiles[testedProfile] == null) {
|
||||
error("testedProfile is not defined: " + testedProfile);
|
||||
} else {
|
||||
testOnlyProfilesPrebuilt["run-test-prebuilt"]["target_os"]
|
||||
= profiles[testedProfile]["target_os"];
|
||||
testOnlyProfilesPrebuilt["run-test-prebuilt"]["target_cpu"]
|
||||
= profiles[testedProfile]["target_cpu"];
|
||||
}
|
||||
}
|
||||
profiles = concatObjects(profiles, testOnlyProfilesPrebuilt);
|
||||
|
||||
//
|
||||
// Define artifacts for profiles
|
||||
//
|
||||
// Macosx bundles are named osx and Windows demo bundles use zip instead of
|
||||
// tar.gz.
|
||||
var artifactData = {
|
||||
"linux-x64": {
|
||||
platform: "linux-x64",
|
||||
demo_ext: "tar.gz"
|
||||
},
|
||||
"linux-x86": {
|
||||
platform: "linux-x86",
|
||||
demo_ext: "tar.gz"
|
||||
},
|
||||
"macosx-x64": {
|
||||
platform: "osx-x64",
|
||||
demo_ext: "tar.gz"
|
||||
},
|
||||
"solaris-x64": {
|
||||
platform: "solaris-x64",
|
||||
demo_ext: "tar.gz"
|
||||
},
|
||||
"solaris-sparcv9": {
|
||||
platform: "solaris-sparcv9",
|
||||
demo_ext: "tar.gz"
|
||||
},
|
||||
"windows-x64": {
|
||||
platform: "windows-x64",
|
||||
demo_ext: "zip"
|
||||
},
|
||||
"windows-x86": {
|
||||
platform: "windows-x86",
|
||||
demo_ext: "zip"
|
||||
}
|
||||
}
|
||||
// Generate common artifacts for all main profiles
|
||||
common.main_profile_names.forEach(function (name) {
|
||||
profiles[name] = concatObjects(profiles[name],
|
||||
common.main_profile_artifacts(artifactData[name].platform, artifactData[name].demo_ext));
|
||||
});
|
||||
|
||||
// Generate common artifacts for all debug profiles
|
||||
common.main_profile_names.forEach(function (name) {
|
||||
var debugName = name + common.debug_suffix;
|
||||
profiles[debugName] = concatObjects(profiles[debugName],
|
||||
common.debug_profile_artifacts(artifactData[name].platform));
|
||||
});
|
||||
|
||||
// Extra profile specific artifacts
|
||||
profilesArtifacts = {
|
||||
"linux-x64": {
|
||||
artifacts: {
|
||||
doc_api_spec: {
|
||||
local: "bundles/\\(jdk.*doc-api-spec.tar.gz\\)",
|
||||
remote: [
|
||||
"bundles/common/jdk-" + data.version + "_doc-api-spec.tar.gz",
|
||||
"bundles/linux-x64/\\1"
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
"linux-x64-open": {
|
||||
artifacts: {
|
||||
jdk: {
|
||||
local: "bundles/\\(jdk.*bin.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/linux-x64/\\1",
|
||||
},
|
||||
jre: {
|
||||
local: "bundles/\\(jre.*bin.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/linux-x64/\\1",
|
||||
},
|
||||
test: {
|
||||
local: "bundles/\\(jdk.*bin-tests.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/linux-x64/\\1",
|
||||
},
|
||||
jdk_symbols: {
|
||||
local: "bundles/\\(jdk.*bin-symbols.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/linux-x64/\\1",
|
||||
},
|
||||
jre_symbols: {
|
||||
local: "bundles/\\(jre.*bin-symbols.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/linux-x64/\\1",
|
||||
},
|
||||
demo: {
|
||||
local: "bundles/\\(jdk.*demo.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/linux-x64/\\1",
|
||||
},
|
||||
doc_api_spec: {
|
||||
local: "bundles/\\(jdk.*doc-api-spec.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/linux-x64/\\1",
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
"linux-x86-open": {
|
||||
artifacts: {
|
||||
jdk: {
|
||||
local: "bundles/\\(jdk.*bin.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/profile/linux-x86/\\1",
|
||||
},
|
||||
jre: {
|
||||
local: "bundles/\\(jre.*[0-9]_linux-x86_bin.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/profile/linux-x86/\\1",
|
||||
},/* The build does not create these
|
||||
jre_compact1: {
|
||||
local: "bundles/\\(jre.*-compact1_linux-x86_bin.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/profile/linux-x86/\\1",
|
||||
},
|
||||
jre_compact2: {
|
||||
local: "bundles/\\(jre.*-compact2_linux-x86_bin.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/profile/linux-x86/\\1",
|
||||
},
|
||||
jre_compact3: {
|
||||
local: "bundles/\\(jre.*-compact3_linux-x86_bin.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/profile/linux-x86/\\1",
|
||||
},*/
|
||||
}
|
||||
},
|
||||
|
||||
"windows-x86-open": {
|
||||
artifacts: {
|
||||
jdk: {
|
||||
local: "bundles/\\(jdk.*bin.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/windows-x86/\\1",
|
||||
},
|
||||
jre: {
|
||||
local: "bundles/\\(jre.*bin.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/windows-x86/\\1"
|
||||
},
|
||||
test: {
|
||||
local: "bundles/\\(jdk.*bin-tests.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/windows-x86/\\1",
|
||||
},
|
||||
jdk_symbols: {
|
||||
local: "bundles/\\(jdk.*bin-symbols.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/windows-x86/\\1"
|
||||
},
|
||||
jre_symbols: {
|
||||
local: "bundles/\\(jre.*bin-symbols.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/windows-x86/\\1",
|
||||
},
|
||||
demo: {
|
||||
local: "bundles/\\(jdk.*demo.zip\\)",
|
||||
remote: "bundles/openjdk/GPL/windows-x86/\\1",
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"linux-x86-open-debug": {
|
||||
artifacts: {
|
||||
jdk: {
|
||||
local: "bundles/\\(jdk.*bin-debug.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/profile/linux-x86/\\1",
|
||||
},
|
||||
jre: {
|
||||
local: "bundles/\\(jre.*bin-debug.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/profile/linux-x86/\\1",
|
||||
},
|
||||
jdk_symbols: {
|
||||
local: "bundles/\\(jdk.*bin-debug-symbols.tar.gz\\)",
|
||||
remote: "bundles/openjdk/GPL/profile/linux-x86/\\1",
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
profiles = concatObjects(profiles, profilesArtifacts);
|
||||
|
||||
|
||||
// Define the reference implementation profiles. These are basically the same
|
||||
// as the open profiles, but upload artifacts to a different location and
|
||||
// are only defined for specific platforms.
|
||||
profiles["linux-x64-ri"] = clone(profiles["linux-x64-open"]);
|
||||
profiles["linux-x86-ri"] = clone(profiles["linux-x86-open"]);
|
||||
profiles["linux-x86-ri-debug"] = clone(profiles["linux-x86-open-debug"]);
|
||||
profiles["windows-x86-ri"] = clone(profiles["windows-x86-open"]);
|
||||
|
||||
// Generate artifacts for ri profiles
|
||||
[ "linux-x64-ri", "linux-x86-ri", "linux-x86-ri-debug", "windows-x86-ri" ]
|
||||
.forEach(function (name) {
|
||||
// Rewrite all remote dirs to "bundles/openjdk/BCL/..."
|
||||
for (artifactName in profiles[name].artifacts) {
|
||||
var artifact = profiles[name].artifacts[artifactName];
|
||||
artifact.remote = replaceAll("\/GPL\/", "/BCL/",
|
||||
(artifact.remote != null ? artifact.remote : artifact.local));
|
||||
}
|
||||
});
|
||||
|
||||
// Generate the missing platform attributes
|
||||
profiles = generatePlatformAttributes(profiles);
|
||||
profiles = generateDefaultMakeTargetsConfigureArg(common, profiles);
|
||||
@ -513,78 +917,6 @@ var generatePlatformAttributes = function (profiles) {
|
||||
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].default_make_targets
|
||||
= common.default_make_targets_debug;
|
||||
newProfiles[debugProfile].labels
|
||||
= concat(newProfiles[debugProfile].labels || [], "debug"),
|
||||
newProfiles[debugProfile].configure_args
|
||||
= concat(newProfiles[debugProfile].configure_args,
|
||||
common.configure_args_debug);
|
||||
}
|
||||
return newProfiles;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates slowdebug 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 generateSlowdebugProfiles = function (common, profiles) {
|
||||
var newProfiles = {};
|
||||
for (var profile in profiles) {
|
||||
var debugProfile = profile + "-slowdebug";
|
||||
newProfiles[debugProfile] = clone(profiles[profile]);
|
||||
newProfiles[debugProfile].debug_level = "slowdebug";
|
||||
newProfiles[debugProfile].default_make_targets
|
||||
= common.default_make_targets_slowdebug;
|
||||
newProfiles[debugProfile].labels
|
||||
= concat(newProfiles[debugProfile].labels || [], "slowdebug"),
|
||||
newProfiles[debugProfile].configure_args
|
||||
= concat(newProfiles[debugProfile].configure_args,
|
||||
common.configure_args_slowdebug);
|
||||
}
|
||||
return newProfiles;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates open only versions of profiles. Clones the given profiles and adds
|
||||
* open metadata.
|
||||
*
|
||||
* @param common Common values
|
||||
* @param profiles Profiles map to generate open only profiles for
|
||||
* @returns {{}} New map of profiles containing open only profiles
|
||||
*/
|
||||
var generateOpenOnlyProfiles = function (common, profiles) {
|
||||
var newProfiles = {};
|
||||
for (var profile in profiles) {
|
||||
var openProfile = profile + "-open";
|
||||
newProfiles[openProfile] = clone(profiles[profile]);
|
||||
newProfiles[openProfile].labels
|
||||
= concat(newProfiles[openProfile].labels || [], "open"),
|
||||
newProfiles[openProfile].configure_args
|
||||
= concat(newProfiles[openProfile].configure_args,
|
||||
"--enable-openjdk-only");
|
||||
}
|
||||
return newProfiles;
|
||||
};
|
||||
|
||||
/**
|
||||
* The default_make_targets attribute on a profile is not a real Jib attribute.
|
||||
* This function rewrites that attribute into the corresponding configure arg.
|
||||
@ -602,10 +934,12 @@ var generateDefaultMakeTargetsConfigureArg = function (common, profiles) {
|
||||
// Iterate over all configure args and see if --with-default-make-target
|
||||
// is already there and change it, otherwise add it.
|
||||
var found = false;
|
||||
for (var arg in ret[profile].configure_args) {
|
||||
if (arg.startsWith("--with-default-make-target")) {
|
||||
for (var i in ret[profile].configure_args) {
|
||||
var arg = ret[profile].configure_args[i];
|
||||
if (arg != null && arg.startsWith("--with-default-make-target=")) {
|
||||
found = true;
|
||||
arg.replace(/=.*/, "=" + targetsString);
|
||||
ret[profile].configure_args[i]
|
||||
= "--with-default-make-target=" + targetsString;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
@ -618,6 +952,16 @@ var generateDefaultMakeTargetsConfigureArg = function (common, profiles) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
var getBuildId = function (input) {
|
||||
if (input.build_id != null) {
|
||||
return input.build_id;
|
||||
} else {
|
||||
var topdir = new java.io.File(__DIR__, "../..").getCanonicalFile().getName();
|
||||
var userName = java.lang.System.getProperty("user.name");
|
||||
return userName + "." + topdir;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deep clones an object tree.
|
||||
*
|
||||
@ -638,25 +982,25 @@ var concat = function () {
|
||||
};
|
||||
|
||||
/**
|
||||
* Copies all elements in an array into a new array but replacing all
|
||||
* occurrences of original with replacement.
|
||||
* Takes a String or Array of Strings and does a replace operation on each
|
||||
* of them.
|
||||
*
|
||||
* @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
|
||||
* @param pattern Pattern to look for
|
||||
* @param replacement Replacement text to insert
|
||||
* @param a String or Array of Strings to replace
|
||||
* @returns {Array} Either a new array or a new string depending on the input
|
||||
*/
|
||||
var replace = function (original, replacement, a) {
|
||||
var replaceAll = function (pattern, replacement, a) {
|
||||
// If a is an array
|
||||
if (Array === a.constructor) {
|
||||
var newA = [];
|
||||
for (var i in a) {
|
||||
if (original == a[i]) {
|
||||
newA.push(replacement);
|
||||
} else {
|
||||
newA.push(a[i]);
|
||||
newA.push(a[i].replace(pattern, replacement));
|
||||
}
|
||||
return newA;
|
||||
} else {
|
||||
return a.replace(pattern, replacement);
|
||||
}
|
||||
return newA;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -669,20 +1013,26 @@ var replace = function (original, replacement, a) {
|
||||
* @returns {{}} New object tree containing the concatenation of o1 and o2
|
||||
*/
|
||||
var concatObjects = function (o1, o2) {
|
||||
if (o1 == null) {
|
||||
return clone(o2);
|
||||
}
|
||||
if (o2 == null) {
|
||||
return clone(o1);
|
||||
}
|
||||
var ret = {};
|
||||
for (var a in o1) {
|
||||
if (o2[a] == null) {
|
||||
ret[a] = o1[a];
|
||||
ret[a] = clone(o1[a]);
|
||||
}
|
||||
}
|
||||
for (var a in o2) {
|
||||
if (o1[a] == null) {
|
||||
ret[a] = o2[a];
|
||||
ret[a] = clone(o2[a]);
|
||||
} else {
|
||||
if (typeof o1[a] == 'string') {
|
||||
ret[a] = [o1[a]].concat(o2[a]);
|
||||
ret[a] = clone([o1[a]].concat(o2[a]));
|
||||
} else if (Array.isArray(o1[a])) {
|
||||
ret[a] = o1[a].concat(o2[a]);
|
||||
ret[a] = clone(o1[a].concat(o2[a]));
|
||||
} else if (typeof o1[a] == 'object') {
|
||||
ret[a] = concatObjects(o1[a], o2[a]);
|
||||
}
|
||||
@ -690,3 +1040,45 @@ var concatObjects = function (o1, o2) {
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs the numeric version string from reading the
|
||||
* common/autoconf/version-numbers file and removing all trailing ".0".
|
||||
*
|
||||
* @param major Override major version
|
||||
* @param minor Override minor version
|
||||
* @param security Override security version
|
||||
* @param patch Override patch version
|
||||
* @returns {String} The numeric version string
|
||||
*/
|
||||
var getVersion = function (major, minor, security, patch) {
|
||||
var version_numbers = getVersionNumbers();
|
||||
var version = (major != null ? major : version_numbers.get("DEFAULT_VERSION_MAJOR"))
|
||||
+ "." + (minor != null ? minor : version_numbers.get("DEFAULT_VERSION_MINOR"))
|
||||
+ "." + (security != null ? security : version_numbers.get("DEFAULT_VERSION_SECURITY"))
|
||||
+ "." + (patch != null ? patch : version_numbers.get("DEFAULT_VERSION_PATCH"));
|
||||
while (version.match(".*\.0$")) {
|
||||
version = version.substring(0, version.length - 2);
|
||||
}
|
||||
return version;
|
||||
};
|
||||
|
||||
// Properties representation of the common/autoconf/version-numbers file. Lazily
|
||||
// initiated by the function below.
|
||||
var version_numbers;
|
||||
|
||||
/**
|
||||
* Read the common/autoconf/version-numbers file into a Properties object.
|
||||
*
|
||||
* @returns {java.utilProperties}
|
||||
*/
|
||||
var getVersionNumbers = function () {
|
||||
// Read version information from common/autoconf/version-numbers
|
||||
if (version_numbers == null) {
|
||||
version_numbers = new java.util.Properties();
|
||||
var stream = new java.io.FileInputStream(__DIR__ + "/../../common/autoconf/version-numbers");
|
||||
version_numbers.load(stream);
|
||||
stream.close();
|
||||
}
|
||||
return version_numbers;
|
||||
}
|
||||
|
@ -552,3 +552,4 @@ a82cb5350cad96a0b4de496afebe3ded89f27efa jdk-9+146
|
||||
132a72c782071cc11ab25cc7c9ee167c3632fea4 jdk-9+147
|
||||
5e4e893520ecdbd517c6ed6375f0885664fe62c4 jdk-9+148
|
||||
30e1996bd55da36183434f24ed964adebf9ca71e jdk-9+149
|
||||
98fe046473c90204cbc9b34c512b9fc10dfb8479 jdk-9+150
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -188,7 +188,6 @@ ifeq ($(call check-jvm-feature, dtrace), true)
|
||||
LIBS := $(LIBDL) -lc -lthread -ldoor, \
|
||||
MAPFILE := $(HOTSPOT_TOPDIR)/make/mapfiles/libjvm_dtrace/mapfile-vers, \
|
||||
OBJECT_DIR := $(LIBJVM_DTRACE_OUTPUTDIR)/objs, \
|
||||
STRIP_SYMBOLS := true, \
|
||||
))
|
||||
|
||||
LIBJVM_DB_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_db
|
||||
@ -206,7 +205,6 @@ ifeq ($(call check-jvm-feature, dtrace), true)
|
||||
LIBS := -lc, \
|
||||
MAPFILE := $(HOTSPOT_TOPDIR)/make/mapfiles/libjvm_db/mapfile-vers, \
|
||||
OBJECT_DIR := $(LIBJVM_DB_OUTPUTDIR)/objs, \
|
||||
STRIP_SYMBOLS := true, \
|
||||
))
|
||||
|
||||
# We need the generated JvmOffsets.h before we can compile the libjvm_db source code.
|
||||
|
@ -54,6 +54,13 @@ endif
|
||||
|
||||
# Disabling switch warning for clang because of test source.
|
||||
|
||||
# Note: On AIX, the gtest test classes linked into the libjvm.so push the TOC
|
||||
# size beyond 64k, so we need to link with bigtoc. However, this means that
|
||||
# -qpic=large would be advisable to lessen the performance effect of bigtoc.
|
||||
# But we want to avoid imposing -qpic=large onto the regular libjvm.so, which
|
||||
# has no problem with its TOC, so do this only for object files which are
|
||||
# exclusive to the gtest libjvm.so.
|
||||
|
||||
$(eval $(call SetupNativeCompilation, BUILD_GTEST_LIBJVM, \
|
||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
||||
LIBRARY := jvm, \
|
||||
@ -72,6 +79,7 @@ $(eval $(call SetupNativeCompilation, BUILD_GTEST_LIBJVM, \
|
||||
CFLAGS_windows := -EHsc, \
|
||||
CFLAGS_solaris := -DGTEST_HAS_EXCEPTIONS=0 -library=stlport4, \
|
||||
CFLAGS_macosx := -DGTEST_OS_MAC=1, \
|
||||
CFLAGS_aix := -qpic=large, \
|
||||
CFLAGS_DEBUG_SYMBOLS := $(JVM_CFLAGS_SYMBOLS), \
|
||||
CXXFLAGS_DEBUG_SYMBOLS := $(JVM_CFLAGS_SYMBOLS), \
|
||||
DISABLED_WARNINGS_gcc := undef, \
|
||||
@ -80,12 +88,14 @@ $(eval $(call SetupNativeCompilation, BUILD_GTEST_LIBJVM, \
|
||||
DISABLED_WARNINGS_solstudio := identexpected, \
|
||||
LDFLAGS := $(JVM_LDFLAGS), \
|
||||
LDFLAGS_solaris := -library=stlport4 $(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
LDFLAGS_aix := -bbigtoc, \
|
||||
LIBS := $(JVM_LIBS), \
|
||||
OPTIMIZATION := $(JVM_OPTIMIZATION), \
|
||||
MAPFILE := $(GTEST_JVM_MAPFILE), \
|
||||
USE_MAPFILE_FOR_SYMBOLS := true, \
|
||||
COPY_DEBUG_SYMBOLS := $(GTEST_COPY_DEBUG_SYMBOLS), \
|
||||
ZIP_EXTERNAL_DEBUG_SYMBOLS := false, \
|
||||
STRIP_SYMBOLS := false, \
|
||||
PRECOMPILED_HEADER := $(JVM_PRECOMPILED_HEADER), \
|
||||
PRECOMPILED_HEADER_EXCLUDE := gtest-all.cc gtestMain.cpp, \
|
||||
))
|
||||
|
@ -113,7 +113,6 @@ $(eval $(call SetupNativeCompilation, BUILD_LIBSA, \
|
||||
LIBS := $(SA_LIBS), \
|
||||
MAPFILE := $(SA_MAPFILE), \
|
||||
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libsa, \
|
||||
STRIP_SYMBOLS := true, \
|
||||
))
|
||||
|
||||
TARGETS += $(BUILD_LIBSA)
|
||||
|
@ -14086,7 +14086,7 @@ instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2)
|
||||
|
||||
format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t"
|
||||
"smulh rscratch2, $op1, $op2\n\t"
|
||||
"cmp rscratch2, rscratch1, ASR #31\n\t"
|
||||
"cmp rscratch2, rscratch1, ASR #63\n\t"
|
||||
"movw rscratch1, #0x80000000\n\t"
|
||||
"cselw rscratch1, rscratch1, zr, NE\n\t"
|
||||
"cmpw rscratch1, #1" %}
|
||||
@ -14094,7 +14094,7 @@ instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2)
|
||||
ins_encode %{
|
||||
__ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63
|
||||
__ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
|
||||
__ cmp(rscratch2, rscratch1, Assembler::ASR, 31); // Top is pure sign ext
|
||||
__ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext
|
||||
__ movw(rscratch1, 0x80000000); // Develop 0 (EQ),
|
||||
__ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
|
||||
__ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS
|
||||
@ -14112,7 +14112,7 @@ instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rF
|
||||
|
||||
format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t"
|
||||
"smulh rscratch2, $op1, $op2\n\t"
|
||||
"cmp rscratch2, rscratch1, ASR #31\n\t"
|
||||
"cmp rscratch2, rscratch1, ASR #63\n\t"
|
||||
"b$cmp $labl" %}
|
||||
ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST
|
||||
ins_encode %{
|
||||
@ -14120,7 +14120,7 @@ instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rF
|
||||
Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
|
||||
__ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63
|
||||
__ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
|
||||
__ cmp(rscratch2, rscratch1, Assembler::ASR, 31); // Top is pure sign ext
|
||||
__ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext
|
||||
__ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
|
||||
%}
|
||||
|
||||
|
@ -3111,7 +3111,7 @@ void LIR_Assembler::peephole(LIR_List *lir) {
|
||||
}
|
||||
|
||||
void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp_op) {
|
||||
Address addr = as_Address(src->as_address_ptr(), noreg);
|
||||
Address addr = as_Address(src->as_address_ptr());
|
||||
BasicType type = src->type();
|
||||
bool is_oop = type == T_OBJECT || type == T_ARRAY;
|
||||
|
||||
|
@ -195,95 +195,22 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
|
||||
}
|
||||
}
|
||||
|
||||
// Zero words; len is in bytes
|
||||
// Destroys all registers except addr
|
||||
// len must be a nonzero multiple of wordSize
|
||||
void C1_MacroAssembler::zero_memory(Register addr, Register len, Register t1) {
|
||||
assert_different_registers(addr, len, t1, rscratch1, rscratch2);
|
||||
|
||||
#ifdef ASSERT
|
||||
{ Label L;
|
||||
tst(len, BytesPerWord - 1);
|
||||
br(Assembler::EQ, L);
|
||||
stop("len is not a multiple of BytesPerWord");
|
||||
bind(L);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PRODUCT
|
||||
block_comment("zero memory");
|
||||
#endif
|
||||
|
||||
Label loop;
|
||||
Label entry;
|
||||
|
||||
// Algorithm:
|
||||
//
|
||||
// scratch1 = cnt & 7;
|
||||
// cnt -= scratch1;
|
||||
// p += scratch1;
|
||||
// switch (scratch1) {
|
||||
// do {
|
||||
// cnt -= 8;
|
||||
// p[-8] = 0;
|
||||
// case 7:
|
||||
// p[-7] = 0;
|
||||
// case 6:
|
||||
// p[-6] = 0;
|
||||
// // ...
|
||||
// case 1:
|
||||
// p[-1] = 0;
|
||||
// case 0:
|
||||
// p += 8;
|
||||
// } while (cnt);
|
||||
// }
|
||||
|
||||
const int unroll = 8; // Number of str(zr) instructions we'll unroll
|
||||
|
||||
lsr(len, len, LogBytesPerWord);
|
||||
andr(rscratch1, len, unroll - 1); // tmp1 = cnt % unroll
|
||||
sub(len, len, rscratch1); // cnt -= unroll
|
||||
// t1 always points to the end of the region we're about to zero
|
||||
add(t1, addr, rscratch1, Assembler::LSL, LogBytesPerWord);
|
||||
adr(rscratch2, entry);
|
||||
sub(rscratch2, rscratch2, rscratch1, Assembler::LSL, 2);
|
||||
br(rscratch2);
|
||||
bind(loop);
|
||||
sub(len, len, unroll);
|
||||
for (int i = -unroll; i < 0; i++)
|
||||
str(zr, Address(t1, i * wordSize));
|
||||
bind(entry);
|
||||
add(t1, t1, unroll * wordSize);
|
||||
cbnz(len, loop);
|
||||
}
|
||||
|
||||
// preserves obj, destroys len_in_bytes
|
||||
void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1) {
|
||||
assert(hdr_size_in_bytes >= 0, "header size must be positive or 0");
|
||||
Label done;
|
||||
assert(obj != len_in_bytes && obj != t1 && t1 != len_in_bytes, "registers must be different");
|
||||
assert((hdr_size_in_bytes & (BytesPerWord - 1)) == 0, "header size is not a multiple of BytesPerWord");
|
||||
Register index = len_in_bytes;
|
||||
// index is positive and ptr sized
|
||||
subs(index, index, hdr_size_in_bytes);
|
||||
|
||||
// len_in_bytes is positive and ptr sized
|
||||
subs(len_in_bytes, len_in_bytes, hdr_size_in_bytes);
|
||||
br(Assembler::EQ, done);
|
||||
// note: for the remaining code to work, index must be a multiple of BytesPerWord
|
||||
#ifdef ASSERT
|
||||
{ Label L;
|
||||
tst(index, BytesPerWord - 1);
|
||||
br(Assembler::EQ, L);
|
||||
stop("index is not a multiple of BytesPerWord");
|
||||
bind(L);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Preserve obj
|
||||
if (hdr_size_in_bytes)
|
||||
add(obj, obj, hdr_size_in_bytes);
|
||||
zero_memory(obj, index, t1);
|
||||
zero_memory(obj, len_in_bytes, t1);
|
||||
if (hdr_size_in_bytes)
|
||||
sub(obj, obj, hdr_size_in_bytes);
|
||||
|
||||
// done
|
||||
bind(done);
|
||||
}
|
||||
|
||||
@ -294,57 +221,59 @@ void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2,
|
||||
|
||||
try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case);
|
||||
|
||||
initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2);
|
||||
initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2, UseTLAB);
|
||||
}
|
||||
|
||||
void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2) {
|
||||
void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, bool is_tlab_allocated) {
|
||||
assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0,
|
||||
"con_size_in_bytes is not multiple of alignment");
|
||||
const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize;
|
||||
|
||||
initialize_header(obj, klass, noreg, t1, t2);
|
||||
|
||||
// clear rest of allocated space
|
||||
const Register index = t2;
|
||||
const int threshold = 16 * BytesPerWord; // approximate break even point for code size (see comments below)
|
||||
if (var_size_in_bytes != noreg) {
|
||||
mov(index, var_size_in_bytes);
|
||||
initialize_body(obj, index, hdr_size_in_bytes, t1);
|
||||
} else if (con_size_in_bytes <= threshold) {
|
||||
// use explicit null stores
|
||||
int i = hdr_size_in_bytes;
|
||||
if (i < con_size_in_bytes && (con_size_in_bytes % (2 * BytesPerWord))) {
|
||||
str(zr, Address(obj, i));
|
||||
i += BytesPerWord;
|
||||
}
|
||||
for (; i < con_size_in_bytes; i += 2 * BytesPerWord)
|
||||
stp(zr, zr, Address(obj, i));
|
||||
} else if (con_size_in_bytes > hdr_size_in_bytes) {
|
||||
block_comment("zero memory");
|
||||
// use loop to null out the fields
|
||||
if (!(UseTLAB && ZeroTLAB && is_tlab_allocated)) {
|
||||
// clear rest of allocated space
|
||||
const Register index = t2;
|
||||
const int threshold = 16 * BytesPerWord; // approximate break even point for code size (see comments below)
|
||||
if (var_size_in_bytes != noreg) {
|
||||
mov(index, var_size_in_bytes);
|
||||
initialize_body(obj, index, hdr_size_in_bytes, t1);
|
||||
} else if (con_size_in_bytes <= threshold) {
|
||||
// use explicit null stores
|
||||
int i = hdr_size_in_bytes;
|
||||
if (i < con_size_in_bytes && (con_size_in_bytes % (2 * BytesPerWord))) {
|
||||
str(zr, Address(obj, i));
|
||||
i += BytesPerWord;
|
||||
}
|
||||
for (; i < con_size_in_bytes; i += 2 * BytesPerWord)
|
||||
stp(zr, zr, Address(obj, i));
|
||||
} else if (con_size_in_bytes > hdr_size_in_bytes) {
|
||||
block_comment("zero memory");
|
||||
// use loop to null out the fields
|
||||
|
||||
int words = (con_size_in_bytes - hdr_size_in_bytes) / BytesPerWord;
|
||||
mov(index, words / 8);
|
||||
int words = (con_size_in_bytes - hdr_size_in_bytes) / BytesPerWord;
|
||||
mov(index, words / 8);
|
||||
|
||||
const int unroll = 8; // Number of str(zr) instructions we'll unroll
|
||||
int remainder = words % unroll;
|
||||
lea(rscratch1, Address(obj, hdr_size_in_bytes + remainder * BytesPerWord));
|
||||
const int unroll = 8; // Number of str(zr) instructions we'll unroll
|
||||
int remainder = words % unroll;
|
||||
lea(rscratch1, Address(obj, hdr_size_in_bytes + remainder * BytesPerWord));
|
||||
|
||||
Label entry_point, loop;
|
||||
b(entry_point);
|
||||
Label entry_point, loop;
|
||||
b(entry_point);
|
||||
|
||||
bind(loop);
|
||||
sub(index, index, 1);
|
||||
for (int i = -unroll; i < 0; i++) {
|
||||
if (-i == remainder)
|
||||
bind(entry_point);
|
||||
str(zr, Address(rscratch1, i * wordSize));
|
||||
}
|
||||
if (remainder == 0)
|
||||
bind(entry_point);
|
||||
add(rscratch1, rscratch1, unroll * wordSize);
|
||||
cbnz(index, loop);
|
||||
bind(loop);
|
||||
sub(index, index, 1);
|
||||
for (int i = -unroll; i < 0; i++) {
|
||||
if (-i == remainder)
|
||||
bind(entry_point);
|
||||
str(zr, Address(rscratch1, i * wordSize));
|
||||
}
|
||||
if (remainder == 0)
|
||||
bind(entry_point);
|
||||
add(rscratch1, rscratch1, unroll * wordSize);
|
||||
cbnz(index, loop);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
membar(StoreStore);
|
||||
|
@ -36,7 +36,6 @@ using MacroAssembler::null_check;
|
||||
// initialization
|
||||
void pd_init() { _rsp_offset = 0; }
|
||||
|
||||
void zero_memory(Register addr, Register len, Register t1);
|
||||
|
||||
public:
|
||||
void try_allocate(
|
||||
@ -75,7 +74,8 @@ void zero_memory(Register addr, Register len, Register t1);
|
||||
Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
|
||||
int con_size_in_bytes, // object size in bytes if known at compile time
|
||||
Register t1, // temp register
|
||||
Register t2 // temp register
|
||||
Register t2, // temp register
|
||||
bool is_tlab_allocated // the object was allocated in a TLAB; relevant for the implementation of ZeroTLAB
|
||||
);
|
||||
|
||||
// allocation of fixed-size objects
|
||||
|
@ -728,7 +728,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
|
||||
__ tlab_allocate(obj, obj_size, 0, t1, t2, slow_path);
|
||||
|
||||
__ initialize_object(obj, klass, obj_size, 0, t1, t2);
|
||||
__ initialize_object(obj, klass, obj_size, 0, t1, t2, /* is_tlab_allocated */ true);
|
||||
__ verify_oop(obj);
|
||||
__ ldp(r5, r19, Address(__ post(sp, 2 * wordSize)));
|
||||
__ ret(lr);
|
||||
@ -740,7 +740,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
__ eden_allocate(obj, obj_size, 0, t1, slow_path);
|
||||
__ incr_allocated_bytes(rthread, obj_size, 0, rscratch1);
|
||||
|
||||
__ initialize_object(obj, klass, obj_size, 0, t1, t2);
|
||||
__ initialize_object(obj, klass, obj_size, 0, t1, t2, /* is_tlab_allocated */ false);
|
||||
__ verify_oop(obj);
|
||||
__ ldp(r5, r19, Address(__ post(sp, 2 * wordSize)));
|
||||
__ ret(lr);
|
||||
@ -853,7 +853,9 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
__ andr(t1, t1, Klass::_lh_header_size_mask);
|
||||
__ sub(arr_size, arr_size, t1); // body length
|
||||
__ add(t1, t1, obj); // body start
|
||||
__ initialize_body(t1, arr_size, 0, t2);
|
||||
if (!ZeroTLAB) {
|
||||
__ initialize_body(t1, arr_size, 0, t2);
|
||||
}
|
||||
__ verify_oop(obj);
|
||||
|
||||
__ ret(lr);
|
||||
|
@ -3944,12 +3944,82 @@ Register MacroAssembler::tlab_refill(Label& retry,
|
||||
add(top, top, t1);
|
||||
sub(top, top, (int32_t)ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
|
||||
str(top, Address(rthread, in_bytes(JavaThread::tlab_end_offset())));
|
||||
|
||||
if (ZeroTLAB) {
|
||||
// This is a fast TLAB refill, therefore the GC is not notified of it.
|
||||
// So compiled code must fill the new TLAB with zeroes.
|
||||
ldr(top, Address(rthread, in_bytes(JavaThread::tlab_start_offset())));
|
||||
zero_memory(top,t1,t2);
|
||||
}
|
||||
|
||||
verify_tlab();
|
||||
b(retry);
|
||||
|
||||
return rthread; // for use by caller
|
||||
}
|
||||
|
||||
// Zero words; len is in bytes
|
||||
// Destroys all registers except addr
|
||||
// len must be a nonzero multiple of wordSize
|
||||
void MacroAssembler::zero_memory(Register addr, Register len, Register t1) {
|
||||
assert_different_registers(addr, len, t1, rscratch1, rscratch2);
|
||||
|
||||
#ifdef ASSERT
|
||||
{ Label L;
|
||||
tst(len, BytesPerWord - 1);
|
||||
br(Assembler::EQ, L);
|
||||
stop("len is not a multiple of BytesPerWord");
|
||||
bind(L);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PRODUCT
|
||||
block_comment("zero memory");
|
||||
#endif
|
||||
|
||||
Label loop;
|
||||
Label entry;
|
||||
|
||||
// Algorithm:
|
||||
//
|
||||
// scratch1 = cnt & 7;
|
||||
// cnt -= scratch1;
|
||||
// p += scratch1;
|
||||
// switch (scratch1) {
|
||||
// do {
|
||||
// cnt -= 8;
|
||||
// p[-8] = 0;
|
||||
// case 7:
|
||||
// p[-7] = 0;
|
||||
// case 6:
|
||||
// p[-6] = 0;
|
||||
// // ...
|
||||
// case 1:
|
||||
// p[-1] = 0;
|
||||
// case 0:
|
||||
// p += 8;
|
||||
// } while (cnt);
|
||||
// }
|
||||
|
||||
const int unroll = 8; // Number of str(zr) instructions we'll unroll
|
||||
|
||||
lsr(len, len, LogBytesPerWord);
|
||||
andr(rscratch1, len, unroll - 1); // tmp1 = cnt % unroll
|
||||
sub(len, len, rscratch1); // cnt -= unroll
|
||||
// t1 always points to the end of the region we're about to zero
|
||||
add(t1, addr, rscratch1, Assembler::LSL, LogBytesPerWord);
|
||||
adr(rscratch2, entry);
|
||||
sub(rscratch2, rscratch2, rscratch1, Assembler::LSL, 2);
|
||||
br(rscratch2);
|
||||
bind(loop);
|
||||
sub(len, len, unroll);
|
||||
for (int i = -unroll; i < 0; i++)
|
||||
str(zr, Address(t1, i * wordSize));
|
||||
bind(entry);
|
||||
add(t1, t1, unroll * wordSize);
|
||||
cbnz(len, loop);
|
||||
}
|
||||
|
||||
// Defines obj, preserves var_size_in_bytes
|
||||
void MacroAssembler::eden_allocate(Register obj,
|
||||
Register var_size_in_bytes,
|
||||
|
@ -857,6 +857,7 @@ public:
|
||||
Label& slow_case // continuation point if fast allocation fails
|
||||
);
|
||||
Register tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); // returns TLS address
|
||||
void zero_memory(Register addr, Register len, Register t1);
|
||||
void verify_tlab();
|
||||
|
||||
void incr_allocated_bytes(Register thread,
|
||||
|
@ -282,7 +282,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
regs[i].set_bad();
|
||||
break;
|
||||
case T_LONG:
|
||||
assert(sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
// fall through
|
||||
case T_OBJECT:
|
||||
case T_ARRAY:
|
||||
@ -303,7 +303,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
assert(sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
if (fp_args < Argument::n_float_register_parameters_j) {
|
||||
regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg());
|
||||
} else {
|
||||
@ -840,7 +840,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
break;
|
||||
case T_LONG:
|
||||
assert(sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
// fall through
|
||||
case T_OBJECT:
|
||||
case T_ARRAY:
|
||||
@ -862,7 +862,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
assert(sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
if (fp_args < Argument::n_float_register_parameters_c) {
|
||||
regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg());
|
||||
} else {
|
||||
|
@ -453,7 +453,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
break;
|
||||
case T_LONG:
|
||||
assert(sig_bt[i+1] == T_VOID, "missing Half" );
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "missing Half" );
|
||||
// fall through
|
||||
case T_ARRAY:
|
||||
case T_OBJECT:
|
||||
@ -478,7 +478,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
assert(sig_bt[i+1] == T_VOID, "missing Half" );
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "missing Half" );
|
||||
if (fp_reg < FPR_PARAMS) {
|
||||
FloatRegister r = as_FloatRegister(fp_reg);
|
||||
regs[i].set2(r->as_VMReg());
|
||||
@ -532,7 +532,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||
#ifndef __ABI_HARD__
|
||||
case T_DOUBLE:
|
||||
#endif // !__ABI_HARD__
|
||||
assert(sig_bt[i+1] == T_VOID, "missing Half" );
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "missing Half" );
|
||||
if (ireg <= 2) {
|
||||
#if (ALIGN_WIDE_ARGUMENTS == 1)
|
||||
if(ireg & 1) ireg++; // Aligned location required
|
||||
|
@ -51,19 +51,25 @@ int AbstractInterpreter::BasicType_as_index(BasicType type) {
|
||||
return i;
|
||||
}
|
||||
|
||||
// Support abs and sqrt like in compiler.
|
||||
// For others we can use a normal (native) entry.
|
||||
bool AbstractInterpreter::math_entry_available(AbstractInterpreter::MethodKind kind) {
|
||||
if (!InlineIntrinsics) return false;
|
||||
|
||||
return ((kind==Interpreter::java_lang_math_sqrt && VM_Version::has_fsqrt()) ||
|
||||
(kind==Interpreter::java_lang_math_abs));
|
||||
}
|
||||
|
||||
// These should never be compiled since the interpreter will prefer
|
||||
// the compiled version to the intrinsic version.
|
||||
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
|
||||
return !math_entry_available(method_kind(m));
|
||||
switch (method_kind(m)) {
|
||||
case Interpreter::java_lang_math_sin : // fall thru
|
||||
case Interpreter::java_lang_math_cos : // fall thru
|
||||
case Interpreter::java_lang_math_tan : // fall thru
|
||||
case Interpreter::java_lang_math_abs : // fall thru
|
||||
case Interpreter::java_lang_math_log : // fall thru
|
||||
case Interpreter::java_lang_math_log10 : // fall thru
|
||||
case Interpreter::java_lang_math_sqrt : // fall thru
|
||||
case Interpreter::java_lang_math_pow : // fall thru
|
||||
case Interpreter::java_lang_math_exp : // fall thru
|
||||
case Interpreter::java_lang_math_fmaD : // fall thru
|
||||
case Interpreter::java_lang_math_fmaF :
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// How much stack a method activation needs in stack slots.
|
||||
|
@ -460,16 +460,15 @@ class Assembler : public AbstractAssembler {
|
||||
FCTIWZ_OPCODE = (63u << OPCODE_SHIFT | 15u << 1),
|
||||
FRSP_OPCODE = (63u << OPCODE_SHIFT | 12u << 1),
|
||||
|
||||
// WARNING: using fmadd results in a non-compliant vm. Some floating
|
||||
// point tck tests will fail.
|
||||
FMADD_OPCODE = (59u << OPCODE_SHIFT | 29u << 1),
|
||||
DMADD_OPCODE = (63u << OPCODE_SHIFT | 29u << 1),
|
||||
FMSUB_OPCODE = (59u << OPCODE_SHIFT | 28u << 1),
|
||||
DMSUB_OPCODE = (63u << OPCODE_SHIFT | 28u << 1),
|
||||
FNMADD_OPCODE = (59u << OPCODE_SHIFT | 31u << 1),
|
||||
DNMADD_OPCODE = (63u << OPCODE_SHIFT | 31u << 1),
|
||||
FNMSUB_OPCODE = (59u << OPCODE_SHIFT | 30u << 1),
|
||||
DNMSUB_OPCODE = (63u << OPCODE_SHIFT | 30u << 1),
|
||||
// Fused multiply-accumulate instructions.
|
||||
FMADD_OPCODE = (63u << OPCODE_SHIFT | 29u << 1),
|
||||
FMADDS_OPCODE = (59u << OPCODE_SHIFT | 29u << 1),
|
||||
FMSUB_OPCODE = (63u << OPCODE_SHIFT | 28u << 1),
|
||||
FMSUBS_OPCODE = (59u << OPCODE_SHIFT | 28u << 1),
|
||||
FNMADD_OPCODE = (63u << OPCODE_SHIFT | 31u << 1),
|
||||
FNMADDS_OPCODE = (59u << OPCODE_SHIFT | 31u << 1),
|
||||
FNMSUB_OPCODE = (63u << OPCODE_SHIFT | 30u << 1),
|
||||
FNMSUBS_OPCODE = (59u << OPCODE_SHIFT | 30u << 1),
|
||||
|
||||
LFD_OPCODE = (50u << OPCODE_SHIFT | 00u << 1),
|
||||
LFDU_OPCODE = (51u << OPCODE_SHIFT | 00u << 1),
|
||||
@ -1939,6 +1938,26 @@ class Assembler : public AbstractAssembler {
|
||||
inline void fdivs( FloatRegister d, FloatRegister a, FloatRegister b);
|
||||
inline void fdivs_(FloatRegister d, FloatRegister a, FloatRegister b);
|
||||
|
||||
// Fused multiply-accumulate instructions.
|
||||
// WARNING: Use only when rounding between the 2 parts is not desired.
|
||||
// Some floating point tck tests will fail if used incorrectly.
|
||||
inline void fmadd( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
inline void fmadd_( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
inline void fmadds( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
inline void fmadds_( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
inline void fmsub( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
inline void fmsub_( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
inline void fmsubs( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
inline void fmsubs_( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
inline void fnmadd( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
inline void fnmadd_( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
inline void fnmadds( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
inline void fnmadds_(FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
inline void fnmsub( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
inline void fnmsub_( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
inline void fnmsubs( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
inline void fnmsubs_(FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b);
|
||||
|
||||
// PPC 1, section 4.6.6 Floating-Point Rounding and Conversion Instructions
|
||||
inline void frsp( FloatRegister d, FloatRegister b);
|
||||
inline void fctid( FloatRegister d, FloatRegister b);
|
||||
|
@ -700,6 +700,26 @@ inline void Assembler::fdiv_( FloatRegister d, FloatRegister a, FloatRegister b)
|
||||
inline void Assembler::fdivs( FloatRegister d, FloatRegister a, FloatRegister b) { emit_int32( FDIVS_OPCODE | frt(d) | fra(a) | frb(b) | rc(0)); }
|
||||
inline void Assembler::fdivs_(FloatRegister d, FloatRegister a, FloatRegister b) { emit_int32( FDIVS_OPCODE | frt(d) | fra(a) | frb(b) | rc(1)); }
|
||||
|
||||
// Fused multiply-accumulate instructions.
|
||||
// WARNING: Use only when rounding between the 2 parts is not desired.
|
||||
// Some floating point tck tests will fail if used incorrectly.
|
||||
inline void Assembler::fmadd( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FMADD_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(0)); }
|
||||
inline void Assembler::fmadd_( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FMADD_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(1)); }
|
||||
inline void Assembler::fmadds( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FMADDS_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(0)); }
|
||||
inline void Assembler::fmadds_( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FMADDS_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(1)); }
|
||||
inline void Assembler::fmsub( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FMSUB_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(0)); }
|
||||
inline void Assembler::fmsub_( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FMSUB_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(1)); }
|
||||
inline void Assembler::fmsubs( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FMSUBS_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(0)); }
|
||||
inline void Assembler::fmsubs_( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FMSUBS_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(1)); }
|
||||
inline void Assembler::fnmadd( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FNMADD_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(0)); }
|
||||
inline void Assembler::fnmadd_( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FNMADD_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(1)); }
|
||||
inline void Assembler::fnmadds( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FNMADDS_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(0)); }
|
||||
inline void Assembler::fnmadds_(FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FNMADDS_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(1)); }
|
||||
inline void Assembler::fnmsub( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FNMSUB_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(0)); }
|
||||
inline void Assembler::fnmsub_( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FNMSUB_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(1)); }
|
||||
inline void Assembler::fnmsubs( FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FNMSUBS_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(0)); }
|
||||
inline void Assembler::fnmsubs_(FloatRegister d, FloatRegister a, FloatRegister c, FloatRegister b) { emit_int32( FNMSUBS_OPCODE | frt(d) | fra(a) | frb(b) | frc(c) | rc(1)); }
|
||||
|
||||
// PPC 1, section 4.6.6 Floating-Point Rounding and Conversion Instructions
|
||||
inline void Assembler::frsp( FloatRegister d, FloatRegister b) { emit_int32( FRSP_OPCODE | frt(d) | frb(b) | rc(0)); }
|
||||
inline void Assembler::fctid( FloatRegister d, FloatRegister b) { emit_int32( FCTID_OPCODE | frt(d) | frb(b) | rc(0)); }
|
||||
|
@ -292,28 +292,28 @@ void LIR_Assembler::klass2reg_with_patching(Register reg, CodeEmitInfo *info) {
|
||||
}
|
||||
|
||||
|
||||
void LIR_Assembler::emit_op3(LIR_Op3* op) {
|
||||
const bool is_int = op->result_opr()->is_single_cpu();
|
||||
Register Rdividend = is_int ? op->in_opr1()->as_register() : op->in_opr1()->as_register_lo();
|
||||
void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info) {
|
||||
const bool is_int = result->is_single_cpu();
|
||||
Register Rdividend = is_int ? left->as_register() : left->as_register_lo();
|
||||
Register Rdivisor = noreg;
|
||||
Register Rscratch = op->in_opr3()->as_register();
|
||||
Register Rresult = is_int ? op->result_opr()->as_register() : op->result_opr()->as_register_lo();
|
||||
Register Rscratch = temp->as_register();
|
||||
Register Rresult = is_int ? result->as_register() : result->as_register_lo();
|
||||
long divisor = -1;
|
||||
|
||||
if (op->in_opr2()->is_register()) {
|
||||
Rdivisor = is_int ? op->in_opr2()->as_register() : op->in_opr2()->as_register_lo();
|
||||
if (right->is_register()) {
|
||||
Rdivisor = is_int ? right->as_register() : right->as_register_lo();
|
||||
} else {
|
||||
divisor = is_int ? op->in_opr2()->as_constant_ptr()->as_jint()
|
||||
: op->in_opr2()->as_constant_ptr()->as_jlong();
|
||||
divisor = is_int ? right->as_constant_ptr()->as_jint()
|
||||
: right->as_constant_ptr()->as_jlong();
|
||||
}
|
||||
|
||||
assert(Rdividend != Rscratch, "");
|
||||
assert(Rdivisor != Rscratch, "");
|
||||
assert(op->code() == lir_idiv || op->code() == lir_irem, "Must be irem or idiv");
|
||||
assert(code == lir_idiv || code == lir_irem, "Must be irem or idiv");
|
||||
|
||||
if (Rdivisor == noreg) {
|
||||
if (divisor == 1) { // stupid, but can happen
|
||||
if (op->code() == lir_idiv) {
|
||||
if (code == lir_idiv) {
|
||||
__ mr_if_needed(Rresult, Rdividend);
|
||||
} else {
|
||||
__ li(Rresult, 0);
|
||||
@ -340,7 +340,7 @@ void LIR_Assembler::emit_op3(LIR_Op3* op) {
|
||||
}
|
||||
__ add(Rscratch, Rdividend, Rscratch);
|
||||
|
||||
if (op->code() == lir_idiv) {
|
||||
if (code == lir_idiv) {
|
||||
if (is_int) {
|
||||
__ srawi(Rresult, Rscratch, log2);
|
||||
} else {
|
||||
@ -352,7 +352,7 @@ void LIR_Assembler::emit_op3(LIR_Op3* op) {
|
||||
}
|
||||
|
||||
} else if (divisor == -1) {
|
||||
if (op->code() == lir_idiv) {
|
||||
if (code == lir_idiv) {
|
||||
__ neg(Rresult, Rdividend);
|
||||
} else {
|
||||
__ li(Rresult, 0);
|
||||
@ -360,7 +360,7 @@ void LIR_Assembler::emit_op3(LIR_Op3* op) {
|
||||
|
||||
} else {
|
||||
__ load_const_optimized(Rscratch, divisor);
|
||||
if (op->code() == lir_idiv) {
|
||||
if (code == lir_idiv) {
|
||||
if (is_int) {
|
||||
__ divw(Rresult, Rdividend, Rscratch); // Can't divide minint/-1.
|
||||
} else {
|
||||
@ -389,7 +389,7 @@ void LIR_Assembler::emit_op3(LIR_Op3* op) {
|
||||
__ cmpdi(CCR0, Rdivisor, -1);
|
||||
}
|
||||
__ bne(CCR0, regular);
|
||||
if (op->code() == lir_idiv) {
|
||||
if (code == lir_idiv) {
|
||||
__ neg(Rresult, Rdividend);
|
||||
__ b(done);
|
||||
__ bind(regular);
|
||||
@ -415,6 +415,26 @@ void LIR_Assembler::emit_op3(LIR_Op3* op) {
|
||||
}
|
||||
|
||||
|
||||
void LIR_Assembler::emit_op3(LIR_Op3* op) {
|
||||
switch (op->code()) {
|
||||
case lir_idiv:
|
||||
case lir_irem:
|
||||
arithmetic_idiv(op->code(), op->in_opr1(), op->in_opr2(), op->in_opr3(),
|
||||
op->result_opr(), op->info());
|
||||
break;
|
||||
case lir_fmad:
|
||||
__ fmadd(op->result_opr()->as_double_reg(), op->in_opr1()->as_double_reg(),
|
||||
op->in_opr2()->as_double_reg(), op->in_opr3()->as_double_reg());
|
||||
break;
|
||||
case lir_fmaf:
|
||||
__ fmadds(op->result_opr()->as_float_reg(), op->in_opr1()->as_float_reg(),
|
||||
op->in_opr2()->as_float_reg(), op->in_opr3()->as_float_reg());
|
||||
break;
|
||||
default: ShouldNotReachHere(); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LIR_Assembler::emit_opBranch(LIR_OpBranch* op) {
|
||||
#ifdef ASSERT
|
||||
assert(op->block() == NULL || op->block()->label() == op->label(), "wrong label");
|
||||
|
@ -1435,7 +1435,26 @@ void LIRGenerator::do_update_CRC32(Intrinsic* x) {
|
||||
}
|
||||
|
||||
void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {
|
||||
fatal("FMA intrinsic is not implemented on this platform");
|
||||
assert(x->number_of_arguments() == 3, "wrong type");
|
||||
assert(UseFMA, "Needs FMA instructions support.");
|
||||
LIRItem value(x->argument_at(0), this);
|
||||
LIRItem value1(x->argument_at(1), this);
|
||||
LIRItem value2(x->argument_at(2), this);
|
||||
|
||||
value.load_item();
|
||||
value1.load_item();
|
||||
value2.load_item();
|
||||
|
||||
LIR_Opr calc_input = value.result();
|
||||
LIR_Opr calc_input1 = value1.result();
|
||||
LIR_Opr calc_input2 = value2.result();
|
||||
LIR_Opr calc_result = rlock_result(x);
|
||||
|
||||
switch (x->id()) {
|
||||
case vmIntrinsics::_fmaD: __ fmad(calc_input, calc_input1, calc_input2, calc_result); break;
|
||||
case vmIntrinsics::_fmaF: __ fmaf(calc_input, calc_input1, calc_input2, calc_result); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {
|
||||
|
@ -42,6 +42,9 @@ define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs pas
|
||||
|
||||
#define DEFAULT_STACK_YELLOW_PAGES (2)
|
||||
#define DEFAULT_STACK_RED_PAGES (1)
|
||||
// Java_java_net_SocketOutputStream_socketWrite0() uses a 64k buffer on the
|
||||
// stack if compiled for unix and LP64. To pass stack overflow tests we need
|
||||
// 20 shadow pages.
|
||||
#define DEFAULT_STACK_SHADOW_PAGES (20 DEBUG_ONLY(+2))
|
||||
#define DEFAULT_STACK_RESERVED_PAGES (1)
|
||||
|
||||
|
@ -9569,6 +9569,117 @@ instruct roundFloat_nop(regF dst) %{
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
|
||||
// Multiply-Accumulate
|
||||
// src1 * src2 + src3
|
||||
instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
|
||||
match(Set dst (FmaF src3 (Binary src1 src2)));
|
||||
|
||||
format %{ "FMADDS $dst, $src1, $src2, $src3" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
// TODO: PPC port $archOpcode(ppc64Opcode_fmadds);
|
||||
__ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
// src1 * src2 + src3
|
||||
instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
|
||||
match(Set dst (FmaD src3 (Binary src1 src2)));
|
||||
|
||||
format %{ "FMADD $dst, $src1, $src2, $src3" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
// TODO: PPC port $archOpcode(ppc64Opcode_fmadd);
|
||||
__ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
// -src1 * src2 + src3 = -(src1*src2-src3)
|
||||
instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
|
||||
match(Set dst (FmaF src3 (Binary (NegF src1) src2)));
|
||||
match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
|
||||
|
||||
format %{ "FNMSUBS $dst, $src1, $src2, $src3" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
// TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs);
|
||||
__ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
// -src1 * src2 + src3 = -(src1*src2-src3)
|
||||
instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
|
||||
match(Set dst (FmaD src3 (Binary (NegD src1) src2)));
|
||||
match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
|
||||
|
||||
format %{ "FNMSUB $dst, $src1, $src2, $src3" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
// TODO: PPC port $archOpcode(ppc64Opcode_fnmsub);
|
||||
__ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
// -src1 * src2 - src3 = -(src1*src2+src3)
|
||||
instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
|
||||
match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2)));
|
||||
match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
|
||||
|
||||
format %{ "FNMADDS $dst, $src1, $src2, $src3" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
// TODO: PPC port $archOpcode(ppc64Opcode_fnmadds);
|
||||
__ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
// -src1 * src2 - src3 = -(src1*src2+src3)
|
||||
instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
|
||||
match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2)));
|
||||
match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
|
||||
|
||||
format %{ "FNMADD $dst, $src1, $src2, $src3" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
// TODO: PPC port $archOpcode(ppc64Opcode_fnmadd);
|
||||
__ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
// src1 * src2 - src3
|
||||
instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
|
||||
match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
|
||||
|
||||
format %{ "FMSUBS $dst, $src1, $src2, $src3" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
// TODO: PPC port $archOpcode(ppc64Opcode_fmsubs);
|
||||
__ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
// src1 * src2 - src3
|
||||
instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
|
||||
match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
|
||||
|
||||
format %{ "FMSUB $dst, $src1, $src2, $src3" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
// TODO: PPC port $archOpcode(ppc64Opcode_fmsub);
|
||||
__ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
|
||||
//----------Logical Instructions-----------------------------------------------
|
||||
|
||||
// And Instructions
|
||||
|
@ -594,7 +594,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
regs[i].set1(reg);
|
||||
break;
|
||||
case T_LONG:
|
||||
assert(sig_bt[i+1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "expecting half");
|
||||
if (ireg < num_java_iarg_registers) {
|
||||
// Put long in register.
|
||||
reg = java_iarg_reg[ireg];
|
||||
@ -637,7 +637,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
regs[i].set1(reg);
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
assert(sig_bt[i+1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "expecting half");
|
||||
if (freg < num_java_farg_registers) {
|
||||
// Put double in register.
|
||||
reg = java_farg_reg[freg];
|
||||
@ -809,7 +809,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||
regs[i].set1(reg);
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
assert(sig_bt[i+1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "expecting half");
|
||||
if (freg < Argument::n_float_register_parameters_c) {
|
||||
// Put double in register ...
|
||||
reg = farg_reg[freg];
|
||||
|
@ -1134,14 +1134,57 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist
|
||||
// End of helpers
|
||||
|
||||
address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
|
||||
if (!Interpreter::math_entry_available(kind)) {
|
||||
NOT_PRODUCT(__ should_not_reach_here();)
|
||||
return NULL;
|
||||
|
||||
// Decide what to do: Use same platform specific instructions and runtime calls as compilers.
|
||||
bool use_instruction = false;
|
||||
address runtime_entry = NULL;
|
||||
int num_args = 1;
|
||||
bool double_precision = true;
|
||||
|
||||
// PPC64 specific:
|
||||
switch (kind) {
|
||||
case Interpreter::java_lang_math_sqrt: use_instruction = VM_Version::has_fsqrt(); break;
|
||||
case Interpreter::java_lang_math_abs: use_instruction = true; break;
|
||||
case Interpreter::java_lang_math_fmaF:
|
||||
case Interpreter::java_lang_math_fmaD: use_instruction = UseFMA; break;
|
||||
default: break; // Fall back to runtime call.
|
||||
}
|
||||
|
||||
switch (kind) {
|
||||
case Interpreter::java_lang_math_sin : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsin); break;
|
||||
case Interpreter::java_lang_math_cos : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dcos); break;
|
||||
case Interpreter::java_lang_math_tan : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dtan); break;
|
||||
case Interpreter::java_lang_math_abs : /* run interpreted */ break;
|
||||
case Interpreter::java_lang_math_sqrt : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsqrt); break;
|
||||
case Interpreter::java_lang_math_log : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog); break;
|
||||
case Interpreter::java_lang_math_log10: runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10); break;
|
||||
case Interpreter::java_lang_math_pow : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dpow); num_args = 2; break;
|
||||
case Interpreter::java_lang_math_exp : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dexp); break;
|
||||
case Interpreter::java_lang_math_fmaF : /* run interpreted */ num_args = 3; double_precision = false; break;
|
||||
case Interpreter::java_lang_math_fmaD : /* run interpreted */ num_args = 3; break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
|
||||
// Use normal entry if neither instruction nor runtime call is used.
|
||||
if (!use_instruction && runtime_entry == NULL) return NULL;
|
||||
|
||||
address entry = __ pc();
|
||||
|
||||
__ lfd(F1_RET, Interpreter::stackElementSize, R15_esp);
|
||||
// Load arguments
|
||||
assert(num_args <= 13, "passed in registers");
|
||||
if (double_precision) {
|
||||
int offset = (2 * num_args - 1) * Interpreter::stackElementSize;
|
||||
for (int i = 0; i < num_args; ++i) {
|
||||
__ lfd(as_FloatRegister(F1_ARG1->encoding() + i), offset, R15_esp);
|
||||
offset -= 2 * Interpreter::stackElementSize;
|
||||
}
|
||||
} else {
|
||||
int offset = num_args * Interpreter::stackElementSize;
|
||||
for (int i = 0; i < num_args; ++i) {
|
||||
__ lfs(as_FloatRegister(F1_ARG1->encoding() + i), offset, R15_esp);
|
||||
offset -= Interpreter::stackElementSize;
|
||||
}
|
||||
}
|
||||
|
||||
// Pop c2i arguments (if any) off when we return.
|
||||
#ifdef ASSERT
|
||||
@ -1152,15 +1195,30 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
||||
#endif // ASSERT
|
||||
__ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.
|
||||
|
||||
if (kind == Interpreter::java_lang_math_sqrt) {
|
||||
__ fsqrt(F1_RET, F1_RET);
|
||||
} else if (kind == Interpreter::java_lang_math_abs) {
|
||||
__ fabs(F1_RET, F1_RET);
|
||||
if (use_instruction) {
|
||||
switch (kind) {
|
||||
case Interpreter::java_lang_math_sqrt: __ fsqrt(F1_RET, F1); break;
|
||||
case Interpreter::java_lang_math_abs: __ fabs(F1_RET, F1); break;
|
||||
case Interpreter::java_lang_math_fmaF: __ fmadds(F1_RET, F1, F2, F3); break;
|
||||
case Interpreter::java_lang_math_fmaD: __ fmadd(F1_RET, F1, F2, F3); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
// Comment: Can use tail call if the unextended frame is always C ABI compliant:
|
||||
//__ load_const_optimized(R12_scratch2, runtime_entry, R0);
|
||||
//__ call_c_and_return_to_caller(R12_scratch2);
|
||||
|
||||
// Push a new C frame and save LR.
|
||||
__ save_LR_CR(R0);
|
||||
__ push_frame_reg_args(0, R11_scratch1);
|
||||
|
||||
__ call_VM_leaf(runtime_entry);
|
||||
|
||||
// Pop the C frame and restore LR.
|
||||
__ pop_frame();
|
||||
__ restore_LR_CR(R0);
|
||||
}
|
||||
|
||||
// And we're done.
|
||||
__ blr();
|
||||
|
||||
__ flush();
|
||||
|
@ -230,9 +230,8 @@ void VM_Version::initialize() {
|
||||
FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
|
||||
}
|
||||
|
||||
if (UseFMA) {
|
||||
warning("FMA instructions are not available on this CPU");
|
||||
FLAG_SET_DEFAULT(UseFMA, false);
|
||||
if (FLAG_IS_DEFAULT(UseFMA)) {
|
||||
FLAG_SET_DEFAULT(UseFMA, true);
|
||||
}
|
||||
|
||||
if (UseSHA) {
|
||||
|
@ -790,6 +790,16 @@ class Assembler : public AbstractAssembler {
|
||||
#define MDB_ZOPC (unsigned long)(237L << 40 | 28)
|
||||
#define MXDB_ZOPC (unsigned long)(237L << 40 | 7)
|
||||
|
||||
// Multiply-Add
|
||||
#define MAEBR_ZOPC (unsigned int)(179 << 24 | 14 << 16)
|
||||
#define MADBR_ZOPC (unsigned int)(179 << 24 | 30 << 16)
|
||||
#define MSEBR_ZOPC (unsigned int)(179 << 24 | 15 << 16)
|
||||
#define MSDBR_ZOPC (unsigned int)(179 << 24 | 31 << 16)
|
||||
#define MAEB_ZOPC (unsigned long)(237L << 40 | 14)
|
||||
#define MADB_ZOPC (unsigned long)(237L << 40 | 30)
|
||||
#define MSEB_ZOPC (unsigned long)(237L << 40 | 15)
|
||||
#define MSDB_ZOPC (unsigned long)(237L << 40 | 31)
|
||||
|
||||
// Divide
|
||||
// RR, signed
|
||||
#define DSGFR_ZOPC (unsigned int)(0xb91d << 16)
|
||||
@ -2205,6 +2215,20 @@ class Assembler : public AbstractAssembler {
|
||||
inline void z_meeb( FloatRegister f1, const Address& a);
|
||||
inline void z_mdb( FloatRegister f1, const Address& a);
|
||||
|
||||
// MUL-ADD
|
||||
inline void z_maebr(FloatRegister f1, FloatRegister f3, FloatRegister f2); // f1 = f3 * f2 + f1 ; float
|
||||
inline void z_madbr(FloatRegister f1, FloatRegister f3, FloatRegister f2); // f1 = f3 * f2 + f1 ; double
|
||||
inline void z_msebr(FloatRegister f1, FloatRegister f3, FloatRegister f2); // f1 = f3 * f2 - f1 ; float
|
||||
inline void z_msdbr(FloatRegister f1, FloatRegister f3, FloatRegister f2); // f1 = f3 * f2 - f1 ; double
|
||||
inline void z_maeb(FloatRegister f1, FloatRegister f3, int64_t d2, Register x2, Register b2); // f1 = f3 * *(d2+x2+b2) + f1 ; float
|
||||
inline void z_madb(FloatRegister f1, FloatRegister f3, int64_t d2, Register x2, Register b2); // f1 = f3 * *(d2+x2+b2) + f1 ; double
|
||||
inline void z_mseb(FloatRegister f1, FloatRegister f3, int64_t d2, Register x2, Register b2); // f1 = f3 * *(d2+x2+b2) - f1 ; float
|
||||
inline void z_msdb(FloatRegister f1, FloatRegister f3, int64_t d2, Register x2, Register b2); // f1 = f3 * *(d2+x2+b2) - f1 ; double
|
||||
inline void z_maeb(FloatRegister f1, FloatRegister f3, const Address& a);
|
||||
inline void z_madb(FloatRegister f1, FloatRegister f3, const Address& a);
|
||||
inline void z_mseb(FloatRegister f1, FloatRegister f3, const Address& a);
|
||||
inline void z_msdb(FloatRegister f1, FloatRegister f3, const Address& a);
|
||||
|
||||
// DIV
|
||||
inline void z_debr( FloatRegister f1, FloatRegister f2); // f1 = f1 / f2 ; float
|
||||
inline void z_ddbr( FloatRegister f1, FloatRegister f2); // f1 = f1 / f2 ; double
|
||||
|
@ -777,6 +777,23 @@ inline void Assembler::z_meeb( FloatRegister r1, const Address& a)
|
||||
inline void Assembler::z_mdb( FloatRegister r1, const Address& a) { z_mdb( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
|
||||
|
||||
|
||||
//---------------
|
||||
// MUL-ADD
|
||||
//---------------
|
||||
inline void Assembler::z_maebr(FloatRegister f1, FloatRegister f3, FloatRegister f2) { emit_32( MAEBR_ZOPC | fregt(f1, 16, 32) | freg(f3, 24, 32) | freg(f2, 28, 32) );}
|
||||
inline void Assembler::z_madbr(FloatRegister f1, FloatRegister f3, FloatRegister f2) { emit_32( MADBR_ZOPC | fregt(f1, 16, 32) | freg(f3, 24, 32) | freg(f2, 28, 32) );}
|
||||
inline void Assembler::z_msebr(FloatRegister f1, FloatRegister f3, FloatRegister f2) { emit_32( MSEBR_ZOPC | fregt(f1, 16, 32) | freg(f3, 24, 32) | freg(f2, 28, 32) );}
|
||||
inline void Assembler::z_msdbr(FloatRegister f1, FloatRegister f3, FloatRegister f2) { emit_32( MSDBR_ZOPC | fregt(f1, 16, 32) | freg(f3, 24, 32) | freg(f2, 28, 32) );}
|
||||
inline void Assembler::z_maeb(FloatRegister f1, FloatRegister f3, int64_t d2, Register x2, Register b2) { emit_48( MAEB_ZOPC | fregt(f1, 32, 48) | freg(f3, 8, 48) | uimm12(d2, 20, 48) | reg(x2, 12, 48) | regz(b2, 16, 48) );}
|
||||
inline void Assembler::z_madb(FloatRegister f1, FloatRegister f3, int64_t d2, Register x2, Register b2) { emit_48( MADB_ZOPC | fregt(f1, 32, 48) | freg(f3, 8, 48) | uimm12(d2, 20, 48) | reg(x2, 12, 48) | regz(b2, 16, 48) );}
|
||||
inline void Assembler::z_mseb(FloatRegister f1, FloatRegister f3, int64_t d2, Register x2, Register b2) { emit_48( MSEB_ZOPC | fregt(f1, 32, 48) | freg(f3, 8, 48) | uimm12(d2, 20, 48) | reg(x2, 12, 48) | regz(b2, 16, 48) );}
|
||||
inline void Assembler::z_msdb(FloatRegister f1, FloatRegister f3, int64_t d2, Register x2, Register b2) { emit_48( MSDB_ZOPC | fregt(f1, 32, 48) | freg(f3, 8, 48) | uimm12(d2, 20, 48) | reg(x2, 12, 48) | regz(b2, 16, 48) );}
|
||||
inline void Assembler::z_maeb(FloatRegister f1, FloatRegister f3, const Address& a) { z_maeb(f1, f3, a.disp(), a.indexOrR0(), a.baseOrR0()); }
|
||||
inline void Assembler::z_madb(FloatRegister f1, FloatRegister f3, const Address& a) { z_madb(f1, f3, a.disp(), a.indexOrR0(), a.baseOrR0()); }
|
||||
inline void Assembler::z_mseb(FloatRegister f1, FloatRegister f3, const Address& a) { z_mseb(f1, f3, a.disp(), a.indexOrR0(), a.baseOrR0()); }
|
||||
inline void Assembler::z_msdb(FloatRegister f1, FloatRegister f3, const Address& a) { z_msdb(f1, f3, a.disp(), a.indexOrR0(), a.baseOrR0()); }
|
||||
|
||||
|
||||
//---------------
|
||||
// DIV
|
||||
//---------------
|
||||
|
@ -324,6 +324,22 @@ void LIR_Assembler::emit_op3(LIR_Op3* op) {
|
||||
op->result_opr(),
|
||||
op->info());
|
||||
break;
|
||||
case lir_fmad: {
|
||||
const FloatRegister opr1 = op->in_opr1()->as_double_reg(),
|
||||
opr2 = op->in_opr2()->as_double_reg(),
|
||||
opr3 = op->in_opr3()->as_double_reg(),
|
||||
res = op->result_opr()->as_double_reg();
|
||||
__ z_madbr(opr3, opr1, opr2);
|
||||
if (res != opr3) { __ z_ldr(res, opr3); }
|
||||
} break;
|
||||
case lir_fmaf: {
|
||||
const FloatRegister opr1 = op->in_opr1()->as_float_reg(),
|
||||
opr2 = op->in_opr2()->as_float_reg(),
|
||||
opr3 = op->in_opr3()->as_float_reg(),
|
||||
res = op->result_opr()->as_float_reg();
|
||||
__ z_maebr(opr3, opr1, opr2);
|
||||
if (res != opr3) { __ z_ler(res, opr3); }
|
||||
} break;
|
||||
default: ShouldNotReachHere(); break;
|
||||
}
|
||||
}
|
||||
|
@ -1237,7 +1237,28 @@ void LIRGenerator::do_update_CRC32C(Intrinsic* x) {
|
||||
}
|
||||
|
||||
void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {
|
||||
fatal("FMA intrinsic is not implemented on this platform");
|
||||
assert(x->number_of_arguments() == 3, "wrong type");
|
||||
assert(UseFMA, "Needs FMA instructions support.");
|
||||
LIRItem value(x->argument_at(0), this);
|
||||
LIRItem value1(x->argument_at(1), this);
|
||||
LIRItem value2(x->argument_at(2), this);
|
||||
|
||||
value2.set_destroys_register();
|
||||
|
||||
value.load_item();
|
||||
value1.load_item();
|
||||
value2.load_item();
|
||||
|
||||
LIR_Opr calc_input = value.result();
|
||||
LIR_Opr calc_input1 = value1.result();
|
||||
LIR_Opr calc_input2 = value2.result();
|
||||
LIR_Opr calc_result = rlock_result(x);
|
||||
|
||||
switch (x->id()) {
|
||||
case vmIntrinsics::_fmaD: __ fmad(calc_input, calc_input1, calc_input2, calc_result); break;
|
||||
case vmIntrinsics::_fmaF: __ fmaf(calc_input, calc_input1, calc_input2, calc_result); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {
|
||||
|
@ -7249,6 +7249,171 @@ instruct mulD_reg_mem(regD dst, memoryRX src)%{
|
||||
ins_pipe(pipe_class_dummy);
|
||||
%}
|
||||
|
||||
// Multiply-Accumulate
|
||||
// src1 * src2 + dst
|
||||
instruct maddF_reg_reg(regF dst, regF src1, regF src2) %{
|
||||
match(Set dst (FmaF dst (Binary src1 src2)));
|
||||
// CC unchanged by MUL-ADD.
|
||||
ins_cost(ALU_REG_COST);
|
||||
size(4);
|
||||
format %{ "MAEBR $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
__ z_maebr($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_dummy);
|
||||
%}
|
||||
|
||||
// src1 * src2 + dst
|
||||
instruct maddD_reg_reg(regD dst, regD src1, regD src2) %{
|
||||
match(Set dst (FmaD dst (Binary src1 src2)));
|
||||
// CC unchanged by MUL-ADD.
|
||||
ins_cost(ALU_REG_COST);
|
||||
size(4);
|
||||
format %{ "MADBR $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
__ z_madbr($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_dummy);
|
||||
%}
|
||||
|
||||
// src1 * src2 - dst
|
||||
instruct msubF_reg_reg(regF dst, regF src1, regF src2) %{
|
||||
match(Set dst (FmaF (NegF dst) (Binary src1 src2)));
|
||||
// CC unchanged by MUL-SUB.
|
||||
ins_cost(ALU_REG_COST);
|
||||
size(4);
|
||||
format %{ "MSEBR $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
__ z_msebr($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_dummy);
|
||||
%}
|
||||
|
||||
// src1 * src2 - dst
|
||||
instruct msubD_reg_reg(regD dst, regD src1, regD src2) %{
|
||||
match(Set dst (FmaD (NegD dst) (Binary src1 src2)));
|
||||
// CC unchanged by MUL-SUB.
|
||||
ins_cost(ALU_REG_COST);
|
||||
size(4);
|
||||
format %{ "MSDBR $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
__ z_msdbr($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_dummy);
|
||||
%}
|
||||
|
||||
// src1 * src2 + dst
|
||||
instruct maddF_reg_mem(regF dst, regF src1, memoryRX src2) %{
|
||||
match(Set dst (FmaF dst (Binary src1 (LoadF src2))));
|
||||
// CC unchanged by MUL-ADD.
|
||||
ins_cost(ALU_MEMORY_COST);
|
||||
size(6);
|
||||
format %{ "MAEB $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
__ z_maeb($dst$$FloatRegister, $src1$$FloatRegister,
|
||||
Address(reg_to_register_object($src2$$base), $src2$$index$$Register, $src2$$disp));
|
||||
%}
|
||||
ins_pipe(pipe_class_dummy);
|
||||
%}
|
||||
|
||||
// src1 * src2 + dst
|
||||
instruct maddD_reg_mem(regD dst, regD src1, memoryRX src2) %{
|
||||
match(Set dst (FmaD dst (Binary src1 (LoadD src2))));
|
||||
// CC unchanged by MUL-ADD.
|
||||
ins_cost(ALU_MEMORY_COST);
|
||||
size(6);
|
||||
format %{ "MADB $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
__ z_madb($dst$$FloatRegister, $src1$$FloatRegister,
|
||||
Address(reg_to_register_object($src2$$base), $src2$$index$$Register, $src2$$disp));
|
||||
%}
|
||||
ins_pipe(pipe_class_dummy);
|
||||
%}
|
||||
|
||||
// src1 * src2 - dst
|
||||
instruct msubF_reg_mem(regF dst, regF src1, memoryRX src2) %{
|
||||
match(Set dst (FmaF (NegF dst) (Binary src1 (LoadF src2))));
|
||||
// CC unchanged by MUL-SUB.
|
||||
ins_cost(ALU_MEMORY_COST);
|
||||
size(6);
|
||||
format %{ "MSEB $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
__ z_mseb($dst$$FloatRegister, $src1$$FloatRegister,
|
||||
Address(reg_to_register_object($src2$$base), $src2$$index$$Register, $src2$$disp));
|
||||
%}
|
||||
ins_pipe(pipe_class_dummy);
|
||||
%}
|
||||
|
||||
// src1 * src2 - dst
|
||||
instruct msubD_reg_mem(regD dst, regD src1, memoryRX src2) %{
|
||||
match(Set dst (FmaD (NegD dst) (Binary src1 (LoadD src2))));
|
||||
// CC unchanged by MUL-SUB.
|
||||
ins_cost(ALU_MEMORY_COST);
|
||||
size(6);
|
||||
format %{ "MSDB $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
__ z_msdb($dst$$FloatRegister, $src1$$FloatRegister,
|
||||
Address(reg_to_register_object($src2$$base), $src2$$index$$Register, $src2$$disp));
|
||||
%}
|
||||
ins_pipe(pipe_class_dummy);
|
||||
%}
|
||||
|
||||
// src1 * src2 + dst
|
||||
instruct maddF_mem_reg(regF dst, memoryRX src1, regF src2) %{
|
||||
match(Set dst (FmaF dst (Binary (LoadF src1) src2)));
|
||||
// CC unchanged by MUL-ADD.
|
||||
ins_cost(ALU_MEMORY_COST);
|
||||
size(6);
|
||||
format %{ "MAEB $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
__ z_maeb($dst$$FloatRegister, $src2$$FloatRegister,
|
||||
Address(reg_to_register_object($src1$$base), $src1$$index$$Register, $src1$$disp));
|
||||
%}
|
||||
ins_pipe(pipe_class_dummy);
|
||||
%}
|
||||
|
||||
// src1 * src2 + dst
|
||||
instruct maddD_mem_reg(regD dst, memoryRX src1, regD src2) %{
|
||||
match(Set dst (FmaD dst (Binary (LoadD src1) src2)));
|
||||
// CC unchanged by MUL-ADD.
|
||||
ins_cost(ALU_MEMORY_COST);
|
||||
size(6);
|
||||
format %{ "MADB $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
__ z_madb($dst$$FloatRegister, $src2$$FloatRegister,
|
||||
Address(reg_to_register_object($src1$$base), $src1$$index$$Register, $src1$$disp));
|
||||
%}
|
||||
ins_pipe(pipe_class_dummy);
|
||||
%}
|
||||
|
||||
// src1 * src2 - dst
|
||||
instruct msubF_mem_reg(regF dst, memoryRX src1, regF src2) %{
|
||||
match(Set dst (FmaF (NegF dst) (Binary (LoadF src1) src2)));
|
||||
// CC unchanged by MUL-SUB.
|
||||
ins_cost(ALU_MEMORY_COST);
|
||||
size(6);
|
||||
format %{ "MSEB $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
__ z_mseb($dst$$FloatRegister, $src2$$FloatRegister,
|
||||
Address(reg_to_register_object($src1$$base), $src1$$index$$Register, $src1$$disp));
|
||||
%}
|
||||
ins_pipe(pipe_class_dummy);
|
||||
%}
|
||||
|
||||
// src1 * src2 - dst
|
||||
instruct msubD_mem_reg(regD dst, memoryRX src1, regD src2) %{
|
||||
match(Set dst (FmaD (NegD dst) (Binary (LoadD src1) src2)));
|
||||
// CC unchanged by MUL-SUB.
|
||||
ins_cost(ALU_MEMORY_COST);
|
||||
size(6);
|
||||
format %{ "MSDB $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
__ z_msdb($dst$$FloatRegister, $src2$$FloatRegister,
|
||||
Address(reg_to_register_object($src1$$base), $src1$$index$$Register, $src1$$disp));
|
||||
%}
|
||||
ins_pipe(pipe_class_dummy);
|
||||
%}
|
||||
|
||||
// DIV
|
||||
|
||||
// Div float single precision
|
||||
|
@ -683,7 +683,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
break;
|
||||
case T_LONG:
|
||||
assert(sig_bt[i+1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "expecting half");
|
||||
if (ireg < z_num_iarg_registers) {
|
||||
// Put long in register.
|
||||
regs[i].set2(z_iarg_reg[ireg]);
|
||||
@ -723,7 +723,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
assert(sig_bt[i+1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "expecting half");
|
||||
if (freg < z_num_farg_registers) {
|
||||
// Put double in register.
|
||||
regs[i].set2(z_farg_reg[freg]);
|
||||
@ -822,7 +822,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
assert(sig_bt[i+1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "expecting half");
|
||||
if (freg < z_num_farg_registers) {
|
||||
regs[i].set2(z_farg_reg[freg]);
|
||||
++freg;
|
||||
|
@ -2038,15 +2038,15 @@ class StubGenerator: public StubCodeGenerator {
|
||||
generate_push_parmBlk(keylen, fCode, parmBlk, key, cv, true);
|
||||
|
||||
// Prepare other registers for instruction.
|
||||
// __ z_lgr(src, from); // Not needed, registers are the same.
|
||||
// __ z_lgr(src, from); // Not needed, registers are the same.
|
||||
__ z_lgr(dst, to);
|
||||
__ z_lgr(srclen, msglen);
|
||||
__ z_llgfr(srclen, msglen); // We pass the offsets as ints, not as longs as required.
|
||||
|
||||
__ kmc(dst, src); // Decipher the message.
|
||||
__ kmc(dst, src); // Decipher the message.
|
||||
|
||||
generate_pop_parmBlk(keylen, parmBlk, key, cv);
|
||||
|
||||
__ z_lgr(Z_RET, msglen);
|
||||
__ z_llgfr(Z_RET, msglen); // We pass the offsets as ints, not as longs as required.
|
||||
__ z_br(Z_R14);
|
||||
|
||||
return __ addr_at(start_off);
|
||||
|
@ -1297,36 +1297,96 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
|
||||
// Math function, frame manager must set up an interpreter state, etc.
|
||||
address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
|
||||
|
||||
if (!InlineIntrinsics) { return NULL; } // Generate a vanilla entry.
|
||||
// Decide what to do: Use same platform specific instructions and runtime calls as compilers.
|
||||
bool use_instruction = false;
|
||||
address runtime_entry = NULL;
|
||||
int num_args = 1;
|
||||
bool double_precision = true;
|
||||
|
||||
// Only support absolute value and square root.
|
||||
if (kind != Interpreter::java_lang_math_abs && kind != Interpreter::java_lang_math_sqrt) {
|
||||
return NULL;
|
||||
// s390 specific:
|
||||
switch (kind) {
|
||||
case Interpreter::java_lang_math_sqrt:
|
||||
case Interpreter::java_lang_math_abs: use_instruction = true; break;
|
||||
case Interpreter::java_lang_math_fmaF:
|
||||
case Interpreter::java_lang_math_fmaD: use_instruction = UseFMA; break;
|
||||
default: break; // Fall back to runtime call.
|
||||
}
|
||||
|
||||
BLOCK_COMMENT("math_entry {");
|
||||
switch (kind) {
|
||||
case Interpreter::java_lang_math_sin : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsin); break;
|
||||
case Interpreter::java_lang_math_cos : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dcos); break;
|
||||
case Interpreter::java_lang_math_tan : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dtan); break;
|
||||
case Interpreter::java_lang_math_abs : /* run interpreted */ break;
|
||||
case Interpreter::java_lang_math_sqrt : /* runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsqrt); not available */ break;
|
||||
case Interpreter::java_lang_math_log : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog); break;
|
||||
case Interpreter::java_lang_math_log10: runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10); break;
|
||||
case Interpreter::java_lang_math_pow : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dpow); num_args = 2; break;
|
||||
case Interpreter::java_lang_math_exp : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dexp); break;
|
||||
case Interpreter::java_lang_math_fmaF : /* run interpreted */ num_args = 3; double_precision = false; break;
|
||||
case Interpreter::java_lang_math_fmaD : /* run interpreted */ num_args = 3; break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
|
||||
address math_entry = __ pc();
|
||||
// Use normal entry if neither instruction nor runtime call is used.
|
||||
if (!use_instruction && runtime_entry == NULL) return NULL;
|
||||
|
||||
if (kind == Interpreter::java_lang_math_abs) {
|
||||
// Load operand from stack.
|
||||
__ mem2freg_opt(Z_FRET, Address(Z_esp, Interpreter::stackElementSize));
|
||||
__ z_lpdbr(Z_FRET);
|
||||
address entry = __ pc();
|
||||
|
||||
if (use_instruction) {
|
||||
switch (kind) {
|
||||
case Interpreter::java_lang_math_sqrt:
|
||||
// Can use memory operand directly.
|
||||
__ z_sqdb(Z_FRET, Interpreter::stackElementSize, Z_esp);
|
||||
break;
|
||||
case Interpreter::java_lang_math_abs:
|
||||
// Load operand from stack.
|
||||
__ mem2freg_opt(Z_FRET, Address(Z_esp, Interpreter::stackElementSize));
|
||||
__ z_lpdbr(Z_FRET);
|
||||
break;
|
||||
case Interpreter::java_lang_math_fmaF:
|
||||
__ mem2freg_opt(Z_FRET, Address(Z_esp, Interpreter::stackElementSize)); // result reg = arg3
|
||||
__ mem2freg_opt(Z_FARG2, Address(Z_esp, 3 * Interpreter::stackElementSize)); // arg1
|
||||
__ z_maeb(Z_FRET, Z_FARG2, Address(Z_esp, 2 * Interpreter::stackElementSize));
|
||||
break;
|
||||
case Interpreter::java_lang_math_fmaD:
|
||||
__ mem2freg_opt(Z_FRET, Address(Z_esp, Interpreter::stackElementSize)); // result reg = arg3
|
||||
__ mem2freg_opt(Z_FARG2, Address(Z_esp, 5 * Interpreter::stackElementSize)); // arg1
|
||||
__ z_madb(Z_FRET, Z_FARG2, Address(Z_esp, 3 * Interpreter::stackElementSize));
|
||||
break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
} else {
|
||||
// sqrt
|
||||
// Can use memory operand directly.
|
||||
__ z_sqdb(Z_FRET, Interpreter::stackElementSize, Z_esp);
|
||||
// Load arguments
|
||||
assert(num_args <= 4, "passed in registers");
|
||||
if (double_precision) {
|
||||
int offset = (2 * num_args - 1) * Interpreter::stackElementSize;
|
||||
for (int i = 0; i < num_args; ++i) {
|
||||
__ mem2freg_opt(as_FloatRegister(Z_FARG1->encoding() + 2 * i), Address(Z_esp, offset));
|
||||
offset -= 2 * Interpreter::stackElementSize;
|
||||
}
|
||||
} else {
|
||||
int offset = num_args * Interpreter::stackElementSize;
|
||||
for (int i = 0; i < num_args; ++i) {
|
||||
__ mem2freg_opt(as_FloatRegister(Z_FARG1->encoding() + 2 * i), Address(Z_esp, offset));
|
||||
offset -= Interpreter::stackElementSize;
|
||||
}
|
||||
}
|
||||
// Call runtime
|
||||
__ save_return_pc(); // Save Z_R14.
|
||||
__ push_frame_abi160(0); // Without new frame the RT call could overwrite the saved Z_R14.
|
||||
|
||||
__ call_VM_leaf(runtime_entry);
|
||||
|
||||
__ pop_frame();
|
||||
__ restore_return_pc(); // Restore Z_R14.
|
||||
}
|
||||
|
||||
// Restore caller sp for c2i case.
|
||||
// Pop c2i arguments (if any) off when we return.
|
||||
__ resize_frame_absolute(Z_R10, Z_R0, true); // Cut the stack back to where the caller started.
|
||||
|
||||
// We are done, return.
|
||||
__ z_br(Z_R14);
|
||||
|
||||
BLOCK_COMMENT("} math_entry");
|
||||
|
||||
return math_entry;
|
||||
return entry;
|
||||
}
|
||||
|
||||
// Interpreter stub for calling a native method. (asm interpreter).
|
||||
|
@ -155,9 +155,8 @@ void VM_Version::initialize() {
|
||||
FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
|
||||
}
|
||||
|
||||
if (UseFMA) {
|
||||
warning("FMA instructions are not available on this CPU");
|
||||
FLAG_SET_DEFAULT(UseFMA, false);
|
||||
if (FLAG_IS_DEFAULT(UseFMA)) {
|
||||
FLAG_SET_DEFAULT(UseFMA, true);
|
||||
}
|
||||
|
||||
// On z/Architecture, we take UseSHA as the general switch to enable/disable the SHA intrinsics.
|
||||
|
@ -425,7 +425,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
|
||||
#ifdef _LP64
|
||||
case T_LONG:
|
||||
assert(sig_bt[i+1] == T_VOID, "expecting VOID in other half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "expecting VOID in other half");
|
||||
// fall-through
|
||||
case T_OBJECT:
|
||||
case T_ARRAY:
|
||||
@ -441,7 +441,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
break;
|
||||
#else
|
||||
case T_LONG:
|
||||
assert(sig_bt[i+1] == T_VOID, "expecting VOID in other half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "expecting VOID in other half");
|
||||
// On 32-bit SPARC put longs always on the stack to keep the pressure off
|
||||
// integer argument registers. They should be used for oops.
|
||||
slot = round_to(slot, 2); // align
|
||||
@ -460,7 +460,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
break;
|
||||
|
||||
case T_DOUBLE:
|
||||
assert(sig_bt[i+1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "expecting half");
|
||||
if (round_to(flt_reg, 2) + 1 < flt_reg_max) {
|
||||
flt_reg = round_to(flt_reg, 2); // align
|
||||
FloatRegister r = as_FloatRegister(flt_reg);
|
||||
@ -1174,7 +1174,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||
regs[i].set1(int_stk_helper(j));
|
||||
break;
|
||||
case T_LONG:
|
||||
assert(sig_bt[i+1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "expecting half");
|
||||
case T_ADDRESS: // raw pointers, like current thread, for VM calls
|
||||
case T_ARRAY:
|
||||
case T_OBJECT:
|
||||
@ -1209,7 +1209,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
{
|
||||
assert(sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
// V9ism: doubles go in EVEN/ODD regs and stack slots
|
||||
int double_index = (j << 1);
|
||||
param_array_reg.set2(VMRegImpl::stack2reg(double_index));
|
||||
@ -1261,7 +1261,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
case T_LONG:
|
||||
assert(sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
regs[i].set_pair(int_stk_helper(i + 1), int_stk_helper(i));
|
||||
break;
|
||||
case T_VOID: regs[i].set_bad(); break;
|
||||
|
@ -63,9 +63,10 @@ define_pd_global(intx, InlineSmallCode, 1000);
|
||||
#define MIN_STACK_RED_PAGES DEFAULT_STACK_RED_PAGES
|
||||
#define MIN_STACK_RESERVED_PAGES (0)
|
||||
|
||||
#ifdef AMD64
|
||||
// Very large C++ stack frames using solaris-amd64 optimized builds
|
||||
// due to lack of optimization caused by C++ compiler bugs
|
||||
#ifdef _LP64
|
||||
// Java_java_net_SocketOutputStream_socketWrite0() uses a 64k buffer on the
|
||||
// stack if compiled for unix and LP64. To pass stack overflow tests we need
|
||||
// 20 shadow pages.
|
||||
#define DEFAULT_STACK_SHADOW_PAGES (NOT_WIN64(20) WIN64_ONLY(7) DEBUG_ONLY(+2))
|
||||
// For those clients that do not use write socket, we allow
|
||||
// the min range value to be below that of the default
|
||||
@ -73,7 +74,7 @@ define_pd_global(intx, InlineSmallCode, 1000);
|
||||
#else
|
||||
#define DEFAULT_STACK_SHADOW_PAGES (4 DEBUG_ONLY(+5))
|
||||
#define MIN_STACK_SHADOW_PAGES DEFAULT_STACK_SHADOW_PAGES
|
||||
#endif // AMD64
|
||||
#endif // _LP64
|
||||
|
||||
define_pd_global(intx, StackYellowPages, DEFAULT_STACK_YELLOW_PAGES);
|
||||
define_pd_global(intx, StackRedPages, DEFAULT_STACK_RED_PAGES);
|
||||
|
@ -478,12 +478,12 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
break;
|
||||
case T_LONG:
|
||||
assert(sig_bt[i+1] == T_VOID, "missing Half" );
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "missing Half" );
|
||||
regs[i].set2(VMRegImpl::stack2reg(dstack));
|
||||
dstack += 2;
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
assert(sig_bt[i+1] == T_VOID, "missing Half" );
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "missing Half" );
|
||||
if( freg_arg0 == (uint)i ) {
|
||||
regs[i].set2(xmm0->as_VMReg());
|
||||
} else if( freg_arg1 == (uint)i ) {
|
||||
@ -1001,7 +1001,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||
case T_DOUBLE: // The stack numbering is reversed from Java
|
||||
// Since C arguments do not get reversed, the ordering for
|
||||
// doubles on the stack must be opposite the Java convention
|
||||
assert(sig_bt[i+1] == T_VOID, "missing Half" );
|
||||
assert((i + 1) < total_args_passed && sig_bt[i+1] == T_VOID, "missing Half" );
|
||||
regs[i].set2(VMRegImpl::stack2reg(stack));
|
||||
stack += 2;
|
||||
break;
|
||||
|
@ -474,7 +474,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
regs[i].set_bad();
|
||||
break;
|
||||
case T_LONG:
|
||||
assert(sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
// fall through
|
||||
case T_OBJECT:
|
||||
case T_ARRAY:
|
||||
@ -495,7 +495,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
assert(sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
if (fp_args < Argument::n_float_register_parameters_j) {
|
||||
regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg());
|
||||
} else {
|
||||
@ -1014,7 +1014,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
break;
|
||||
case T_LONG:
|
||||
assert(sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
// fall through
|
||||
case T_OBJECT:
|
||||
case T_ARRAY:
|
||||
@ -1045,7 +1045,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
assert(sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
|
||||
if (fp_args < Argument::n_float_register_parameters_c) {
|
||||
regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg());
|
||||
#ifdef _WIN64
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -44,10 +44,14 @@ public class ClassLoaderData extends VMObject {
|
||||
Type type = db.lookupType("ClassLoaderData");
|
||||
classLoaderField = type.getOopField("_class_loader");
|
||||
nextField = type.getAddressField("_next");
|
||||
klassesField = type.getAddressField("_klasses");
|
||||
isAnonymousField = new CIntField(type.getCIntegerField("_is_anonymous"), 0);
|
||||
}
|
||||
|
||||
private static sun.jvm.hotspot.types.OopField classLoaderField;
|
||||
private static AddressField nextField;
|
||||
private static AddressField klassesField;
|
||||
private static CIntField isAnonymousField;
|
||||
|
||||
public ClassLoaderData(Address addr) {
|
||||
super(addr);
|
||||
@ -63,4 +67,16 @@ public class ClassLoaderData extends VMObject {
|
||||
public Oop getClassLoader() {
|
||||
return VM.getVM().getObjectHeap().newOop(classLoaderField.getValue(getAddress()));
|
||||
}
|
||||
|
||||
public boolean getIsAnonymous() {
|
||||
return isAnonymousField.getValue(this) != 0;
|
||||
}
|
||||
|
||||
public ClassLoaderData next() {
|
||||
return instantiateWrapperFor(nextField.getValue(getAddress()));
|
||||
}
|
||||
|
||||
public Klass getKlasses() {
|
||||
return (InstanceKlass)Metadata.instantiateWrapperFor(klassesField.getValue(getAddress()));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.jvm.hotspot.classfile;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.*;
|
||||
import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.runtime.*;
|
||||
import sun.jvm.hotspot.oops.*;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
|
||||
public class ClassLoaderDataGraph {
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
public void update(Observable o, Object data) {
|
||||
initialize(VM.getVM().getTypeDataBase());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
||||
Type type = db.lookupType("ClassLoaderDataGraph");
|
||||
|
||||
headField = type.getAddressField("_head");
|
||||
}
|
||||
|
||||
private static AddressField headField;
|
||||
|
||||
public ClassLoaderData getClassLoaderGraphHead() {
|
||||
return ClassLoaderData.instantiateWrapperFor(headField.getValue());
|
||||
}
|
||||
|
||||
public static interface KlassVisitor {
|
||||
public void visit(Klass k);
|
||||
}
|
||||
|
||||
/** Iterate over all anonymous class loaders and the klasses in those */
|
||||
public void allAnonymousKlassesDo(final KlassVisitor v) {
|
||||
for (ClassLoaderData cl = getClassLoaderGraphHead();
|
||||
cl != null;
|
||||
cl = cl.next()) {
|
||||
if (cl.getIsAnonymous() == true) {
|
||||
for (Klass k = cl.getKlasses(); k != null; k = k.getNextLinkKlass()) {
|
||||
v.visit(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -61,6 +61,7 @@ public class Klass extends Metadata implements ClassConstants {
|
||||
}
|
||||
subklass = new MetadataField(type.getAddressField("_subklass"), 0);
|
||||
nextSibling = new MetadataField(type.getAddressField("_next_sibling"), 0);
|
||||
nextLink = new MetadataField(type.getAddressField("_next_link"), 0);
|
||||
vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), 0);
|
||||
|
||||
LH_INSTANCE_SLOW_PATH_BIT = db.lookupIntConstant("Klass::_lh_instance_slow_path_bit").intValue();
|
||||
@ -92,6 +93,7 @@ public class Klass extends Metadata implements ClassConstants {
|
||||
private static CIntField accessFlags;
|
||||
private static MetadataField subklass;
|
||||
private static MetadataField nextSibling;
|
||||
private static MetadataField nextLink;
|
||||
private static sun.jvm.hotspot.types.Field traceIDField;
|
||||
private static CIntField vtableLen;
|
||||
|
||||
@ -114,6 +116,7 @@ public class Klass extends Metadata implements ClassConstants {
|
||||
public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags()); }
|
||||
public Klass getSubklassKlass() { return (Klass) subklass.getValue(this); }
|
||||
public Klass getNextSiblingKlass() { return (Klass) nextSibling.getValue(this); }
|
||||
public Klass getNextLinkKlass() { return (Klass) nextLink.getValue(this); }
|
||||
public long getVtableLen() { return vtableLen.getValue(this); }
|
||||
|
||||
public long traceID() {
|
||||
|
@ -38,6 +38,7 @@ import sun.jvm.hotspot.oops.*;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
import sun.jvm.hotspot.utilities.*;
|
||||
import sun.jvm.hotspot.runtime.*;
|
||||
import sun.jvm.hotspot.classfile.*;
|
||||
|
||||
/** <P> This class encapsulates the global state of the VM; the
|
||||
universe, object heap, interpreter, etc. It is a Singleton and
|
||||
@ -80,6 +81,7 @@ public class VM {
|
||||
private SymbolTable symbols;
|
||||
private StringTable strings;
|
||||
private SystemDictionary dict;
|
||||
private ClassLoaderDataGraph cldGraph;
|
||||
private Threads threads;
|
||||
private ObjectSynchronizer synchronizer;
|
||||
private JNIHandles handles;
|
||||
@ -660,6 +662,13 @@ public class VM {
|
||||
return dict;
|
||||
}
|
||||
|
||||
public ClassLoaderDataGraph getClassLoaderDataGraph() {
|
||||
if (cldGraph == null) {
|
||||
cldGraph = new ClassLoaderDataGraph();
|
||||
}
|
||||
return cldGraph;
|
||||
}
|
||||
|
||||
public Threads getThreads() {
|
||||
if (threads == null) {
|
||||
threads = new Threads();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,6 +31,7 @@ import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.memory.*;
|
||||
import sun.jvm.hotspot.oops.*;
|
||||
import sun.jvm.hotspot.runtime.*;
|
||||
import sun.jvm.hotspot.classfile.*;
|
||||
|
||||
/*
|
||||
* This class writes Java heap in hprof binary format. This format is
|
||||
@ -379,6 +380,8 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
||||
private static final int JVM_SIGNATURE_ARRAY = '[';
|
||||
private static final int JVM_SIGNATURE_CLASS = 'L';
|
||||
|
||||
int serialNum = 1;
|
||||
|
||||
public synchronized void write(String fileName) throws IOException {
|
||||
// open file stream and create buffered data output stream
|
||||
fos = new FileOutputStream(fileName);
|
||||
@ -516,6 +519,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
||||
|
||||
private void writeClassDumpRecords() throws IOException {
|
||||
SystemDictionary sysDict = VM.getVM().getSystemDictionary();
|
||||
ClassLoaderDataGraph cldGraph = VM.getVM().getClassLoaderDataGraph();
|
||||
try {
|
||||
sysDict.allClassesDo(new SystemDictionary.ClassVisitor() {
|
||||
public void visit(Klass k) {
|
||||
@ -528,6 +532,19 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
||||
}
|
||||
}
|
||||
});
|
||||
// Add the anonymous classes also which are not present in the
|
||||
// System Dictionary
|
||||
cldGraph.allAnonymousKlassesDo(new ClassLoaderDataGraph.KlassVisitor() {
|
||||
public void visit(Klass k) {
|
||||
try {
|
||||
writeHeapRecordPrologue();
|
||||
writeClassDumpRecord(k);
|
||||
writeHeapRecordEpilogue();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (RuntimeException re) {
|
||||
handleRuntimeException(re);
|
||||
}
|
||||
@ -799,17 +816,6 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
||||
writeObjectID(klass.getJavaMirror());
|
||||
|
||||
ClassData cd = (ClassData) classDataCache.get(klass);
|
||||
if (cd == null) {
|
||||
// The class is not present in the system dictionary, probably Lambda.
|
||||
// Add it to cache here
|
||||
if (klass instanceof InstanceKlass) {
|
||||
InstanceKlass ik = (InstanceKlass) klass;
|
||||
List fields = getInstanceFields(ik);
|
||||
int instSize = getSizeForFields(fields);
|
||||
cd = new ClassData(instSize, fields);
|
||||
classDataCache.put(ik, cd);
|
||||
}
|
||||
}
|
||||
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(cd != null, "can not get class data for " + klass.getName().asString() + klass.getAddress());
|
||||
@ -950,9 +956,24 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
||||
private void writeClasses() throws IOException {
|
||||
// write class list (id, name) association
|
||||
SystemDictionary sysDict = VM.getVM().getSystemDictionary();
|
||||
ClassLoaderDataGraph cldGraph = VM.getVM().getClassLoaderDataGraph();
|
||||
try {
|
||||
sysDict.allClassesDo(new SystemDictionary.ClassVisitor() {
|
||||
private int serialNum = 1;
|
||||
public void visit(Klass k) {
|
||||
try {
|
||||
Instance clazz = k.getJavaMirror();
|
||||
writeHeader(HPROF_LOAD_CLASS, 2 * (OBJ_ID_SIZE + 4));
|
||||
out.writeInt(serialNum);
|
||||
writeObjectID(clazz);
|
||||
out.writeInt(DUMMY_STACK_TRACE_ID);
|
||||
writeSymbolID(k.getName());
|
||||
serialNum++;
|
||||
} catch (IOException exp) {
|
||||
throw new RuntimeException(exp);
|
||||
}
|
||||
}
|
||||
});
|
||||
cldGraph.allAnonymousKlassesDo(new ClassLoaderDataGraph.KlassVisitor() {
|
||||
public void visit(Klass k) {
|
||||
try {
|
||||
Instance clazz = k.getJavaMirror();
|
||||
|
@ -53,6 +53,7 @@ import org.graalvm.compiler.hotspot.stubs.ExceptionHandlerStub;
|
||||
import org.graalvm.compiler.hotspot.stubs.Stub;
|
||||
import org.graalvm.compiler.hotspot.stubs.UnwindExceptionToCallerStub;
|
||||
import org.graalvm.compiler.hotspot.word.KlassPointer;
|
||||
import org.graalvm.compiler.hotspot.word.MethodCountersPointer;
|
||||
import org.graalvm.compiler.lir.LIR;
|
||||
import org.graalvm.compiler.lir.LIRFrameState;
|
||||
import org.graalvm.compiler.lir.LIRInstruction;
|
||||
@ -316,8 +317,8 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
|
||||
/**
|
||||
* Tiered support.
|
||||
*/
|
||||
public static final ForeignCallDescriptor INVOCATION_EVENT = new ForeignCallDescriptor("invocation_event", void.class, Word.class);
|
||||
public static final ForeignCallDescriptor BACKEDGE_EVENT = new ForeignCallDescriptor("backedge_event", void.class, Word.class, int.class, int.class);
|
||||
public static final ForeignCallDescriptor INVOCATION_EVENT = new ForeignCallDescriptor("invocation_event", void.class, MethodCountersPointer.class);
|
||||
public static final ForeignCallDescriptor BACKEDGE_EVENT = new ForeignCallDescriptor("backedge_event", void.class, MethodCountersPointer.class, int.class, int.class);
|
||||
|
||||
/**
|
||||
* @see UncommonTrapCallNode
|
||||
|
@ -848,13 +848,13 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||
|
||||
assert(thread->osthread() == NULL, "caller responsible");
|
||||
|
||||
// Allocate the OSThread object
|
||||
// Allocate the OSThread object.
|
||||
OSThread* osthread = new OSThread(NULL, NULL);
|
||||
if (osthread == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// set the correct thread state
|
||||
// Set the correct thread state.
|
||||
osthread->set_thread_type(thr_type);
|
||||
|
||||
// Initial state is ALLOCATED but not INITIALIZED
|
||||
@ -862,7 +862,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||
|
||||
thread->set_osthread(osthread);
|
||||
|
||||
// init thread attributes
|
||||
// Init thread attributes.
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
guarantee(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0, "???");
|
||||
@ -871,15 +871,18 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||
if (os::Aix::on_aix()) {
|
||||
guarantee(pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) == 0, "???");
|
||||
guarantee(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0, "???");
|
||||
} // end: aix
|
||||
}
|
||||
|
||||
// Start in suspended state, and in os::thread_start, wake the thread up.
|
||||
guarantee(pthread_attr_setsuspendstate_np(&attr, PTHREAD_CREATE_SUSPENDED_NP) == 0, "???");
|
||||
|
||||
// calculate stack size if it's not specified by caller
|
||||
// Calculate stack size if it's not specified by caller.
|
||||
size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size);
|
||||
pthread_attr_setstacksize(&attr, stack_size);
|
||||
|
||||
// Configure libc guard page.
|
||||
pthread_attr_setguardsize(&attr, os::Aix::default_guard_size(thr_type));
|
||||
|
||||
pthread_t tid;
|
||||
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);
|
||||
|
||||
@ -895,7 +898,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
if (ret != 0) {
|
||||
// Need to clean up stuff we've allocated so far
|
||||
// Need to clean up stuff we've allocated so far.
|
||||
thread->set_osthread(NULL);
|
||||
delete osthread;
|
||||
return false;
|
||||
@ -3032,6 +3035,19 @@ bool os::Aix::chained_handler(int sig, siginfo_t* siginfo, void* context) {
|
||||
return chained;
|
||||
}
|
||||
|
||||
size_t os::Aix::default_guard_size(os::ThreadType thr_type) {
|
||||
// Creating guard page is very expensive. Java thread has HotSpot
|
||||
// guard pages, only enable glibc guard page for non-Java threads.
|
||||
// (Remember: compiler thread is a Java thread, too!)
|
||||
//
|
||||
// Aix can have different page sizes for stack (4K) and heap (64K).
|
||||
// As Hotspot knows only one page size, we assume the stack has
|
||||
// the same page size as the heap. Returning page_size() here can
|
||||
// cause 16 guard pages which we want to avoid. Thus we return 4K
|
||||
// which will be rounded to the real page size by the OS.
|
||||
return ((thr_type == java_thread || thr_type == compiler_thread) ? 0 : 4 * K);
|
||||
}
|
||||
|
||||
struct sigaction* os::Aix::get_preinstalled_handler(int sig) {
|
||||
if (sigismember(&sigs, sig)) {
|
||||
return &sigact[sig];
|
||||
|
@ -140,6 +140,9 @@ class Aix {
|
||||
// libpthread version string
|
||||
static void libpthread_init();
|
||||
|
||||
// Return default libc guard size for the specified thread type.
|
||||
static size_t default_guard_size(os::ThreadType thr_type);
|
||||
|
||||
// Function returns true if we run on OS/400 (pase), false if we run
|
||||
// on AIX.
|
||||
static bool on_pase() {
|
||||
|
@ -716,11 +716,18 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
|
||||
// calculate stack size if it's not specified by caller
|
||||
// Calculate stack size if it's not specified by caller.
|
||||
size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size);
|
||||
// In the Linux NPTL pthread implementation the guard size mechanism
|
||||
// is not implemented properly. The posix standard requires adding
|
||||
// the size of the guard pages to the stack size, instead Linux
|
||||
// takes the space out of 'stacksize'. Thus we adapt the requested
|
||||
// stack_size by the size of the guard pages to mimick proper
|
||||
// behaviour.
|
||||
stack_size = align_size_up(stack_size + os::Linux::default_guard_size(thr_type), vm_page_size());
|
||||
pthread_attr_setstacksize(&attr, stack_size);
|
||||
|
||||
// glibc guard page
|
||||
// Configure glibc guard page.
|
||||
pthread_attr_setguardsize(&attr, os::Linux::default_guard_size(thr_type));
|
||||
|
||||
ThreadState state;
|
||||
@ -920,9 +927,21 @@ static bool find_vma(address addr, address* vma_low, address* vma_high) {
|
||||
|
||||
// Locate initial thread stack. This special handling of initial thread stack
|
||||
// is needed because pthread_getattr_np() on most (all?) Linux distros returns
|
||||
// bogus value for initial thread.
|
||||
// bogus value for the primordial process thread. While the launcher has created
|
||||
// the VM in a new thread since JDK 6, we still have to allow for the use of the
|
||||
// JNI invocation API from a primordial thread.
|
||||
void os::Linux::capture_initial_stack(size_t max_size) {
|
||||
// stack size is the easy part, get it from RLIMIT_STACK
|
||||
|
||||
// max_size is either 0 (which means accept OS default for thread stacks) or
|
||||
// a user-specified value known to be at least the minimum needed. If we
|
||||
// are actually on the primordial thread we can make it appear that we have a
|
||||
// smaller max_size stack by inserting the guard pages at that location. But we
|
||||
// cannot do anything to emulate a larger stack than what has been provided by
|
||||
// the OS or threading library. In fact if we try to use a stack greater than
|
||||
// what is set by rlimit then we will crash the hosting process.
|
||||
|
||||
// Maximum stack size is the easy part, get it from RLIMIT_STACK.
|
||||
// If this is "unlimited" then it will be a huge value.
|
||||
struct rlimit rlim;
|
||||
getrlimit(RLIMIT_STACK, &rlim);
|
||||
size_t stack_size = rlim.rlim_cur;
|
||||
@ -932,17 +951,6 @@ void os::Linux::capture_initial_stack(size_t max_size) {
|
||||
// so we won't install guard page on ld.so's data section.
|
||||
stack_size -= 2 * page_size();
|
||||
|
||||
// 4441425: avoid crash with "unlimited" stack size on SuSE 7.1 or Redhat
|
||||
// 7.1, in both cases we will get 2G in return value.
|
||||
// 4466587: glibc 2.2.x compiled w/o "--enable-kernel=2.4.0" (RH 7.0,
|
||||
// SuSE 7.2, Debian) can not handle alternate signal stack correctly
|
||||
// for initial thread if its stack size exceeds 6M. Cap it at 2M,
|
||||
// in case other parts in glibc still assumes 2M max stack size.
|
||||
// FIXME: alt signal stack is gone, maybe we can relax this constraint?
|
||||
// Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small
|
||||
if (stack_size > 2 * K * K IA64_ONLY(*2)) {
|
||||
stack_size = 2 * K * K IA64_ONLY(*2);
|
||||
}
|
||||
// Try to figure out where the stack base (top) is. This is harder.
|
||||
//
|
||||
// When an application is started, glibc saves the initial stack pointer in
|
||||
@ -1102,14 +1110,29 @@ void os::Linux::capture_initial_stack(size_t max_size) {
|
||||
// stack_top could be partially down the page so align it
|
||||
stack_top = align_size_up(stack_top, page_size());
|
||||
|
||||
if (max_size && stack_size > max_size) {
|
||||
_initial_thread_stack_size = max_size;
|
||||
// Allowed stack value is minimum of max_size and what we derived from rlimit
|
||||
if (max_size > 0) {
|
||||
_initial_thread_stack_size = MIN2(max_size, stack_size);
|
||||
} else {
|
||||
_initial_thread_stack_size = stack_size;
|
||||
// Accept the rlimit max, but if stack is unlimited then it will be huge, so
|
||||
// clamp it at 8MB as we do on Solaris
|
||||
_initial_thread_stack_size = MIN2(stack_size, 8*M);
|
||||
}
|
||||
|
||||
_initial_thread_stack_size = align_size_down(_initial_thread_stack_size, page_size());
|
||||
_initial_thread_stack_bottom = (address)stack_top - _initial_thread_stack_size;
|
||||
|
||||
assert(_initial_thread_stack_bottom < (address)stack_top, "overflow!");
|
||||
|
||||
if (log_is_enabled(Info, os, thread)) {
|
||||
// See if we seem to be on primordial process thread
|
||||
bool primordial = uintptr_t(&rlim) > uintptr_t(_initial_thread_stack_bottom) &&
|
||||
uintptr_t(&rlim) < stack_top;
|
||||
|
||||
log_info(os, thread)("Capturing initial stack in %s thread: req. size: " SIZE_FORMAT "K, actual size: "
|
||||
SIZE_FORMAT "K, top=" INTPTR_FORMAT ", bottom=" INTPTR_FORMAT,
|
||||
primordial ? "primordial" : "user", max_size / K, _initial_thread_stack_size / K,
|
||||
stack_top, intptr_t(_initial_thread_stack_bottom));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -2833,6 +2856,13 @@ bool os::Linux::libnuma_init() {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
|
||||
// Creating guard page is very expensive. Java thread has HotSpot
|
||||
// guard pages, only enable glibc guard page for non-Java threads.
|
||||
// (Remember: compiler thread is a Java thread, too!)
|
||||
return ((thr_type == java_thread || thr_type == compiler_thread) ? 0 : page_size());
|
||||
}
|
||||
|
||||
// rebuild_cpu_to_node_map() constructs a table mapping cpud id to node id.
|
||||
// The table is later used in get_node_by_cpu().
|
||||
void os::Linux::rebuild_cpu_to_node_map() {
|
||||
@ -6065,6 +6095,101 @@ bool os::start_debugging(char *buf, int buflen) {
|
||||
return yes;
|
||||
}
|
||||
|
||||
|
||||
// Java/Compiler thread:
|
||||
//
|
||||
// Low memory addresses
|
||||
// P0 +------------------------+
|
||||
// | |\ Java thread created by VM does not have glibc
|
||||
// | glibc guard page | - guard page, attached Java thread usually has
|
||||
// | |/ 1 glibc guard page.
|
||||
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
|
||||
// | |\
|
||||
// | HotSpot Guard Pages | - red, yellow and reserved pages
|
||||
// | |/
|
||||
// +------------------------+ JavaThread::stack_reserved_zone_base()
|
||||
// | |\
|
||||
// | Normal Stack | -
|
||||
// | |/
|
||||
// P2 +------------------------+ Thread::stack_base()
|
||||
//
|
||||
// Non-Java thread:
|
||||
//
|
||||
// Low memory addresses
|
||||
// P0 +------------------------+
|
||||
// | |\
|
||||
// | glibc guard page | - usually 1 page
|
||||
// | |/
|
||||
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
|
||||
// | |\
|
||||
// | Normal Stack | -
|
||||
// | |/
|
||||
// P2 +------------------------+ Thread::stack_base()
|
||||
//
|
||||
// ** P1 (aka bottom) and size (P2 = P1 - size) are the address and stack size
|
||||
// returned from pthread_attr_getstack().
|
||||
// ** Due to NPTL implementation error, linux takes the glibc guard page out
|
||||
// of the stack size given in pthread_attr. We work around this for
|
||||
// threads created by the VM. (We adapt bottom to be P1 and size accordingly.)
|
||||
//
|
||||
#ifndef ZERO
|
||||
static void current_stack_region(address * bottom, size_t * size) {
|
||||
if (os::Linux::is_initial_thread()) {
|
||||
// initial thread needs special handling because pthread_getattr_np()
|
||||
// may return bogus value.
|
||||
*bottom = os::Linux::initial_thread_stack_bottom();
|
||||
*size = os::Linux::initial_thread_stack_size();
|
||||
} else {
|
||||
pthread_attr_t attr;
|
||||
|
||||
int rslt = pthread_getattr_np(pthread_self(), &attr);
|
||||
|
||||
// JVM needs to know exact stack location, abort if it fails
|
||||
if (rslt != 0) {
|
||||
if (rslt == ENOMEM) {
|
||||
vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
|
||||
} else {
|
||||
fatal("pthread_getattr_np failed with error = %d", rslt);
|
||||
}
|
||||
}
|
||||
|
||||
if (pthread_attr_getstack(&attr, (void **)bottom, size) != 0) {
|
||||
fatal("Cannot locate current stack attributes!");
|
||||
}
|
||||
|
||||
// Work around NPTL stack guard error.
|
||||
size_t guard_size = 0;
|
||||
rslt = pthread_attr_getguardsize(&attr, &guard_size);
|
||||
if (rslt != 0) {
|
||||
fatal("pthread_attr_getguardsize failed with error = %d", rslt);
|
||||
}
|
||||
*bottom += guard_size;
|
||||
*size -= guard_size;
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
}
|
||||
assert(os::current_stack_pointer() >= *bottom &&
|
||||
os::current_stack_pointer() < *bottom + *size, "just checking");
|
||||
}
|
||||
|
||||
address os::current_stack_base() {
|
||||
address bottom;
|
||||
size_t size;
|
||||
current_stack_region(&bottom, &size);
|
||||
return (bottom + size);
|
||||
}
|
||||
|
||||
size_t os::current_stack_size() {
|
||||
// This stack size includes the usable stack and HotSpot guard pages
|
||||
// (for the threads that have Hotspot guard pages).
|
||||
address bottom;
|
||||
size_t size;
|
||||
current_stack_region(&bottom, &size);
|
||||
return size;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline struct timespec get_mtime(const char* filename) {
|
||||
struct stat st;
|
||||
int ret = os::stat(filename, &st);
|
||||
|
@ -1096,6 +1096,8 @@ char* os::Posix::describe_pthread_attr(char* buf, size_t buflen, const pthread_a
|
||||
int detachstate = 0;
|
||||
pthread_attr_getstacksize(attr, &stack_size);
|
||||
pthread_attr_getguardsize(attr, &guard_size);
|
||||
// Work around linux NPTL implementation error, see also os::create_thread() in os_linux.cpp.
|
||||
LINUX_ONLY(stack_size -= guard_size);
|
||||
pthread_attr_getdetachstate(attr, &detachstate);
|
||||
jio_snprintf(buf, buflen, "stacksize: " SIZE_FORMAT "k, guardsize: " SIZE_FORMAT "k, %s",
|
||||
stack_size / 1024, guard_size / 1024,
|
||||
@ -1105,14 +1107,18 @@ char* os::Posix::describe_pthread_attr(char* buf, size_t buflen, const pthread_a
|
||||
|
||||
// Check minimum allowable stack sizes for thread creation and to initialize
|
||||
// the java system classes, including StackOverflowError - depends on page
|
||||
// size. Add two 4K pages for compiler2 recursion in main thread.
|
||||
// Add in 4*BytesPerWord 4K pages to account for VM stack during
|
||||
// class initialization depending on 32 or 64 bit VM.
|
||||
// size.
|
||||
// The space needed for frames during startup is platform dependent. It
|
||||
// depends on word size, platform calling conventions, C frame layout and
|
||||
// interpreter/C1/C2 design decisions. Therefore this is given in a
|
||||
// platform (os/cpu) dependent constant.
|
||||
// To this, space for guard mechanisms is added, which depends on the
|
||||
// page size which again depends on the concrete system the VM is running
|
||||
// on. Space for libc guard pages is not included in this size.
|
||||
jint os::Posix::set_minimum_stack_sizes() {
|
||||
_java_thread_min_stack_allowed = MAX2(_java_thread_min_stack_allowed,
|
||||
JavaThread::stack_guard_zone_size() +
|
||||
JavaThread::stack_shadow_zone_size() +
|
||||
(4 * BytesPerWord COMPILER2_PRESENT(+ 2)) * 4 * K);
|
||||
_java_thread_min_stack_allowed = _java_thread_min_stack_allowed +
|
||||
JavaThread::stack_guard_zone_size() +
|
||||
JavaThread::stack_shadow_zone_size();
|
||||
|
||||
_java_thread_min_stack_allowed = align_size_up(_java_thread_min_stack_allowed, vm_page_size());
|
||||
|
||||
@ -1128,28 +1134,14 @@ jint os::Posix::set_minimum_stack_sizes() {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
#ifdef SOLARIS
|
||||
// For 64kbps there will be a 64kb page size, which makes
|
||||
// the usable default stack size quite a bit less. Increase the
|
||||
// stack for 64kb (or any > than 8kb) pages, this increases
|
||||
// virtual memory fragmentation (since we're not creating the
|
||||
// stack on a power of 2 boundary. The real fix for this
|
||||
// should be to fix the guard page mechanism.
|
||||
|
||||
if (vm_page_size() > 8*K) {
|
||||
stack_size_in_bytes = (stack_size_in_bytes != 0)
|
||||
? stack_size_in_bytes +
|
||||
JavaThread::stack_red_zone_size() +
|
||||
JavaThread::stack_yellow_zone_size()
|
||||
: 0;
|
||||
ThreadStackSize = stack_size_in_bytes/K;
|
||||
}
|
||||
#endif // SOLARIS
|
||||
|
||||
// Make the stack size a multiple of the page size so that
|
||||
// the yellow/red zones can be guarded.
|
||||
JavaThread::set_stack_size_at_create(round_to(stack_size_in_bytes,
|
||||
vm_page_size()));
|
||||
JavaThread::set_stack_size_at_create(round_to(stack_size_in_bytes, vm_page_size()));
|
||||
|
||||
// Reminder: a compiler thread is a Java thread.
|
||||
_compiler_thread_min_stack_allowed = _compiler_thread_min_stack_allowed +
|
||||
JavaThread::stack_guard_zone_size() +
|
||||
JavaThread::stack_shadow_zone_size();
|
||||
|
||||
_compiler_thread_min_stack_allowed = align_size_up(_compiler_thread_min_stack_allowed, vm_page_size());
|
||||
|
||||
|
@ -43,7 +43,11 @@ protected:
|
||||
static void print_load_average(outputStream* st);
|
||||
|
||||
// Minimum stack size a thread can be created with (allowing
|
||||
// the VM to completely create the thread and enter user code)
|
||||
// the VM to completely create the thread and enter user code).
|
||||
// The initial values exclude any guard pages (by HotSpot or libc).
|
||||
// set_minimum_stack_sizes() will add the size required for
|
||||
// HotSpot guard pages depending on page size and flag settings.
|
||||
// Libc guard pages are never considered by these values.
|
||||
static size_t _compiler_thread_min_stack_allowed;
|
||||
static size_t _java_thread_min_stack_allowed;
|
||||
static size_t _vm_internal_thread_min_stack_allowed;
|
||||
|
@ -535,13 +535,15 @@ void os::Aix::init_thread_fpu_state(void) {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// thread stack
|
||||
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 128 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 128 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 128 * K;
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 192 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
|
||||
// return default stack size for thr_type
|
||||
// Return default stack size for thr_type.
|
||||
size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
// default stack size (compiler thread needs larger stack)
|
||||
// Default stack size (compiler thread needs larger stack).
|
||||
size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
|
||||
return s;
|
||||
}
|
||||
|
@ -839,19 +839,20 @@ bool os::is_allocatable(size_t bytes) {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// thread stack
|
||||
|
||||
#ifdef AMD64
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 48 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 48 * K;
|
||||
#ifdef _LP64
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
#else
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
#endif // _LP64
|
||||
|
||||
#ifndef AMD64
|
||||
#ifdef __GNUC__
|
||||
#define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;})
|
||||
#endif
|
||||
|
||||
#endif // AMD64
|
||||
|
||||
// return default stack size for thr_type
|
||||
@ -870,14 +871,14 @@ size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
//
|
||||
// Low memory addresses
|
||||
// +------------------------+
|
||||
// | |\ JavaThread created by VM does not have glibc
|
||||
// | |\ Java thread created by VM does not have glibc
|
||||
// | glibc guard page | - guard, attached Java thread usually has
|
||||
// | |/ 1 page glibc guard.
|
||||
// | |/ 1 glibc guard page.
|
||||
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
|
||||
// | |\
|
||||
// | HotSpot Guard Pages | - red and yellow pages
|
||||
// | HotSpot Guard Pages | - red, yellow and reserved pages
|
||||
// | |/
|
||||
// +------------------------+ JavaThread::stack_yellow_zone_base()
|
||||
// +------------------------+ JavaThread::stack_reserved_zone_base()
|
||||
// | |\
|
||||
// | Normal Stack | -
|
||||
// | |/
|
||||
@ -925,7 +926,7 @@ static void current_stack_region(address * bottom, size_t * size) {
|
||||
int rslt = pthread_stackseg_np(pthread_self(), &ss);
|
||||
|
||||
if (rslt != 0)
|
||||
fatal("pthread_stackseg_np failed with err = %d", rslt);
|
||||
fatal("pthread_stackseg_np failed with error = %d", rslt);
|
||||
|
||||
*bottom = (address)((char *)ss.ss_sp - ss.ss_size);
|
||||
*size = ss.ss_size;
|
||||
@ -936,12 +937,12 @@ static void current_stack_region(address * bottom, size_t * size) {
|
||||
|
||||
// JVM needs to know exact stack location, abort if it fails
|
||||
if (rslt != 0)
|
||||
fatal("pthread_attr_init failed with err = %d", rslt);
|
||||
fatal("pthread_attr_init failed with error = %d", rslt);
|
||||
|
||||
rslt = pthread_attr_get_np(pthread_self(), &attr);
|
||||
|
||||
if (rslt != 0)
|
||||
fatal("pthread_attr_get_np failed with err = %d", rslt);
|
||||
fatal("pthread_attr_get_np failed with error = %d", rslt);
|
||||
|
||||
if (pthread_attr_getstackaddr(&attr, (void **)bottom) != 0 ||
|
||||
pthread_attr_getstacksize(&attr, size) != 0) {
|
||||
|
@ -310,7 +310,7 @@ static void current_stack_region(address *bottom, size_t *size) {
|
||||
int rslt = pthread_stackseg_np(pthread_self(), &ss);
|
||||
|
||||
if (rslt != 0)
|
||||
fatal("pthread_stackseg_np failed with err = " INT32_FORMAT, rslt);
|
||||
fatal("pthread_stackseg_np failed with error = " INT32_FORMAT, rslt);
|
||||
|
||||
stack_top = (address) ss.ss_sp;
|
||||
stack_bytes = ss.ss_size;
|
||||
@ -322,12 +322,12 @@ static void current_stack_region(address *bottom, size_t *size) {
|
||||
|
||||
// JVM needs to know exact stack location, abort if it fails
|
||||
if (rslt != 0)
|
||||
fatal("pthread_attr_init failed with err = " INT32_FORMAT, rslt);
|
||||
fatal("pthread_attr_init failed with error = " INT32_FORMAT, rslt);
|
||||
|
||||
rslt = pthread_attr_get_np(pthread_self(), &attr);
|
||||
|
||||
if (rslt != 0)
|
||||
fatal("pthread_attr_get_np failed with err = " INT32_FORMAT, rslt);
|
||||
fatal("pthread_attr_get_np failed with error = " INT32_FORMAT, rslt);
|
||||
|
||||
if (pthread_attr_getstackaddr(&attr, (void **) &stack_bottom) != 0 ||
|
||||
pthread_attr_getstacksize(&attr, &stack_bytes) != 0) {
|
||||
|
@ -473,8 +473,10 @@ bool os::is_allocatable(size_t bytes) {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// thread stack
|
||||
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 32 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 32 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
|
||||
// return default stack size for thr_type
|
||||
@ -484,91 +486,6 @@ size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
|
||||
// Creating guard page is very expensive. Java thread has HotSpot
|
||||
// guard page, only enable glibc guard page for non-Java threads.
|
||||
return (thr_type == java_thread ? 0 : page_size());
|
||||
}
|
||||
|
||||
// Java thread:
|
||||
//
|
||||
// Low memory addresses
|
||||
// +------------------------+
|
||||
// | |\ JavaThread created by VM does not have glibc
|
||||
// | glibc guard page | - guard, attached Java thread usually has
|
||||
// | |/ 1 page glibc guard.
|
||||
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
|
||||
// | |\
|
||||
// | HotSpot Guard Pages | - red and yellow pages
|
||||
// | |/
|
||||
// +------------------------+ JavaThread::stack_yellow_zone_base()
|
||||
// | |\
|
||||
// | Normal Stack | -
|
||||
// | |/
|
||||
// P2 +------------------------+ Thread::stack_base()
|
||||
//
|
||||
// Non-Java thread:
|
||||
//
|
||||
// Low memory addresses
|
||||
// +------------------------+
|
||||
// | |\
|
||||
// | glibc guard page | - usually 1 page
|
||||
// | |/
|
||||
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
|
||||
// | |\
|
||||
// | Normal Stack | -
|
||||
// | |/
|
||||
// P2 +------------------------+ Thread::stack_base()
|
||||
//
|
||||
// ** P1 (aka bottom) and size ( P2 = P1 - size) are the address and stack size returned from
|
||||
// pthread_attr_getstack()
|
||||
|
||||
static void current_stack_region(address * bottom, size_t * size) {
|
||||
if (os::Linux::is_initial_thread()) {
|
||||
// initial thread needs special handling because pthread_getattr_np()
|
||||
// may return bogus value.
|
||||
*bottom = os::Linux::initial_thread_stack_bottom();
|
||||
*size = os::Linux::initial_thread_stack_size();
|
||||
} else {
|
||||
pthread_attr_t attr;
|
||||
|
||||
int rslt = pthread_getattr_np(pthread_self(), &attr);
|
||||
|
||||
// JVM needs to know exact stack location, abort if it fails
|
||||
if (rslt != 0) {
|
||||
if (rslt == ENOMEM) {
|
||||
vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
|
||||
} else {
|
||||
fatal("pthread_getattr_np failed with errno = %d", rslt);
|
||||
}
|
||||
}
|
||||
|
||||
if (pthread_attr_getstack(&attr, (void **)bottom, size) != 0) {
|
||||
fatal("Can not locate current stack attributes!");
|
||||
}
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
}
|
||||
assert(os::current_stack_pointer() >= *bottom &&
|
||||
os::current_stack_pointer() < *bottom + *size, "just checking");
|
||||
}
|
||||
|
||||
address os::current_stack_base() {
|
||||
address bottom;
|
||||
size_t size;
|
||||
current_stack_region(&bottom, &size);
|
||||
return (bottom + size);
|
||||
}
|
||||
|
||||
size_t os::current_stack_size() {
|
||||
// stack size includes normal stack and HotSpot guard pages
|
||||
address bottom;
|
||||
size_t size;
|
||||
current_stack_region(&bottom, &size);
|
||||
return size;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// helper functions for fatal error handler
|
||||
|
||||
@ -606,8 +523,10 @@ void os::print_context(outputStream *st, const void *context) {
|
||||
st->print(" TRAPNO=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_TRAPNO]);
|
||||
st->cr();
|
||||
#else
|
||||
for (int r = 0; r < 31; r++)
|
||||
st->print_cr( "R%d=" INTPTR_FORMAT, r, (size_t)uc->uc_mcontext.regs[r]);
|
||||
for (int r = 0; r < 31; r++) {
|
||||
st->print("R%-2d=", r);
|
||||
print_location(st, uc->uc_mcontext.regs[r]);
|
||||
}
|
||||
#endif
|
||||
st->cr();
|
||||
|
||||
|
@ -526,8 +526,10 @@ bool os::is_allocatable(size_t bytes) {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// thread stack
|
||||
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = (32 DEBUG_ONLY(+ 4)) * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = (32 DEBUG_ONLY(+ 4)) * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
|
||||
// return default stack size for thr_type
|
||||
@ -537,91 +539,6 @@ size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
|
||||
// Creating guard page is very expensive. Java thread has HotSpot
|
||||
// guard page, only enable glibc guard page for non-Java threads.
|
||||
return (thr_type == java_thread ? 0 : page_size());
|
||||
}
|
||||
|
||||
// Java thread:
|
||||
//
|
||||
// Low memory addresses
|
||||
// +------------------------+
|
||||
// | |\ JavaThread created by VM does not have glibc
|
||||
// | glibc guard page | - guard, attached Java thread usually has
|
||||
// | |/ 1 page glibc guard.
|
||||
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
|
||||
// | |\
|
||||
// | HotSpot Guard Pages | - red and yellow pages
|
||||
// | |/
|
||||
// +------------------------+ JavaThread::stack_yellow_zone_base()
|
||||
// | |\
|
||||
// | Normal Stack | -
|
||||
// | |/
|
||||
// P2 +------------------------+ Thread::stack_base()
|
||||
//
|
||||
// Non-Java thread:
|
||||
//
|
||||
// Low memory addresses
|
||||
// +------------------------+
|
||||
// | |\
|
||||
// | glibc guard page | - usually 1 page
|
||||
// | |/
|
||||
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
|
||||
// | |\
|
||||
// | Normal Stack | -
|
||||
// | |/
|
||||
// P2 +------------------------+ Thread::stack_base()
|
||||
//
|
||||
// ** P1 (aka bottom) and size ( P2 = P1 - size) are the address and stack size returned from
|
||||
// pthread_attr_getstack()
|
||||
|
||||
static void current_stack_region(address * bottom, size_t * size) {
|
||||
if (os::Linux::is_initial_thread()) {
|
||||
// initial thread needs special handling because pthread_getattr_np()
|
||||
// may return bogus value.
|
||||
*bottom = os::Linux::initial_thread_stack_bottom();
|
||||
*size = os::Linux::initial_thread_stack_size();
|
||||
} else {
|
||||
pthread_attr_t attr;
|
||||
|
||||
int rslt = pthread_getattr_np(pthread_self(), &attr);
|
||||
|
||||
// JVM needs to know exact stack location, abort if it fails
|
||||
if (rslt != 0) {
|
||||
if (rslt == ENOMEM) {
|
||||
vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
|
||||
} else {
|
||||
fatal("pthread_getattr_np failed");
|
||||
}
|
||||
}
|
||||
|
||||
if (pthread_attr_getstack(&attr, (void **)bottom, size) != 0) {
|
||||
fatal("Can not locate current stack attributes!");
|
||||
}
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
}
|
||||
assert(os::current_stack_pointer() >= *bottom &&
|
||||
os::current_stack_pointer() < *bottom + *size, "just checking");
|
||||
}
|
||||
|
||||
address os::current_stack_base() {
|
||||
address bottom;
|
||||
size_t size;
|
||||
current_stack_region(&bottom, &size);
|
||||
return (bottom + size);
|
||||
}
|
||||
|
||||
size_t os::current_stack_size() {
|
||||
// stack size includes normal stack and HotSpot guard pages
|
||||
address bottom;
|
||||
size_t size;
|
||||
current_stack_region(&bottom, &size);
|
||||
return size;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// helper functions for fatal error handler
|
||||
|
||||
|
@ -535,100 +535,19 @@ void os::Linux::set_fpu_control_word(int fpu_control) {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// thread stack
|
||||
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 128 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 128 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 128 * K;
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
|
||||
// return default stack size for thr_type
|
||||
// Return default stack size for thr_type.
|
||||
size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
// default stack size (compiler thread needs larger stack)
|
||||
// Default stack size (compiler thread needs larger stack).
|
||||
size_t s = (thr_type == os::compiler_thread ? 4 * M : 1024 * K);
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
|
||||
return 2 * page_size();
|
||||
}
|
||||
|
||||
// Java thread:
|
||||
//
|
||||
// Low memory addresses
|
||||
// +------------------------+
|
||||
// | |\ JavaThread created by VM does not have glibc
|
||||
// | glibc guard page | - guard, attached Java thread usually has
|
||||
// | |/ 1 page glibc guard.
|
||||
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
|
||||
// | |\
|
||||
// | HotSpot Guard Pages | - red and yellow pages
|
||||
// | |/
|
||||
// +------------------------+ JavaThread::stack_yellow_zone_base()
|
||||
// | |\
|
||||
// | Normal Stack | -
|
||||
// | |/
|
||||
// P2 +------------------------+ Thread::stack_base()
|
||||
//
|
||||
// Non-Java thread:
|
||||
//
|
||||
// Low memory addresses
|
||||
// +------------------------+
|
||||
// | |\
|
||||
// | glibc guard page | - usually 1 page
|
||||
// | |/
|
||||
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
|
||||
// | |\
|
||||
// | Normal Stack | -
|
||||
// | |/
|
||||
// P2 +------------------------+ Thread::stack_base()
|
||||
//
|
||||
// ** P1 (aka bottom) and size ( P2 = P1 - size) are the address and stack size returned from
|
||||
// pthread_attr_getstack()
|
||||
|
||||
static void current_stack_region(address * bottom, size_t * size) {
|
||||
if (os::Linux::is_initial_thread()) {
|
||||
// initial thread needs special handling because pthread_getattr_np()
|
||||
// may return bogus value.
|
||||
*bottom = os::Linux::initial_thread_stack_bottom();
|
||||
*size = os::Linux::initial_thread_stack_size();
|
||||
} else {
|
||||
pthread_attr_t attr;
|
||||
|
||||
int rslt = pthread_getattr_np(pthread_self(), &attr);
|
||||
|
||||
// JVM needs to know exact stack location, abort if it fails
|
||||
if (rslt != 0) {
|
||||
if (rslt == ENOMEM) {
|
||||
vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
|
||||
} else {
|
||||
fatal("pthread_getattr_np failed with errno = %d", rslt);
|
||||
}
|
||||
}
|
||||
|
||||
if (pthread_attr_getstack(&attr, (void **)bottom, size) != 0) {
|
||||
fatal("Can not locate current stack attributes!");
|
||||
}
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
}
|
||||
assert(os::current_stack_pointer() >= *bottom &&
|
||||
os::current_stack_pointer() < *bottom + *size, "just checking");
|
||||
}
|
||||
|
||||
address os::current_stack_base() {
|
||||
address bottom;
|
||||
size_t size;
|
||||
current_stack_region(&bottom, &size);
|
||||
return (bottom + size);
|
||||
}
|
||||
|
||||
size_t os::current_stack_size() {
|
||||
// stack size includes normal stack and HotSpot guard pages
|
||||
address bottom;
|
||||
size_t size;
|
||||
current_stack_region(&bottom, &size);
|
||||
return size;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// helper functions for fatal error handler
|
||||
|
||||
|
@ -473,103 +473,19 @@ void os::Linux::set_fpu_control_word(int fpu_control) {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// thread stack
|
||||
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 128 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 128 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 128 * K;
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = (52 DEBUG_ONLY(+ 32)) * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = (32 DEBUG_ONLY(+ 8)) * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 32 * K;
|
||||
|
||||
// return default stack size for thr_type
|
||||
// Return default stack size for thr_type.
|
||||
size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
// default stack size (compiler thread needs larger stack)
|
||||
// Default stack size (compiler thread needs larger stack).
|
||||
size_t s = (thr_type == os::compiler_thread ? 4 * M : 1024 * K);
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
|
||||
// z/Architecture: put 2 guard pages right in the middle of thread stack. This value
|
||||
// should be consistent with the value used by register stack handling code.
|
||||
return 2 * page_size();
|
||||
}
|
||||
|
||||
// Java thread:
|
||||
//
|
||||
// Low memory addresses
|
||||
// +------------------------+
|
||||
// | |\
|
||||
// | glibc guard page | - Right in the middle of stack, 2 pages
|
||||
// | |/
|
||||
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
|
||||
// | |\
|
||||
// | HotSpot Guard Pages | - red and yellow pages
|
||||
// | |/
|
||||
// +------------------------+ JavaThread::stack_yellow_zone_base()
|
||||
// | |\
|
||||
// | Normal Stack | -
|
||||
// | |/
|
||||
// P2 +------------------------+ Thread::stack_base()
|
||||
//
|
||||
// Non-Java thread:
|
||||
//
|
||||
// Low memory addresses
|
||||
// +------------------------+
|
||||
// | |\
|
||||
// | glibc guard page | - Right in the middle of stack, 2 pages
|
||||
// | |/
|
||||
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
|
||||
// | |\
|
||||
// | Normal Stack | -
|
||||
// | |/
|
||||
// P2 +------------------------+ Thread::stack_base()
|
||||
//
|
||||
// ** P2 is the address returned from pthread_attr_getstackaddr(), P2 - P1
|
||||
// is the stack size returned by pthread_attr_getstacksize().
|
||||
|
||||
|
||||
static void current_stack_region(address * bottom, size_t * size) {
|
||||
if (os::Linux::is_initial_thread()) {
|
||||
// Initial thread needs special handling because pthread_getattr_np()
|
||||
// may return bogus value.
|
||||
*bottom = os::Linux::initial_thread_stack_bottom();
|
||||
*size = os::Linux::initial_thread_stack_size();
|
||||
} else {
|
||||
pthread_attr_t attr;
|
||||
|
||||
int rslt = pthread_getattr_np(pthread_self(), &attr);
|
||||
|
||||
// JVM needs to know exact stack location, abort if it fails
|
||||
if (rslt != 0) {
|
||||
if (rslt == ENOMEM) {
|
||||
vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
|
||||
} else {
|
||||
fatal("pthread_getattr_np failed with errno = %d", rslt);
|
||||
}
|
||||
}
|
||||
|
||||
if (pthread_attr_getstack(&attr, (void **)bottom, size) != 0) {
|
||||
fatal("Can not locate current stack attributes!");
|
||||
}
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
}
|
||||
assert(os::current_stack_pointer() >= *bottom &&
|
||||
os::current_stack_pointer() < *bottom + *size, "just checking");
|
||||
}
|
||||
|
||||
address os::current_stack_base() {
|
||||
address bottom;
|
||||
size_t size;
|
||||
current_stack_region(&bottom, &size);
|
||||
return (bottom + size);
|
||||
}
|
||||
|
||||
size_t os::current_stack_size() {
|
||||
// stack size includes normal stack and HotSpot guard pages
|
||||
address bottom;
|
||||
size_t size;
|
||||
current_stack_region(&bottom, &size);
|
||||
return size;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// helper functions for fatal error handler
|
||||
|
||||
|
@ -156,51 +156,6 @@ address os::current_stack_pointer() {
|
||||
return (address)sp;
|
||||
}
|
||||
|
||||
static void current_stack_region(address* bottom, size_t* size) {
|
||||
if (os::Linux::is_initial_thread()) {
|
||||
// initial thread needs special handling because pthread_getattr_np()
|
||||
// may return bogus value.
|
||||
*bottom = os::Linux::initial_thread_stack_bottom();
|
||||
*size = os::Linux::initial_thread_stack_size();
|
||||
} else {
|
||||
pthread_attr_t attr;
|
||||
|
||||
int rslt = pthread_getattr_np(pthread_self(), &attr);
|
||||
|
||||
// JVM needs to know exact stack location, abort if it fails
|
||||
if (rslt != 0) {
|
||||
if (rslt == ENOMEM) {
|
||||
vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
|
||||
} else {
|
||||
fatal("pthread_getattr_np failed with errno = %d", rslt);
|
||||
}
|
||||
}
|
||||
|
||||
if (pthread_attr_getstack(&attr, (void**)bottom, size) != 0) {
|
||||
fatal("Can not locate current stack attributes!");
|
||||
}
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
}
|
||||
assert(os::current_stack_pointer() >= *bottom &&
|
||||
os::current_stack_pointer() < *bottom + *size, "just checking");
|
||||
}
|
||||
|
||||
address os::current_stack_base() {
|
||||
address bottom;
|
||||
size_t size;
|
||||
current_stack_region(&bottom, &size);
|
||||
return bottom + size;
|
||||
}
|
||||
|
||||
size_t os::current_stack_size() {
|
||||
// stack size includes normal stack and HotSpot guard pages
|
||||
address bottom;
|
||||
size_t size;
|
||||
current_stack_region(&bottom, &size);
|
||||
return size;
|
||||
}
|
||||
|
||||
char* os::non_memory_address_word() {
|
||||
// Must never look like an address returned by reserve_memory,
|
||||
// even in its subfields (as defined by the CPU immediate fields,
|
||||
@ -726,8 +681,10 @@ bool os::is_allocatable(size_t bytes) {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// thread stack
|
||||
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 128 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 128 * K;
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 128 * K;
|
||||
|
||||
// return default stack size for thr_type
|
||||
@ -737,12 +694,6 @@ size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
|
||||
// Creating guard page is very expensive. Java thread has HotSpot
|
||||
// guard page, only enable glibc guard page for non-Java threads.
|
||||
return (thr_type == java_thread ? 0 : page_size());
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void os::verify_stack_alignment() {
|
||||
}
|
||||
|
@ -677,15 +677,15 @@ bool os::is_allocatable(size_t bytes) {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// thread stack
|
||||
|
||||
#ifdef AMD64
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 48 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 40 * K;
|
||||
#ifdef _LP64
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
#else
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
#endif // AMD64
|
||||
#endif // _LP64
|
||||
|
||||
// return default stack size for thr_type
|
||||
size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
@ -698,91 +698,6 @@ size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
|
||||
// Creating guard page is very expensive. Java thread has HotSpot
|
||||
// guard page, only enable glibc guard page for non-Java threads.
|
||||
return (thr_type == java_thread ? 0 : page_size());
|
||||
}
|
||||
|
||||
// Java thread:
|
||||
//
|
||||
// Low memory addresses
|
||||
// +------------------------+
|
||||
// | |\ JavaThread created by VM does not have glibc
|
||||
// | glibc guard page | - guard, attached Java thread usually has
|
||||
// | |/ 1 page glibc guard.
|
||||
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
|
||||
// | |\
|
||||
// | HotSpot Guard Pages | - red and yellow pages
|
||||
// | |/
|
||||
// +------------------------+ JavaThread::stack_yellow_zone_base()
|
||||
// | |\
|
||||
// | Normal Stack | -
|
||||
// | |/
|
||||
// P2 +------------------------+ Thread::stack_base()
|
||||
//
|
||||
// Non-Java thread:
|
||||
//
|
||||
// Low memory addresses
|
||||
// +------------------------+
|
||||
// | |\
|
||||
// | glibc guard page | - usually 1 page
|
||||
// | |/
|
||||
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
|
||||
// | |\
|
||||
// | Normal Stack | -
|
||||
// | |/
|
||||
// P2 +------------------------+ Thread::stack_base()
|
||||
//
|
||||
// ** P1 (aka bottom) and size ( P2 = P1 - size) are the address and stack size returned from
|
||||
// pthread_attr_getstack()
|
||||
|
||||
static void current_stack_region(address * bottom, size_t * size) {
|
||||
if (os::Linux::is_initial_thread()) {
|
||||
// initial thread needs special handling because pthread_getattr_np()
|
||||
// may return bogus value.
|
||||
*bottom = os::Linux::initial_thread_stack_bottom();
|
||||
*size = os::Linux::initial_thread_stack_size();
|
||||
} else {
|
||||
pthread_attr_t attr;
|
||||
|
||||
int rslt = pthread_getattr_np(pthread_self(), &attr);
|
||||
|
||||
// JVM needs to know exact stack location, abort if it fails
|
||||
if (rslt != 0) {
|
||||
if (rslt == ENOMEM) {
|
||||
vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
|
||||
} else {
|
||||
fatal("pthread_getattr_np failed with errno = %d", rslt);
|
||||
}
|
||||
}
|
||||
|
||||
if (pthread_attr_getstack(&attr, (void **)bottom, size) != 0) {
|
||||
fatal("Can not locate current stack attributes!");
|
||||
}
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
}
|
||||
assert(os::current_stack_pointer() >= *bottom &&
|
||||
os::current_stack_pointer() < *bottom + *size, "just checking");
|
||||
}
|
||||
|
||||
address os::current_stack_base() {
|
||||
address bottom;
|
||||
size_t size;
|
||||
current_stack_region(&bottom, &size);
|
||||
return (bottom + size);
|
||||
}
|
||||
|
||||
size_t os::current_stack_size() {
|
||||
// stack size includes normal stack and HotSpot guard pages
|
||||
address bottom;
|
||||
size_t size;
|
||||
current_stack_region(&bottom, &size);
|
||||
return size;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// helper functions for fatal error handler
|
||||
|
||||
|
@ -320,12 +320,6 @@ size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
|
||||
// Only enable glibc guard pages for non-Java threads
|
||||
// (Java threads have HotSpot guard pages)
|
||||
return (thr_type == java_thread ? 0 : page_size());
|
||||
}
|
||||
|
||||
static void current_stack_region(address *bottom, size_t *size) {
|
||||
pthread_attr_t attr;
|
||||
int res = pthread_getattr_np(pthread_self(), &attr);
|
||||
@ -334,7 +328,7 @@ static void current_stack_region(address *bottom, size_t *size) {
|
||||
vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
|
||||
}
|
||||
else {
|
||||
fatal("pthread_getattr_np failed with errno = %d", res);
|
||||
fatal("pthread_getattr_np failed with error = %d", res);
|
||||
}
|
||||
}
|
||||
|
||||
@ -342,7 +336,7 @@ static void current_stack_region(address *bottom, size_t *size) {
|
||||
size_t stack_bytes;
|
||||
res = pthread_attr_getstack(&attr, (void **) &stack_bottom, &stack_bytes);
|
||||
if (res != 0) {
|
||||
fatal("pthread_attr_getstack failed with errno = %d", res);
|
||||
fatal("pthread_attr_getstack failed with error = %d", res);
|
||||
}
|
||||
address stack_top = stack_bottom + stack_bytes;
|
||||
|
||||
|
@ -81,15 +81,13 @@
|
||||
|
||||
#define MAX_PATH (2 * K)
|
||||
|
||||
// Minimum stack size for the VM. It's easier to document a constant
|
||||
// but it's different for x86 and sparc because the page sizes are different.
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 104 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 86 * K;
|
||||
#ifdef _LP64
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 128 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 128 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 128 * K;
|
||||
#else
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 96 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 96 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 96 * K;
|
||||
#endif
|
||||
|
||||
|
@ -86,19 +86,23 @@
|
||||
|
||||
#define MAX_PATH (2 * K)
|
||||
|
||||
// Minimum stack sizes for the VM. It's easier to document a constant value
|
||||
// but it's different for x86 and sparc because the page sizes are different.
|
||||
#ifdef AMD64
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 394 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 224 * K;
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
#ifdef _LP64
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 202 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 48 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 224 * K;
|
||||
#else
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 32 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 32 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
#endif // _LP64
|
||||
|
||||
#ifdef AMD64
|
||||
#define REG_SP REG_RSP
|
||||
#define REG_PC REG_RIP
|
||||
#define REG_FP REG_RBP
|
||||
#else
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
#define REG_SP UESP
|
||||
#define REG_PC EIP
|
||||
#define REG_FP EBP
|
||||
|
@ -677,9 +677,7 @@ void LIR_OpVisitState::visit(LIR_Op* op) {
|
||||
|
||||
// LIR_Op3
|
||||
case lir_idiv:
|
||||
case lir_irem:
|
||||
case lir_fmad:
|
||||
case lir_fmaf: {
|
||||
case lir_irem: {
|
||||
assert(op->as_Op3() != NULL, "must be");
|
||||
LIR_Op3* op3= (LIR_Op3*)op;
|
||||
|
||||
@ -697,6 +695,17 @@ void LIR_OpVisitState::visit(LIR_Op* op) {
|
||||
break;
|
||||
}
|
||||
|
||||
case lir_fmad:
|
||||
case lir_fmaf: {
|
||||
assert(op->as_Op3() != NULL, "must be");
|
||||
LIR_Op3* op3= (LIR_Op3*)op;
|
||||
assert(op3->_info == NULL, "no info");
|
||||
do_input(op3->_opr1);
|
||||
do_input(op3->_opr2);
|
||||
do_input(op3->_opr3);
|
||||
do_output(op3->_result);
|
||||
break;
|
||||
}
|
||||
|
||||
// LIR_OpJavaCall
|
||||
case lir_static_call:
|
||||
|
@ -84,7 +84,6 @@ typedef jboolean (JNICALL *ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned ch
|
||||
typedef jzentry* (JNICALL *GetNextEntry_t)(jzfile *zip, jint n);
|
||||
typedef jboolean (JNICALL *ZipInflateFully_t)(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg);
|
||||
typedef jint (JNICALL *Crc32_t)(jint crc, const jbyte *buf, jint len);
|
||||
typedef void (JNICALL *FreeEntry_t)(jzfile *zip, jzentry *entry);
|
||||
|
||||
static ZipOpen_t ZipOpen = NULL;
|
||||
static ZipClose_t ZipClose = NULL;
|
||||
@ -94,7 +93,6 @@ static GetNextEntry_t GetNextEntry = NULL;
|
||||
static canonicalize_fn_t CanonicalizeEntry = NULL;
|
||||
static ZipInflateFully_t ZipInflateFully = NULL;
|
||||
static Crc32_t Crc32 = NULL;
|
||||
static FreeEntry_t FreeEntry = NULL;
|
||||
|
||||
// Entry points for jimage.dll for loading jimage file entries
|
||||
|
||||
@ -150,7 +148,6 @@ int ClassLoader::_num_entries = 0;
|
||||
GrowableArray<char*>* ClassLoader::_boot_modules_array = NULL;
|
||||
GrowableArray<char*>* ClassLoader::_platform_modules_array = NULL;
|
||||
SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL;
|
||||
int ClassLoader::_num_patch_mod_prefixes = 0;
|
||||
#endif
|
||||
|
||||
// helper routines
|
||||
@ -320,20 +317,6 @@ ClassPathZipEntry::~ClassPathZipEntry() {
|
||||
FREE_C_HEAP_ARRAY(char, _zip_name);
|
||||
}
|
||||
|
||||
bool ClassPathZipEntry::stream_exists(const char* name) {
|
||||
// enable call to C land
|
||||
JavaThread* thread = JavaThread::current();
|
||||
ThreadToNativeFromVM ttn(thread);
|
||||
// check whether zip archive contains name
|
||||
jint name_len, filesize;
|
||||
jzentry* entry = (*FindEntry)(_zip, name, &filesize, &name_len);
|
||||
if (entry != NULL) {
|
||||
(*FreeEntry)(_zip, entry);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
u1* ClassPathZipEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) {
|
||||
// enable call to C land
|
||||
JavaThread* thread = JavaThread::current();
|
||||
@ -1090,7 +1073,6 @@ void ClassLoader::load_zip_library() {
|
||||
GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, os::dll_lookup(handle, "ZIP_GetNextEntry"));
|
||||
ZipInflateFully = CAST_TO_FN_PTR(ZipInflateFully_t, os::dll_lookup(handle, "ZIP_InflateFully"));
|
||||
Crc32 = CAST_TO_FN_PTR(Crc32_t, os::dll_lookup(handle, "ZIP_CRC32"));
|
||||
FreeEntry = CAST_TO_FN_PTR(FreeEntry_t, os::dll_lookup(handle, "ZIP_FreeEntry"));
|
||||
|
||||
// ZIP_Close is not exported on Windows in JDK5.0 so don't abort if ZIP_Close is NULL
|
||||
if (ZipOpen == NULL || FindEntry == NULL || ReadEntry == NULL ||
|
||||
@ -1418,57 +1400,6 @@ ClassFileStream* ClassLoader::search_module_entries(const GrowableArray<ModuleCl
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
// The following function is only used during CDS dump time.
|
||||
// It checks if a class can be found in the jar entries of the _patch_mod_entries.
|
||||
// It does not support non-jar entries.
|
||||
bool ClassLoader::is_in_patch_module(const char* const file_name) {
|
||||
assert(DumpSharedSpaces, "dump time only");
|
||||
if (_patch_mod_entries == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int num_of_entries = _patch_mod_entries->length();
|
||||
char* class_module_name = NULL;
|
||||
ResourceMark rm;
|
||||
const char *pkg_name = package_from_name(file_name);
|
||||
// Using the jimage to obtain the class' module name.
|
||||
// The ModuleEntryTable cannot be used at this point during dump time
|
||||
// because the module system hasn't been initialized yet.
|
||||
if (pkg_name != NULL) {
|
||||
JImageFile *jimage = _jrt_entry->jimage();
|
||||
class_module_name = (char*)(*JImagePackageToModule)(jimage, pkg_name);
|
||||
}
|
||||
|
||||
if (class_module_name == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Loop through all the patch module entries looking for module
|
||||
for (int i = 0; i < num_of_entries; i++) {
|
||||
ModuleClassPathList* module_cpl = _patch_mod_entries->at(i);
|
||||
Symbol* module_cpl_name = module_cpl->module_name();
|
||||
|
||||
if (strcmp(module_cpl_name->as_C_string(), class_module_name) == 0) {
|
||||
// Class' module has been located, attempt to locate
|
||||
// the class from the module's ClassPathEntry list.
|
||||
ClassPathEntry* e = module_cpl->module_first_entry();
|
||||
while (e != NULL) {
|
||||
if (e->is_jar_file()) {
|
||||
if (e->stream_exists(file_name)) {
|
||||
return true;
|
||||
} else {
|
||||
e = e->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif // INCLUDE_CDS
|
||||
|
||||
instanceKlassHandle ClassLoader::load_class(Symbol* name, bool search_append_only, TRAPS) {
|
||||
assert(name != NULL, "invariant");
|
||||
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
||||
@ -1494,8 +1425,6 @@ instanceKlassHandle ClassLoader::load_class(Symbol* name, bool search_append_onl
|
||||
|
||||
// If DumpSharedSpaces is true boot loader visibility boundaries are set to:
|
||||
// - [jimage] + [_first_append_entry to _last_append_entry] (all path entries).
|
||||
// If a class is found in the --patch-module entries, the class will not be included in the
|
||||
// CDS archive. Also, CDS is not supported if exploded module builds are used.
|
||||
//
|
||||
// If search_append_only is true, boot loader visibility boundaries are
|
||||
// set to be _first_append_entry to the end. This includes:
|
||||
@ -1519,15 +1448,13 @@ instanceKlassHandle ClassLoader::load_class(Symbol* name, bool search_append_onl
|
||||
// Note: The --patch-module entries are never searched if the boot loader's
|
||||
// visibility boundary is limited to only searching the append entries.
|
||||
if (_patch_mod_entries != NULL && !search_append_only) {
|
||||
// At CDS dump time, the --patch-module entries are ignored. That means a
|
||||
// class is still loaded from the runtime image even if it might
|
||||
// appear in the _patch_mod_entries. The runtime shared class visibility
|
||||
// check will determine if a shared class is visible based on the runtime
|
||||
// environemnt, including the runtime --patch-module setting.
|
||||
if (!DumpSharedSpaces) {
|
||||
stream = search_module_entries(_patch_mod_entries, class_name, file_name, CHECK_NULL);
|
||||
} else {
|
||||
#if INCLUDE_CDS
|
||||
if (is_in_patch_module(file_name)) {
|
||||
tty->print_cr("Preload Warning: Skip archiving class %s found in --patch-module entry", class_name);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1679,57 +1606,8 @@ void ClassLoader::initialize() {
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
// Capture all the --patch-module entries specified during CDS dump time.
|
||||
// It also captures the non-existing path(s) and the required file(s) during inspecting
|
||||
// the entries.
|
||||
void ClassLoader::setup_patch_mod_path() {
|
||||
assert(DumpSharedSpaces, "only used with -Xshare:dump");
|
||||
ResourceMark rm;
|
||||
GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix();
|
||||
if (patch_mod_args != NULL) {
|
||||
int num_of_entries = patch_mod_args->length();
|
||||
for (int i = 0; i < num_of_entries; i++) {
|
||||
const char* module_name = (patch_mod_args->at(i))->module_name();
|
||||
const char* module_path = (patch_mod_args->at(i))->path_string();
|
||||
int path_len = (int)strlen(module_path);
|
||||
int name_len = (int)strlen(module_name);
|
||||
int buf_len = name_len + path_len + 2; // add 2 for the '=' and NULL terminator
|
||||
int end = 0;
|
||||
char* buf = NEW_C_HEAP_ARRAY(char, buf_len, mtInternal);
|
||||
// Iterate over the module's class path entries
|
||||
for (int start = 0; start < path_len; start = end) {
|
||||
while (module_path[end] && module_path[end] != os::path_separator()[0]) {
|
||||
end++;
|
||||
}
|
||||
strncpy(buf, &module_path[start], end - start);
|
||||
buf[end - start] = '\0';
|
||||
struct stat st;
|
||||
if (os::stat(buf, &st) != 0) {
|
||||
// File not found
|
||||
_shared_paths_misc_info->add_nonexist_path(buf);
|
||||
} else {
|
||||
if ((st.st_mode & S_IFMT) != S_IFREG) { // is not a regular file
|
||||
vm_exit_during_initialization(
|
||||
"--patch-module requires a regular file during dumping", buf);
|
||||
} else {
|
||||
_shared_paths_misc_info->add_required_file(buf);
|
||||
}
|
||||
}
|
||||
while (module_path[end] == os::path_separator()[0]) {
|
||||
end++;
|
||||
}
|
||||
};
|
||||
jio_snprintf(buf, buf_len, "%s=%s", module_name, module_path);
|
||||
_shared_paths_misc_info->add_patch_mod_classpath((const char*)buf);
|
||||
_num_patch_mod_prefixes++;
|
||||
FREE_C_HEAP_ARRAY(char, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoader::initialize_shared_path() {
|
||||
if (DumpSharedSpaces) {
|
||||
setup_patch_mod_path();
|
||||
ClassLoaderExt::setup_search_paths();
|
||||
_shared_paths_misc_info->write_jint(0); // see comments in SharedPathsMiscInfo::check()
|
||||
}
|
||||
|
@ -69,7 +69,6 @@ public:
|
||||
// Attempt to locate file_name through this class path entry.
|
||||
// Returns a class file parsing stream if successfull.
|
||||
virtual ClassFileStream* open_stream(const char* name, TRAPS) = 0;
|
||||
virtual bool stream_exists(const char* name) = 0;
|
||||
// Debugging
|
||||
NOT_PRODUCT(virtual void compile_the_world(Handle loader, TRAPS) = 0;)
|
||||
};
|
||||
@ -84,7 +83,6 @@ class ClassPathDirEntry: public ClassPathEntry {
|
||||
JImageFile* jimage() const { return NULL; }
|
||||
ClassPathDirEntry(const char* dir);
|
||||
ClassFileStream* open_stream(const char* name, TRAPS);
|
||||
bool stream_exists(const char* name) { return false; }
|
||||
// Debugging
|
||||
NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
|
||||
};
|
||||
@ -128,7 +126,6 @@ class ClassPathZipEntry: public ClassPathEntry {
|
||||
ClassFileStream* open_stream(const char* name, TRAPS);
|
||||
void contents_do(void f(const char* name, void* context), void* context);
|
||||
bool is_multiple_versioned(TRAPS) NOT_CDS_RETURN_(false);
|
||||
bool stream_exists(const char* name);
|
||||
// Debugging
|
||||
NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
|
||||
};
|
||||
@ -148,7 +145,6 @@ public:
|
||||
ClassPathImageEntry(JImageFile* jimage, const char* name);
|
||||
~ClassPathImageEntry();
|
||||
ClassFileStream* open_stream(const char* name, TRAPS);
|
||||
bool stream_exists(const char* name) { return false; }
|
||||
|
||||
// Debugging
|
||||
NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
|
||||
@ -259,7 +255,6 @@ class ClassLoader: AllStatic {
|
||||
|
||||
// Info used by CDS
|
||||
CDS_ONLY(static SharedPathsMiscInfo * _shared_paths_misc_info;)
|
||||
CDS_ONLY(static int _num_patch_mod_prefixes;)
|
||||
|
||||
// Initialization:
|
||||
// - setup the boot loader's system class path
|
||||
@ -434,9 +429,6 @@ class ClassLoader: AllStatic {
|
||||
static void initialize_module_loader_map(JImageFile* jimage);
|
||||
static s2 classloader_type(Symbol* class_name, ClassPathEntry* e,
|
||||
int classpath_index, TRAPS);
|
||||
static bool is_in_patch_module(const char* const file_name);
|
||||
static void setup_patch_mod_path(); // Only when -Xshare:dump
|
||||
static int num_patch_mod_prefixes() { return _num_patch_mod_prefixes; }
|
||||
#endif
|
||||
|
||||
static void trace_class_path(const char* msg, const char* name = NULL);
|
||||
|
@ -108,6 +108,18 @@ bool ModuleEntry::can_read(ModuleEntry* m) const {
|
||||
}
|
||||
|
||||
MutexLocker m1(Module_lock);
|
||||
// This is a guard against possible race between agent threads that redefine
|
||||
// or retransform classes in this module. Only one of them is adding the
|
||||
// default read edges to the unnamed modules of the boot and app class loaders
|
||||
// with an upcall to jdk.internal.module.Modules.transformedByAgent.
|
||||
// At the same time, another thread can instrument the module classes by
|
||||
// injecting dependencies that require the default read edges for resolution.
|
||||
if (this->has_default_read_edges() && !m->is_named()) {
|
||||
ClassLoaderData* cld = m->loader_data();
|
||||
if (cld->is_the_null_class_loader_data() || cld->is_system_class_loader_data()) {
|
||||
return true; // default read edge
|
||||
}
|
||||
}
|
||||
if (!has_reads()) {
|
||||
return false;
|
||||
} else {
|
||||
|
@ -86,9 +86,6 @@ void SharedPathsMiscInfo::print_path(int type, const char* path) {
|
||||
case REQUIRED:
|
||||
out->print("Expecting that file %s must exist and is not altered", path);
|
||||
break;
|
||||
case PATCH_MOD:
|
||||
out->print("Expecting --patch-module=%s", path);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
@ -167,26 +164,6 @@ bool SharedPathsMiscInfo::check(jint type, const char* path) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PATCH_MOD:
|
||||
{
|
||||
GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix();
|
||||
if (patch_mod_args != NULL) {
|
||||
int num_of_entries = patch_mod_args->length();
|
||||
for (int i = 0; i < num_of_entries; i++) {
|
||||
const char* module_name = (patch_mod_args->at(i))->module_name();
|
||||
const char* path_string = (patch_mod_args->at(i))->path_string();
|
||||
size_t n = strlen(module_name);
|
||||
// path contains the module name, followed by '=', and one or more entries.
|
||||
// E.g.: "java.base=foo" or "java.naming=dir1:dir2:dir3"
|
||||
if ((strncmp(module_name, path, n) != 0) ||
|
||||
(path[n] != '=') ||
|
||||
(strcmp(path + n + 1, path_string) != 0)) {
|
||||
return fail("--patch-module mismatch, path not found in run time: ", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return fail("Corrupted archive file header");
|
||||
}
|
||||
|
@ -104,28 +104,10 @@ public:
|
||||
add_path(path, NON_EXIST);
|
||||
}
|
||||
|
||||
// The path must exist and have required size and modification time
|
||||
void add_required_file(const char* path) {
|
||||
add_path(path, REQUIRED);
|
||||
|
||||
struct stat st;
|
||||
if (os::stat(path, &st) != 0) {
|
||||
assert(0, "sanity");
|
||||
#if INCLUDE_CDS
|
||||
ClassLoader::exit_with_path_failure("failed to os::stat(%s)", path); // should not happen
|
||||
#endif
|
||||
}
|
||||
write_time(st.st_mtime);
|
||||
write_long(st.st_size);
|
||||
}
|
||||
|
||||
// The path must exist, and must contain exactly <num_entries> files/dirs
|
||||
void add_boot_classpath(const char* path) {
|
||||
add_path(path, BOOT);
|
||||
}
|
||||
void add_patch_mod_classpath(const char* path) {
|
||||
add_path(path, PATCH_MOD);
|
||||
}
|
||||
int write_jint(jint num) {
|
||||
write(&num, sizeof(num));
|
||||
return 0;
|
||||
@ -147,8 +129,7 @@ public:
|
||||
enum {
|
||||
BOOT = 1,
|
||||
NON_EXIST = 2,
|
||||
REQUIRED = 3,
|
||||
PATCH_MOD = 4
|
||||
REQUIRED = 3
|
||||
};
|
||||
|
||||
virtual const char* type_name(int type) {
|
||||
@ -156,7 +137,6 @@ public:
|
||||
case BOOT: return "BOOT";
|
||||
case NON_EXIST: return "NON_EXIST";
|
||||
case REQUIRED: return "REQUIRED";
|
||||
case PATCH_MOD: return "PATCH_MOD";
|
||||
default: ShouldNotReachHere(); return "?";
|
||||
}
|
||||
}
|
||||
|
@ -1231,6 +1231,8 @@ instanceKlassHandle SystemDictionary::load_shared_class(
|
||||
bool SystemDictionary::is_shared_class_visible(Symbol* class_name,
|
||||
instanceKlassHandle ik,
|
||||
Handle class_loader, TRAPS) {
|
||||
assert(!ModuleEntryTable::javabase_moduleEntry()->is_patched(),
|
||||
"Cannot use sharing if java.base is patched");
|
||||
ResourceMark rm;
|
||||
int path_index = ik->shared_classpath_index();
|
||||
SharedClassPathEntry* ent =
|
||||
@ -1258,6 +1260,12 @@ bool SystemDictionary::is_shared_class_visible(Symbol* class_name,
|
||||
}
|
||||
}
|
||||
|
||||
// If the archived class is from a module that has been patched at runtime,
|
||||
// the class cannot be loaded from the archive.
|
||||
if (mod_entry != NULL && mod_entry->is_patched()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (class_loader.is_null()) {
|
||||
assert(ent != NULL, "Shared class for NULL classloader must have valid SharedClassPathEntry");
|
||||
// The NULL classloader can load archived class originated from the
|
||||
|
@ -299,10 +299,6 @@ class AbstractInterpreter: AllStatic {
|
||||
}
|
||||
|
||||
static void initialize_method_handle_entries();
|
||||
|
||||
// PPC-only: Support abs and sqrt like in compiler.
|
||||
// For others we can use a normal (native) entry.
|
||||
static bool math_entry_available(MethodKind kind);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -57,6 +57,8 @@ void CppInterpreterGenerator::generate_all() {
|
||||
method_entry(java_lang_math_log10 );
|
||||
method_entry(java_lang_math_pow );
|
||||
method_entry(java_lang_math_exp );
|
||||
method_entry(java_lang_math_fmaD );
|
||||
method_entry(java_lang_math_fmaF );
|
||||
method_entry(java_lang_ref_reference_get);
|
||||
|
||||
AbstractInterpreter::initialize_method_handle_entries();
|
||||
@ -95,7 +97,9 @@ address CppInterpreterGenerator::generate_method_entry(
|
||||
case Interpreter::java_lang_math_log10 : // fall thru
|
||||
case Interpreter::java_lang_math_sqrt : // fall thru
|
||||
case Interpreter::java_lang_math_pow : // fall thru
|
||||
case Interpreter::java_lang_math_exp : entry_point = generate_math_entry(kind); break;
|
||||
case Interpreter::java_lang_math_exp : // fall thru
|
||||
case Interpreter::java_lang_math_fmaD : // fall thru
|
||||
case Interpreter::java_lang_math_fmaF : entry_point = generate_math_entry(kind); break;
|
||||
case Interpreter::java_lang_ref_reference_get
|
||||
: entry_point = generate_Reference_get_entry(); break;
|
||||
default:
|
||||
|
@ -426,15 +426,16 @@ void Rewriter::scan_method(Method* method, bool reverse, bool* invokespecial_err
|
||||
Symbol* field_sig = cp->signature_ref_at(bc_index);
|
||||
|
||||
fieldDescriptor fd;
|
||||
klass->find_field(field_name, field_sig, &fd);
|
||||
if (fd.access_flags().is_final()) {
|
||||
if (fd.access_flags().is_static()) {
|
||||
if (!method->is_static_initializer()) {
|
||||
fd.set_has_initialized_final_update(true);
|
||||
}
|
||||
} else {
|
||||
if (!method->is_object_initializer()) {
|
||||
fd.set_has_initialized_final_update(true);
|
||||
if (klass->find_field(field_name, field_sig, &fd) != NULL) {
|
||||
if (fd.access_flags().is_final()) {
|
||||
if (fd.access_flags().is_static()) {
|
||||
if (!method->is_static_initializer()) {
|
||||
fd.set_has_initialized_final_update(true);
|
||||
}
|
||||
} else {
|
||||
if (!method->is_object_initializer()) {
|
||||
fd.set_has_initialized_final_update(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -967,7 +967,7 @@ GrowableArray<ScopeValue*>* CodeInstaller::record_virtual_objects(Handle debug_i
|
||||
return objects;
|
||||
}
|
||||
|
||||
void CodeInstaller::record_scope(jint pc_offset, Handle debug_info, ScopeMode scope_mode, TRAPS) {
|
||||
void CodeInstaller::record_scope(jint pc_offset, Handle debug_info, ScopeMode scope_mode, bool return_oop, TRAPS) {
|
||||
Handle position = DebugInfo::bytecodePosition(debug_info);
|
||||
if (position.is_null()) {
|
||||
// Stubs do not record scope info, just oop maps
|
||||
@ -980,10 +980,10 @@ void CodeInstaller::record_scope(jint pc_offset, Handle debug_info, ScopeMode sc
|
||||
} else {
|
||||
objectMapping = NULL;
|
||||
}
|
||||
record_scope(pc_offset, position, scope_mode, objectMapping, CHECK);
|
||||
record_scope(pc_offset, position, scope_mode, objectMapping, return_oop, CHECK);
|
||||
}
|
||||
|
||||
void CodeInstaller::record_scope(jint pc_offset, Handle position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, TRAPS) {
|
||||
void CodeInstaller::record_scope(jint pc_offset, Handle position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, bool return_oop, TRAPS) {
|
||||
Handle frame;
|
||||
if (scope_mode == CodeInstaller::FullFrame) {
|
||||
if (!position->is_a(BytecodeFrame::klass())) {
|
||||
@ -993,7 +993,7 @@ void CodeInstaller::record_scope(jint pc_offset, Handle position, ScopeMode scop
|
||||
}
|
||||
Handle caller_frame = BytecodePosition::caller(position);
|
||||
if (caller_frame.not_null()) {
|
||||
record_scope(pc_offset, caller_frame, scope_mode, objects, CHECK);
|
||||
record_scope(pc_offset, caller_frame, scope_mode, objects, return_oop, CHECK);
|
||||
}
|
||||
|
||||
Handle hotspot_method = BytecodePosition::method(position);
|
||||
@ -1083,7 +1083,7 @@ void CodeInstaller::record_scope(jint pc_offset, Handle position, ScopeMode scop
|
||||
throw_exception = BytecodeFrame::rethrowException(frame) == JNI_TRUE;
|
||||
}
|
||||
|
||||
_debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false,
|
||||
_debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, return_oop,
|
||||
locals_token, expressions_token, monitors_token);
|
||||
}
|
||||
|
||||
@ -1139,7 +1139,10 @@ 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, CodeInstaller::FullFrame, CHECK);
|
||||
|
||||
bool return_oop = hotspot_method.not_null() && getMethodFromHotSpotMethod(hotspot_method())->is_returning_oop();
|
||||
|
||||
record_scope(next_pc_offset, debug_info, CodeInstaller::FullFrame, return_oop, CHECK);
|
||||
}
|
||||
|
||||
if (foreign_call.not_null()) {
|
||||
|
@ -254,8 +254,11 @@ protected:
|
||||
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_scope(jint pc_offset, Handle debug_info, ScopeMode scope_mode, bool return_oop, TRAPS);
|
||||
void record_scope(jint pc_offset, Handle debug_info, ScopeMode scope_mode, TRAPS) {
|
||||
record_scope(pc_offset, debug_info, scope_mode, false /* return_oop */, THREAD);
|
||||
}
|
||||
void record_scope(jint pc_offset, Handle position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, bool return_oop, TRAPS);
|
||||
void record_object_value(ObjectValue* sv, Handle value, GrowableArray<ScopeValue*>* objects, TRAPS);
|
||||
|
||||
GrowableArray<ScopeValue*>* record_virtual_objects(Handle debug_info, TRAPS);
|
||||
|
@ -29,11 +29,17 @@
|
||||
#include "memory/allocation.inline.hpp"
|
||||
|
||||
static bool initialized;
|
||||
static char stdoutmem[sizeof(LogStdoutOutput)];
|
||||
static char stderrmem[sizeof(LogStderrOutput)];
|
||||
static union {
|
||||
char stdoutmem[sizeof(LogStdoutOutput)];
|
||||
jlong dummy;
|
||||
} aligned_stdoutmem;
|
||||
static union {
|
||||
char stderrmem[sizeof(LogStderrOutput)];
|
||||
jlong dummy;
|
||||
} aligned_stderrmem;
|
||||
|
||||
LogStdoutOutput &StdoutLog = reinterpret_cast<LogStdoutOutput&>(stdoutmem);
|
||||
LogStderrOutput &StderrLog = reinterpret_cast<LogStderrOutput&>(stderrmem);
|
||||
LogStdoutOutput &StdoutLog = reinterpret_cast<LogStdoutOutput&>(aligned_stdoutmem.stdoutmem);
|
||||
LogStderrOutput &StderrLog = reinterpret_cast<LogStderrOutput&>(aligned_stderrmem.stderrmem);
|
||||
|
||||
LogFileStreamInitializer::LogFileStreamInitializer() {
|
||||
if (!initialized) {
|
||||
|
@ -179,7 +179,6 @@ void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment
|
||||
_classpath_entry_table_size = mapinfo->_classpath_entry_table_size;
|
||||
_classpath_entry_table = mapinfo->_classpath_entry_table;
|
||||
_classpath_entry_size = mapinfo->_classpath_entry_size;
|
||||
_num_patch_mod_prefixes = ClassLoader::num_patch_mod_prefixes();
|
||||
|
||||
// The following fields are for sanity checks for whether this archive
|
||||
// will function correctly with this JVM and the bootclasspath it's
|
||||
@ -948,23 +947,6 @@ bool FileMapInfo::FileMapHeader::validate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if there is a mismatch in --patch-module entry counts between dump time and run time.
|
||||
// More checks will be performed on individual --patch-module entry in the
|
||||
// SharedPathsMiscInfo::check() function.
|
||||
GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix();
|
||||
if (patch_mod_args != NULL) {
|
||||
if (_num_patch_mod_prefixes == 0) {
|
||||
FileMapInfo::fail_stop("--patch-module found in run time but none was specified in dump time");
|
||||
}
|
||||
if (patch_mod_args->length() != _num_patch_mod_prefixes) {
|
||||
FileMapInfo::fail_stop("mismatched --patch-module entry counts between dump time and run time");
|
||||
}
|
||||
} else {
|
||||
if (_num_patch_mod_prefixes > 0) {
|
||||
FileMapInfo::fail_stop("--patch-module specified in dump time but none was specified in run time");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,6 @@ public:
|
||||
// loading failures during runtime.
|
||||
int _classpath_entry_table_size;
|
||||
size_t _classpath_entry_size;
|
||||
int _num_patch_mod_prefixes; // number of --patch-module entries
|
||||
SharedClassPathEntry* _classpath_entry_table;
|
||||
|
||||
char* region_addr(int idx);
|
||||
|
@ -59,7 +59,6 @@
|
||||
#include "opto/mulnode.hpp"
|
||||
#include "opto/runtime.hpp"
|
||||
#include "opto/subnode.hpp"
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/fprofiler.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
@ -1458,11 +1457,6 @@ address OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address r
|
||||
}
|
||||
#endif
|
||||
|
||||
JvmtiThreadState *state = thread->jvmti_thread_state();
|
||||
if (state != NULL) {
|
||||
state->set_exception_detected();
|
||||
}
|
||||
|
||||
thread->set_vm_result(exception);
|
||||
// Frame not compiled (handles deoptimization blob)
|
||||
return SharedRuntime::raw_exception_handler_for_return_address(thread, ret_pc);
|
||||
|
@ -130,15 +130,15 @@ class JvmtiEventMark : public StackObj {
|
||||
private:
|
||||
JavaThread *_thread;
|
||||
JNIEnv* _jni_env;
|
||||
bool _exception_detected;
|
||||
bool _exception_caught;
|
||||
JvmtiThreadState::ExceptionState _saved_exception_state;
|
||||
#if 0
|
||||
JNIHandleBlock* _hblock;
|
||||
#endif
|
||||
|
||||
public:
|
||||
JvmtiEventMark(JavaThread *thread) : _thread(thread),
|
||||
_jni_env(thread->jni_environment()) {
|
||||
_jni_env(thread->jni_environment()),
|
||||
_saved_exception_state(JvmtiThreadState::ES_CLEARED) {
|
||||
#if 0
|
||||
_hblock = thread->active_handles();
|
||||
_hblock->clear_thoroughly(); // so we can be safe
|
||||
@ -149,11 +149,7 @@ public:
|
||||
// we are before an event.
|
||||
// Save current jvmti thread exception state.
|
||||
if (state != NULL) {
|
||||
_exception_detected = state->is_exception_detected();
|
||||
_exception_caught = state->is_exception_caught();
|
||||
} else {
|
||||
_exception_detected = false;
|
||||
_exception_caught = false;
|
||||
_saved_exception_state = state->get_exception_state();
|
||||
}
|
||||
|
||||
JNIHandleBlock* old_handles = thread->active_handles();
|
||||
@ -186,12 +182,7 @@ public:
|
||||
// we are continuing after an event.
|
||||
if (state != NULL) {
|
||||
// Restore the jvmti thread exception state.
|
||||
if (_exception_detected) {
|
||||
state->set_exception_detected();
|
||||
}
|
||||
if (_exception_caught) {
|
||||
state->set_exception_caught();
|
||||
}
|
||||
state->restore_exception_state(_saved_exception_state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1552,7 +1543,6 @@ void JvmtiExport::post_single_step(JavaThread *thread, Method* method, address l
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void JvmtiExport::post_exception_throw(JavaThread *thread, Method* method, address location, oop exception) {
|
||||
HandleMark hm(thread);
|
||||
methodHandle mh(thread, method);
|
||||
@ -2454,7 +2444,7 @@ void JvmtiExport::clear_detected_exception(JavaThread* thread) {
|
||||
|
||||
JvmtiThreadState* state = thread->jvmti_thread_state();
|
||||
if (state != NULL) {
|
||||
state->clear_exception_detected();
|
||||
state->clear_exception_state();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,8 +50,7 @@ JvmtiThreadState::JvmtiThreadState(JavaThread* thread)
|
||||
: _thread_event_enable() {
|
||||
assert(JvmtiThreadState_lock->is_locked(), "sanity check");
|
||||
_thread = thread;
|
||||
_exception_detected = false;
|
||||
_exception_caught = false;
|
||||
_exception_state = ES_CLEARED;
|
||||
_debuggable = true;
|
||||
_hide_single_stepping = false;
|
||||
_hide_level = 0;
|
||||
@ -310,7 +309,7 @@ void JvmtiThreadState::process_pending_step_for_popframe() {
|
||||
// an exception.
|
||||
//
|
||||
if (is_exception_detected()) {
|
||||
clear_exception_detected();
|
||||
clear_exception_state();
|
||||
}
|
||||
// If step is pending for popframe then it may not be
|
||||
// a repeat step. The new_bci and method_id is same as current_bci
|
||||
@ -385,7 +384,7 @@ void JvmtiThreadState::process_pending_step_for_earlyret() {
|
||||
// an exception.
|
||||
//
|
||||
if (is_exception_detected()) {
|
||||
clear_exception_detected();
|
||||
clear_exception_state();
|
||||
}
|
||||
// If step is pending for earlyret then it may not be a repeat step.
|
||||
// The new_bci and method_id is same as current_bci and current
|
||||
|
@ -76,13 +76,21 @@ class JvmtiThreadState : public CHeapObj<mtInternal> {
|
||||
private:
|
||||
friend class JvmtiEnv;
|
||||
JavaThread *_thread;
|
||||
bool _exception_detected;
|
||||
bool _exception_caught;
|
||||
bool _hide_single_stepping;
|
||||
bool _pending_step_for_popframe;
|
||||
bool _pending_step_for_earlyret;
|
||||
int _hide_level;
|
||||
|
||||
public:
|
||||
enum ExceptionState {
|
||||
ES_CLEARED,
|
||||
ES_DETECTED,
|
||||
ES_CAUGHT
|
||||
};
|
||||
|
||||
private:
|
||||
ExceptionState _exception_state;
|
||||
|
||||
// Used to send class being redefined/retransformed and kind of transform
|
||||
// info to the class file load hook event handler.
|
||||
KlassHandle *_class_being_redefined;
|
||||
@ -161,16 +169,18 @@ class JvmtiThreadState : public CHeapObj<mtInternal> {
|
||||
int count_frames();
|
||||
|
||||
inline JavaThread *get_thread() { return _thread; }
|
||||
inline bool is_exception_detected() { return _exception_detected; }
|
||||
inline bool is_exception_caught() { return _exception_caught; }
|
||||
inline void set_exception_detected() { _exception_detected = true;
|
||||
_exception_caught = false; }
|
||||
inline void clear_exception_detected() {
|
||||
_exception_detected = false;
|
||||
assert(_exception_caught == false, "_exception_caught is out of phase");
|
||||
}
|
||||
inline void set_exception_caught() { _exception_caught = true;
|
||||
_exception_detected = false; }
|
||||
|
||||
inline bool is_exception_detected() { return _exception_state == ES_DETECTED; }
|
||||
inline bool is_exception_caught() { return _exception_state == ES_CAUGHT; }
|
||||
|
||||
inline void set_exception_detected() { _exception_state = ES_DETECTED; }
|
||||
inline void set_exception_caught() { _exception_state = ES_CAUGHT; }
|
||||
|
||||
inline void clear_exception_state() { _exception_state = ES_CLEARED; }
|
||||
|
||||
// We need to save and restore exception state inside JvmtiEventMark
|
||||
inline ExceptionState get_exception_state() { return _exception_state; }
|
||||
inline void restore_exception_state(ExceptionState state) { _exception_state = state; }
|
||||
|
||||
inline void clear_hide_single_stepping() {
|
||||
if (_hide_level > 0) {
|
||||
|
@ -1323,26 +1323,32 @@ void Arguments::check_unsupported_dumping_properties() {
|
||||
"jdk.module.limitmods",
|
||||
"jdk.module.path",
|
||||
"jdk.module.upgrade.path",
|
||||
"jdk.module.addmods.0" };
|
||||
const char* unsupported_options[] = { "-m",
|
||||
"--limit-modules",
|
||||
"--module-path",
|
||||
"--upgrade-module-path",
|
||||
"--add-modules" };
|
||||
"jdk.module.addmods.0",
|
||||
"jdk.module.patch.0" };
|
||||
const char* unsupported_options[] = { "-m", // cannot use at dump time
|
||||
"--limit-modules", // ignored at dump time
|
||||
"--module-path", // ignored at dump time
|
||||
"--upgrade-module-path", // ignored at dump time
|
||||
"--add-modules", // ignored at dump time
|
||||
"--patch-module" // ignored at dump time
|
||||
};
|
||||
assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be");
|
||||
// If a vm option is found in the unsupported_options array with index less than the warning_idx,
|
||||
// vm will exit with an error message. Otherwise, it will result in a warning message.
|
||||
uint warning_idx = 2;
|
||||
// If a vm option is found in the unsupported_options array with index less than the info_idx,
|
||||
// vm will exit with an error message. Otherwise, it will print an informational message if
|
||||
// PrintSharedSpaces is enabled.
|
||||
uint info_idx = 1;
|
||||
SystemProperty* sp = system_properties();
|
||||
while (sp != NULL) {
|
||||
for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) {
|
||||
if (strcmp(sp->key(), unsupported_properties[i]) == 0) {
|
||||
if (i < warning_idx) {
|
||||
if (i < info_idx) {
|
||||
vm_exit_during_initialization(
|
||||
"Cannot use the following option when dumping the shared archive", unsupported_options[i]);
|
||||
} else {
|
||||
warning(
|
||||
"the %s option is ignored when dumping the shared archive", unsupported_options[i]);
|
||||
if (PrintSharedSpaces) {
|
||||
tty->print_cr(
|
||||
"Info: the %s option is ignored when dumping the shared archive", unsupported_options[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1419,10 +1425,8 @@ void Arguments::set_mode_flags(Mode mode) {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(COMPILER2) || INCLUDE_JVMCI || defined(_LP64) || !INCLUDE_CDS
|
||||
// Conflict: required to use shared spaces (-Xshare:on), but
|
||||
// incompatible command line options were chosen.
|
||||
|
||||
static void no_shared_spaces(const char* message) {
|
||||
if (RequireSharedSpaces) {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
@ -1432,7 +1436,6 @@ static void no_shared_spaces(const char* message) {
|
||||
FLAG_SET_DEFAULT(UseSharedSpaces, false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Returns threshold scaled with the value of scale.
|
||||
// If scale < 0.0, threshold is returned without scaling.
|
||||
@ -2680,6 +2683,12 @@ jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
|
||||
return result;
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
if (UseSharedSpaces && patch_mod_javabase) {
|
||||
no_shared_spaces("CDS is disabled when " JAVA_BASE_NAME " module is patched.");
|
||||
}
|
||||
#endif
|
||||
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
@ -4408,7 +4417,6 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) {
|
||||
}
|
||||
|
||||
jint Arguments::apply_ergo() {
|
||||
|
||||
// Set flags based on ergonomics.
|
||||
set_ergonomics_flags();
|
||||
|
||||
|
@ -436,7 +436,7 @@ class os: AllStatic {
|
||||
vm_thread,
|
||||
cgc_thread, // Concurrent GC thread
|
||||
pgc_thread, // Parallel GC thread
|
||||
java_thread,
|
||||
java_thread, // Java, CodeCacheSweeper, JVMTIAgent and Service threads.
|
||||
compiler_thread,
|
||||
watcher_thread,
|
||||
os_thread
|
||||
|
@ -288,7 +288,8 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
|
||||
nonstatic_field(Klass, _access_flags, AccessFlags) \
|
||||
nonstatic_field(Klass, _prototype_header, markOop) \
|
||||
nonstatic_field(Klass, _next_sibling, Klass*) \
|
||||
nonstatic_field(Klass, _vtable_len, int) \
|
||||
nonstatic_field(Klass, _next_link, Klass*) \
|
||||
nonstatic_field(Klass, _vtable_len, int) \
|
||||
nonstatic_field(vtableEntry, _method, Method*) \
|
||||
nonstatic_field(MethodData, _size, int) \
|
||||
nonstatic_field(MethodData, _method, Method*) \
|
||||
@ -712,6 +713,8 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
|
||||
\
|
||||
nonstatic_field(ClassLoaderData, _class_loader, oop) \
|
||||
nonstatic_field(ClassLoaderData, _next, ClassLoaderData*) \
|
||||
volatile_nonstatic_field(ClassLoaderData, _klasses, Klass*) \
|
||||
nonstatic_field(ClassLoaderData, _is_anonymous, bool) \
|
||||
\
|
||||
static_field(ClassLoaderDataGraph, _head, ClassLoaderData*) \
|
||||
\
|
||||
|
@ -71,7 +71,6 @@ runtime/SharedArchiveFile/DefaultUseWithClient.java 8154204 generic-all
|
||||
|
||||
# :hotspot_serviceability
|
||||
|
||||
serviceability/dcmd/jvmti/LoadAgentDcmdTest.java 8150318 generic-all
|
||||
serviceability/jdwp/AllModulesCommandTest.java 8168478 generic-all
|
||||
serviceability/sa/sadebugd/SADebugDTest.java 8163805 generic-all
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,35 +26,28 @@
|
||||
* @bug 7005594
|
||||
* @summary Array overflow not handled correctly with loop optimzations
|
||||
*
|
||||
* @run shell Test7005594.sh
|
||||
* @run main/othervm -Xcomp
|
||||
-XX:CompileOnly=compiler.c2.Test7005594::test
|
||||
compiler.c2.Test7005594
|
||||
*/
|
||||
|
||||
package compiler.c2.cr7005594;
|
||||
package compiler.c2;
|
||||
|
||||
public class Test7005594 {
|
||||
static int test(byte a[]){
|
||||
int result = 0;
|
||||
for (int i = 1; i < a.length; i += Integer.MAX_VALUE) {
|
||||
result += a[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test(byte a[]){
|
||||
int result=0;
|
||||
for( int i=0; i<a.length; i+=((0x7fffffff>>1)+1) ){
|
||||
result += a[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void main(String [] args){
|
||||
byte a[]=new byte[(0x7fffffff>>1)+2];
|
||||
int result = 0;
|
||||
try {
|
||||
result = test(a);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
e.printStackTrace(System.out);
|
||||
System.out.println("Passed");
|
||||
System.exit(95);
|
||||
}
|
||||
System.out.println(result);
|
||||
System.out.println("FAILED");
|
||||
System.exit(97);
|
||||
}
|
||||
|
||||
public static void main(String [] args){
|
||||
try {
|
||||
int result = test(new byte[2]);
|
||||
throw new AssertionError("Expected ArrayIndexOutOfBoundsException was not thrown");
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
System.out.println("Expected " + e + " was thrown");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,111 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
#
|
||||
## some tests require path to find test source dir
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then
|
||||
TESTSRC=${PWD}
|
||||
echo "TESTSRC not set. Using "${TESTSRC}" as default"
|
||||
fi
|
||||
echo "TESTSRC=${TESTSRC}"
|
||||
## Adding common setup Variables for running shell tests.
|
||||
. ${TESTSRC}/../../../test_env.sh
|
||||
|
||||
# Amount of physical memory in megabytes
|
||||
MEM=0
|
||||
if [ -f "/proc/meminfo" ]; then
|
||||
# Linux, Windows/Cygwin
|
||||
MEM=`cat /proc/meminfo |grep ^MemTotal: | awk '{print $2}'`
|
||||
MEM="$(($MEM / 1024))"
|
||||
elif [ -x "/usr/sbin/prtconf" ]; then
|
||||
# Solaris
|
||||
MEM=`/usr/sbin/prtconf | grep "^Memory size" | awk '{print $3}'`
|
||||
elif [ -x "/usr/sbin/system_profiler" ]; then
|
||||
# MacOS
|
||||
MEMo=`/usr/sbin/system_profiler SPHardwareDataType | grep Memory:`
|
||||
MEM=`echo "$MEMo" | awk '{print $2}'`
|
||||
MEMu=`echo "$MEMo" | awk '{print $3}'`
|
||||
case $MEMu in
|
||||
GB)
|
||||
MEM="$(($MEM * 1024))"
|
||||
;;
|
||||
MB)
|
||||
;;
|
||||
*)
|
||||
echo "Unknown memory unit in system_profile output: $MEMu"
|
||||
;;
|
||||
esac
|
||||
elif [ -n "$ROOTDIR" -a -x "$ROOTDIR/mksnt/sysinf" ]; then
|
||||
# Windows/MKS
|
||||
MEM=`"$ROOTDIR/mksnt/sysinf" memory -v | grep "Total Physical Memory: " | sed 's/Total Physical Memory: *//g'`
|
||||
MEM="$(($machine_memory / 1024))"
|
||||
else
|
||||
echo "Unable to determine amount of physical memory on the machine"
|
||||
fi
|
||||
|
||||
if [ $MEM -lt 2000 ]; then
|
||||
echo "Test skipped due to low (or unknown) memory on the system: $MEM Mb"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "MEMORY=$MEM Mb"
|
||||
|
||||
set -x
|
||||
|
||||
cp ${TESTSRC}/Test7005594.java .
|
||||
cp ${TESTSRC}/Test7005594.sh .
|
||||
|
||||
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test7005594.java
|
||||
|
||||
${TESTJAVA}/bin/java ${TESTOPTS} -Xmx1600m -Xms1600m -XX:+IgnoreUnrecognizedVMOptions \
|
||||
-XX:-ZapUnusedHeapArea -Xcomp -XX:CompileCommand=quiet \
|
||||
-XX:CompileOnly=compiler.c2.cr7005594.Test7005594::test \
|
||||
compiler.c2.cr7005594.Test7005594 > test.out 2>&1
|
||||
|
||||
result=$?
|
||||
|
||||
cat test.out
|
||||
|
||||
if [ $result -eq 95 ]
|
||||
then
|
||||
echo "Passed"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ $result -eq 97 ]
|
||||
then
|
||||
echo "Failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The test should pass when no enough space for object heap
|
||||
grep "Could not reserve enough space for .*object heap" test.out
|
||||
if [ $? = 0 ]
|
||||
then
|
||||
echo "Passed"
|
||||
exit 0
|
||||
else
|
||||
echo "Failed"
|
||||
exit 1
|
||||
fi
|
@ -215,7 +215,7 @@ public abstract class CiReplayBase {
|
||||
try(BufferedReader br = new BufferedReader(new FileReader(REPLAY_FILE_NAME))) {
|
||||
return br.lines()
|
||||
.filter(s -> s.startsWith("compile "))
|
||||
.map(s -> s.substring(s.lastIndexOf(' ') + 1))
|
||||
.map(s -> s.split("\\s+")[5])
|
||||
.map(Integer::parseInt)
|
||||
.findAny()
|
||||
.get();
|
||||
|
167
hotspot/test/compiler/floatingpoint/TestFMABrokenC1RegAlloc.java
Normal file
167
hotspot/test/compiler/floatingpoint/TestFMABrokenC1RegAlloc.java
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 8171092
|
||||
* @summary C1's Math.fma() intrinsic doesn't correctly marks its inputs
|
||||
* @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestFMABrokenC1RegAlloc
|
||||
*
|
||||
*/
|
||||
|
||||
public class TestFMABrokenC1RegAlloc {
|
||||
|
||||
double dummy0;
|
||||
double dummy1;
|
||||
double dummy2;
|
||||
double dummy3;
|
||||
double dummy4;
|
||||
double dummy5;
|
||||
double dummy6;
|
||||
double dummy7;
|
||||
double dummy8;
|
||||
double dummy9;
|
||||
double dummy10;
|
||||
double dummy11;
|
||||
double dummy12;
|
||||
double dummy13;
|
||||
double dummy14;
|
||||
double dummy15;
|
||||
double dummy16;
|
||||
double dummy17;
|
||||
double dummy18;
|
||||
double dummy19;
|
||||
double dummy20;
|
||||
double dummy21;
|
||||
double dummy22;
|
||||
double dummy23;
|
||||
double dummy24;
|
||||
double dummy25;
|
||||
double dummy26;
|
||||
double dummy27;
|
||||
double dummy28;
|
||||
double dummy29;
|
||||
double dummy30;
|
||||
double dummy31;
|
||||
double dummy32;
|
||||
double dummy33;
|
||||
double dummy34;
|
||||
double dummy35;
|
||||
double dummy36;
|
||||
double dummy37;
|
||||
double dummy38;
|
||||
double dummy39;
|
||||
|
||||
double test(double a, double b, double c) {
|
||||
double dummy0 = this.dummy0;
|
||||
double dummy1 = this.dummy1;
|
||||
double dummy2 = this.dummy2;
|
||||
double dummy3 = this.dummy3;
|
||||
double dummy4 = this.dummy4;
|
||||
double dummy5 = this.dummy5;
|
||||
double dummy6 = this.dummy6;
|
||||
double dummy7 = this.dummy7;
|
||||
double dummy8 = this.dummy8;
|
||||
double dummy9 = this.dummy9;
|
||||
double dummy10 = this.dummy10;
|
||||
double dummy11 = this.dummy11;
|
||||
double dummy12 = this.dummy12;
|
||||
double dummy13 = this.dummy13;
|
||||
double dummy14 = this.dummy14;
|
||||
double dummy15 = this.dummy15;
|
||||
double dummy16 = this.dummy16;
|
||||
double dummy17 = this.dummy17;
|
||||
double dummy18 = this.dummy18;
|
||||
double dummy19 = this.dummy19;
|
||||
double dummy20 = this.dummy20;
|
||||
double dummy21 = this.dummy21;
|
||||
double dummy22 = this.dummy22;
|
||||
double dummy23 = this.dummy23;
|
||||
double dummy24 = this.dummy24;
|
||||
double dummy25 = this.dummy25;
|
||||
double dummy26 = this.dummy26;
|
||||
double dummy27 = this.dummy27;
|
||||
double dummy28 = this.dummy28;
|
||||
double dummy29 = this.dummy29;
|
||||
double dummy30 = this.dummy30;
|
||||
double dummy31 = this.dummy31;
|
||||
double dummy32 = this.dummy32;
|
||||
double dummy33 = this.dummy33;
|
||||
double dummy34 = this.dummy34;
|
||||
double dummy35 = this.dummy35;
|
||||
double dummy36 = this.dummy36;
|
||||
double dummy37 = this.dummy37;
|
||||
double dummy38 = this.dummy38;
|
||||
double dummy39 = this.dummy39;
|
||||
return Math.fma(a, b, c) +
|
||||
dummy0 +
|
||||
dummy1 +
|
||||
dummy2 +
|
||||
dummy3 +
|
||||
dummy4 +
|
||||
dummy5 +
|
||||
dummy6 +
|
||||
dummy7 +
|
||||
dummy8 +
|
||||
dummy9 +
|
||||
dummy10 +
|
||||
dummy11 +
|
||||
dummy12 +
|
||||
dummy13 +
|
||||
dummy14 +
|
||||
dummy15 +
|
||||
dummy16 +
|
||||
dummy17 +
|
||||
dummy18 +
|
||||
dummy19 +
|
||||
dummy20 +
|
||||
dummy21 +
|
||||
dummy22 +
|
||||
dummy23 +
|
||||
dummy24 +
|
||||
dummy25 +
|
||||
dummy26 +
|
||||
dummy27 +
|
||||
dummy28 +
|
||||
dummy29 +
|
||||
dummy30 +
|
||||
dummy31 +
|
||||
dummy32 +
|
||||
dummy33 +
|
||||
dummy34 +
|
||||
dummy35 +
|
||||
dummy36 +
|
||||
dummy37 +
|
||||
dummy38 +
|
||||
dummy39;
|
||||
}
|
||||
|
||||
static public void main(String[] args) {
|
||||
TestFMABrokenC1RegAlloc t = new TestFMABrokenC1RegAlloc();
|
||||
for (int i = 0; i < 5000; i++) {
|
||||
if (t.test(5.0, 10.0, 7.0) != 57.0) {
|
||||
throw new RuntimeException("Failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -241,7 +241,7 @@ public class RTMTestBase {
|
||||
CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
|
||||
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
|
||||
"-Xbootclasspath/a:.", "-XX:+WhiteBoxAPI",
|
||||
"-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED");
|
||||
"--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED");
|
||||
|
||||
if (test != null) {
|
||||
for (String method : test.getMethodsToCompileNames()) {
|
||||
|
@ -59,6 +59,20 @@ static inline void create_directory(const char* name) {
|
||||
assert(!failed, "failed to create directory %s", name);
|
||||
}
|
||||
|
||||
static inline void delete_empty_directory(const char* name) {
|
||||
#ifdef _WINDOWS
|
||||
if (!file_exists(name)) {
|
||||
return;
|
||||
}
|
||||
bool failed;
|
||||
failed = !RemoveDirectory(name);
|
||||
EXPECT_FALSE(failed) << "failed to remove directory '" << name
|
||||
<< "': LastError = " << GetLastError();
|
||||
#else
|
||||
delete_file(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void init_log_file(const char* filename, const char* options = "") {
|
||||
LogStreamHandle(Error, logging) stream;
|
||||
bool success = LogConfiguration::parse_log_arguments(filename, "logging=trace", "", options, &stream);
|
||||
|
@ -103,7 +103,7 @@ TEST_VM(LogFileOutput, filesize_overflow) {
|
||||
EXPECT_FALSE(fo.initialize(buf, &ss)) << "Accepted filesize that overflows";
|
||||
}
|
||||
|
||||
TEST(LogFileOutput, startup_rotation) {
|
||||
TEST_VM(LogFileOutput, startup_rotation) {
|
||||
const size_t rotations = 5;
|
||||
const char* filename = "start-rotate-test";
|
||||
char* rotated_file[rotations];
|
||||
@ -140,7 +140,7 @@ TEST(LogFileOutput, startup_rotation) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LogFileOutput, startup_truncation) {
|
||||
TEST_VM(LogFileOutput, startup_truncation) {
|
||||
const char* filename = "start-truncate-test";
|
||||
const char* archived_filename = "start-truncate-test.0";
|
||||
|
||||
@ -168,7 +168,7 @@ TEST(LogFileOutput, startup_truncation) {
|
||||
delete_file(archived_filename);
|
||||
}
|
||||
|
||||
TEST(LogFileOutput, invalid_file) {
|
||||
TEST_VM(LogFileOutput, invalid_file) {
|
||||
ResourceMark rm;
|
||||
stringStream ss;
|
||||
|
||||
@ -179,5 +179,5 @@ TEST(LogFileOutput, invalid_file) {
|
||||
<< "file was initialized when there was an existing directory with the same name";
|
||||
EXPECT_TRUE(string_contains_substring(ss.as_string(), "tmplogdir is not a regular file"))
|
||||
<< "missing expected error message, received msg: %s" << ss.as_string();
|
||||
remove("tmplogdir");
|
||||
delete_empty_directory("tmplogdir");
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* ac_heapanied this code).
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
@ -19,8 +19,8 @@
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "logTestFixture.hpp"
|
||||
#include "logTestUtils.inline.hpp"
|
||||
|
@ -41,41 +41,41 @@ void LogStreamTest::verify_stream(outputStream* stream) {
|
||||
EXPECT_TRUE(file_contains_substring(TestLogFileName, "3 workers\n"));
|
||||
}
|
||||
|
||||
TEST_F(LogStreamTest, from_log) {
|
||||
TEST_VM_F(LogStreamTest, from_log) {
|
||||
Log(gc) log;
|
||||
LogStream stream(log.debug());
|
||||
|
||||
verify_stream(&stream);
|
||||
}
|
||||
|
||||
TEST_F(LogStreamTest, from_logtarget) {
|
||||
TEST_VM_F(LogStreamTest, from_logtarget) {
|
||||
LogTarget(Debug, gc) log;
|
||||
LogStream stream(log);
|
||||
|
||||
verify_stream(&stream);
|
||||
}
|
||||
|
||||
TEST_F(LogStreamTest, handle) {
|
||||
TEST_VM_F(LogStreamTest, handle) {
|
||||
LogStreamHandle(Debug, gc) stream;
|
||||
|
||||
verify_stream(&stream);
|
||||
}
|
||||
|
||||
TEST_F(LogStreamTest, no_rm) {
|
||||
TEST_VM_F(LogStreamTest, no_rm) {
|
||||
ResourceMark rm;
|
||||
outputStream* stream = LogTarget(Debug, gc)::stream();
|
||||
|
||||
verify_stream(stream);
|
||||
}
|
||||
|
||||
TEST_F(LogStreamTest, c_heap_stream) {
|
||||
TEST_VM_F(LogStreamTest, c_heap_stream) {
|
||||
Log(gc) log;
|
||||
LogStreamCHeap stream(log.debug());
|
||||
|
||||
verify_stream(&stream);
|
||||
}
|
||||
|
||||
TEST_F(LogStreamTest, c_heap_stream_target) {
|
||||
TEST_VM_F(LogStreamTest, c_heap_stream_target) {
|
||||
LogTarget(Debug, gc) log;
|
||||
LogStreamCHeap stream(log);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user