This commit is contained in:
Vladimir Kozlov 2016-06-06 12:56:40 -07:00
commit 47b35cab0e
1657 changed files with 111949 additions and 51095 deletions

View File

@ -361,3 +361,5 @@ c84d0cce090e161d736de69e941830adf8c2f87a jdk-9+114
84aba7335005a3a47751dcf1f37935f97df9f99a jdk-9+116 84aba7335005a3a47751dcf1f37935f97df9f99a jdk-9+116
82b8d12a553f5617737c238cec060281d52e351c jdk-9+117 82b8d12a553f5617737c238cec060281d52e351c jdk-9+117
7c04fcb12bd4a31570a238e663fa846dfa5ec3b8 jdk-9+118 7c04fcb12bd4a31570a238e663fa846dfa5ec3b8 jdk-9+118
caf97b37ebec84288c112d21d3a60cb628cba1e8 jdk-9+119
9330543436402b8f3bd070524846a464d8143557 jdk-9+120

View File

@ -361,3 +361,5 @@ f900d5afd9c83a0df8f36161c27c5e4c86a66f4c jdk-9+111
6743a8e0cab7b5f6f4a0575f6664892f0ab740af jdk-9+116 6743a8e0cab7b5f6f4a0575f6664892f0ab740af jdk-9+116
e882bcdbdac436523f3d5681611d3118a3804ea7 jdk-9+117 e882bcdbdac436523f3d5681611d3118a3804ea7 jdk-9+117
047f95de8f918d8ff5e8cd2636a2abb5c3c8adb8 jdk-9+118 047f95de8f918d8ff5e8cd2636a2abb5c3c8adb8 jdk-9+118
3463a3f14f0f0e8a68f29ac6405454f2fa2f598a jdk-9+119
647e0142a5a52749db572b5e6638d561def6479e jdk-9+120

View File

@ -484,6 +484,8 @@ AC_DEFUN_ONCE([BASIC_SETUP_FUNDAMENTAL_TOOLS],
BASIC_REQUIRE_PROGS(FILE, file) BASIC_REQUIRE_PROGS(FILE, file)
BASIC_REQUIRE_PROGS(FIND, find) BASIC_REQUIRE_PROGS(FIND, find)
BASIC_REQUIRE_PROGS(HEAD, head) BASIC_REQUIRE_PROGS(HEAD, head)
BASIC_REQUIRE_PROGS(GUNZIP, gunzip)
BASIC_REQUIRE_PROGS(GZIP, pigz gzip)
BASIC_REQUIRE_PROGS(LN, ln) BASIC_REQUIRE_PROGS(LN, ln)
BASIC_REQUIRE_PROGS(LS, ls) BASIC_REQUIRE_PROGS(LS, ls)
BASIC_REQUIRE_PROGS(MKDIR, mkdir) BASIC_REQUIRE_PROGS(MKDIR, mkdir)
@ -496,7 +498,7 @@ AC_DEFUN_ONCE([BASIC_SETUP_FUNDAMENTAL_TOOLS],
BASIC_REQUIRE_PROGS(SH, sh) BASIC_REQUIRE_PROGS(SH, sh)
BASIC_REQUIRE_PROGS(SORT, sort) BASIC_REQUIRE_PROGS(SORT, sort)
BASIC_REQUIRE_PROGS(TAIL, tail) BASIC_REQUIRE_PROGS(TAIL, tail)
BASIC_REQUIRE_PROGS(TAR, tar) BASIC_REQUIRE_PROGS(TAR, gtar tar)
BASIC_REQUIRE_PROGS(TEE, tee) BASIC_REQUIRE_PROGS(TEE, tee)
BASIC_REQUIRE_PROGS(TOUCH, touch) BASIC_REQUIRE_PROGS(TOUCH, touch)
BASIC_REQUIRE_PROGS(TR, tr) BASIC_REQUIRE_PROGS(TR, tr)
@ -839,8 +841,6 @@ AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR],
# The spec.gmk file contains all variables for the make system. # The spec.gmk file contains all variables for the make system.
AC_CONFIG_FILES([$OUTPUT_ROOT/spec.gmk:$AUTOCONF_DIR/spec.gmk.in]) AC_CONFIG_FILES([$OUTPUT_ROOT/spec.gmk:$AUTOCONF_DIR/spec.gmk.in])
# The hotspot-spec.gmk file contains legacy variables for the hotspot make system.
AC_CONFIG_FILES([$OUTPUT_ROOT/hotspot-spec.gmk:$AUTOCONF_DIR/hotspot-spec.gmk.in])
# The bootcycle-spec.gmk file contains support for boot cycle builds. # The bootcycle-spec.gmk file contains support for boot cycle builds.
AC_CONFIG_FILES([$OUTPUT_ROOT/bootcycle-spec.gmk:$AUTOCONF_DIR/bootcycle-spec.gmk.in]) AC_CONFIG_FILES([$OUTPUT_ROOT/bootcycle-spec.gmk:$AUTOCONF_DIR/bootcycle-spec.gmk.in])
# The buildjdk-spec.gmk file contains support for building a buildjdk when cross compiling. # The buildjdk-spec.gmk file contains support for building a buildjdk when cross compiling.
@ -1009,11 +1009,36 @@ AC_DEFUN([BASIC_CHECK_FIND_DELETE],
AC_SUBST(FIND_DELETE) AC_SUBST(FIND_DELETE)
]) ])
AC_DEFUN([BASIC_CHECK_TAR],
[
# Test which kind of tar was found
if test "x$($TAR --version | $GREP "GNU tar")" != "x"; then
TAR_TYPE="gnu"
elif test "x$($TAR -v | $GREP "bsdtar")" != "x"; then
TAR_TYPE="bsd"
elif test "x$OPENJDK_BUILD_OS" = "xsolaris"; then
TAR_TYPE="solaris"
fi
AC_MSG_CHECKING([what type of tar was found])
AC_MSG_RESULT([$TAR_TYPE])
if test "x$TAR_TYPE" = "xgnu"; then
TAR_INCLUDE_PARAM="T"
TAR_SUPPORTS_TRANSFORM="true"
else
TAR_INCLUDE_PARAM="I"
TAR_SUPPORTS_TRANSFORM="false"
fi
AC_SUBST(TAR_INCLUDE_PARAM)
AC_SUBST(TAR_SUPPORTS_TRANSFORM)
])
AC_DEFUN_ONCE([BASIC_SETUP_COMPLEX_TOOLS], AC_DEFUN_ONCE([BASIC_SETUP_COMPLEX_TOOLS],
[ [
BASIC_CHECK_GNU_MAKE BASIC_CHECK_GNU_MAKE
BASIC_CHECK_FIND_DELETE BASIC_CHECK_FIND_DELETE
BASIC_CHECK_TAR
# These tools might not be installed by default, # These tools might not be installed by default,
# need hint on how to install them. # need hint on how to install them.

View File

@ -134,8 +134,9 @@ ifeq ($(JVM_INTERPRETER), cpp)
endif endif
HOTSPOT_MAKE_ARGS := product docs export_product HOTSPOT_MAKE_ARGS := product docs export_product
# Control wether Hotspot runs Queens test after building
TEST_IN_BUILD := false # Control wether Hotspot builds gtest tests
BUILD_GTEST := false
USE_PRECOMPILED_HEADER := @USE_PRECOMPILED_HEADER@ USE_PRECOMPILED_HEADER := @USE_PRECOMPILED_HEADER@

View File

@ -48,6 +48,7 @@ export EXPR="@EXPR@"
export FILE="@FILE@" export FILE="@FILE@"
export FIND="@FIND@" export FIND="@FIND@"
export GREP="@GREP@" export GREP="@GREP@"
export GUNZIP="@GUNZIP@"
export LDD="@LDD@" export LDD="@LDD@"
export LN="@LN@" export LN="@LN@"
export MKDIR="@MKDIR@" export MKDIR="@MKDIR@"
@ -63,10 +64,11 @@ export SED="@SED@"
export SORT="@SORT@" export SORT="@SORT@"
export STAT="@STAT@" export STAT="@STAT@"
export STRIP="@STRIP@ @STRIPFLAGS@" export STRIP="@STRIP@ @STRIPFLAGS@"
export TAR="@TAR@"
export TEE="@TEE@" export TEE="@TEE@"
export UNIQ="@UNIQ@" export UNIQ="@UNIQ@"
export UNPACK200="@FIXPATH@ @BOOT_JDK@/bin/unpack200" export UNPACK200="@FIXPATH@ @BOOT_JDK@/bin/unpack200"
export UNARCHIVE="@UNZIP@ -q" export UNARCHIVE="@UNZIP@ -q -o"
export SRC_ROOT="@TOPDIR@" export SRC_ROOT="@TOPDIR@"
export OUTPUT_ROOT="@OUTPUT_ROOT@" export OUTPUT_ROOT="@OUTPUT_ROOT@"

View File

@ -207,6 +207,7 @@ JDKOPT_SETUP_CODE_COVERAGE
# Need toolchain to setup dtrace # Need toolchain to setup dtrace
HOTSPOT_SETUP_DTRACE HOTSPOT_SETUP_DTRACE
HOTSPOT_SETUP_JVM_FEATURES HOTSPOT_SETUP_JVM_FEATURES
HOTSPOT_ENABLE_DISABLE_GTEST
############################################################################### ###############################################################################
# #
@ -226,9 +227,9 @@ LIB_SETUP_LIBRARIES
# #
############################################################################### ###############################################################################
HOTSPOT_SETUP_LEGACY_BUILD
JDKOPT_DETECT_INTREE_EC JDKOPT_DETECT_INTREE_EC
JDKOPT_ENABLE_DISABLE_FAILURE_HANDLER JDKOPT_ENABLE_DISABLE_FAILURE_HANDLER
JDKOPT_ENABLE_DISABLE_GENERATE_CLASSLIST
############################################################################### ###############################################################################
# #

File diff suppressed because it is too large Load Diff

View File

@ -1,158 +0,0 @@
#
# 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
# 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.
#
# Chaining of spec files
HOTSPOT_SPEC:=$(dir $(SPEC))hotspot-spec.gmk
override SPEC=$(HOTSPOT_SPEC)
# Now include the base spec.gmk file
include $(BASE_SPEC)
# Additional legacy variables defined for Hotspot
@SET_OPENJDK@
@HOTSPOT_SET_WARNINGS_AS_ERRORS@
# Legacy defines controlled by the SUPPORT_HEADLESS and SUPPORT_HEADFUL options.
@BUILD_HEADLESS@
JVM_VARIANTS:=@JVM_VARIANTS_COMMA@
JVM_VARIANT_SERVER:=@JVM_VARIANT_SERVER@
JVM_VARIANT_CLIENT:=@JVM_VARIANT_CLIENT@
JVM_VARIANT_MINIMAL1:=@JVM_VARIANT_MINIMAL1@
JVM_VARIANT_CORE:=@JVM_VARIANT_CORE@
JVM_VARIANT_ZERO:=@JVM_VARIANT_ZERO@
JVM_VARIANT_ZEROSHARK:=@JVM_VARIANT_ZEROSHARK@
JVM_VARIANT_CUSTOM:=@JVM_VARIANT_HOTSPOT@
# Legacy setting: OPT or DBG
VARIANT:=@VARIANT@
# Legacy setting: true or false
FASTDEBUG:=@FASTDEBUG@
# Legacy setting: debugging the class files?
DEBUG_CLASSFILES:=@DEBUG_CLASSFILES@
ALT_CUPS_HEADERS_PATH:=$(patsubst -I%,%,$(filter -I%,@CUPS_CFLAGS@))
# The HOSTCC/HOSTCXX is Hotspot terminology for the BUILD_CC/BUILD_CXX, i.e. the
# compiler that produces code that can be run on the build platform.
HOSTCC:=@FIXPATH@ @BUILD_ICECC@ @BUILD_CC@ $(BUILD_SYSROOT_CFLAGS)
HOSTCXX:=@FIXPATH@ @BUILD_ICECC@ @BUILD_CXX@ $(BUILD_SYSROOT_CFLAGS)
####################################################
#
# Legacy Hotspot support
# If cross compiling, then define CROSS_COMPILE_ARCH:=cpu_name here.
@DEFINE_CROSS_COMPILE_ARCH@
# Old name for OPENJDK_TARGET_OS (aix,bsd,hpux,linux,macosx,solaris,windows etc)
PLATFORM=$(OPENJDK_TARGET_OS)
# 32 or 64 bit
ARCH_DATA_MODEL=$(OPENJDK_TARGET_CPU_BITS)
ALT_BOOTDIR=$(BOOT_JDK)
# Can be /sparcv9 or /amd64 on Solaris
ISA_DIR=$(OPENJDK_TARGET_CPU_ISADIR)
# Yet another name for arch used for an extra subdir below the jvm lib.
# Uses i386 and amd64, instead of x86 and x86_64.
LIBARCH=$(OPENJDK_TARGET_CPU_LEGACY_LIB)
# Set the cpu architecture
ARCH=$(OPENJDK_TARGET_CPU_ARCH)
# Legacy setting for building for a 64 bit machine.
# If yes then this expands to _LP64:=1
@LP64@
# Legacy settings for zero
ZERO_ENDIANNESS=$(OPENJDK_TARGET_CPU_ENDIAN)
ZERO_LIBARCH=$(OPENJDK_TARGET_CPU_LEGACY_LIB)
ZERO_ARCHDEF=@ZERO_ARCHDEF@
ZERO_ARCHFLAG=@ZERO_ARCHFLAG@
LIBFFI_CFLAGS=@LIBFFI_CFLAGS@
LIBFFI_LIBS=@LIBFFI_LIBS@
# Legacy settings for zeroshark
LLVM_CFLAGS=@LLVM_CFLAGS@
LLVM_LIBS=@LLVM_LIBS@
LLVM_LDFLAGS=@LLVM_LDFLAGS@
ALT_OUTPUTDIR=$(HOTSPOT_OUTPUTDIR)
ALT_EXPORT_PATH=$(HOTSPOT_DIST)
ifeq ($(HOTSPOT_TARGET_CPU), zero)
CC_INTERP=true
endif
HOTSPOT_MAKE_ARGS:=@HOTSPOT_MAKE_ARGS@ @STATIC_CXX_SETTING@
# Control wether Hotspot runs Queens test after building
TEST_IN_BUILD=@TEST_IN_BUILD@
USE_CLANG := @USE_CLANG@
# For hotspot, override compiler/tools definition to not include FIXPATH prefix.
# Hotspot has its own handling on the Windows path situation.
CXX:=@CCACHE@ @ICECC@ @HOTSPOT_CXX@
LD:=@HOTSPOT_LD@
MT:=@HOTSPOT_MT@
RC:=@HOTSPOT_RC@
EXTRA_CFLAGS=@LEGACY_EXTRA_CFLAGS@ $(CFLAGS_CCACHE) $(NO_NULL_POINTER_CHECK_FLAG) \
$(NO_LIFETIME_DSE_CFLAG) $(CXXSTD_CXXFLAG)
EXTRA_CXXFLAGS=@LEGACY_EXTRA_CXXFLAGS@ $(CFLAGS_CCACHE)
EXTRA_LDFLAGS=@LEGACY_EXTRA_LDFLAGS@
USE_PRECOMPILED_HEADER=@USE_PRECOMPILED_HEADER@
# Hotspot expects the variable FULL_DEBUG_SYMBOLS=1/0 to control debug symbols
# creation.
ifeq ($(COPY_DEBUG_SYMBOLS), true)
FULL_DEBUG_SYMBOLS=1
# Ensure hotspot uses the objcopy that configure located
ALT_OBJCOPY:=$(OBJCOPY)
else
FULL_DEBUG_SYMBOLS=0
endif
# Hotspot expects the variable ZIP_DEBUGINFO_FILES=1/0 and not true/false.
ifeq ($(ZIP_EXTERNAL_DEBUG_SYMBOLS), true)
ZIP_DEBUGINFO_FILES:=1
else
ZIP_DEBUGINFO_FILES:=0
endif
DEBUG_BINARIES := @DEBUG_BINARIES@
STRIP_POLICY := @STRIP_POLICY@
ifeq ($(OPENJDK_TARGET_OS), windows)
# On Windows, the Visual Studio toolchain needs the LIB and INCLUDE
# environment variables (in Windows path style).
export INCLUDE:=@VS_INCLUDE@
export LIB:=@VS_LIB@
endif
# Sneak this in via the spec.gmk file, since we don't want to mess around too much with the Hotspot make files.
# This is needed to get the LOG setting to work properly.
include $(SRC_ROOT)/make/common/MakeBase.gmk

View File

@ -93,7 +93,10 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_VARIANTS],
# Check that the selected variants are valid # Check that the selected variants are valid
# grep filter function inspired by a comment to http://stackoverflow.com/a/1617326 # grep filter function inspired by a comment to http://stackoverflow.com/a/1617326
INVALID_VARIANTS=`$GREP -Fvx "${VALID_JVM_VARIANTS// /$'\n'}" <<< "${JVM_VARIANTS// /$'\n'}"` # Notice that the original variant failes on SLES 10 and 11
NEEDLE=${VALID_JVM_VARIANTS// /$'\n'}
STACK=${JVM_VARIANTS// /$'\n'}
INVALID_VARIANTS=`$GREP -Fvx "${NEEDLE}" <<< "${STACK}"`
if test "x$INVALID_VARIANTS" != x; then if test "x$INVALID_VARIANTS" != x; then
AC_MSG_NOTICE([Unknown variant(s) specified: $INVALID_VARIANTS]) AC_MSG_NOTICE([Unknown variant(s) specified: $INVALID_VARIANTS])
AC_MSG_ERROR([The available JVM variants are: $VALID_JVM_VARIANTS]) AC_MSG_ERROR([The available JVM variants are: $VALID_JVM_VARIANTS])
@ -101,7 +104,9 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_VARIANTS],
# All "special" variants share the same output directory ("server") # All "special" variants share the same output directory ("server")
VALID_MULTIPLE_JVM_VARIANTS="server client minimal" VALID_MULTIPLE_JVM_VARIANTS="server client minimal"
INVALID_MULTIPLE_VARIANTS=`$GREP -Fvx "${VALID_MULTIPLE_JVM_VARIANTS// /$'\n'}" <<< "${JVM_VARIANTS// /$'\n'}"` NEEDLE=${VALID_MULTIPLE_JVM_VARIANTS// /$'\n'}
STACK=${JVM_VARIANTS// /$'\n'}
INVALID_MULTIPLE_VARIANTS=`$GREP -Fvx "${NEEDLE}" <<< "${STACK}"`
if test "x$INVALID_MULTIPLE_VARIANTS" != x && test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = xtrue; then if test "x$INVALID_MULTIPLE_VARIANTS" != x && test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = xtrue; then
AC_MSG_ERROR([You cannot build multiple variants with anything else than $VALID_MULTIPLE_JVM_VARIANTS.]) AC_MSG_ERROR([You cannot build multiple variants with anything else than $VALID_MULTIPLE_JVM_VARIANTS.])
fi fi
@ -293,146 +298,51 @@ AC_DEFUN_ONCE([HOTSPOT_VALIDATE_JVM_FEATURES],
features_var_name=JVM_FEATURES_$variant features_var_name=JVM_FEATURES_$variant
JVM_FEATURES_TO_TEST=${!features_var_name} JVM_FEATURES_TO_TEST=${!features_var_name}
AC_MSG_RESULT([$JVM_FEATURES_TO_TEST]) AC_MSG_RESULT([$JVM_FEATURES_TO_TEST])
INVALID_FEATURES=`$GREP -Fvx "${VALID_JVM_FEATURES// /$'\n'}" <<< "${JVM_FEATURES_TO_TEST// /$'\n'}"` NEEDLE=${VALID_JVM_FEATURES// /$'\n'}
STACK=${JVM_FEATURES_TO_TEST// /$'\n'}
INVALID_FEATURES=`$GREP -Fvx "${NEEDLE}" <<< "${STACK}"`
if test "x$INVALID_FEATURES" != x; then if test "x$INVALID_FEATURES" != x; then
AC_MSG_ERROR([Invalid JVM feature(s): $INVALID_FEATURES]) AC_MSG_ERROR([Invalid JVM feature(s): $INVALID_FEATURES])
fi fi
done done
]) ])
############################################################################### ################################################################################
# Support for old hotspot build. Remove once new hotspot build has proven # Check if gtest should be built
# to work satisfactory.
# #
AC_DEFUN_ONCE([HOTSPOT_SETUP_LEGACY_BUILD], AC_DEFUN_ONCE([HOTSPOT_ENABLE_DISABLE_GTEST],
[ [
AC_ARG_ENABLE(new-hotspot-build, [AS_HELP_STRING([--disable-new-hotspot-build], AC_ARG_ENABLE([hotspot-gtest], [AS_HELP_STRING([--disable-hotspot-gtest],
[disable the new hotspot build system (use the old) @<:@enabled@:>@])]) [Disables building of the Hotspot unit tests])])
if test "x$enable_new_hotspot_build" = "x" || test "x$enable_new_hotspot_build" = "xyes"; then if test -e "$HOTSPOT_TOPDIR/test/native"; then
USE_NEW_HOTSPOT_BUILD=true GTEST_DIR_EXISTS="true"
else else
USE_NEW_HOTSPOT_BUILD=false GTEST_DIR_EXISTS="false"
fi
AC_SUBST(USE_NEW_HOTSPOT_BUILD)
case $HOTSPOT_DEBUG_LEVEL in
product )
VARIANT="OPT"
FASTDEBUG="false"
DEBUG_CLASSFILES="false"
;;
fastdebug )
VARIANT="DBG"
FASTDEBUG="true"
DEBUG_CLASSFILES="true"
;;
debug )
VARIANT="DBG"
FASTDEBUG="false"
DEBUG_CLASSFILES="true"
;;
optimized )
VARIANT="OPT"
FASTDEBUG="false"
DEBUG_CLASSFILES="false"
;;
esac
AC_SUBST(VARIANT)
AC_SUBST(FASTDEBUG)
AC_SUBST(DEBUG_CLASSFILES)
if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
MACOSX_UNIVERSAL="true"
fi fi
AC_SUBST(MACOSX_UNIVERSAL) AC_MSG_CHECKING([if Hotspot gtest unit tests should be built])
if test "x$enable_hotspot_gtest" = "xyes"; then
# Make sure JVM_VARIANTS_COMMA use minimal1 for backwards compatibility if test "x$GTEST_DIR_EXISTS" = "xtrue"; then
JVM_VARIANTS_COMMA=`$ECHO ,$JVM_VARIANTS_OPT, | $SED -e 's/,minimal,/,minimal1,/'` AC_MSG_RESULT([yes, forced])
BUILD_GTEST="true"
JVM_VARIANT_SERVER=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,server,/!s/.*/false/g' -e '/,server,/s/.*/true/g'`
JVM_VARIANT_CLIENT=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,client,/!s/.*/false/g' -e '/,client,/s/.*/true/g'`
JVM_VARIANT_MINIMAL1=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,minimal1\?,/!s/.*/false/g' -e '/,minimal1\?,/s/.*/true/g'`
JVM_VARIANT_CORE=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,core,/!s/.*/false/g' -e '/,core,/s/.*/true/g'`
JVM_VARIANT_ZERO=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,zero,/!s/.*/false/g' -e '/,zero,/s/.*/true/g'`
JVM_VARIANT_ZEROSHARK=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,zeroshark,/!s/.*/false/g' -e '/,zeroshark,/s/.*/true/g'`
JVM_VARIANT_CUSTOM=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,custom,/!s/.*/false/g' -e '/,custom,/s/.*/true/g'`
#####
# Generate the legacy makefile targets for hotspot.
HOTSPOT_TARGET=""
if test "x$JVM_VARIANT_SERVER" = xtrue; then
HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL} "
fi
if test "x$JVM_VARIANT_CLIENT" = xtrue; then
HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}1 "
fi
if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}minimal1 "
fi
if test "x$JVM_VARIANT_ZERO" = xtrue; then
HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}zero "
fi
if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}shark "
fi
if test "x$JVM_VARIANT_CORE" = xtrue; then
HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}core "
fi
HOTSPOT_TARGET="$HOTSPOT_TARGET docs export_$HOTSPOT_DEBUG_LEVEL"
# On Macosx universal binaries are produced, but they only contain
# 64 bit intel. This invalidates control of which jvms are built
# from configure, but only server is valid anyway. Fix this
# when hotspot makefiles are rewritten.
if test "x$MACOSX_UNIVERSAL" = xtrue; then
HOTSPOT_TARGET=universal_${HOTSPOT_DEBUG_LEVEL}
fi
HOTSPOT_MAKE_ARGS="$HOTSPOT_TARGET"
AC_SUBST(HOTSPOT_MAKE_ARGS)
# Control wether Hotspot runs Queens test after build.
AC_ARG_ENABLE([hotspot-test-in-build], [AS_HELP_STRING([--enable-hotspot-test-in-build],
[run the Queens test after Hotspot build @<:@disabled@:>@])],,
[enable_hotspot_test_in_build=no])
if test "x$enable_hotspot_test_in_build" = "xyes"; then
TEST_IN_BUILD=true
else else
TEST_IN_BUILD=false AC_MSG_ERROR([Cannot build gtest without the test source])
fi fi
AC_SUBST(TEST_IN_BUILD) elif test "x$enable_hotspot_gtest" = "xno"; then
AC_MSG_RESULT([no, forced])
if test "x$USE_NEW_HOTSPOT_BUILD" = xfalse; then BUILD_GTEST="false"
if test "x$JVM_VARIANT_CLIENT" = xtrue; then elif test "x$enable_hotspot_gtest" = "x"; then
if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then if test "x$GTEST_DIR_EXISTS" = "xtrue"; then
AC_MSG_ERROR([You cannot build a client JVM for a 64-bit machine.]) AC_MSG_RESULT([yes])
fi BUILD_GTEST="true"
fi else
if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then AC_MSG_RESULT([no])
if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then BUILD_GTEST="false"
AC_MSG_ERROR([You cannot build a minimal JVM for a 64-bit machine.])
fi
fi
if test "x$JVM_VARIANT_CUSTOM" = xtrue; then
AC_MSG_ERROR([You cannot build a custom JVM using the old hotspot build system.])
fi fi
else
AC_MSG_ERROR([--enable-gtest must be either yes or no])
fi fi
AC_SUBST(JVM_VARIANTS_COMMA) AC_SUBST(BUILD_GTEST)
AC_SUBST(JVM_VARIANT_SERVER)
AC_SUBST(JVM_VARIANT_CLIENT)
AC_SUBST(JVM_VARIANT_MINIMAL1)
AC_SUBST(JVM_VARIANT_HOTSPOT)
AC_SUBST(JVM_VARIANT_ZERO)
AC_SUBST(JVM_VARIANT_ZEROSHARK)
AC_SUBST(JVM_VARIANT_CORE)
]) ])

View File

@ -209,9 +209,6 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_OPTIONS],
if test "x$OPENJDK_TARGET_OS" = xaix ; then if test "x$OPENJDK_TARGET_OS" = xaix ; then
INCLUDE_SA=false INCLUDE_SA=false
fi fi
if test "x$OPENJDK_TARGET_CPU" = xaarch64; then
INCLUDE_SA=false
fi
AC_SUBST(INCLUDE_SA) AC_SUBST(INCLUDE_SA)
# Compress jars # Compress jars
@ -494,3 +491,46 @@ AC_DEFUN_ONCE([JDKOPT_ENABLE_DISABLE_FAILURE_HANDLER],
AC_SUBST(BUILD_FAILURE_HANDLER) AC_SUBST(BUILD_FAILURE_HANDLER)
]) ])
################################################################################
#
# Enable or disable generation of the classlist at build time
#
AC_DEFUN_ONCE([JDKOPT_ENABLE_DISABLE_GENERATE_CLASSLIST],
[
AC_ARG_ENABLE([generate-classlist], [AS_HELP_STRING([--disable-generate-classlist],
[forces enabling or disabling of the generation of a CDS classlist at build time.
Default is to generate it when either the server or client JVMs are built.])])
# Check if it's likely that it's possible to generate the classlist. Depending
# on exact jvm configuration it could be possible anyway.
if HOTSPOT_CHECK_JVM_VARIANT(server) || HOTSPOT_CHECK_JVM_VARIANT(client); then
ENABLE_GENERATE_CLASSLIST_POSSIBLE="true"
else
ENABLE_GENERATE_CLASSLIST_POSSIBLE="false"
fi
AC_MSG_CHECKING([if the CDS classlist generation should be enabled])
if test "x$enable_generate_classlist" = "xyes"; then
AC_MSG_RESULT([yes, forced])
ENABLE_GENERATE_CLASSLIST="true"
if test "x$ENABLE_GENERATE_CLASSLIST_POSSIBLE" = "xfalse"; then
AC_MSG_WARN([Generation of classlist might not be possible with JVM Variants $JVM_VARIANTS])
fi
elif test "x$enable_generate_classlist" = "xno"; then
AC_MSG_RESULT([no, forced])
ENABLE_GENERATE_CLASSLIST="false"
elif test "x$enable_generate_classlist" = "x"; then
if test "x$ENABLE_GENERATE_CLASSLIST_POSSIBLE" = "xtrue"; then
AC_MSG_RESULT([yes])
ENABLE_GENERATE_CLASSLIST="true"
else
AC_MSG_RESULT([no])
ENABLE_GENERATE_CLASSLIST="false"
fi
else
AC_MSG_ERROR([Invalid value for --enable-generate-classlist: $enable_generate_classlist])
fi
AC_SUBST([ENABLE_GENERATE_CLASSLIST])
])

View File

@ -95,6 +95,7 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBRARIES],
LIB_SETUP_LLVM LIB_SETUP_LLVM
LIB_SETUP_BUNDLED_LIBS LIB_SETUP_BUNDLED_LIBS
LIB_SETUP_MISC_LIBS LIB_SETUP_MISC_LIBS
LIB_SETUP_SOLARIS_STLPORT
]) ])
################################################################################ ################################################################################
@ -189,3 +190,26 @@ AC_DEFUN_ONCE([LIB_SETUP_MISC_LIBS],
LIBZIP_CAN_USE_MMAP=true LIBZIP_CAN_USE_MMAP=true
AC_SUBST(LIBZIP_CAN_USE_MMAP) AC_SUBST(LIBZIP_CAN_USE_MMAP)
]) ])
################################################################################
# libstlport.so.1 is needed for running gtest on Solaris. Find it to
# redistribute it in the test image.
################################################################################
AC_DEFUN_ONCE([LIB_SETUP_SOLARIS_STLPORT],
[
if test "$OPENJDK_TARGET_OS" = "solaris"; then
# Find the root of the Solaris Studio installation from the compiler path
SOLARIS_STUDIO_DIR="$(dirname $CC)/.."
STLPORT_LIB="$SOLARIS_STUDIO_DIR/lib/stlport4$OPENJDK_TARGET_CPU_ISADIR/libstlport.so.1"
AC_MSG_CHECKING([for libstlport.so.1])
if test -f "$STLPORT_LIB"; then
AC_MSG_RESULT([yes, $STLPORT_LIB])
BASIC_FIXUP_PATH([STLPORT_LIB])
else
AC_MSG_RESULT([no, not found at $STLPORT_LIB])
AC_MSG_ERROR([Failed to find libstlport.so.1, cannot build Hotspot gtests])
fi
AC_SUBST(STLPORT_LIB)
fi
])

View File

@ -366,6 +366,23 @@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS_HELPER],
fi fi
AC_SUBST(OPENJDK_$1_OS_EXPORT_DIR) AC_SUBST(OPENJDK_$1_OS_EXPORT_DIR)
# The new version string in JDK 9 also defined new naming of OS and ARCH for bundles
# Macosx is osx and x86_64 is x64
if test "x$OPENJDK_$1_OS" = xmacosx; then
OPENJDK_$1_OS_BUNDLE="osx"
else
OPENJDK_$1_OS_BUNDLE="$OPENJDK_TARGET_OS"
fi
if test "x$OPENJDK_$1_CPU" = xx86_64; then
OPENJDK_$1_CPU_BUNDLE="x64"
else
OPENJDK_$1_CPU_BUNDLE="$OPENJDK_$1_CPU"
fi
OPENJDK_$1_BUNDLE_PLATFORM="${OPENJDK_$1_OS_BUNDLE}-${OPENJDK_$1_CPU_BUNDLE}"
AC_SUBST(OPENJDK_$1_OS_BUNDLE)
AC_SUBST(OPENJDK_$1_CPU_BUNDLE)
AC_SUBST(OPENJDK_$1_BUNDLE_PLATFORM)
if test "x$OPENJDK_$1_CPU_BITS" = x64; then if test "x$OPENJDK_$1_CPU_BITS" = x64; then
A_LP64="LP64:=" A_LP64="LP64:="
# -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in # -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in

View File

@ -89,6 +89,10 @@ HOTSPOT_TARGET_CPU := @HOTSPOT_TARGET_CPU@
HOTSPOT_TARGET_CPU_ARCH := @HOTSPOT_TARGET_CPU_ARCH@ HOTSPOT_TARGET_CPU_ARCH := @HOTSPOT_TARGET_CPU_ARCH@
HOTSPOT_TARGET_CPU_DEFINE := @HOTSPOT_TARGET_CPU_DEFINE@ HOTSPOT_TARGET_CPU_DEFINE := @HOTSPOT_TARGET_CPU_DEFINE@
OPENJDK_TARGET_CPU_BUNDLE:=@OPENJDK_TARGET_CPU_BUNDLE@
OPENJDK_TARGET_OS_BUNDLE:=@OPENJDK_TARGET_OS_BUNDLE@
OPENJDK_TARGET_BUNDLE_PLATFORM:=@OPENJDK_TARGET_BUNDLE_PLATFORM@
# We are building on this build system. # We are building on this build system.
# When not cross-compiling, it is the same as the target. # When not cross-compiling, it is the same as the target.
OPENJDK_BUILD_OS:=@OPENJDK_BUILD_OS@ OPENJDK_BUILD_OS:=@OPENJDK_BUILD_OS@
@ -232,6 +236,9 @@ JVM_FEATURES_custom := @JVM_FEATURES_custom@
VALID_JVM_FEATURES := @VALID_JVM_FEATURES@ VALID_JVM_FEATURES := @VALID_JVM_FEATURES@
VALID_JVM_VARIANTS := @VALID_JVM_VARIANTS@ VALID_JVM_VARIANTS := @VALID_JVM_VARIANTS@
# Control wether Hotspot builds gtest tests
BUILD_GTEST := @BUILD_GTEST@
# Control use of precompiled header in hotspot libjvm build # Control use of precompiled header in hotspot libjvm build
USE_PRECOMPILED_HEADER := @USE_PRECOMPILED_HEADER@ USE_PRECOMPILED_HEADER := @USE_PRECOMPILED_HEADER@
@ -265,6 +272,7 @@ BUILDTOOLS_OUTPUTDIR=$(BUILD_OUTPUT)/buildtools
HOTSPOT_OUTPUTDIR=$(BUILD_OUTPUT)/hotspot HOTSPOT_OUTPUTDIR=$(BUILD_OUTPUT)/hotspot
JDK_OUTPUTDIR=$(BUILD_OUTPUT)/jdk JDK_OUTPUTDIR=$(BUILD_OUTPUT)/jdk
IMAGES_OUTPUTDIR=$(BUILD_OUTPUT)/images IMAGES_OUTPUTDIR=$(BUILD_OUTPUT)/images
BUNDLES_OUTPUTDIR=$(BUILD_OUTPUT)/bundles
TESTMAKE_OUTPUTDIR=$(BUILD_OUTPUT)/test-make TESTMAKE_OUTPUTDIR=$(BUILD_OUTPUT)/test-make
MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/make-support MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/make-support
# This does not get overridden in a bootcycle build # This does not get overridden in a bootcycle build
@ -277,6 +285,8 @@ BUILD_HOTSPOT=@BUILD_HOTSPOT@
BUILD_FAILURE_HANDLER := @BUILD_FAILURE_HANDLER@ BUILD_FAILURE_HANDLER := @BUILD_FAILURE_HANDLER@
ENABLE_GENERATE_CLASSLIST := @ENABLE_GENERATE_CLASSLIST@
# The boot jdk to use. This is overridden in bootcycle-spec.gmk. Make sure to keep # The boot jdk to use. This is overridden in bootcycle-spec.gmk. Make sure to keep
# it in sync. # it in sync.
BOOT_JDK:=@BOOT_JDK@ BOOT_JDK:=@BOOT_JDK@
@ -629,6 +639,7 @@ ECHO:=@ECHO@
EGREP:=@EGREP@ EGREP:=@EGREP@
FGREP:=@FGREP@ FGREP:=@FGREP@
GREP:=@GREP@ GREP:=@GREP@
GZIP:=@GZIP@
HEAD:=@HEAD@ HEAD:=@HEAD@
LS:=@LS@ LS:=@LS@
LN:=@LN@ LN:=@LN@
@ -676,6 +687,9 @@ XCODEBUILD=@XCODEBUILD@
DTRACE := @DTRACE@ DTRACE := @DTRACE@
FIXPATH:=@FIXPATH@ FIXPATH:=@FIXPATH@
TAR_INCLUDE_PARAM:=@TAR_INCLUDE_PARAM@
TAR_SUPPORTS_TRANSFORM:=@TAR_SUPPORTS_TRANSFORM@
# Build setup # Build setup
ENABLE_JFR=@ENABLE_JFR@ ENABLE_JFR=@ENABLE_JFR@
ENABLE_INTREE_EC=@ENABLE_INTREE_EC@ ENABLE_INTREE_EC=@ENABLE_INTREE_EC@
@ -685,6 +699,7 @@ USE_EXTERNAL_LIBZ:=@USE_EXTERNAL_LIBZ@
LIBZIP_CAN_USE_MMAP:=@LIBZIP_CAN_USE_MMAP@ LIBZIP_CAN_USE_MMAP:=@LIBZIP_CAN_USE_MMAP@
MSVCR_DLL:=@MSVCR_DLL@ MSVCR_DLL:=@MSVCR_DLL@
MSVCP_DLL:=@MSVCP_DLL@ MSVCP_DLL:=@MSVCP_DLL@
STLPORT_LIB:=@STLPORT_LIB@
#################################################### ####################################################
# #
@ -781,11 +796,46 @@ SYMBOLS_IMAGE_DIR=$(IMAGES_OUTPUTDIR)/$(SYMBOLS_IMAGE_SUBDIR)
# Interim image # Interim image
INTERIM_IMAGE_DIR := $(SUPPORT_OUTPUTDIR)/interim-image INTERIM_IMAGE_DIR := $(SUPPORT_OUTPUTDIR)/interim-image
# Docs image
DOCS_IMAGE_SUBDIR := docs
DOCS_IMAGE_DIR := $(IMAGES_OUTPUTDIR)/$(DOCS_IMAGE_SUBDIR)
# Macosx bundles directory definitions # Macosx bundles directory definitions
JDK_MACOSX_BUNDLE_SUBDIR=jdk-bundle/jdk-$(VERSION_NUMBER).jdk/Contents JDK_MACOSX_BUNDLE_SUBDIR=jdk-bundle
JRE_MACOSX_BUNDLE_SUBDIR=jre-bundle/jre-$(VERSION_NUMBER).jre/Contents JRE_MACOSX_BUNDLE_SUBDIR=jre-bundle
JDK_MACOSX_BUNDLE_DIR=$(IMAGES_OUTPUTDIR)/$(JDK_MACOSX_BUNDLE_SUBDIR) JDK_MACOSX_BUNDLE_DIR=$(IMAGES_OUTPUTDIR)/$(JDK_MACOSX_BUNDLE_SUBDIR)
JRE_MACOSX_BUNDLE_DIR=$(IMAGES_OUTPUTDIR)/$(JRE_MACOSX_BUNDLE_SUBDIR) JRE_MACOSX_BUNDLE_DIR=$(IMAGES_OUTPUTDIR)/$(JRE_MACOSX_BUNDLE_SUBDIR)
JDK_MACOSX_CONTENTS_SUBDIR=jdk-$(VERSION_NUMBER).jdk/Contents
JRE_MACOSX_CONTENTS_SUBDIR=jre-$(VERSION_NUMBER).jre/Contents
JDK_MACOSX_CONTENTS_DIR=$(JDK_MACOSX_BUNDLE_DIR)/$(JDK_MACOSX_CONTENTS_SUBDIR)
JRE_MACOSX_CONTENTS_DIR=$(JRE_MACOSX_BUNDLE_DIR)/$(JRE_MACOSX_CONTENTS_SUBDIR)
# Bundle names
BASE_NAME := $(VERSION_SHORT)+$(VERSION_BUILD)_$(OPENJDK_TARGET_BUNDLE_PLATFORM)
ifeq ($(DEBUG_LEVEL), fastdebug)
DEBUG_PART := -debug
else ifneq ($(DEBUG_LEVEL), release)
DEBUG_PART := -$(DEBUG_LEVEL)
endif
JDK_BUNDLE_NAME := jdk-$(BASE_NAME)_bin$(DEBUG_PART).tar.gz
JRE_BUNDLE_NAME := jre-$(BASE_NAME)_bin$(DEBUG_PART).tar.gz
JDK_SYMBOLS_BUNDLE_NAME := jdk-$(BASE_NAME)_bin$(DEBUG_PART)-symbols.tar.gz
JRE_SYMBOLS_BUNDLE_NAME := jre-$(BASE_NAME)_bin$(DEBUG_PART)-symbols.tar.gz
ifeq ($(OPENJDK_TARGET_OS), windows)
DEMOS_BUNDLE_NAME := jdk-$(BASE_NAME)_demo$(DEBUG_PART).zip
else
DEMOS_BUNDLE_NAME := jdk-$(BASE_NAME)_demo$(DEBUG_PART).tar.gz
endif
TEST_BUNDLE_NAME := jdk-$(BASE_NAME)_bin-tests$(DEBUG_PART).tar.gz
DOCS_BUNDLE_NAME := jdk-$(BASE_NAME)_doc-api-spec$(DEBUG_PART).tar.gz
JDK_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(JDK_BUNDLE_NAME)
JRE_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(JRE_BUNDLE_NAME)
JDK_SYMBOLS_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(JDK_SYMBOLS_BUNDLE_NAME)
JRE_SYMBOLS_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(JRE_SYMBOLS_BUNDLE_NAME)
DEMOS_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(DEMOS_BUNDLE_NAME)
TEST_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(TEST_BUNDLE_NAME)
DOCS_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(DOCS_BUNDLE_NAME)
# This macro is called to allow inclusion of closed source counterparts. # This macro is called to allow inclusion of closed source counterparts.
# Unless overridden in closed sources, it expands to nothing. # Unless overridden in closed sources, it expands to nothing.

View File

@ -274,14 +274,19 @@ compare_file_types() {
$MKDIR -p $WORK_DIR $MKDIR -p $WORK_DIR
FILE_TYPES_FILTER="$SED \
-e 's/BuildID[^,]*//' \
-e 's/last modified: .*//' \
"
echo -n File types... echo -n File types...
found="" found=""
for f in `cd $OTHER_DIR && $FIND . ! -type d` for f in `cd $OTHER_DIR && $FIND . ! -type d`
do do
if [ ! -f ${OTHER_DIR}/$f ]; then continue; fi if [ ! -f ${OTHER_DIR}/$f ]; then continue; fi
if [ ! -f ${THIS_DIR}/$f ]; then continue; fi if [ ! -f ${THIS_DIR}/$f ]; then continue; fi
OF=`cd ${OTHER_DIR} && $FILE -h $f | $SED 's/BuildID[^,]*//g'` OF=$(cd ${OTHER_DIR} && $FILE -h $f | eval $FILE_TYPES_FILTER)
TF=`cd ${THIS_DIR} && $FILE -h $f | $SED 's/BuildID[^,]*//g'` TF=$(cd ${THIS_DIR} && $FILE -h $f | eval $FILE_TYPES_FILTER)
if [ "$OF" != "$TF" ] if [ "$OF" != "$TF" ]
then then
if [ "`echo $OF | $GREP -c 'Zip archive data'`" -gt 0 ] \ if [ "`echo $OF | $GREP -c 'Zip archive data'`" -gt 0 ] \
@ -320,7 +325,7 @@ compare_general_files() {
! -name "*.obj" ! -name "*.o" ! -name "JavaControlPanelHelper" \ ! -name "*.obj" ! -name "*.o" ! -name "JavaControlPanelHelper" \
! -name "JavaUpdater" ! -name "JavaWSApplicationStub" \ ! -name "JavaUpdater" ! -name "JavaWSApplicationStub" \
! -name "jspawnhelper" ! -name "JavawsLauncher" ! -name "*.a" \ ! -name "jspawnhelper" ! -name "JavawsLauncher" ! -name "*.a" \
! -name "finish_installation" ! -name "Sparkle" \ ! -name "finish_installation" ! -name "Sparkle" ! -name "*.tar.gz" \
| $GREP -v "./bin/" | $SORT | $FILTER) | $GREP -v "./bin/" | $SORT | $FILTER)
echo Other files with binary differences... echo Other files with binary differences...
@ -423,6 +428,10 @@ compare_zip_file() {
then then
(cd $THIS_UNZIPDIR && $UNARCHIVE $THIS_ZIP) (cd $THIS_UNZIPDIR && $UNARCHIVE $THIS_ZIP)
(cd $OTHER_UNZIPDIR && $UNARCHIVE $OTHER_ZIP) (cd $OTHER_UNZIPDIR && $UNARCHIVE $OTHER_ZIP)
elif [ "$TYPE" = "gz" ]
then
(cd $THIS_UNZIPDIR && $GUNZIP -c $THIS_ZIP | $TAR xf -)
(cd $OTHER_UNZIPDIR && $GUNZIP -c $OTHER_ZIP | $TAR xf -)
else else
(cd $THIS_UNZIPDIR && $JIMAGE extract $THIS_ZIP) (cd $THIS_UNZIPDIR && $JIMAGE extract $THIS_ZIP)
(cd $OTHER_UNZIPDIR && $JIMAGE extract $OTHER_ZIP) (cd $OTHER_UNZIPDIR && $JIMAGE extract $OTHER_ZIP)
@ -526,10 +535,11 @@ compare_all_zip_files() {
OTHER_DIR=$2 OTHER_DIR=$2
WORK_DIR=$3 WORK_DIR=$3
ZIPS=$(cd $THIS_DIR && $FIND . -type f -name "*.zip" | $SORT | $FILTER ) ZIPS=$(cd $THIS_DIR && $FIND . -type f -name "*.zip" -o -name "*.tar.gz" \
| $SORT | $FILTER )
if [ -n "$ZIPS" ]; then if [ -n "$ZIPS" ]; then
echo Zip files... echo Zip/tar.gz files...
return_value=0 return_value=0
for f in $ZIPS; do for f in $ZIPS; do

View File

@ -155,6 +155,14 @@ addBuildDir() {
printf "%s\n" "$mn" >> $IDEA_ANT printf "%s\n" "$mn" >> $IDEA_ANT
} }
JTREG_HOME=" <property name=\"jtreg.home\" value=\"####\" />"
addJtregHome() {
DIR=`dirname $SPEC`
mn="`echo "$JTREG_HOME" | sed -e s@"\(.*\)####\(.*\)"@"\1$JT_HOME\2"@`"
printf "%s\n" "$mn" >> $IDEA_ANT
}
### Generate ant.xml ### Generate ant.xml
rm -f $IDEA_ANT rm -f $IDEA_ANT
@ -162,6 +170,8 @@ while IFS= read -r line
do do
if echo "$line" | egrep "^ .* <property name=\"module.name\"" > /dev/null ; then if echo "$line" | egrep "^ .* <property name=\"module.name\"" > /dev/null ; then
addModuleName addModuleName
elif echo "$line" | egrep "^ .* <property name=\"jtreg.home\"" > /dev/null ; then
addJtregHome
elif echo "$line" | egrep "^ .* <property name=\"build.target.dir\"" > /dev/null ; then elif echo "$line" | egrep "^ .* <property name=\"build.target.dir\"" > /dev/null ; then
addBuildDir addBuildDir
else else

View File

@ -215,11 +215,11 @@ var getJibProfilesCommon = function (input) {
var common = {}; var common = {};
common.dependencies = ["boot_jdk", "gnumake", "jtreg"], common.dependencies = ["boot_jdk", "gnumake", "jtreg"],
common.default_make_targets = ["product-images", "test-image"], common.default_make_targets = ["product-bundles", "test-bundles"],
common.default_make_targets_debug = common.default_make_targets; common.default_make_targets_debug = common.default_make_targets;
common.default_make_targets_slowdebug = common.default_make_targets; common.default_make_targets_slowdebug = common.default_make_targets;
common.configure_args = ["--enable-jtreg-failure-handler"], common.configure_args = ["--enable-jtreg-failure-handler"],
common.configure_args_32bit = ["--with-target-bits=32", "--with-jvm-variants=client,server"], common.configure_args_32bit = ["--with-target-bits=32"],
common.configure_args_debug = ["--enable-debug"], common.configure_args_debug = ["--enable-debug"],
common.configure_args_slowdebug = ["--with-debug-level=slowdebug"], common.configure_args_slowdebug = ["--with-debug-level=slowdebug"],
common.organization = "jpg.infra.builddeps" common.organization = "jpg.infra.builddeps"
@ -245,7 +245,7 @@ var getJibProfilesProfiles = function (input, common) {
target_cpu: "x64", target_cpu: "x64",
dependencies: concat(common.dependencies, "devkit"), dependencies: concat(common.dependencies, "devkit"),
configure_args: concat(common.configure_args, "--with-zlib=system"), configure_args: concat(common.configure_args, "--with-zlib=system"),
default_make_targets: concat(common.default_make_targets, "docs-image") default_make_targets: concat(common.default_make_targets, "docs-bundles")
}, },
"linux-x86": { "linux-x86": {
@ -254,7 +254,7 @@ var getJibProfilesProfiles = function (input, common) {
build_cpu: "x64", build_cpu: "x64",
dependencies: concat(common.dependencies, "devkit"), dependencies: concat(common.dependencies, "devkit"),
configure_args: concat(common.configure_args, common.configure_args_32bit, configure_args: concat(common.configure_args, common.configure_args_32bit,
"--with-zlib=system"), "--with-jvm-variants=minimal,client,server", "--with-zlib=system"),
default_make_targets: common.default_make_targets default_make_targets: common.default_make_targets
}, },
@ -295,7 +295,8 @@ var getJibProfilesProfiles = function (input, common) {
target_cpu: "x86", target_cpu: "x86",
build_cpu: "x64", build_cpu: "x64",
dependencies: concat(common.dependencies, "devkit", "freetype"), dependencies: concat(common.dependencies, "devkit", "freetype"),
configure_args: concat(common.configure_args, common.configure_args_32bit), configure_args: concat(common.configure_args,
"--with-jvm-variants=client,server", common.configure_args_32bit),
default_make_targets: common.default_make_targets default_make_targets: common.default_make_targets
} }
}; };

View File

@ -361,3 +361,5 @@ cc30faa2da498c478e89ab062ff160653ca1b170 jdk-9+113
7dfa7377a5e601b8f740741a9a80e04c72dd04d6 jdk-9+116 7dfa7377a5e601b8f740741a9a80e04c72dd04d6 jdk-9+116
7a1b36bf2fe55a9a7732489ccdd326c910329a7e jdk-9+117 7a1b36bf2fe55a9a7732489ccdd326c910329a7e jdk-9+117
8c2c2d17f7ce92a31c9ccb44a122ec62f5a85ace jdk-9+118 8c2c2d17f7ce92a31c9ccb44a122ec62f5a85ace jdk-9+118
daf533920b1266603b5cbdab31908d2a931c5361 jdk-9+119
5943b791e131e79b969d4cea053aecda34801723 jdk-9+120

View File

@ -522,3 +522,4 @@ b64432bae5271735fd53300b2005b713e98ef411 jdk-9+114
88170d3642905b9e6cac03e8efcc976885a7e6da jdk-9+117 88170d3642905b9e6cac03e8efcc976885a7e6da jdk-9+117
9b1075cac08dc836ec32e7b368415cbe3aceaf8c jdk-9+118 9b1075cac08dc836ec32e7b368415cbe3aceaf8c jdk-9+118
15f3fe264872766bcb205696198f0c1502420e17 jdk-9+119 15f3fe264872766bcb205696198f0c1502420e17 jdk-9+119
0be6f4f5d18671184e62583668cb1d783dffa128 jdk-9+120

View File

@ -3,7 +3,7 @@ The GNU General Public License (GPL)
Version 2, June 1991 Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc. Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies of this license Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed. document, but changing it is not allowed.
@ -287,8 +287,8 @@ pointer to where the full notice is found.
more details. more details.
You should have received a copy of the GNU General Public License along You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc., 59 with this program; if not, write to the Free Software Foundation, Inc.,
Temple Place, Suite 330, Boston, MA 02111-1307 USA 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved. * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -1547,6 +1547,10 @@ class Assembler : public AbstractAssembler {
inline void ld( Register d, int si16, Register s1); inline void ld( Register d, int si16, Register s1);
inline void ldu( Register d, int si16, Register s1); inline void ldu( Register d, int si16, Register s1);
// For convenience. Load pointer into d from b+s1.
inline void ld_ptr(Register d, int b, Register s1);
DEBUG_ONLY(inline void ld_ptr(Register d, ByteSize b, Register s1);)
// PPC 1, section 3.3.3 Fixed-Point Store Instructions // PPC 1, section 3.3.3 Fixed-Point Store Instructions
inline void stwx( Register d, Register s1, Register s2); inline void stwx( Register d, Register s1, Register s2);
inline void stw( Register d, int si16, Register s1); inline void stw( Register d, int si16, Register s1);
@ -2215,7 +2219,8 @@ class Assembler : public AbstractAssembler {
void add( Register d, RegisterOrConstant roc, Register s1); void add( Register d, RegisterOrConstant roc, Register s1);
void subf(Register d, RegisterOrConstant roc, Register s1); void subf(Register d, RegisterOrConstant roc, Register s1);
void cmpd(ConditionRegister d, RegisterOrConstant roc, Register s1); void cmpd(ConditionRegister d, RegisterOrConstant roc, Register s1);
// Load pointer d from s1+roc.
void ld_ptr(Register d, RegisterOrConstant roc, Register s1 = noreg) { ld(d, roc, s1); }
// Emit several instructions to load a 64 bit constant. This issues a fixed // Emit several instructions to load a 64 bit constant. This issues a fixed
// instruction pattern so that the constant can be patched later on. // instruction pattern so that the constant can be patched later on.

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved. * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -328,6 +328,9 @@ inline void Assembler::ld( Register d, int si16, Register s1) { emit_int32(
inline void Assembler::ldx( Register d, Register s1, Register s2) { emit_int32(LDX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));} inline void Assembler::ldx( Register d, Register s1, Register s2) { emit_int32(LDX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::ldu( Register d, int si16, Register s1) { assert(d != s1, "according to ibm manual"); emit_int32(LDU_OPCODE | rt(d) | ds(si16) | rta0mem(s1));} inline void Assembler::ldu( Register d, int si16, Register s1) { assert(d != s1, "according to ibm manual"); emit_int32(LDU_OPCODE | rt(d) | ds(si16) | rta0mem(s1));}
inline void Assembler::ld_ptr(Register d, int b, Register s1) { ld(d, b, s1); }
DEBUG_ONLY(inline void Assembler::ld_ptr(Register d, ByteSize b, Register s1) { ld(d, in_bytes(b), s1); })
// PPC 1, section 3.3.3 Fixed-Point Store Instructions // PPC 1, section 3.3.3 Fixed-Point Store Instructions
inline void Assembler::stwx( Register d, Register s1, Register s2) { emit_int32(STWX_OPCODE | rs(d) | ra0mem(s1) | rb(s2));} inline void Assembler::stwx( Register d, Register s1, Register s2) { emit_int32(STWX_OPCODE | rs(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::stw( Register d, int si16, Register s1) { emit_int32(STW_OPCODE | rs(d) | d1(si16) | ra0mem(s1));} inline void Assembler::stw( Register d, int si16, Register s1) { emit_int32(STW_OPCODE | rs(d) | d1(si16) | ra0mem(s1));}

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved. * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -1242,7 +1242,7 @@ void LIR_Assembler::reg2mem(LIR_Opr from_reg, LIR_Opr dest, BasicType type,
void LIR_Assembler::return_op(LIR_Opr result) { void LIR_Assembler::return_op(LIR_Opr result) {
const Register return_pc = R11; const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone().
const Register polling_page = R12; const Register polling_page = R12;
// Pop the stack before the safepoint code. // Pop the stack before the safepoint code.
@ -1265,6 +1265,10 @@ void LIR_Assembler::return_op(LIR_Opr result) {
// Move return pc to LR. // Move return pc to LR.
__ mtlr(return_pc); __ mtlr(return_pc);
if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) {
__ reserved_stack_check(return_pc);
}
// We need to mark the code position where the load from the safepoint // We need to mark the code position where the load from the safepoint
// polling page was emitted as relocInfo::poll_return_type here. // polling page was emitted as relocInfo::poll_return_type here.
__ relocate(relocInfo::poll_return_type); __ relocate(relocInfo::poll_return_type);

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved. * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -52,4 +52,6 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
#define INCLUDE_RTM_OPT 1 #define INCLUDE_RTM_OPT 1
#endif #endif
#define SUPPORT_RESERVED_STACK_AREA
#endif // CPU_PPC_VM_GLOBALDEFINITIONS_PPC_HPP #endif // CPU_PPC_VM_GLOBALDEFINITIONS_PPC_HPP

View File

@ -43,7 +43,7 @@ define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs pas
#define DEFAULT_STACK_YELLOW_PAGES (6) #define DEFAULT_STACK_YELLOW_PAGES (6)
#define DEFAULT_STACK_RED_PAGES (1) #define DEFAULT_STACK_RED_PAGES (1)
#define DEFAULT_STACK_SHADOW_PAGES (6 DEBUG_ONLY(+2)) #define DEFAULT_STACK_SHADOW_PAGES (6 DEBUG_ONLY(+2))
#define DEFAULT_STACK_RESERVED_PAGES (0) #define DEFAULT_STACK_RESERVED_PAGES (1)
#define MIN_STACK_YELLOW_PAGES DEFAULT_STACK_YELLOW_PAGES #define MIN_STACK_YELLOW_PAGES DEFAULT_STACK_YELLOW_PAGES
#define MIN_STACK_RED_PAGES DEFAULT_STACK_RED_PAGES #define MIN_STACK_RED_PAGES DEFAULT_STACK_RED_PAGES

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved. * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -480,6 +480,7 @@ void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass, Register
void InterpreterMacroAssembler::generate_stack_overflow_check_with_compare_and_throw(Register Rmem_frame_size, Register Rscratch1) { void InterpreterMacroAssembler::generate_stack_overflow_check_with_compare_and_throw(Register Rmem_frame_size, Register Rscratch1) {
Label done; Label done;
BLOCK_COMMENT("stack_overflow_check_with_compare_and_throw {");
sub(Rmem_frame_size, R1_SP, Rmem_frame_size); sub(Rmem_frame_size, R1_SP, Rmem_frame_size);
ld(Rscratch1, thread_(stack_overflow_limit)); ld(Rscratch1, thread_(stack_overflow_limit));
cmpld(CCR0/*is_stack_overflow*/, Rmem_frame_size, Rscratch1); cmpld(CCR0/*is_stack_overflow*/, Rmem_frame_size, Rscratch1);
@ -501,6 +502,7 @@ void InterpreterMacroAssembler::generate_stack_overflow_check_with_compare_and_t
align(32, 12); align(32, 12);
bind(done); bind(done);
BLOCK_COMMENT("} stack_overflow_check_with_compare_and_throw");
} }
// Separate these two to allow for delay slot in middle. // Separate these two to allow for delay slot in middle.
@ -805,16 +807,41 @@ void InterpreterMacroAssembler::narrow(Register result) {
void InterpreterMacroAssembler::remove_activation(TosState state, void InterpreterMacroAssembler::remove_activation(TosState state,
bool throw_monitor_exception, bool throw_monitor_exception,
bool install_monitor_exception) { bool install_monitor_exception) {
BLOCK_COMMENT("remove_activation {");
unlock_if_synchronized_method(state, throw_monitor_exception, install_monitor_exception); unlock_if_synchronized_method(state, throw_monitor_exception, install_monitor_exception);
// Save result (push state before jvmti call and pop it afterwards) and notify jvmti. // Save result (push state before jvmti call and pop it afterwards) and notify jvmti.
notify_method_exit(false, state, NotifyJVMTI, true); notify_method_exit(false, state, NotifyJVMTI, true);
BLOCK_COMMENT("reserved_stack_check:");
if (StackReservedPages > 0) {
// Test if reserved zone needs to be enabled.
Label no_reserved_zone_enabling;
// Compare frame pointers. There is no good stack pointer, as with stack
// frame compression we can get different SPs when we do calls. A subsequent
// call could have a smaller SP, so that this compare succeeds for an
// inner call of the method annotated with ReservedStack.
ld_ptr(R0, JavaThread::reserved_stack_activation_offset(), R16_thread);
ld_ptr(R11_scratch1, _abi(callers_sp), R1_SP); // Load frame pointer.
cmpld(CCR0, R11_scratch1, R0);
blt_predict_taken(CCR0, no_reserved_zone_enabling);
// Enable reserved zone again, throw stack overflow exception.
call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), R16_thread);
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_delayed_StackOverflowError));
should_not_reach_here();
bind(no_reserved_zone_enabling);
}
verify_oop(R17_tos, state); verify_oop(R17_tos, state);
verify_thread(); verify_thread();
merge_frames(/*top_frame_sp*/ R21_sender_SP, /*return_pc*/ R0, R11_scratch1, R12_scratch2); merge_frames(/*top_frame_sp*/ R21_sender_SP, /*return_pc*/ R0, R11_scratch1, R12_scratch2);
mtlr(R0); mtlr(R0);
BLOCK_COMMENT("} remove_activation");
} }
// Lock object // Lock object

View File

@ -1400,6 +1400,28 @@ address MacroAssembler::get_stack_bang_address(int instruction, void *ucontext)
#endif #endif
} }
void MacroAssembler::reserved_stack_check(Register return_pc) {
// Test if reserved zone needs to be enabled.
Label no_reserved_zone_enabling;
ld_ptr(R0, JavaThread::reserved_stack_activation_offset(), R16_thread);
cmpld(CCR0, R1_SP, R0);
blt_predict_taken(CCR0, no_reserved_zone_enabling);
// Enable reserved zone again, throw stack overflow exception.
push_frame_reg_args(0, R0);
call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), R16_thread);
pop_frame();
mtlr(return_pc);
load_const_optimized(R0, StubRoutines::throw_delayed_StackOverflowError_entry());
mtctr(R0);
bctr();
should_not_reach_here();
bind(no_reserved_zone_enabling);
}
// CmpxchgX sets condition register to cmpX(current, compare). // CmpxchgX sets condition register to cmpX(current, compare).
void MacroAssembler::cmpxchgw(ConditionRegister flag, Register dest_current_value, void MacroAssembler::cmpxchgw(ConditionRegister flag, Register dest_current_value,
Register compare_value, Register exchange_value, Register compare_value, Register exchange_value,

View File

@ -411,6 +411,10 @@ class MacroAssembler: public Assembler {
// stdux, return the banged address. Otherwise, return 0. // stdux, return the banged address. Otherwise, return 0.
static address get_stack_bang_address(int instruction, void* ucontext); static address get_stack_bang_address(int instruction, void* ucontext);
// Check for reserved stack access in method being exited. If the reserved
// stack area was accessed, protect it again and throw StackOverflowError.
void reserved_stack_check(Register return_pc);
// Atomics // Atomics
// CmpxchgX sets condition register to cmpX(current, compare). // CmpxchgX sets condition register to cmpX(current, compare).
// (flag == ne) => (dest_current_value != compare_value), (!swapped) // (flag == ne) => (dest_current_value != compare_value), (!swapped)

View File

@ -1432,7 +1432,7 @@ void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
const bool method_needs_polling = do_polling() && C->is_method_compilation(); const bool method_needs_polling = do_polling() && C->is_method_compilation();
const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
const Register return_pc = R11; const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone().
const Register polling_page = R12; const Register polling_page = R12;
if (!method_is_frameless) { if (!method_is_frameless) {
@ -1456,6 +1456,10 @@ void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
__ addi(R1_SP, R1_SP, (int)framesize); __ addi(R1_SP, R1_SP, (int)framesize);
} }
if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
__ reserved_stack_check(return_pc);
}
if (method_needs_polling) { if (method_needs_polling) {
// We need to mark the code position where the load from the safepoint // We need to mark the code position where the load from the safepoint
// polling page was emitted as relocInfo::poll_return_type here. // polling page was emitted as relocInfo::poll_return_type here.

View File

@ -3123,6 +3123,9 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::_throw_StackOverflowError_entry = StubRoutines::_throw_StackOverflowError_entry =
generate_throw_exception("StackOverflowError throw_exception", generate_throw_exception("StackOverflowError throw_exception",
CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError), false); CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError), false);
StubRoutines::_throw_delayed_StackOverflowError_entry =
generate_throw_exception("delayed StackOverflowError throw_exception",
CAST_FROM_FN_PTR(address, SharedRuntime::throw_delayed_StackOverflowError), false);
// CRC32 Intrinsics. // CRC32 Intrinsics.
if (UseCRC32Intrinsics) { if (UseCRC32Intrinsics) {

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015 SAP SE. All rights reserved. * Copyright (c) 2015, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -562,10 +562,16 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
return NULL; return NULL;
} }
// Actually we should never reach here since we do stack overflow checks before pushing any frame.
address TemplateInterpreterGenerator::generate_StackOverflowError_handler() { address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
address entry = __ pc(); address entry = __ pc();
__ unimplemented("generate_StackOverflowError_handler");
// Expression stack must be empty before entering the VM if an
// exception happened.
__ empty_expression_stack();
// Throw exception.
__ call_VM(noreg,
CAST_FROM_FN_PTR(address,
InterpreterRuntime::throw_StackOverflowError));
return entry; return entry;
} }
@ -944,7 +950,7 @@ void TemplateInterpreterGenerator::lock_method(Register Rflags, Register Rscratc
// The top most frame needs an abi space of 112 bytes. This space is needed, // The top most frame needs an abi space of 112 bytes. This space is needed,
// since we call to c. The c function may spill their arguments to the caller // since we call to c. The c function may spill their arguments to the caller
// frame. When we call to java, we don't need these spill slots. In order to save // frame. When we call to java, we don't need these spill slots. In order to save
// space on the stack, we resize the caller. However, java local reside in // space on the stack, we resize the caller. However, java locals reside in
// the caller frame and the frame has to be increased. The frame_size for the // the caller frame and the frame has to be increased. The frame_size for the
// current frame was calculated based on max_stack as size for the expression // current frame was calculated based on max_stack as size for the expression
// stack. At the call, just a part of the expression stack might be used. // stack. At the call, just a part of the expression stack might be used.
@ -1007,7 +1013,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist
// parent_frame_resize = (locals-parameters) - (ESP-SP-ABI48) Rounded to frame alignment size. // parent_frame_resize = (locals-parameters) - (ESP-SP-ABI48) Rounded to frame alignment size.
// Enlarge by locals-parameters (not in case of native_call), shrink by ESP-SP-ABI48. // Enlarge by locals-parameters (not in case of native_call), shrink by ESP-SP-ABI48.
{ if (!native_call) {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Stack overflow check // Stack overflow check
@ -1047,7 +1053,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist
__ addi(R26_monitor, R1_SP, - frame::ijava_state_size); __ addi(R26_monitor, R1_SP, - frame::ijava_state_size);
__ addi(R15_esp, R26_monitor, - Interpreter::stackElementSize); __ addi(R15_esp, R26_monitor, - Interpreter::stackElementSize);
// Get mirror and store it in the frame as GC root for this Method* // Get mirror and store it in the frame as GC root for this Method*.
__ load_mirror(R12_scratch2, R19_method); __ load_mirror(R12_scratch2, R19_method);
// Store values. // Store values.
@ -1133,6 +1139,29 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
return entry; return entry;
} }
void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
// Quick & dirty stack overflow checking: bang the stack & handle trap.
// Note that we do the banging after the frame is setup, since the exception
// handling code expects to find a valid interpreter frame on the stack.
// Doing the banging earlier fails if the caller frame is not an interpreter
// frame.
// (Also, the exception throwing code expects to unlock any synchronized
// method receiever, so do the banging after locking the receiver.)
// Bang each page in the shadow zone. We can't assume it's been done for
// an interpreter frame with greater than a page of locals, so each page
// needs to be checked. Only true for non-native.
if (UseStackBanging) {
const int page_size = os::vm_page_size();
const int n_shadow_pages = ((int)JavaThread::stack_shadow_zone_size()) / page_size;
const int start_page = native_call ? n_shadow_pages : 1;
BLOCK_COMMENT("bang_stack_shadow_pages:");
for (int pages = start_page; pages <= n_shadow_pages; pages++) {
__ bang_stack_with_offset(pages*page_size);
}
}
}
// Interpreter stub for calling a native method. (asm interpreter) // Interpreter stub for calling a native method. (asm interpreter)
// This sets up a somewhat different looking stack for calling the // This sets up a somewhat different looking stack for calling the
// native method than the typical interpreter frame setup. // native method than the typical interpreter frame setup.
@ -1156,7 +1185,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// This is not a full-blown interpreter frame, but in particular, the // This is not a full-blown interpreter frame, but in particular, the
// following registers are valid after this: // following registers are valid after this:
// - R19_method // - R19_method
// - R18_local (points to start of argumuments to native function) // - R18_local (points to start of arguments to native function)
// //
// abstract stack (grows up) // abstract stack (grows up)
// [ IJava (caller of JNI callee) ] <-- ASP // [ IJava (caller of JNI callee) ] <-- ASP
@ -1207,6 +1236,11 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
generate_counter_incr(&invocation_counter_overflow, NULL, NULL); generate_counter_incr(&invocation_counter_overflow, NULL, NULL);
BIND(continue_after_compile); BIND(continue_after_compile);
}
bang_stack_shadow_pages(true);
if (inc_counter) {
// Reset the _do_not_unlock_if_synchronized flag. // Reset the _do_not_unlock_if_synchronized flag.
if (synchronized) { if (synchronized) {
__ li(R0, 0); __ li(R0, 0);
@ -1595,6 +1629,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame. Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame.
Rsize_of_locals = R5_ARG3; // Written by generate_fixed_frame. Rsize_of_locals = R5_ARG3; // Written by generate_fixed_frame.
// Does also a stack check to assure this frame fits on the stack.
generate_fixed_frame(false, Rsize_of_parameters, Rsize_of_locals); generate_fixed_frame(false, Rsize_of_parameters, Rsize_of_locals);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@ -1651,7 +1686,11 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
} }
__ bind(profile_method_continue); __ bind(profile_method_continue);
}
bang_stack_shadow_pages(false);
if (inc_counter || ProfileInterpreter) {
// Reset the _do_not_unlock_if_synchronized flag. // Reset the _do_not_unlock_if_synchronized flag.
if (synchronized) { if (synchronized) {
__ li(R0, 0); __ li(R0, 0);

View File

@ -1712,6 +1712,7 @@ public class CommandProcessor {
// called after debuggee attach // called after debuggee attach
private void postAttach() { private void postAttach() {
// create JavaScript engine and start it // create JavaScript engine and start it
try {
jsengine = new JSJavaScriptEngine() { jsengine = new JSJavaScriptEngine() {
private ObjectReader reader = new ObjectReader(); private ObjectReader reader = new ObjectReader();
private JSJavaFactory factory = new JSJavaFactoryImpl(); private JSJavaFactory factory = new JSJavaFactoryImpl();
@ -1747,6 +1748,13 @@ public class CommandProcessor {
} }
jsengine.start(); jsengine.start();
} }
catch (Exception ex) {
System.out.println("Warning! JS Engine can't start, some commands will not be available.");
if (verboseExceptions) {
ex.printStackTrace(out);
}
}
}
public void registerCommand(String cmd, String usage, final String func) { public void registerCommand(String cmd, String usage, final String func) {
commands.put(cmd, new Command(cmd, usage, false) { commands.put(cmd, new Command(cmd, usage, false) {

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2015 SAP SE. All rights reserved. * Copyright (c) 2013, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -128,6 +128,8 @@ class Aix {
// Set PC into context. Needed for continuation after signal. // Set PC into context. Needed for continuation after signal.
static void ucontext_set_pc(ucontext_t* uc, address pc); static void ucontext_set_pc(ucontext_t* uc, address pc);
static bool get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr);
// This boolean allows users to forward their own non-matching signals // This boolean allows users to forward their own non-matching signals
// to JVM_handle_aix_signal, harmlessly. // to JVM_handle_aix_signal, harmlessly.
static bool signal_handlers_are_installed; static bool signal_handlers_are_installed;

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2014 SAP SE. All rights reserved. * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,7 +24,7 @@
*/ */
// no precompiled headers // no precompiled headers
#include "assembler_ppc.inline.hpp" #include "asm/assembler.inline.hpp"
#include "classfile/classLoader.hpp" #include "classfile/classLoader.hpp"
#include "classfile/systemDictionary.hpp" #include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp" #include "classfile/vmSymbols.hpp"
@ -145,6 +145,41 @@ frame os::fetch_frame_from_context(const void* ucVoid) {
return fr; return fr;
} }
bool os::Aix::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
address pc = (address) os::Aix::ucontext_get_pc(uc);
if (Interpreter::contains(pc)) {
// Interpreter performs stack banging after the fixed frame header has
// been generated while the compilers perform it before. To maintain
// semantic consistency between interpreted and compiled frames, the
// method returns the Java sender of the current frame.
*fr = os::fetch_frame_from_context(uc);
if (!fr->is_first_java_frame()) {
assert(fr->safe_for_sender(thread), "Safety check");
*fr = fr->java_sender();
}
} else {
// More complex code with compiled code.
assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
CodeBlob* cb = CodeCache::find_blob(pc);
if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
// Not sure where the pc points to, fallback to default
// stack overflow handling. In compiled code, we bang before
// the frame is complete.
return false;
} else {
intptr_t* sp = os::Aix::ucontext_get_sp(uc);
*fr = frame(sp, (address)*sp);
if (!fr->is_java_frame()) {
assert(fr->safe_for_sender(thread), "Safety check");
assert(!fr->is_first_frame(), "Safety check");
*fr = fr->java_sender();
}
}
}
assert(fr->is_java_frame(), "Safety check");
return true;
}
frame os::get_sender_for_C_frame(frame* fr) { frame os::get_sender_for_C_frame(frame* fr) {
if (*fr->sp() == NULL) { if (*fr->sp() == NULL) {
// fr is the last C frame // fr is the last C frame
@ -246,14 +281,32 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
// to continue with yellow zone disabled, but that doesn't buy us much and prevents // to continue with yellow zone disabled, but that doesn't buy us much and prevents
// hs_err_pid files. // hs_err_pid files.
if (thread->in_stack_yellow_reserved_zone(addr)) { if (thread->in_stack_yellow_reserved_zone(addr)) {
thread->disable_stack_yellow_reserved_zone();
if (thread->thread_state() == _thread_in_Java) { if (thread->thread_state() == _thread_in_Java) {
if (thread->in_stack_reserved_zone(addr)) {
frame fr;
if (os::Aix::get_frame_at_stack_banging_point(thread, uc, &fr)) {
assert(fr.is_java_frame(), "Must be a Javac frame");
frame activation =
SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
if (activation.sp() != NULL) {
thread->disable_stack_reserved_zone();
if (activation.is_interpreted_frame()) {
thread->set_reserved_stack_activation((address)activation.fp());
} else {
thread->set_reserved_stack_activation((address)activation.unextended_sp());
}
return 1;
}
}
}
// Throw a stack overflow exception. // Throw a stack overflow exception.
// Guard pages will be reenabled while unwinding the stack. // Guard pages will be reenabled while unwinding the stack.
thread->disable_stack_yellow_reserved_zone();
stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
goto run_stub; goto run_stub;
} else { } else {
// Thread was in the vm or native code. Return and try to finish. // Thread was in the vm or native code. Return and try to finish.
thread->disable_stack_yellow_reserved_zone();
return 1; return 1;
} }
} else if (thread->in_stack_red_zone(addr)) { } else if (thread->in_stack_red_zone(addr)) {

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved. * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,7 +24,7 @@
*/ */
// no precompiled headers // no precompiled headers
#include "assembler_ppc.inline.hpp" #include "asm/assembler.inline.hpp"
#include "classfile/classLoader.hpp" #include "classfile/classLoader.hpp"
#include "classfile/systemDictionary.hpp" #include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp" #include "classfile/vmSymbols.hpp"
@ -157,6 +157,42 @@ frame os::fetch_frame_from_context(const void* ucVoid) {
return frame(sp, epc.pc()); return frame(sp, epc.pc());
} }
bool os::Linux::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
address pc = (address) os::Linux::ucontext_get_pc(uc);
if (Interpreter::contains(pc)) {
// Interpreter performs stack banging after the fixed frame header has
// been generated while the compilers perform it before. To maintain
// semantic consistency between interpreted and compiled frames, the
// method returns the Java sender of the current frame.
*fr = os::fetch_frame_from_context(uc);
if (!fr->is_first_java_frame()) {
assert(fr->safe_for_sender(thread), "Safety check");
*fr = fr->java_sender();
}
} else {
// More complex code with compiled code.
assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
CodeBlob* cb = CodeCache::find_blob(pc);
if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
// Not sure where the pc points to, fallback to default
// stack overflow handling. In compiled code, we bang before
// the frame is complete.
return false;
} else {
intptr_t* fp = os::Linux::ucontext_get_fp(uc);
intptr_t* sp = os::Linux::ucontext_get_sp(uc);
*fr = frame(sp, (address)*sp);
if (!fr->is_java_frame()) {
assert(fr->safe_for_sender(thread), "Safety check");
assert(!fr->is_first_frame(), "Safety check");
*fr = fr->java_sender();
}
}
}
assert(fr->is_java_frame(), "Safety check");
return true;
}
frame os::get_sender_for_C_frame(frame* fr) { frame os::get_sender_for_C_frame(frame* fr) {
if (*fr->sp() == 0) { if (*fr->sp() == 0) {
// fr is the last C frame // fr is the last C frame
@ -243,13 +279,31 @@ JVM_handle_linux_signal(int sig,
if (thread->on_local_stack(addr)) { if (thread->on_local_stack(addr)) {
// stack overflow // stack overflow
if (thread->in_stack_yellow_reserved_zone(addr)) { if (thread->in_stack_yellow_reserved_zone(addr)) {
thread->disable_stack_yellow_reserved_zone();
if (thread->thread_state() == _thread_in_Java) { if (thread->thread_state() == _thread_in_Java) {
if (thread->in_stack_reserved_zone(addr)) {
frame fr;
if (os::Linux::get_frame_at_stack_banging_point(thread, uc, &fr)) {
assert(fr.is_java_frame(), "Must be a Javac frame");
frame activation =
SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
if (activation.sp() != NULL) {
thread->disable_stack_reserved_zone();
if (activation.is_interpreted_frame()) {
thread->set_reserved_stack_activation((address)activation.fp());
} else {
thread->set_reserved_stack_activation((address)activation.unextended_sp());
}
return 1;
}
}
}
// Throw a stack overflow exception. // Throw a stack overflow exception.
// Guard pages will be reenabled while unwinding the stack. // Guard pages will be reenabled while unwinding the stack.
thread->disable_stack_yellow_reserved_zone();
stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
} else { } else {
// Thread was in the vm or native code. Return and try to finish. // Thread was in the vm or native code. Return and try to finish.
thread->disable_stack_yellow_reserved_zone();
return 1; return 1;
} }
} else if (thread->in_stack_red_zone(addr)) { } else if (thread->in_stack_red_zone(addr)) {

View File

@ -704,13 +704,14 @@ Method* ciEnv::lookup_method(InstanceKlass* accessor,
InstanceKlass* holder, InstanceKlass* holder,
Symbol* name, Symbol* name,
Symbol* sig, Symbol* sig,
Bytecodes::Code bc) { Bytecodes::Code bc,
constantTag tag) {
EXCEPTION_CONTEXT; EXCEPTION_CONTEXT;
KlassHandle h_accessor(THREAD, accessor); KlassHandle h_accessor(THREAD, accessor);
KlassHandle h_holder(THREAD, holder); KlassHandle h_holder(THREAD, holder);
LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL)); LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL));
methodHandle dest_method; methodHandle dest_method;
LinkInfo link_info(h_holder, name, sig, h_accessor, /*check_access*/true); LinkInfo link_info(h_holder, name, sig, h_accessor, LinkInfo::needs_access_check, tag);
switch (bc) { switch (bc) {
case Bytecodes::_invokestatic: case Bytecodes::_invokestatic:
dest_method = dest_method =
@ -796,7 +797,9 @@ ciMethod* ciEnv::get_method_by_index_impl(const constantPoolHandle& cpool,
if (holder_is_accessible) { // Our declared holder is loaded. if (holder_is_accessible) { // Our declared holder is loaded.
InstanceKlass* lookup = declared_holder->get_instanceKlass(); InstanceKlass* lookup = declared_holder->get_instanceKlass();
Method* m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc); constantTag tag = cpool->tag_ref_at(index);
assert(accessor->get_instanceKlass() == cpool->pool_holder(), "not the pool holder?");
Method* m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc, tag);
if (m != NULL && if (m != NULL &&
(bc == Bytecodes::_invokestatic (bc == Bytecodes::_invokestatic
? m->method_holder()->is_not_initialized() ? m->method_holder()->is_not_initialized()

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -156,7 +156,8 @@ private:
InstanceKlass* holder, InstanceKlass* holder,
Symbol* name, Symbol* name,
Symbol* sig, Symbol* sig,
Bytecodes::Code bc); Bytecodes::Code bc,
constantTag tag);
// Get a ciObject from the object factory. Ensures uniqueness // Get a ciObject from the object factory. Ensures uniqueness
// of ciObjects. // of ciObjects.

View File

@ -789,7 +789,8 @@ ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, boo
Symbol* h_name = name()->get_symbol(); Symbol* h_name = name()->get_symbol();
Symbol* h_signature = signature()->get_symbol(); Symbol* h_signature = signature()->get_symbol();
LinkInfo link_info(h_resolved, h_name, h_signature, caller_klass, check_access); LinkInfo link_info(h_resolved, h_name, h_signature, caller_klass,
check_access ? LinkInfo::needs_access_check : LinkInfo::skip_access_check);
methodHandle m; methodHandle m;
// Only do exact lookup if receiver klass has been linked. Otherwise, // Only do exact lookup if receiver klass has been linked. Otherwise,
// the vtable has not been setup, and the LinkResolver will fail. // the vtable has not been setup, and the LinkResolver will fail.

View File

@ -657,7 +657,7 @@ void ClassLoader::setup_xpatch_entries() {
int num_of_entries = xpatch_args->length(); int num_of_entries = xpatch_args->length();
// Set up the boot loader's xpatch_entries list // Set up the boot loader's xpatch_entries list
_xpatch_entries = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<ModuleClassPathList*>(num_of_entries, true); _xpatch_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(num_of_entries, true);
for (int i = 0; i < num_of_entries; i++) { for (int i = 0; i < num_of_entries; i++) {
const char* module_name = (xpatch_args->at(i))->module_name(); const char* module_name = (xpatch_args->at(i))->module_name();
@ -1069,9 +1069,9 @@ void ClassLoader::initialize_module_loader_map(JImageFile* jimage) {
char* begin_ptr = char_buf; char* begin_ptr = char_buf;
char* end_ptr = strchr(begin_ptr, '\n'); char* end_ptr = strchr(begin_ptr, '\n');
bool process_boot_modules = false; bool process_boot_modules = false;
_boot_modules_array = new (ResourceObj::C_HEAP, mtInternal) _boot_modules_array = new (ResourceObj::C_HEAP, mtModule)
GrowableArray<char*>(INITIAL_BOOT_MODULES_ARRAY_SIZE, true); GrowableArray<char*>(INITIAL_BOOT_MODULES_ARRAY_SIZE, true);
_platform_modules_array = new (ResourceObj::C_HEAP, mtInternal) _platform_modules_array = new (ResourceObj::C_HEAP, mtModule)
GrowableArray<char*>(INITIAL_PLATFORM_MODULES_ARRAY_SIZE, true); GrowableArray<char*>(INITIAL_PLATFORM_MODULES_ARRAY_SIZE, true);
while (end_ptr != NULL && (end_ptr - char_buf) < buflen) { while (end_ptr != NULL && (end_ptr - char_buf) < buflen) {
// Allocate a buffer from the C heap to be appended to the _boot_modules_array // Allocate a buffer from the C heap to be appended to the _boot_modules_array

View File

@ -67,6 +67,7 @@
#include "runtime/javaCalls.hpp" #include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.hpp" #include "runtime/jniHandles.hpp"
#include "runtime/mutex.hpp" #include "runtime/mutex.hpp"
#include "runtime/orderAccess.hpp"
#include "runtime/safepoint.hpp" #include "runtime/safepoint.hpp"
#include "runtime/synchronizer.hpp" #include "runtime/synchronizer.hpp"
#include "utilities/growableArray.hpp" #include "utilities/growableArray.hpp"
@ -76,6 +77,11 @@
#include "trace/tracing.hpp" #include "trace/tracing.hpp"
#endif #endif
// helper function to avoid in-line casts
template <typename T> static T* load_ptr_acquire(T* volatile *p) {
return static_cast<T*>(OrderAccess::load_ptr_acquire(p));
}
ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL; ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) : ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) :
@ -147,20 +153,23 @@ void ClassLoaderData::Dependencies::oops_do(OopClosure* f) {
} }
void ClassLoaderData::classes_do(KlassClosure* klass_closure) { void ClassLoaderData::classes_do(KlassClosure* klass_closure) {
for (Klass* k = _klasses; k != NULL; k = k->next_link()) { // Lock-free access requires load_ptr_acquire
for (Klass* k = load_ptr_acquire(&_klasses); k != NULL; k = k->next_link()) {
klass_closure->do_klass(k); klass_closure->do_klass(k);
assert(k != k->next_link(), "no loops!"); assert(k != k->next_link(), "no loops!");
} }
} }
void ClassLoaderData::classes_do(void f(Klass * const)) { void ClassLoaderData::classes_do(void f(Klass * const)) {
assert_locked_or_safepoint(_metaspace_lock);
for (Klass* k = _klasses; k != NULL; k = k->next_link()) { for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
f(k); f(k);
} }
} }
void ClassLoaderData::methods_do(void f(Method*)) { void ClassLoaderData::methods_do(void f(Method*)) {
for (Klass* k = _klasses; k != NULL; k = k->next_link()) { // Lock-free access requires load_ptr_acquire
for (Klass* k = load_ptr_acquire(&_klasses); k != NULL; k = k->next_link()) {
if (k->is_instance_klass()) { if (k->is_instance_klass()) {
InstanceKlass::cast(k)->methods_do(f); InstanceKlass::cast(k)->methods_do(f);
} }
@ -179,7 +188,8 @@ void ClassLoaderData::loaded_classes_do(KlassClosure* klass_closure) {
} }
void ClassLoaderData::classes_do(void f(InstanceKlass*)) { void ClassLoaderData::classes_do(void f(InstanceKlass*)) {
for (Klass* k = _klasses; k != NULL; k = k->next_link()) { // Lock-free access requires load_ptr_acquire
for (Klass* k = load_ptr_acquire(&_klasses); k != NULL; k = k->next_link()) {
if (k->is_instance_klass()) { if (k->is_instance_klass()) {
f(InstanceKlass::cast(k)); f(InstanceKlass::cast(k));
} }
@ -188,6 +198,7 @@ void ClassLoaderData::classes_do(void f(InstanceKlass*)) {
} }
void ClassLoaderData::modules_do(void f(ModuleEntry*)) { void ClassLoaderData::modules_do(void f(ModuleEntry*)) {
assert_locked_or_safepoint(Module_lock);
if (_modules != NULL) { if (_modules != NULL) {
for (int i = 0; i < _modules->table_size(); i++) { for (int i = 0; i < _modules->table_size(); i++) {
for (ModuleEntry* entry = _modules->bucket(i); for (ModuleEntry* entry = _modules->bucket(i);
@ -200,9 +211,11 @@ void ClassLoaderData::modules_do(void f(ModuleEntry*)) {
} }
void ClassLoaderData::packages_do(void f(PackageEntry*)) { void ClassLoaderData::packages_do(void f(PackageEntry*)) {
if (_packages != NULL) { // Lock-free access requires load_ptr_acquire
for (int i = 0; i < _packages->table_size(); i++) { PackageEntryTable* packages = load_ptr_acquire(&_packages);
for (PackageEntry* entry = _packages->bucket(i); if (packages != NULL) {
for (int i = 0; i < packages->table_size(); i++) {
for (PackageEntry* entry = packages->bucket(i);
entry != NULL; entry != NULL;
entry = entry->next()) { entry = entry->next()) {
f(entry); f(entry);
@ -325,10 +338,9 @@ void ClassLoaderData::add_class(Klass* k, bool publicize /* true */) {
MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag); MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag);
Klass* old_value = _klasses; Klass* old_value = _klasses;
k->set_next_link(old_value); k->set_next_link(old_value);
// Make sure linked class is stable, since the class list is walked without a lock // Link the new item into the list, making sure the linked class is stable
OrderAccess::storestore(); // since the list can be walked without a lock
// link the new item into the list OrderAccess::release_store_ptr(&_klasses, k);
_klasses = k;
} }
if (publicize && k->class_loader_data() != NULL) { if (publicize && k->class_loader_data() != NULL) {
@ -343,11 +355,10 @@ void ClassLoaderData::add_class(Klass* k, bool publicize /* true */) {
} }
} }
// This is called by InstanceKlass::deallocate_contents() to remove the // Remove a klass from the _klasses list for scratch_class during redefinition
// scratch_class for redefine classes. We need a lock because there it may not // or parsed class in the case of an error.
// be called at a safepoint if there's an error.
void ClassLoaderData::remove_class(Klass* scratch_class) { void ClassLoaderData::remove_class(Klass* scratch_class) {
MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag); assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
Klass* prev = NULL; Klass* prev = NULL;
for (Klass* k = _klasses; k != NULL; k = k->next_link()) { for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
if (k == scratch_class) { if (k == scratch_class) {
@ -390,42 +401,46 @@ void ClassLoaderData::unload() {
PackageEntryTable* ClassLoaderData::packages() { PackageEntryTable* ClassLoaderData::packages() {
// Lazily create the package entry table at first request. // Lazily create the package entry table at first request.
if (_packages == NULL) { // Lock-free access requires load_ptr_acquire.
PackageEntryTable* packages = load_ptr_acquire(&_packages);
if (packages == NULL) {
MutexLockerEx m1(metaspace_lock(), Mutex::_no_safepoint_check_flag); MutexLockerEx m1(metaspace_lock(), Mutex::_no_safepoint_check_flag);
// Check if _packages got allocated while we were waiting for this lock. // Check if _packages got allocated while we were waiting for this lock.
if (_packages == NULL) { if ((packages = _packages) == NULL) {
_packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size); packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size);
// Ensure _packages is stable, since it is examined without a lock
OrderAccess::release_store_ptr(&_packages, packages);
} }
} }
return _packages; return packages;
} }
ModuleEntryTable* ClassLoaderData::modules() { ModuleEntryTable* ClassLoaderData::modules() {
// Lazily create the module entry table at first request. // Lazily create the module entry table at first request.
if (_modules == NULL) { // Lock-free access requires load_ptr_acquire.
ModuleEntryTable* modules = load_ptr_acquire(&_modules);
if (modules == NULL) {
MutexLocker m1(Module_lock); MutexLocker m1(Module_lock);
// Check again if _modules has been allocated while we were getting this lock. // Check if _modules got allocated while we were waiting for this lock.
if (_modules != NULL) { if ((modules = _modules) == NULL) {
return _modules; modules = new ModuleEntryTable(ModuleEntryTable::_moduletable_entry_size);
}
ModuleEntryTable* temp_table = new ModuleEntryTable(ModuleEntryTable::_moduletable_entry_size);
// Each loader has one unnamed module entry. Create it before // Each loader has one unnamed module entry. Create it before
// any classes, loaded by this loader, are defined in case // any classes, loaded by this loader, are defined in case
// they end up being defined in loader's unnamed module. // they end up being defined in loader's unnamed module.
temp_table->create_unnamed_module(this); modules->create_unnamed_module(this);
{ {
MutexLockerEx m1(metaspace_lock(), Mutex::_no_safepoint_check_flag); MutexLockerEx m1(metaspace_lock(), Mutex::_no_safepoint_check_flag);
// Ensure _modules is stable, since it is examined without a lock // Ensure _modules is stable, since it is examined without a lock
OrderAccess::storestore(); OrderAccess::release_store_ptr(&_modules, modules);
_modules = temp_table;
} }
} }
return _modules; }
return modules;
} }
oop ClassLoaderData::keep_alive_object() const { oop ClassLoaderData::keep_alive_object() const {
assert_locked_or_safepoint(_metaspace_lock);
assert(!keep_alive(), "Don't use with CLDs that are artificially kept alive"); assert(!keep_alive(), "Don't use with CLDs that are artificially kept alive");
return is_anonymous() ? _klasses->java_mirror() : class_loader(); return is_anonymous() ? _klasses->java_mirror() : class_loader();
} }
@ -499,30 +514,33 @@ Metaspace* ClassLoaderData::metaspace_non_null() {
// to create smaller arena for Reflection class loaders also. // to create smaller arena for Reflection class loaders also.
// The reason for the delayed allocation is because some class loaders are // The reason for the delayed allocation is because some class loaders are
// simply for delegating with no metadata of their own. // simply for delegating with no metadata of their own.
if (_metaspace == NULL) { // Lock-free access requires load_ptr_acquire.
MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag); Metaspace* metaspace = load_ptr_acquire(&_metaspace);
// Check again if metaspace has been allocated while we were getting this lock. if (metaspace == NULL) {
if (_metaspace != NULL) { MutexLockerEx ml(_metaspace_lock, Mutex::_no_safepoint_check_flag);
return _metaspace; // Check if _metaspace got allocated while we were waiting for this lock.
} if ((metaspace = _metaspace) == NULL) {
if (this == the_null_class_loader_data()) { if (this == the_null_class_loader_data()) {
assert (class_loader() == NULL, "Must be"); assert (class_loader() == NULL, "Must be");
set_metaspace(new Metaspace(_metaspace_lock, Metaspace::BootMetaspaceType)); metaspace = new Metaspace(_metaspace_lock, Metaspace::BootMetaspaceType);
} else if (is_anonymous()) { } else if (is_anonymous()) {
if (class_loader() != NULL) { if (class_loader() != NULL) {
log_trace(class, loader, data)("is_anonymous: %s", class_loader()->klass()->internal_name()); log_trace(class, loader, data)("is_anonymous: %s", class_loader()->klass()->internal_name());
} }
set_metaspace(new Metaspace(_metaspace_lock, Metaspace::AnonymousMetaspaceType)); metaspace = new Metaspace(_metaspace_lock, Metaspace::AnonymousMetaspaceType);
} else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) {
if (class_loader() != NULL) { if (class_loader() != NULL) {
log_trace(class, loader, data)("is_reflection: %s", class_loader()->klass()->internal_name()); log_trace(class, loader, data)("is_reflection: %s", class_loader()->klass()->internal_name());
} }
set_metaspace(new Metaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType)); metaspace = new Metaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType);
} else { } else {
set_metaspace(new Metaspace(_metaspace_lock, Metaspace::StandardMetaspaceType)); metaspace = new Metaspace(_metaspace_lock, Metaspace::StandardMetaspaceType);
}
// Ensure _metaspace is stable, since it is examined without a lock
OrderAccess::release_store_ptr(&_metaspace, metaspace);
} }
} }
return _metaspace; return metaspace;
} }
JNIHandleBlock* ClassLoaderData::handles() const { return _handles; } JNIHandleBlock* ClassLoaderData::handles() const { return _handles; }
@ -638,6 +656,7 @@ void ClassLoaderData::dump(outputStream * const out) {
#endif // PRODUCT #endif // PRODUCT
void ClassLoaderData::verify() { void ClassLoaderData::verify() {
assert_locked_or_safepoint(_metaspace_lock);
oop cl = class_loader(); oop cl = class_loader();
guarantee(this == class_loader_data(cl) || is_anonymous(), "Must be the same"); guarantee(this == class_loader_data(cl) || is_anonymous(), "Must be the same");
@ -656,7 +675,8 @@ void ClassLoaderData::verify() {
} }
bool ClassLoaderData::contains_klass(Klass* klass) { bool ClassLoaderData::contains_klass(Klass* klass) {
for (Klass* k = _klasses; k != NULL; k = k->next_link()) { // Lock-free access requires load_ptr_acquire
for (Klass* k = load_ptr_acquire(&_klasses); k != NULL; k = k->next_link()) {
if (k == klass) return true; if (k == klass) return true;
} }
return false; return false;
@ -1046,6 +1066,7 @@ ClassLoaderDataGraphKlassIteratorAtomic::ClassLoaderDataGraphKlassIteratorAtomic
// Find the first klass in the CLDG. // Find the first klass in the CLDG.
while (cld != NULL) { while (cld != NULL) {
assert_locked_or_safepoint(cld->metaspace_lock());
klass = cld->_klasses; klass = cld->_klasses;
if (klass != NULL) { if (klass != NULL) {
_next_klass = klass; _next_klass = klass;
@ -1063,6 +1084,7 @@ Klass* ClassLoaderDataGraphKlassIteratorAtomic::next_klass_in_cldg(Klass* klass)
// No more klasses in the current CLD. Time to find a new CLD. // No more klasses in the current CLD. Time to find a new CLD.
ClassLoaderData* cld = klass->class_loader_data(); ClassLoaderData* cld = klass->class_loader_data();
assert_locked_or_safepoint(cld->metaspace_lock());
while (next == NULL) { while (next == NULL) {
cld = cld->next(); cld = cld->next();
if (cld == NULL) { if (cld == NULL) {

View File

@ -171,7 +171,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
Dependencies _dependencies; // holds dependencies from this class loader Dependencies _dependencies; // holds dependencies from this class loader
// data to others. // data to others.
Metaspace * _metaspace; // Meta-space where meta-data defined by the Metaspace * volatile _metaspace; // Meta-space where meta-data defined by the
// classes in the class loader are allocated. // classes in the class loader are allocated.
Mutex* _metaspace_lock; // Locks the metaspace for allocations and setup. Mutex* _metaspace_lock; // Locks the metaspace for allocations and setup.
bool _unloading; // true if this class loader goes away bool _unloading; // true if this class loader goes away
@ -186,9 +186,9 @@ class ClassLoaderData : public CHeapObj<mtClass> {
JNIHandleBlock* _handles; // Handles to constant pool arrays, Modules, etc, which JNIHandleBlock* _handles; // Handles to constant pool arrays, Modules, etc, which
// have the same life cycle of the corresponding ClassLoader. // have the same life cycle of the corresponding ClassLoader.
Klass* _klasses; // The classes defined by the class loader. Klass* volatile _klasses; // The classes defined by the class loader.
PackageEntryTable* _packages; // The packages defined by the class loader. PackageEntryTable* volatile _packages; // The packages defined by the class loader.
ModuleEntryTable* _modules; // The modules defined by the class loader. ModuleEntryTable* volatile _modules; // The modules defined by the class loader.
// These method IDs are created for the class loader and set to NULL when the // These method IDs are created for the class loader and set to NULL when the
// class loader is unloaded. They are rarely freed, only for redefine classes // class loader is unloaded. They are rarely freed, only for redefine classes
@ -216,8 +216,6 @@ class ClassLoaderData : public CHeapObj<mtClass> {
ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies); ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies);
~ClassLoaderData(); ~ClassLoaderData();
void set_metaspace(Metaspace* m) { _metaspace = m; }
JNIHandleBlock* handles() const; JNIHandleBlock* handles() const;
void set_handles(JNIHandleBlock* handles); void set_handles(JNIHandleBlock* handles);

View File

@ -848,7 +848,7 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
if (!ModuleEntryTable::javabase_defined()) { if (!ModuleEntryTable::javabase_defined()) {
if (fixup_module_field_list() == NULL) { if (fixup_module_field_list() == NULL) {
GrowableArray<Klass*>* list = GrowableArray<Klass*>* list =
new (ResourceObj::C_HEAP, mtClass) GrowableArray<Klass*>(500, true); new (ResourceObj::C_HEAP, mtModule) GrowableArray<Klass*>(500, true);
set_fixup_module_field_list(list); set_fixup_module_field_list(list);
} }
k->class_loader_data()->inc_keep_alive(); k->class_loader_data()->inc_keep_alive();

View File

@ -113,7 +113,7 @@ void ModuleEntry::add_read(ModuleEntry* m) {
} else { } else {
if (_reads == NULL) { if (_reads == NULL) {
// Lazily create a module's reads list // Lazily create a module's reads list
_reads = new (ResourceObj::C_HEAP, mtClass)GrowableArray<ModuleEntry*>(MODULE_READS_SIZE, true); _reads = new (ResourceObj::C_HEAP, mtModule)GrowableArray<ModuleEntry*>(MODULE_READS_SIZE, true);
} }
_reads->append_if_missing(m); _reads->append_if_missing(m);
} }
@ -159,7 +159,7 @@ void ModuleEntry::delete_reads() {
} }
ModuleEntryTable::ModuleEntryTable(int table_size) ModuleEntryTable::ModuleEntryTable(int table_size)
: Hashtable<Symbol*, mtClass>(table_size, sizeof(ModuleEntry)), _unnamed_module(NULL) : Hashtable<Symbol*, mtModule>(table_size, sizeof(ModuleEntry)), _unnamed_module(NULL)
{ {
} }
@ -228,7 +228,7 @@ ModuleEntry* ModuleEntryTable::new_entry(unsigned int hash, Handle module_handle
Symbol* version, Symbol* location, Symbol* version, Symbol* location,
ClassLoaderData* loader_data) { ClassLoaderData* loader_data) {
assert_locked_or_safepoint(Module_lock); assert_locked_or_safepoint(Module_lock);
ModuleEntry* entry = (ModuleEntry*) NEW_C_HEAP_ARRAY(char, entry_size(), mtClass); ModuleEntry* entry = (ModuleEntry*) NEW_C_HEAP_ARRAY(char, entry_size(), mtModule);
// Initialize everything BasicHashtable would // Initialize everything BasicHashtable would
entry->set_next(NULL); entry->set_next(NULL);
@ -259,7 +259,7 @@ ModuleEntry* ModuleEntryTable::new_entry(unsigned int hash, Handle module_handle
void ModuleEntryTable::add_entry(int index, ModuleEntry* new_entry) { void ModuleEntryTable::add_entry(int index, ModuleEntry* new_entry) {
assert_locked_or_safepoint(Module_lock); assert_locked_or_safepoint(Module_lock);
Hashtable<Symbol*, mtClass>::add_entry(index, (HashtableEntry<Symbol*, mtClass>*)new_entry); Hashtable<Symbol*, mtModule>::add_entry(index, (HashtableEntry<Symbol*, mtModule>*)new_entry);
} }
ModuleEntry* ModuleEntryTable::locked_create_entry_or_null(Handle module_handle, ModuleEntry* ModuleEntryTable::locked_create_entry_or_null(Handle module_handle,

View File

@ -49,7 +49,7 @@ class ModuleClosure;
// //
// The Mutex Module_lock is shared between ModuleEntry and PackageEntry, to lock either // The Mutex Module_lock is shared between ModuleEntry and PackageEntry, to lock either
// data structure. // data structure.
class ModuleEntry : public HashtableEntry<Symbol*, mtClass> { class ModuleEntry : public HashtableEntry<Symbol*, mtModule> {
private: private:
jobject _module; // java.lang.reflect.Module jobject _module; // java.lang.reflect.Module
jobject _pd; // java.security.ProtectionDomain, cached jobject _pd; // java.security.ProtectionDomain, cached
@ -127,10 +127,10 @@ public:
} }
ModuleEntry* next() const { ModuleEntry* next() const {
return (ModuleEntry*)HashtableEntry<Symbol*, mtClass>::next(); return (ModuleEntry*)HashtableEntry<Symbol*, mtModule>::next();
} }
ModuleEntry** next_addr() { ModuleEntry** next_addr() {
return (ModuleEntry**)HashtableEntry<Symbol*, mtClass>::next_addr(); return (ModuleEntry**)HashtableEntry<Symbol*, mtModule>::next_addr();
} }
// iteration support for readability // iteration support for readability
@ -166,7 +166,7 @@ class ModuleClosure: public StackObj {
// //
// The ModuleEntryTable's lookup is lock free. // The ModuleEntryTable's lookup is lock free.
// //
class ModuleEntryTable : public Hashtable<Symbol*, mtClass> { class ModuleEntryTable : public Hashtable<Symbol*, mtModule> {
friend class VMStructs; friend class VMStructs;
public: public:
enum Constants { enum Constants {
@ -181,10 +181,10 @@ private:
Symbol* location, ClassLoaderData* class_loader); Symbol* location, ClassLoaderData* class_loader);
void add_entry(int index, ModuleEntry* new_entry); void add_entry(int index, ModuleEntry* new_entry);
int entry_size() const { return BasicHashtable<mtClass>::entry_size(); } int entry_size() const { return BasicHashtable<mtModule>::entry_size(); }
ModuleEntry** bucket_addr(int i) { ModuleEntry** bucket_addr(int i) {
return (ModuleEntry**)Hashtable<Symbol*, mtClass>::bucket_addr(i); return (ModuleEntry**)Hashtable<Symbol*, mtModule>::bucket_addr(i);
} }
static unsigned int compute_hash(Symbol* name) { return ((name == NULL) ? 0 : (unsigned int)(name->identity_hash())); } static unsigned int compute_hash(Symbol* name) { return ((name == NULL) ? 0 : (unsigned int)(name->identity_hash())); }
@ -195,7 +195,7 @@ public:
~ModuleEntryTable(); ~ModuleEntryTable();
ModuleEntry* bucket(int i) { ModuleEntry* bucket(int i) {
return (ModuleEntry*)Hashtable<Symbol*, mtClass>::bucket(i); return (ModuleEntry*)Hashtable<Symbol*, mtModule>::bucket(i);
} }
// Create module in loader's module entry table, if already exists then // Create module in loader's module entry table, if already exists then

View File

@ -145,7 +145,7 @@ static void add_to_exploded_build_list(char *module_name, TRAPS) {
const char* home = Arguments::get_java_home(); const char* home = Arguments::get_java_home();
size_t len = strlen(home) + module_len + 32; size_t len = strlen(home) + module_len + 32;
char* path = NEW_C_HEAP_ARRAY(char, len, mtInternal); char* path = NEW_C_HEAP_ARRAY(char, len, mtModule);
jio_snprintf(path, len, "%s%cmodules%c%s", home, file_sep, file_sep, module_name); jio_snprintf(path, len, "%s%cmodules%c%s", home, file_sep, file_sep, module_name);
struct stat st; struct stat st;
// See if exploded module path exists // See if exploded module path exists
@ -237,13 +237,13 @@ static void define_javabase_module(jobject module, jstring version,
// Ensure java.base's ModuleEntry has been created // Ensure java.base's ModuleEntry has been created
assert(ModuleEntryTable::javabase_module() != NULL, "No ModuleEntry for java.base"); assert(ModuleEntryTable::javabase_module() != NULL, "No ModuleEntry for java.base");
bool duplicate_javabase = false;
{ {
MutexLocker m1(Module_lock, THREAD); MutexLocker m1(Module_lock, THREAD);
if (ModuleEntryTable::javabase_defined()) { if (ModuleEntryTable::javabase_defined()) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), duplicate_javabase = true;
"Module java.base is already defined"); } else {
}
// Verify that all java.base packages created during bootstrapping are in // Verify that all java.base packages created during bootstrapping are in
// pkg_list. If any are not in pkg_list, than a non-java.base class was // pkg_list. If any are not in pkg_list, than a non-java.base class was
@ -267,6 +267,11 @@ static void define_javabase_module(jobject module, jstring version,
// Finish defining java.base's ModuleEntry // Finish defining java.base's ModuleEntry
ModuleEntryTable::finalize_javabase(module_handle, version_symbol, location_symbol); ModuleEntryTable::finalize_javabase(module_handle, version_symbol, location_symbol);
} }
}
if (duplicate_javabase) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Module java.base is already defined");
}
log_debug(modules)("define_javabase_module(): Definition of module: java.base," log_debug(modules)("define_javabase_module(): Definition of module: java.base,"
" version: %s, location: %s, package #: %d", " version: %s, location: %s, package #: %d",

View File

@ -34,15 +34,13 @@
#include "utilities/hashtable.inline.hpp" #include "utilities/hashtable.inline.hpp"
#include "utilities/ostream.hpp" #include "utilities/ostream.hpp"
// Return true if this package is exported to m. // Returns true if this package specifies m as a qualified export, including through an unnamed export
bool PackageEntry::is_qexported_to(ModuleEntry* m) const { bool PackageEntry::is_qexported_to(ModuleEntry* m) const {
assert(m != NULL, "No module to lookup in this package's qualified exports list"); assert(m != NULL, "No module to lookup in this package's qualified exports list");
MutexLocker m1(Module_lock); MutexLocker m1(Module_lock);
if (!_is_exported) { if (is_exported_allUnnamed() && !m->is_named()) {
return false;
} else if (_is_exported_allUnnamed && !m->is_named()) {
return true; return true;
} else if (_qualified_exports == NULL) { } else if (!has_qual_exports_list()) {
return false; return false;
} else { } else {
return _qualified_exports->contains(m); return _qualified_exports->contains(m);
@ -52,17 +50,16 @@ bool PackageEntry::is_qexported_to(ModuleEntry* m) const {
// Add a module to the package's qualified export list. // Add a module to the package's qualified export list.
void PackageEntry::add_qexport(ModuleEntry* m) { void PackageEntry::add_qexport(ModuleEntry* m) {
assert_locked_or_safepoint(Module_lock); assert_locked_or_safepoint(Module_lock);
assert(_is_exported == true, "Adding a qualified export to a package that is not exported"); if (!has_qual_exports_list()) {
if (_qualified_exports == NULL) {
// Lazily create a package's qualified exports list. // Lazily create a package's qualified exports list.
// Initial size is small, do not anticipate export lists to be large. // Initial size is small, do not anticipate export lists to be large.
_qualified_exports = _qualified_exports =
new (ResourceObj::C_HEAP, mtClass) GrowableArray<ModuleEntry*>(QUAL_EXP_SIZE, true); new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleEntry*>(QUAL_EXP_SIZE, true);
} }
_qualified_exports->append_if_missing(m); _qualified_exports->append_if_missing(m);
} }
// Set the package's exported state based on the value of the ModuleEntry. // Set the package's exported states based on the value of the ModuleEntry.
void PackageEntry::set_exported(ModuleEntry* m) { void PackageEntry::set_exported(ModuleEntry* m) {
MutexLocker m1(Module_lock); MutexLocker m1(Module_lock);
if (is_unqual_exported()) { if (is_unqual_exported()) {
@ -73,7 +70,7 @@ void PackageEntry::set_exported(ModuleEntry* m) {
if (m == NULL) { if (m == NULL) {
// NULL indicates the package is being unqualifiedly exported // NULL indicates the package is being unqualifiedly exported
if (_is_exported && _qualified_exports != NULL) { if (has_qual_exports_list()) {
// Legit to transition a package from being qualifiedly exported // Legit to transition a package from being qualifiedly exported
// to unqualified. Clean up the qualified lists at the next // to unqualified. Clean up the qualified lists at the next
// safepoint. // safepoint.
@ -85,11 +82,17 @@ void PackageEntry::set_exported(ModuleEntry* m) {
} else { } else {
// Add the exported module // Add the exported module
_is_exported = true;
add_qexport(m); add_qexport(m);
} }
} }
void PackageEntry::set_is_exported_allUnnamed() {
MutexLocker m1(Module_lock);
if (!is_unqual_exported()) {
_is_exported_allUnnamed = true;
}
}
// Remove dead module entries within the package's exported list. // Remove dead module entries within the package's exported list.
void PackageEntry::purge_qualified_exports() { void PackageEntry::purge_qualified_exports() {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
@ -124,7 +127,7 @@ void PackageEntry::delete_qualified_exports() {
} }
PackageEntryTable::PackageEntryTable(int table_size) PackageEntryTable::PackageEntryTable(int table_size)
: Hashtable<Symbol*, mtClass>(table_size, sizeof(PackageEntry)) : Hashtable<Symbol*, mtModule>(table_size, sizeof(PackageEntry))
{ {
} }
@ -155,7 +158,7 @@ PackageEntryTable::~PackageEntryTable() {
PackageEntry* PackageEntryTable::new_entry(unsigned int hash, Symbol* name, ModuleEntry* module) { PackageEntry* PackageEntryTable::new_entry(unsigned int hash, Symbol* name, ModuleEntry* module) {
assert_locked_or_safepoint(Module_lock); assert_locked_or_safepoint(Module_lock);
PackageEntry* entry = (PackageEntry*) NEW_C_HEAP_ARRAY(char, entry_size(), mtClass); PackageEntry* entry = (PackageEntry*) NEW_C_HEAP_ARRAY(char, entry_size(), mtModule);
// Initialize everything BasicHashtable would // Initialize everything BasicHashtable would
entry->set_next(NULL); entry->set_next(NULL);
@ -170,7 +173,7 @@ PackageEntry* PackageEntryTable::new_entry(unsigned int hash, Symbol* name, Modu
if (!module->is_named()) { if (!module->is_named()) {
// Set the exported state to true because all packages // Set the exported state to true because all packages
// within the unnamed module are unqualifiedly exported // within the unnamed module are unqualifiedly exported
entry->set_exported(true); entry->set_unqual_exported();
} }
entry->set_module(module); entry->set_module(module);
return entry; return entry;
@ -178,7 +181,7 @@ PackageEntry* PackageEntryTable::new_entry(unsigned int hash, Symbol* name, Modu
void PackageEntryTable::add_entry(int index, PackageEntry* new_entry) { void PackageEntryTable::add_entry(int index, PackageEntry* new_entry) {
assert_locked_or_safepoint(Module_lock); assert_locked_or_safepoint(Module_lock);
Hashtable<Symbol*, mtClass>::add_entry(index, (HashtableEntry<Symbol*, mtClass>*)new_entry); Hashtable<Symbol*, mtModule>::add_entry(index, (HashtableEntry<Symbol*, mtModule>*)new_entry);
} }
// Create package in loader's package entry table and return the entry. // Create package in loader's package entry table and return the entry.
@ -248,6 +251,20 @@ void PackageEntryTable::verify_javabase_packages(GrowableArray<Symbol*> *pkg_lis
} }
// iteration of qualified exports
void PackageEntry::package_exports_do(ModuleClosure* const f) {
assert_locked_or_safepoint(Module_lock);
assert(f != NULL, "invariant");
if (has_qual_exports_list()) {
int qe_len = _qualified_exports->length();
for (int i = 0; i < qe_len; ++i) {
f->do_module(_qualified_exports->at(i));
}
}
}
// Remove dead entries from all packages' exported list // Remove dead entries from all packages' exported list
void PackageEntryTable::purge_all_package_exports() { void PackageEntryTable::purge_all_package_exports() {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
@ -281,10 +298,10 @@ void PackageEntryTable::print(outputStream* st) {
void PackageEntry::print(outputStream* st) { void PackageEntry::print(outputStream* st) {
ResourceMark rm; ResourceMark rm;
st->print_cr("package entry "PTR_FORMAT" name %s module %s classpath_index " st->print_cr("package entry "PTR_FORMAT" name %s module %s classpath_index "
INT32_FORMAT " is_exported %d is_exported_allUnnamed %d " "next "PTR_FORMAT, INT32_FORMAT " is_exported_unqualified %d is_exported_allUnnamed %d " "next "PTR_FORMAT,
p2i(this), name()->as_C_string(), p2i(this), name()->as_C_string(),
(module()->is_named() ? module()->name()->as_C_string() : UNNAMED_MODULE), (module()->is_named() ? module()->name()->as_C_string() : UNNAMED_MODULE),
_classpath_index, _is_exported, _is_exported_allUnnamed, p2i(next())); _classpath_index, _is_exported_unqualified, _is_exported_allUnnamed, p2i(next()));
} }
void PackageEntryTable::verify() { void PackageEntryTable::verify() {
@ -305,17 +322,3 @@ void PackageEntryTable::verify() {
void PackageEntry::verify() { void PackageEntry::verify() {
guarantee(name() != NULL, "A package entry must have a corresponding symbol name."); guarantee(name() != NULL, "A package entry must have a corresponding symbol name.");
} }
// iteration of qualified exports
void PackageEntry::package_exports_do(ModuleClosure* const f) {
assert_locked_or_safepoint(Module_lock);
assert(f != NULL, "invariant");
if (is_qual_exported()) {
int qe_len = _qualified_exports->length();
for (int i = 0; i < qe_len; ++i) {
f->do_module(_qualified_exports->at(i));
}
}
}

View File

@ -34,20 +34,36 @@
// A PackageEntry basically represents a Java package. It contains: // A PackageEntry basically represents a Java package. It contains:
// - Symbol* containing the package's name. // - Symbol* containing the package's name.
// - ModuleEntry* for this package's containing module. // - ModuleEntry* for this package's containing module.
// - a flag indicating if package is exported, either qualifiedly or // - a flag indicating if package is exported unqualifiedly
// unqualifiedly.
// - a flag indicating if this package is exported to all unnamed modules. // - a flag indicating if this package is exported to all unnamed modules.
// - a growable array containing other module entries that this // - a growable array containing other module entries that this
// package is exported to. // package is exported to.
// //
// Packages that are: // Packages can be exported in the following 3 ways:
// - not exported: _qualified_exports = NULL && _is_exported is false // - not exported: the package has not been explicitly qualified to a
// - qualified exports: (_qualified_exports != NULL || _is_exported_allUnnamed is true) && _is_exported is true // particular module nor has it been specified to be
// - unqualified exports: (_qualified_exports = NULL && _is_exported_allUnnamed is false) && _is_exported is true // unqualifiedly exported to all modules. If all states
// of exportedness are false, the package is considered
// not exported.
// - qualified exports: the package has been explicitly qualified to at least
// one particular module or has been qualifiedly exported
// to all unnamed modules.
// Note: _is_exported_allUnnamed is a form of a qualified
// export. It is equivalent to the package being
// explicitly exported to all current and future unnamed modules.
// - unqualified exports: the package is exported to all modules.
//
// A package can transition from:
// - being not exported, to being exported either in a qualified or unqualified manner
// - being qualifiedly exported, to unqualifiedly exported. Its exported scope is widened.
//
// A package cannot transition from:
// - being unqualifiedly exported, to exported qualifiedly to a specific module.
// This transition attempt is silently ignored in set_exported.
// //
// The Mutex Module_lock is shared between ModuleEntry and PackageEntry, to lock either // The Mutex Module_lock is shared between ModuleEntry and PackageEntry, to lock either
// data structure. // data structure.
class PackageEntry : public HashtableEntry<Symbol*, mtClass> { class PackageEntry : public HashtableEntry<Symbol*, mtModule> {
private: private:
ModuleEntry* _module; ModuleEntry* _module;
// Used to indicate for packages with classes loaded by the boot loader that // Used to indicate for packages with classes loaded by the boot loader that
@ -55,7 +71,7 @@ private:
// loaded by the boot loader from -Xbootclasspath/a in an unnamed module, it // loaded by the boot loader from -Xbootclasspath/a in an unnamed module, it
// indicates from which class path entry. // indicates from which class path entry.
s2 _classpath_index; s2 _classpath_index;
bool _is_exported; bool _is_exported_unqualified;
bool _is_exported_allUnnamed; bool _is_exported_allUnnamed;
GrowableArray<ModuleEntry*>* _exported_pending_delete; // transitioned from qualified to unqualified, delete at safepoint GrowableArray<ModuleEntry*>* _exported_pending_delete; // transitioned from qualified to unqualified, delete at safepoint
GrowableArray<ModuleEntry*>* _qualified_exports; GrowableArray<ModuleEntry*>* _qualified_exports;
@ -68,7 +84,7 @@ public:
void init() { void init() {
_module = NULL; _module = NULL;
_classpath_index = -1; _classpath_index = -1;
_is_exported = false; _is_exported_unqualified = false;
_is_exported_allUnnamed = false; _is_exported_allUnnamed = false;
_exported_pending_delete = NULL; _exported_pending_delete = NULL;
_qualified_exports = NULL; _qualified_exports = NULL;
@ -83,34 +99,41 @@ public:
void set_module(ModuleEntry* m) { _module = m; } void set_module(ModuleEntry* m) { _module = m; }
// package's export state // package's export state
bool is_exported() const { return _is_exported; } // qualifiedly or unqualifiedly exported bool is_exported() const { // qualifiedly or unqualifiedly exported
return (is_unqual_exported() || has_qual_exports_list() || is_exported_allUnnamed());
}
// Returns true if the package has any explicit qualified exports or is exported to all unnamed
bool is_qual_exported() const { bool is_qual_exported() const {
return (_is_exported && (_qualified_exports != NULL || _is_exported_allUnnamed)); return (has_qual_exports_list() || is_exported_allUnnamed());
}
// Returns true if there are any explicit qualified exports
bool has_qual_exports_list() const {
assert(!(_qualified_exports != NULL && _is_exported_unqualified),
"_qualified_exports set at same time as _is_exported_unqualified");
return (_qualified_exports != NULL);
}
bool is_exported_allUnnamed() const {
assert(!(_is_exported_allUnnamed && _is_exported_unqualified),
"_is_exported_allUnnamed set at same time as _is_exported_unqualified");
return _is_exported_allUnnamed;
} }
bool is_unqual_exported() const { bool is_unqual_exported() const {
return (_is_exported && (_qualified_exports == NULL && !_is_exported_allUnnamed)); assert(!(_qualified_exports != NULL && _is_exported_unqualified),
"_qualified_exports set at same time as _is_exported_unqualified");
assert(!(_is_exported_allUnnamed && _is_exported_unqualified),
"_is_exported_allUnnamed set at same time as _is_exported_unqualified");
return _is_exported_unqualified;
} }
void set_unqual_exported() { void set_unqual_exported() {
_is_exported = true; _is_exported_unqualified = true;
_is_exported_allUnnamed = false; _is_exported_allUnnamed = false;
_qualified_exports = NULL; _qualified_exports = NULL;
} }
bool exported_pending_delete() const { return (_exported_pending_delete != NULL); } bool exported_pending_delete() const { return (_exported_pending_delete != NULL); }
void set_exported(bool e) { _is_exported = e; }
void set_exported(ModuleEntry* m); void set_exported(ModuleEntry* m);
void set_is_exported_allUnnamed() { void set_is_exported_allUnnamed();
if (!is_unqual_exported()) {
_is_exported_allUnnamed = true;
_is_exported = true;
}
}
bool is_exported_allUnnamed() const {
assert(_is_exported || !_is_exported_allUnnamed,
"is_allUnnamed set without is_exported being set");
return _is_exported_allUnnamed;
}
void set_classpath_index(s2 classpath_index) { void set_classpath_index(s2 classpath_index) {
_classpath_index = classpath_index; _classpath_index = classpath_index;
@ -122,18 +145,18 @@ public:
// returns true if the package is defined in the unnamed module // returns true if the package is defined in the unnamed module
bool in_unnamed_module() const { return !_module->is_named(); } bool in_unnamed_module() const { return !_module->is_named(); }
// returns true if the package specifies m as a qualified export // returns true if the package specifies m as a qualified export, including through an unnamed export
bool is_qexported_to(ModuleEntry* m) const; bool is_qexported_to(ModuleEntry* m) const;
// add the module to the package's qualified exports // add the module to the package's qualified exports
void add_qexport(ModuleEntry* m); void add_qexport(ModuleEntry* m);
PackageEntry* next() const { PackageEntry* next() const {
return (PackageEntry*)HashtableEntry<Symbol*, mtClass>::next(); return (PackageEntry*)HashtableEntry<Symbol*, mtModule>::next();
} }
PackageEntry** next_addr() { PackageEntry** next_addr() {
return (PackageEntry**)HashtableEntry<Symbol*, mtClass>::next_addr(); return (PackageEntry**)HashtableEntry<Symbol*, mtModule>::next_addr();
} }
// iteration of qualified exports // iteration of qualified exports
@ -153,7 +176,7 @@ public:
// by a particular class loader. Each package is represented as a PackageEntry node. // by a particular class loader. Each package is represented as a PackageEntry node.
// The PackageEntryTable's lookup is lock free. // The PackageEntryTable's lookup is lock free.
// //
class PackageEntryTable : public Hashtable<Symbol*, mtClass> { class PackageEntryTable : public Hashtable<Symbol*, mtModule> {
friend class VMStructs; friend class VMStructs;
public: public:
enum Constants { enum Constants {
@ -164,10 +187,10 @@ private:
PackageEntry* new_entry(unsigned int hash, Symbol* name, ModuleEntry* module); PackageEntry* new_entry(unsigned int hash, Symbol* name, ModuleEntry* module);
void add_entry(int index, PackageEntry* new_entry); void add_entry(int index, PackageEntry* new_entry);
int entry_size() const { return BasicHashtable<mtClass>::entry_size(); } int entry_size() const { return BasicHashtable<mtModule>::entry_size(); }
PackageEntry** bucket_addr(int i) { PackageEntry** bucket_addr(int i) {
return (PackageEntry**)Hashtable<Symbol*, mtClass>::bucket_addr(i); return (PackageEntry**)Hashtable<Symbol*, mtModule>::bucket_addr(i);
} }
static unsigned int compute_hash(Symbol* name) { return (unsigned int)(name->identity_hash()); } static unsigned int compute_hash(Symbol* name) { return (unsigned int)(name->identity_hash()); }
@ -178,7 +201,7 @@ public:
~PackageEntryTable(); ~PackageEntryTable();
PackageEntry* bucket(int i) { PackageEntry* bucket(int i) {
return (PackageEntry*)Hashtable<Symbol*, mtClass>::bucket(i); return (PackageEntry*)Hashtable<Symbol*, mtModule>::bucket(i);
} }
// Create package in loader's package entry table and return the entry. // Create package in loader's package entry table and return the entry.

View File

@ -1336,9 +1336,12 @@ instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik,
return nh; return nh;
} }
// Found the class, now load the superclass and interfaces. If they // Resolve the superclass and interfaces. They must be the same
// are shared, add them to the main system dictionary and reset // as in dump time, because the layout of <ik> depends on
// their hierarchy references (supers, subs, and interfaces). // the specific layout of ik->super() and ik->local_interfaces().
//
// If unexpected superclass or interfaces are found, we cannot
// load <ik> from the shared archive.
if (ik->super() != NULL) { if (ik->super() != NULL) {
Symbol* cn = ik->super()->name(); Symbol* cn = ik->super()->name();
@ -1348,6 +1351,8 @@ instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik,
// The dynamically resolved super class is not the same as the one we used during dump time, // The dynamically resolved super class is not the same as the one we used during dump time,
// so we cannot use ik. // so we cannot use ik.
return nh; return nh;
} else {
assert(s->is_shared(), "must be");
} }
} }
@ -1366,6 +1371,8 @@ instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik,
// The dynamically resolved interface class is not the same as the one we used during dump time, // The dynamically resolved interface class is not the same as the one we used during dump time,
// so we cannot use ik. // so we cannot use ik.
return nh; return nh;
} else {
assert(i->is_shared(), "must be");
} }
} }

View File

@ -420,9 +420,9 @@ public:
// Initialization // Initialization
static void initialize(TRAPS); static void initialize(TRAPS);
// Fast access to commonly used classes (preloaded) // Checked fast access to commonly used classes - mostly preloaded
static InstanceKlass* check_klass(InstanceKlass* k) { static InstanceKlass* check_klass(InstanceKlass* k) {
assert(k != NULL, "preloaded klass not initialized"); assert(k != NULL, "klass not loaded");
return k; return k;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -386,15 +386,16 @@ class Bytecodes: AllStatic {
static Code non_breakpoint_code_at(const Method* method, address bcp); static Code non_breakpoint_code_at(const Method* method, address bcp);
// Bytecode attributes // Bytecode attributes
static bool is_defined (int code) { return 0 <= code && code < number_of_codes && flags(code, false) != 0; } static bool is_valid (int code) { return 0 <= code && code < number_of_codes; }
static bool is_defined (int code) { return is_valid(code) && flags(code, false) != 0; }
static bool wide_is_defined(int code) { return is_defined(code) && flags(code, true) != 0; } static bool wide_is_defined(int code) { return is_defined(code) && flags(code, true) != 0; }
static const char* name (Code code) { check(code); return _name [code]; } static const char* name (Code code) { check(code); return _name [code]; }
static BasicType result_type (Code code) { check(code); return _result_type [code]; } static BasicType result_type (Code code) { check(code); return _result_type [code]; }
static int depth (Code code) { check(code); return _depth [code]; } static int depth (Code code) { check(code); return _depth [code]; }
// Note: Length functions must return <=0 for invalid bytecodes. // Note: Length functions must return <=0 for invalid bytecodes.
// Calling check(code) in length functions would throw an unwanted assert. // Calling check(code) in length functions would throw an unwanted assert.
static int length_for (Code code) { /*no check*/ return _lengths [code] & 0xF; } static int length_for (Code code) { return is_valid(code) ? _lengths[code] & 0xF : -1; }
static int wide_length_for(Code code) { /*no check*/ return _lengths [code] >> 4; } static int wide_length_for(Code code) { return is_valid(code) ? _lengths[code] >> 4 : -1; }
static bool can_trap (Code code) { check(code); return has_all_flags(code, _bc_can_trap, false); } static bool can_trap (Code code) { check(code); return has_all_flags(code, _bc_can_trap, false); }
static Code java_code (Code code) { check(code); return _java_code [code]; } static Code java_code (Code code) { check(code); return _java_code [code]; }
static bool can_rewrite (Code code) { check(code); return has_all_flags(code, _bc_can_rewrite, false); } static bool can_rewrite (Code code) { check(code); return has_all_flags(code, _bc_can_rewrite, false); }

View File

@ -231,6 +231,7 @@ LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
// Get name, signature, and static klass // Get name, signature, and static klass
_name = pool->name_ref_at(index); _name = pool->name_ref_at(index);
_signature = pool->signature_ref_at(index); _signature = pool->signature_ref_at(index);
_tag = pool->tag_ref_at(index);
_current_klass = KlassHandle(THREAD, pool->pool_holder()); _current_klass = KlassHandle(THREAD, pool->pool_holder());
// Coming from the constant pool always checks access // Coming from the constant pool always checks access
@ -573,7 +574,7 @@ methodHandle LinkResolver::resolve_method_statically(Bytecodes::Code code,
Symbol* method_signature = pool->signature_ref_at(index); Symbol* method_signature = pool->signature_ref_at(index);
KlassHandle current_klass(THREAD, pool->pool_holder()); KlassHandle current_klass(THREAD, pool->pool_holder());
LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass); LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass);
return resolve_method(link_info, /*require_methodref*/false, THREAD); return resolve_method(link_info, code, THREAD);
} }
LinkInfo link_info(pool, index, CHECK_NULL); LinkInfo link_info(pool, index, CHECK_NULL);
@ -591,9 +592,9 @@ methodHandle LinkResolver::resolve_method_statically(Bytecodes::Code code,
if (code == Bytecodes::_invokeinterface) { if (code == Bytecodes::_invokeinterface) {
return resolve_interface_method(link_info, code, THREAD); return resolve_interface_method(link_info, code, THREAD);
} else if (code == Bytecodes::_invokevirtual) { } else if (code == Bytecodes::_invokevirtual) {
return resolve_method(link_info, /*require_methodref*/true, THREAD); return resolve_method(link_info, code, THREAD);
} else if (!resolved_klass->is_interface()) { } else if (!resolved_klass->is_interface()) {
return resolve_method(link_info, /*require_methodref*/false, THREAD); return resolve_method(link_info, code, THREAD);
} else { } else {
return resolve_interface_method(link_info, code, THREAD); return resolve_interface_method(link_info, code, THREAD);
} }
@ -663,13 +664,13 @@ void LinkResolver::check_field_loader_constraints(Symbol* field, Symbol* sig,
} }
methodHandle LinkResolver::resolve_method(const LinkInfo& link_info, methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
bool require_methodref, TRAPS) { Bytecodes::Code code, TRAPS) {
Handle nested_exception; Handle nested_exception;
KlassHandle resolved_klass = link_info.resolved_klass(); KlassHandle resolved_klass = link_info.resolved_klass();
// 1. check if methodref required, that resolved_klass is not interfacemethodref // 1. For invokevirtual, cannot call an interface method
if (require_methodref && resolved_klass->is_interface()) { if (code == Bytecodes::_invokevirtual && resolved_klass->is_interface()) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
char buf[200]; char buf[200];
jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
@ -677,11 +678,20 @@ methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
} }
// 2. lookup method in resolved klass and its super klasses // 2. check constant pool tag for called method - must be JVM_CONSTANT_Methodref
if (!link_info.tag().is_invalid() && !link_info.tag().is_method()) {
ResourceMark rm(THREAD);
char buf[200];
jio_snprintf(buf, sizeof(buf), "Method %s must be Methodref constant", link_info.method_string());
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
// 3. lookup method in resolved klass and its super klasses
methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL); methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL);
// 4. lookup method in all the interfaces implemented by the resolved klass
if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy
// 3. lookup method in all the interfaces implemented by the resolved klass
resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL); resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
if (resolved_method.is_null()) { if (resolved_method.is_null()) {
@ -694,8 +704,8 @@ methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
} }
} }
// 5. method lookup failed
if (resolved_method.is_null()) { if (resolved_method.is_null()) {
// 4. method lookup failed
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
THROW_MSG_CAUSE_(vmSymbols::java_lang_NoSuchMethodError(), THROW_MSG_CAUSE_(vmSymbols::java_lang_NoSuchMethodError(),
Method::name_and_sig_as_C_string(resolved_klass(), Method::name_and_sig_as_C_string(resolved_klass(),
@ -704,7 +714,7 @@ methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
nested_exception, NULL); nested_exception, NULL);
} }
// 5. access checks, access checking may be turned off when calling from within the VM. // 6. access checks, access checking may be turned off when calling from within the VM.
KlassHandle current_klass = link_info.current_klass(); KlassHandle current_klass = link_info.current_klass();
if (link_info.check_access()) { if (link_info.check_access()) {
assert(current_klass.not_null() , "current_klass should not be null"); assert(current_klass.not_null() , "current_klass should not be null");
@ -766,6 +776,14 @@ methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info, B
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
} }
// check constant pool tag for called method - must be JVM_CONSTANT_InterfaceMethodref
if (!link_info.tag().is_invalid() && !link_info.tag().is_interface_method()) {
ResourceMark rm(THREAD);
char buf[200];
jio_snprintf(buf, sizeof(buf), "Method %s must be InterfaceMethodref constant", link_info.method_string());
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
// lookup method in this interface or its super, java.lang.Object // lookup method in this interface or its super, java.lang.Object
// JDK8: also look for static methods // JDK8: also look for static methods
methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL); methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
@ -948,19 +966,18 @@ void LinkResolver::resolve_static_call(CallInfo& result,
methodHandle resolved_method = linktime_resolve_static_method(link_info, CHECK); methodHandle resolved_method = linktime_resolve_static_method(link_info, CHECK);
// The resolved class can change as a result of this resolution. // The resolved class can change as a result of this resolution.
KlassHandle resolved_klass = KlassHandle(THREAD, resolved_method->method_holder()); KlassHandle resolved_klass(THREAD, resolved_method->method_holder());
Method* save_resolved_method = resolved_method();
// Initialize klass (this should only happen if everything is ok) // Initialize klass (this should only happen if everything is ok)
if (initialize_class && resolved_klass->should_be_initialized()) { if (initialize_class && resolved_klass->should_be_initialized()) {
resolved_klass->initialize(CHECK); resolved_klass->initialize(CHECK);
// Use updated LinkInfo (to reresolve with resolved_klass as method_holder?) // Use updated LinkInfo to reresolve with resolved method holder
LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(), LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
link_info.current_klass(), link_info.check_access()); link_info.current_klass(),
link_info.check_access() ? LinkInfo::needs_access_check : LinkInfo::skip_access_check);
resolved_method = linktime_resolve_static_method(new_info, CHECK); resolved_method = linktime_resolve_static_method(new_info, CHECK);
} }
assert(save_resolved_method == resolved_method(), "does this change?");
// setup result // setup result
result.set_static(resolved_klass, resolved_method, CHECK); result.set_static(resolved_klass, resolved_method, CHECK);
} }
@ -971,7 +988,7 @@ methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_i
KlassHandle resolved_klass = link_info.resolved_klass(); KlassHandle resolved_klass = link_info.resolved_klass();
methodHandle resolved_method; methodHandle resolved_method;
if (!resolved_klass->is_interface()) { if (!resolved_klass->is_interface()) {
resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL); resolved_method = resolve_method(link_info, Bytecodes::_invokestatic, CHECK_NULL);
} else { } else {
resolved_method = resolve_interface_method(link_info, Bytecodes::_invokestatic, CHECK_NULL); resolved_method = resolve_interface_method(link_info, Bytecodes::_invokestatic, CHECK_NULL);
} }
@ -1014,7 +1031,7 @@ methodHandle LinkResolver::linktime_resolve_special_method(const LinkInfo& link_
methodHandle resolved_method; methodHandle resolved_method;
if (!resolved_klass->is_interface()) { if (!resolved_klass->is_interface()) {
resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL); resolved_method = resolve_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
} else { } else {
resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL); resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
} }
@ -1164,7 +1181,7 @@ void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHand
methodHandle LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_info, methodHandle LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_info,
TRAPS) { TRAPS) {
// normal method resolution // normal method resolution
methodHandle resolved_method = resolve_method(link_info, /*require_methodref*/true, CHECK_NULL); methodHandle resolved_method = resolve_method(link_info, Bytecodes::_invokevirtual, CHECK_NULL);
assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
@ -1173,6 +1190,7 @@ methodHandle LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_
KlassHandle resolved_klass = link_info.resolved_klass(); KlassHandle resolved_klass = link_info.resolved_klass();
KlassHandle current_klass = link_info.current_klass(); KlassHandle current_klass = link_info.current_klass();
// This is impossible, if resolve_klass is an interface, we've thrown icce in resolve_method
if (resolved_klass->is_interface() && resolved_method->is_private()) { if (resolved_klass->is_interface() && resolved_method->is_private()) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
char buf[200]; char buf[200];
@ -1482,7 +1500,7 @@ void LinkResolver::resolve_invoke(CallInfo& result, Handle& recv,
KlassHandle defc = attached_method->method_holder(); KlassHandle defc = attached_method->method_holder();
Symbol* name = attached_method->name(); Symbol* name = attached_method->name();
Symbol* type = attached_method->signature(); Symbol* type = attached_method->signature();
LinkInfo link_info(defc, name, type, KlassHandle(), /*check_access=*/false); LinkInfo link_info(defc, name, type);
switch(byte) { switch(byte) {
case Bytecodes::_invokevirtual: case Bytecodes::_invokevirtual:
resolve_virtual_call(result, recv, recv->klass(), link_info, resolve_virtual_call(result, recv, recv->klass(), link_info,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -137,20 +137,35 @@ class LinkInfo : public StackObj {
KlassHandle _resolved_klass; // class that the constant pool entry points to KlassHandle _resolved_klass; // class that the constant pool entry points to
KlassHandle _current_klass; // class that owns the constant pool KlassHandle _current_klass; // class that owns the constant pool
bool _check_access; bool _check_access;
constantTag _tag;
public: public:
enum AccessCheck {
needs_access_check,
skip_access_check
};
LinkInfo(const constantPoolHandle& pool, int index, TRAPS); LinkInfo(const constantPoolHandle& pool, int index, TRAPS);
// Condensed information from other call sites within the vm. // Condensed information from other call sites within the vm.
LinkInfo(KlassHandle resolved_klass, Symbol* name, Symbol* signature, LinkInfo(KlassHandle resolved_klass, Symbol* name, Symbol* signature, KlassHandle current_klass,
KlassHandle current_klass, bool check_access = true) : AccessCheck check_access = needs_access_check,
constantTag tag = JVM_CONSTANT_Invalid) :
_resolved_klass(resolved_klass), _resolved_klass(resolved_klass),
_name(name), _signature(signature), _current_klass(current_klass), _name(name), _signature(signature), _current_klass(current_klass),
_check_access(check_access) {} _check_access(check_access == needs_access_check), _tag(tag) {}
// Case where we just find the method and don't check access against the current class
LinkInfo(KlassHandle resolved_klass, Symbol*name, Symbol* signature) :
_resolved_klass(resolved_klass),
_name(name), _signature(signature), _current_klass(NULL),
_check_access(false), _tag(JVM_CONSTANT_Invalid) {}
// accessors // accessors
Symbol* name() const { return _name; } Symbol* name() const { return _name; }
Symbol* signature() const { return _signature; } Symbol* signature() const { return _signature; }
KlassHandle resolved_klass() const { return _resolved_klass; } KlassHandle resolved_klass() const { return _resolved_klass; }
KlassHandle current_klass() const { return _current_klass; } KlassHandle current_klass() const { return _current_klass; }
constantTag tag() const { return _tag; }
bool check_access() const { return _check_access; } bool check_access() const { return _check_access; }
char* method_string() const; char* method_string() const;
@ -192,7 +207,7 @@ class LinkResolver: AllStatic {
KlassHandle sel_klass, TRAPS); KlassHandle sel_klass, TRAPS);
static methodHandle resolve_interface_method(const LinkInfo& link_info, Bytecodes::Code code, TRAPS); static methodHandle resolve_interface_method(const LinkInfo& link_info, Bytecodes::Code code, TRAPS);
static methodHandle resolve_method (const LinkInfo& link_info, bool require_methodref, TRAPS); static methodHandle resolve_method (const LinkInfo& link_info, Bytecodes::Code code, TRAPS);
static methodHandle linktime_resolve_static_method (const LinkInfo& link_info, TRAPS); static methodHandle linktime_resolve_static_method (const LinkInfo& link_info, TRAPS);
static methodHandle linktime_resolve_special_method (const LinkInfo& link_info, TRAPS); static methodHandle linktime_resolve_special_method (const LinkInfo& link_info, TRAPS);

View File

@ -661,8 +661,7 @@ C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject receiver_jvmci_t
Symbol* h_name = method->name(); Symbol* h_name = method->name();
Symbol* h_signature = method->signature(); Symbol* h_signature = method->signature();
bool check_access = true; LinkInfo link_info(h_resolved, h_name, h_signature, caller_klass);
LinkInfo link_info(h_resolved, h_name, h_signature, caller_klass, check_access);
methodHandle m; methodHandle m;
// Only do exact lookup if receiver klass has been linked. Otherwise, // Only do exact lookup if receiver klass has been linked. Otherwise,
// the vtable has not been setup, and the LinkResolver will fail. // the vtable has not been setup, and the LinkResolver will fail.

View File

@ -286,11 +286,12 @@ methodHandle JVMCIEnv::lookup_method(instanceKlassHandle h_accessor,
instanceKlassHandle h_holder, instanceKlassHandle h_holder,
Symbol* name, Symbol* name,
Symbol* sig, Symbol* sig,
Bytecodes::Code bc) { Bytecodes::Code bc,
constantTag tag) {
JVMCI_EXCEPTION_CONTEXT; JVMCI_EXCEPTION_CONTEXT;
LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL)); LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL));
methodHandle dest_method; methodHandle dest_method;
LinkInfo link_info(h_holder, name, sig, h_accessor, /*check_access*/true); LinkInfo link_info(h_holder, name, sig, h_accessor, LinkInfo::needs_access_check, tag);
switch (bc) { switch (bc) {
case Bytecodes::_invokestatic: case Bytecodes::_invokestatic:
dest_method = dest_method =
@ -363,7 +364,8 @@ methodHandle JVMCIEnv::get_method_by_index_impl(const constantPoolHandle& cpool,
if (holder_is_accessible) { // Our declared holder is loaded. if (holder_is_accessible) { // Our declared holder is loaded.
instanceKlassHandle lookup = get_instance_klass_for_declared_method_holder(holder); instanceKlassHandle lookup = get_instance_klass_for_declared_method_holder(holder);
methodHandle m = lookup_method(accessor, lookup, name_sym, sig_sym, bc); constantTag tag = cpool->tag_ref_at(index);
methodHandle m = lookup_method(accessor, lookup, name_sym, sig_sym, bc, tag);
if (!m.is_null() && if (!m.is_null() &&
(bc == Bytecodes::_invokestatic (bc == Bytecodes::_invokestatic
? InstanceKlass::cast(m->method_holder())->is_not_initialized() ? InstanceKlass::cast(m->method_holder())->is_not_initialized()

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -130,7 +130,8 @@ private:
instanceKlassHandle holder, instanceKlassHandle holder,
Symbol* name, Symbol* name,
Symbol* sig, Symbol* sig,
Bytecodes::Code bc); Bytecodes::Code bc,
constantTag tag);
private: private:

View File

@ -415,7 +415,9 @@ void LogConfiguration::describe_available(outputStream* out){
void LogConfiguration::describe_current_configuration(outputStream* out){ void LogConfiguration::describe_current_configuration(outputStream* out){
out->print_cr("Log output configuration:"); out->print_cr("Log output configuration:");
for (size_t i = 0; i < _n_outputs; i++) { for (size_t i = 0; i < _n_outputs; i++) {
out->print("#" SIZE_FORMAT ": %s %s ", i, _outputs[i]->name(), _outputs[i]->config_string()); out->print("#" SIZE_FORMAT ": %s ", i, _outputs[i]->name());
out->print_raw(_outputs[i]->config_string());
out->print(" ");
char delimiter[2] = {0}; char delimiter[2] = {0};
for (size_t d = 0; d < LogDecorators::Count; d++) { for (size_t d = 0; d < LogDecorators::Count; d++) {
LogDecorators::Decorator decorator = static_cast<LogDecorators::Decorator>(d); LogDecorators::Decorator decorator = static_cast<LogDecorators::Decorator>(d);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -144,8 +144,9 @@ enum MemoryType {
mtTracing = 0x0E, // memory used for Tracing mtTracing = 0x0E, // memory used for Tracing
mtLogging = 0x0F, // memory for logging mtLogging = 0x0F, // memory for logging
mtArguments = 0x10, // memory for argument processing mtArguments = 0x10, // memory for argument processing
mtNone = 0x11, // undefined mtModule = 0x11, // memory for module processing
mt_number_of_types = 0x12 // number of memory types (mtDontTrack mtNone = 0x12, // undefined
mt_number_of_types = 0x13 // number of memory types (mtDontTrack
// is not included as validate type) // is not included as validate type)
}; };

View File

@ -191,7 +191,12 @@ static void rewrite_nofast_bytecode(Method* method) {
case Bytecodes::_getfield: *bcs.bcp() = Bytecodes::_nofast_getfield; break; case Bytecodes::_getfield: *bcs.bcp() = Bytecodes::_nofast_getfield; break;
case Bytecodes::_putfield: *bcs.bcp() = Bytecodes::_nofast_putfield; break; case Bytecodes::_putfield: *bcs.bcp() = Bytecodes::_nofast_putfield; break;
case Bytecodes::_aload_0: *bcs.bcp() = Bytecodes::_nofast_aload_0; break; case Bytecodes::_aload_0: *bcs.bcp() = Bytecodes::_nofast_aload_0; break;
case Bytecodes::_iload: *bcs.bcp() = Bytecodes::_nofast_iload; break; case Bytecodes::_iload: {
if (!bcs.is_wide()) {
*bcs.bcp() = Bytecodes::_nofast_iload;
}
break;
}
default: break; default: break;
} }
} }

View File

@ -417,6 +417,19 @@ int ConstantPool::impl_name_and_type_ref_index_at(int which, bool uncached) {
return extract_high_short_from_int(ref_index); return extract_high_short_from_int(ref_index);
} }
constantTag ConstantPool::impl_tag_ref_at(int which, bool uncached) {
int pool_index = which;
if (!uncached && cache() != NULL) {
if (ConstantPool::is_invokedynamic_index(which)) {
// Invokedynamic index is index into resolved_references
pool_index = invokedynamic_cp_cache_entry_at(which)->constant_pool_index();
} else {
// change byte-ordering and go via cache
pool_index = remap_instruction_operand_from_cache(which);
}
}
return tag_at(pool_index);
}
int ConstantPool::impl_klass_ref_index_at(int which, bool uncached) { int ConstantPool::impl_klass_ref_index_at(int which, bool uncached) {
guarantee(!ConstantPool::is_invokedynamic_index(which), guarantee(!ConstantPool::is_invokedynamic_index(which),
@ -672,6 +685,7 @@ oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp, in
int callee_index = this_cp->method_handle_klass_index_at(index); int callee_index = this_cp->method_handle_klass_index_at(index);
Symbol* name = this_cp->method_handle_name_ref_at(index); Symbol* name = this_cp->method_handle_name_ref_at(index);
Symbol* signature = this_cp->method_handle_signature_ref_at(index); Symbol* signature = this_cp->method_handle_signature_ref_at(index);
constantTag m_tag = this_cp->tag_at(this_cp->method_handle_index_at(index));
{ ResourceMark rm(THREAD); { ResourceMark rm(THREAD);
log_debug(class, resolve)("resolve JVM_CONSTANT_MethodHandle:%d [%d/%d/%d] %s.%s", log_debug(class, resolve)("resolve JVM_CONSTANT_MethodHandle:%d [%d/%d/%d] %s.%s",
ref_kind, index, this_cp->method_handle_index_at(index), ref_kind, index, this_cp->method_handle_index_at(index),
@ -681,6 +695,15 @@ oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp, in
{ Klass* k = klass_at_impl(this_cp, callee_index, true, CHECK_NULL); { Klass* k = klass_at_impl(this_cp, callee_index, true, CHECK_NULL);
callee = KlassHandle(THREAD, k); callee = KlassHandle(THREAD, k);
} }
if ((callee->is_interface() && m_tag.is_method()) ||
(!callee->is_interface() && m_tag.is_interface_method())) {
ResourceMark rm(THREAD);
char buf[200];
jio_snprintf(buf, sizeof(buf), "Inconsistent constant data for %s.%s%s at index %d",
callee->name()->as_C_string(), name->as_C_string(), signature->as_C_string(), index);
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
KlassHandle klass(THREAD, this_cp->pool_holder()); KlassHandle klass(THREAD, this_cp->pool_holder());
Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind, Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind,
callee, name, signature, callee, name, signature,

View File

@ -643,6 +643,8 @@ class ConstantPool : public Metadata {
int remap_instruction_operand_from_cache(int operand); // operand must be biased by CPCACHE_INDEX_TAG int remap_instruction_operand_from_cache(int operand); // operand must be biased by CPCACHE_INDEX_TAG
constantTag tag_ref_at(int cp_cache_index) { return impl_tag_ref_at(cp_cache_index, false); }
// Lookup for entries consisting of (name_index, signature_index) // Lookup for entries consisting of (name_index, signature_index)
int name_ref_index_at(int which_nt); // == low-order jshort of name_and_type_at(which_nt) int name_ref_index_at(int which_nt); // == low-order jshort of name_and_type_at(which_nt)
int signature_ref_index_at(int which_nt); // == high-order jshort of name_and_type_at(which_nt) int signature_ref_index_at(int which_nt); // == high-order jshort of name_and_type_at(which_nt)
@ -763,6 +765,7 @@ class ConstantPool : public Metadata {
Symbol* impl_signature_ref_at(int which, bool uncached); Symbol* impl_signature_ref_at(int which, bool uncached);
int impl_klass_ref_index_at(int which, bool uncached); int impl_klass_ref_index_at(int which, bool uncached);
int impl_name_and_type_ref_index_at(int which, bool uncached); int impl_name_and_type_ref_index_at(int which, bool uncached);
constantTag impl_tag_ref_at(int which, bool uncached);
// Used while constructing constant pool (only by ClassFileParser) // Used while constructing constant pool (only by ClassFileParser)
jint klass_index_at(int which) { jint klass_index_at(int which) {

View File

@ -1104,21 +1104,21 @@ void InstanceKlass::call_class_initializer_impl(instanceKlassHandle this_k, TRAP
void InstanceKlass::mask_for(const methodHandle& method, int bci, void InstanceKlass::mask_for(const methodHandle& method, int bci,
InterpreterOopMap* entry_for) { InterpreterOopMap* entry_for) {
// Dirty read, then double-check under a lock. // Lazily create the _oop_map_cache at first request
if (_oop_map_cache == NULL) { // Lock-free access requires load_ptr_acquire.
// Otherwise, allocate a new one. OopMapCache* oop_map_cache =
static_cast<OopMapCache*>(OrderAccess::load_ptr_acquire(&_oop_map_cache));
if (oop_map_cache == NULL) {
MutexLocker x(OopMapCacheAlloc_lock); MutexLocker x(OopMapCacheAlloc_lock);
// First time use. Allocate a cache in C heap // Check if _oop_map_cache was allocated while we were waiting for this lock
if (_oop_map_cache == NULL) { if ((oop_map_cache = _oop_map_cache) == NULL) {
// Release stores from OopMapCache constructor before assignment oop_map_cache = new OopMapCache();
// to _oop_map_cache. C++ compilers on ppc do not emit the // Ensure _oop_map_cache is stable, since it is examined without a lock
// required memory barrier only because of the volatile OrderAccess::release_store_ptr(&_oop_map_cache, oop_map_cache);
// qualifier of _oop_map_cache.
OrderAccess::release_store_ptr(&_oop_map_cache, new OopMapCache());
} }
} }
// _oop_map_cache is constant after init; lookup below does is own locking. // _oop_map_cache is constant after init; lookup below does its own locking.
_oop_map_cache->lookup(method, bci, entry_for); oop_map_cache->lookup(method, bci, entry_for);
} }

View File

@ -713,12 +713,16 @@ Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS
TempNewSymbol type = lookup_signature(type_str(), (mh_invoke_id != vmIntrinsics::_none), CHECK_(empty)); TempNewSymbol type = lookup_signature(type_str(), (mh_invoke_id != vmIntrinsics::_none), CHECK_(empty));
if (type == NULL) return empty; // no such signature exists in the VM if (type == NULL) return empty; // no such signature exists in the VM
LinkInfo::AccessCheck access_check = caller.not_null() ?
LinkInfo::needs_access_check :
LinkInfo::skip_access_check;
// Time to do the lookup. // Time to do the lookup.
switch (flags & ALL_KINDS) { switch (flags & ALL_KINDS) {
case IS_METHOD: case IS_METHOD:
{ {
CallInfo result; CallInfo result;
LinkInfo link_info(defc, name, type, caller, caller.not_null()); LinkInfo link_info(defc, name, type, caller, access_check);
{ {
assert(!HAS_PENDING_EXCEPTION, ""); assert(!HAS_PENDING_EXCEPTION, "");
if (ref_kind == JVM_REF_invokeStatic) { if (ref_kind == JVM_REF_invokeStatic) {
@ -755,7 +759,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS
case IS_CONSTRUCTOR: case IS_CONSTRUCTOR:
{ {
CallInfo result; CallInfo result;
LinkInfo link_info(defc, name, type, caller, caller.not_null()); LinkInfo link_info(defc, name, type, caller, access_check);
{ {
assert(!HAS_PENDING_EXCEPTION, ""); assert(!HAS_PENDING_EXCEPTION, "");
if (name == vmSymbols::object_initializer_name()) { if (name == vmSymbols::object_initializer_name()) {
@ -776,7 +780,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS
fieldDescriptor result; // find_field initializes fd if found fieldDescriptor result; // find_field initializes fd if found
{ {
assert(!HAS_PENDING_EXCEPTION, ""); assert(!HAS_PENDING_EXCEPTION, "");
LinkInfo link_info(defc, name, type, caller, /*check_access*/false); LinkInfo link_info(defc, name, type, caller, LinkInfo::skip_access_check);
LinkResolver::resolve_field(result, link_info, Bytecodes::_nop, false, THREAD); LinkResolver::resolve_field(result, link_info, Bytecodes::_nop, false, THREAD);
if (HAS_PENDING_EXCEPTION) { if (HAS_PENDING_EXCEPTION) {
return empty; return empty;

View File

@ -278,6 +278,49 @@ WB_ENTRY(jint, WB_StressVirtualSpaceResize(JNIEnv* env, jobject o,
(size_t) magnitude, (size_t) iterations); (size_t) magnitude, (size_t) iterations);
WB_END WB_END
static const jint serial_code = 1;
static const jint parallel_code = 2;
static const jint cms_code = 4;
static const jint g1_code = 8;
WB_ENTRY(jint, WB_CurrentGC(JNIEnv* env, jobject o, jobject obj))
if (UseSerialGC) {
return serial_code;
} else if (UseParallelGC || UseParallelOldGC) {
return parallel_code;
} if (UseConcMarkSweepGC) {
return cms_code;
} else if (UseG1GC) {
return g1_code;
}
ShouldNotReachHere();
return 0;
WB_END
WB_ENTRY(jint, WB_AllSupportedGC(JNIEnv* env, jobject o, jobject obj))
#if INCLUDE_ALL_GCS
return serial_code | parallel_code | cms_code | g1_code;
#else
return serial_code;
#endif // INCLUDE_ALL_GCS
WB_END
WB_ENTRY(jboolean, WB_GCSelectedByErgo(JNIEnv* env, jobject o, jobject obj))
if (UseSerialGC) {
return FLAG_IS_ERGO(UseSerialGC);
} else if (UseParallelGC) {
return FLAG_IS_ERGO(UseParallelGC);
} else if (UseParallelOldGC) {
return FLAG_IS_ERGO(UseParallelOldGC);
} else if (UseConcMarkSweepGC) {
return FLAG_IS_ERGO(UseConcMarkSweepGC);
} else if (UseG1GC) {
return FLAG_IS_ERGO(UseG1GC);
}
ShouldNotReachHere();
return false;
WB_END
WB_ENTRY(jboolean, WB_isObjectInOldGen(JNIEnv* env, jobject o, jobject obj)) WB_ENTRY(jboolean, WB_isObjectInOldGen(JNIEnv* env, jobject o, jobject obj))
oop p = JNIHandles::resolve(obj); oop p = JNIHandles::resolve(obj);
#if INCLUDE_ALL_GCS #if INCLUDE_ALL_GCS
@ -1834,6 +1877,9 @@ static JNINativeMethod methods[] = {
{CC"addCompilerDirective", CC"(Ljava/lang/String;)I", {CC"addCompilerDirective", CC"(Ljava/lang/String;)I",
(void*)&WB_AddCompilerDirective }, (void*)&WB_AddCompilerDirective },
{CC"removeCompilerDirective", CC"(I)V", (void*)&WB_RemoveCompilerDirective }, {CC"removeCompilerDirective", CC"(I)V", (void*)&WB_RemoveCompilerDirective },
{CC"currentGC", CC"()I", (void*)&WB_CurrentGC},
{CC"allSupportedGC", CC"()I", (void*)&WB_AllSupportedGC},
{CC"gcSelectedByErgo", CC"()Z", (void*)&WB_GCSelectedByErgo},
}; };
#undef CC #undef CC

View File

@ -183,7 +183,7 @@ void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol*
CallInfo callinfo; CallInfo callinfo;
Handle receiver = args->receiver(); Handle receiver = args->receiver();
KlassHandle recvrKlass(THREAD, receiver.is_null() ? (Klass*)NULL : receiver->klass()); KlassHandle recvrKlass(THREAD, receiver.is_null() ? (Klass*)NULL : receiver->klass());
LinkInfo link_info(spec_klass, name, signature, KlassHandle(), /*check_access*/false); LinkInfo link_info(spec_klass, name, signature);
LinkResolver::resolve_virtual_call( LinkResolver::resolve_virtual_call(
callinfo, receiver, recvrKlass, link_info, true, CHECK); callinfo, receiver, recvrKlass, link_info, true, CHECK);
methodHandle method = callinfo.selected_method(); methodHandle method = callinfo.selected_method();
@ -220,7 +220,7 @@ void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spe
void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
CallInfo callinfo; CallInfo callinfo;
LinkInfo link_info(klass, name, signature, KlassHandle(), /*check_access*/false); LinkInfo link_info(klass, name, signature);
LinkResolver::resolve_special_call(callinfo, link_info, CHECK); LinkResolver::resolve_special_call(callinfo, link_info, CHECK);
methodHandle method = callinfo.selected_method(); methodHandle method = callinfo.selected_method();
assert(method.not_null(), "should have thrown exception"); assert(method.not_null(), "should have thrown exception");
@ -255,7 +255,7 @@ void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle kla
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
CallInfo callinfo; CallInfo callinfo;
LinkInfo link_info(klass, name, signature, KlassHandle(), /*check_access*/false); LinkInfo link_info(klass, name, signature);
LinkResolver::resolve_static_call(callinfo, link_info, true, CHECK); LinkResolver::resolve_static_call(callinfo, link_info, true, CHECK);
methodHandle method = callinfo.selected_method(); methodHandle method = callinfo.selected_method();
assert(method.not_null(), "should have thrown exception"); assert(method.not_null(), "should have thrown exception");

View File

@ -1336,12 +1336,10 @@ bool os::stack_shadow_pages_available(Thread *thread, const methodHandle& method
const int framesize_in_bytes = const int framesize_in_bytes =
Interpreter::size_top_interpreter_activation(method()) * wordSize; Interpreter::size_top_interpreter_activation(method()) * wordSize;
assert((thread->stack_base() - thread->stack_size()) + address limit = ((JavaThread*)thread)->stack_end() +
(JavaThread::stack_guard_zone_size() + (JavaThread::stack_guard_zone_size() + JavaThread::stack_shadow_zone_size());
JavaThread::stack_shadow_zone_size() + framesize_in_bytes) ==
((JavaThread*)thread)->stack_overflow_limit() + framesize_in_bytes, "sanity");
return (sp > ((JavaThread*)thread)->stack_overflow_limit() + framesize_in_bytes); return sp > (limit + framesize_in_bytes);
} }
size_t os::page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned) { size_t os::page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned) {

View File

@ -998,7 +998,7 @@ static methodHandle resolve_interface_call(instanceKlassHandle klass,
Symbol* signature = method->signature(); Symbol* signature = method->signature();
Symbol* name = method->name(); Symbol* name = method->name();
LinkResolver::resolve_interface_call(info, receiver, recv_klass, LinkResolver::resolve_interface_call(info, receiver, recv_klass,
LinkInfo(klass, name, signature, KlassHandle(), false), LinkInfo(klass, name, signature),
true, true,
CHECK_(methodHandle())); CHECK_(methodHandle()));
return info.selected_method(); return info.selected_method();

View File

@ -1371,10 +1371,10 @@ class JavaThread: public Thread {
// | reserved pages | // | reserved pages |
// | | // | |
// -- <-- stack_reserved_zone_base() --- --- // -- <-- stack_reserved_zone_base() --- ---
// /|\ shadow // /|\ shadow <-- stack_overflow_limit() (somewhere in here)
// | zone // | zone
// \|/ size // \|/ size
// some untouched memory --- <-- stack_overflow_limit() // some untouched memory ---
// //
// //
// -- // --
@ -1522,9 +1522,8 @@ class JavaThread: public Thread {
address stack_overflow_limit() { return _stack_overflow_limit; } address stack_overflow_limit() { return _stack_overflow_limit; }
void set_stack_overflow_limit() { void set_stack_overflow_limit() {
_stack_overflow_limit = stack_end() + _stack_overflow_limit =
(JavaThread::stack_guard_zone_size() + stack_end() + MAX2(JavaThread::stack_guard_zone_size(), JavaThread::stack_shadow_zone_size());
JavaThread::stack_shadow_zone_size());
} }
// Misc. accessors/mutators // Misc. accessors/mutators

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -201,10 +201,12 @@ void VM_Verify::doit() {
} }
bool VM_PrintThreads::doit_prologue() { bool VM_PrintThreads::doit_prologue() {
assert(Thread::current()->is_Java_thread(), "just checking");
// Make sure AbstractOwnableSynchronizer is loaded // Make sure AbstractOwnableSynchronizer is loaded
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current()); JavaThread* jt = JavaThread::current();
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(jt);
if (jt->has_pending_exception()) {
return false;
}
// Get Heap_lock if concurrent locks will be dumped // Get Heap_lock if concurrent locks will be dumped
if (_print_concurrent_locks) { if (_print_concurrent_locks) {
@ -240,11 +242,13 @@ VM_FindDeadlocks::~VM_FindDeadlocks() {
} }
bool VM_FindDeadlocks::doit_prologue() { bool VM_FindDeadlocks::doit_prologue() {
assert(Thread::current()->is_Java_thread(), "just checking");
// Load AbstractOwnableSynchronizer class
if (_concurrent_locks) { if (_concurrent_locks) {
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current()); // Make sure AbstractOwnableSynchronizer is loaded
JavaThread* jt = JavaThread::current();
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(jt);
if (jt->has_pending_exception()) {
return false;
}
} }
return true; return true;
@ -298,10 +302,12 @@ VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result,
} }
bool VM_ThreadDump::doit_prologue() { bool VM_ThreadDump::doit_prologue() {
assert(Thread::current()->is_Java_thread(), "just checking"); // Make sure AbstractOwnableSynchronizer is loaded
JavaThread* jt = JavaThread::current();
// Load AbstractOwnableSynchronizer class before taking thread snapshots java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(jt);
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current()); if (jt->has_pending_exception()) {
return false;
}
if (_with_locked_synchronizers) { if (_with_locked_synchronizers) {
// Acquire Heap_lock to dump concurrent locks // Acquire Heap_lock to dump concurrent locks

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -42,6 +42,7 @@ const char* NMTUtil::_memory_type_names[] = {
"Tracing", "Tracing",
"Logging", "Logging",
"Arguments", "Arguments",
"Module",
"Unknown" "Unknown"
}; };

View File

@ -23,7 +23,10 @@
*/ */
#include "precompiled.hpp" #include "precompiled.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/os.hpp"
#include "runtime/threadCritical.hpp" #include "runtime/threadCritical.hpp"
#include "services/memTracker.hpp"
#include "services/virtualMemoryTracker.hpp" #include "services/virtualMemoryTracker.hpp"
size_t VirtualMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(VirtualMemorySnapshot, size_t)]; size_t VirtualMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(VirtualMemorySnapshot, size_t)];
@ -52,46 +55,41 @@ bool ReservedMemoryRegion::add_committed_region(address addr, size_t size, const
if (all_committed()) return true; if (all_committed()) return true;
CommittedMemoryRegion committed_rgn(addr, size, stack); CommittedMemoryRegion committed_rgn(addr, size, stack);
LinkedListNode<CommittedMemoryRegion>* node = _committed_regions.find_node(committed_rgn); LinkedListNode<CommittedMemoryRegion>* node = _committed_regions.head();
if (node != NULL) {
while (node != NULL) {
CommittedMemoryRegion* rgn = node->data(); CommittedMemoryRegion* rgn = node->data();
if (rgn->same_region(addr, size)) { if (rgn->same_region(addr, size)) {
return true; return true;
} }
if (rgn->adjacent_to(addr, size)) { if (rgn->adjacent_to(addr, size)) {
// check if the next region covers this committed region, // special case to expand prior region if there is no next region
// the regions may not be merged due to different call stacks LinkedListNode<CommittedMemoryRegion>* next = node->next();
LinkedListNode<CommittedMemoryRegion>* next = if (next == NULL && rgn->call_stack()->equals(stack)) {
node->next();
if (next != NULL && next->data()->contain_region(addr, size)) {
if (next->data()->same_region(addr, size)) {
next->data()->set_call_stack(stack);
}
return true;
}
if (rgn->call_stack()->equals(stack)) {
VirtualMemorySummary::record_uncommitted_memory(rgn->size(), flag()); VirtualMemorySummary::record_uncommitted_memory(rgn->size(), flag());
// the two adjacent regions have the same call stack, merge them // the two adjacent regions have the same call stack, merge them
rgn->expand_region(addr, size); rgn->expand_region(addr, size);
VirtualMemorySummary::record_committed_memory(rgn->size(), flag()); VirtualMemorySummary::record_committed_memory(rgn->size(), flag());
return true; return true;
} }
VirtualMemorySummary::record_committed_memory(size, flag());
if (rgn->base() > addr) {
return _committed_regions.insert_before(committed_rgn, node) != NULL;
} else {
return _committed_regions.insert_after(committed_rgn, node) != NULL;
} }
if (rgn->overlap_region(addr, size)) {
// Clear a space for this region in the case it overlaps with any regions.
remove_uncommitted_region(addr, size);
break; // commit below
} }
assert(rgn->contain_region(addr, size), "Must cover this region"); if (rgn->end() >= addr + size){
return true; break;
} else { }
node = node->next();
}
// New committed region // New committed region
VirtualMemorySummary::record_committed_memory(size, flag()); VirtualMemorySummary::record_committed_memory(size, flag());
return add_committed_region(committed_rgn); return add_committed_region(committed_rgn);
} }
}
void ReservedMemoryRegion::set_all_committed(bool b) { void ReservedMemoryRegion::set_all_committed(bool b) {
if (all_committed() != b) { if (all_committed() != b) {
@ -175,48 +173,52 @@ bool ReservedMemoryRegion::remove_uncommitted_region(address addr, size_t sz) {
} }
} }
} else { } else {
// we have to walk whole list to remove the committed regions in CommittedMemoryRegion del_rgn(addr, sz, *call_stack());
// specified range address end = addr + sz;
LinkedListNode<CommittedMemoryRegion>* head =
_committed_regions.head();
LinkedListNode<CommittedMemoryRegion>* prev = NULL;
VirtualMemoryRegion uncommitted_rgn(addr, sz);
while (head != NULL && !uncommitted_rgn.is_empty()) { LinkedListNode<CommittedMemoryRegion>* head = _committed_regions.head();
CommittedMemoryRegion* crgn = head->data(); LinkedListNode<CommittedMemoryRegion>* prev = NULL;
// this committed region overlaps to region to uncommit CommittedMemoryRegion* crgn;
if (crgn->overlap_region(uncommitted_rgn.base(), uncommitted_rgn.size())) {
if (crgn->same_region(uncommitted_rgn.base(), uncommitted_rgn.size())) { while (head != NULL) {
// find matched region, remove the node will do crgn = head->data();
VirtualMemorySummary::record_uncommitted_memory(uncommitted_rgn.size(), flag());
if (crgn->same_region(addr, sz)) {
VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
_committed_regions.remove_after(prev); _committed_regions.remove_after(prev);
return true; return true;
} else if (crgn->contain_region(uncommitted_rgn.base(), uncommitted_rgn.size())) { }
// this committed region contains whole uncommitted region
VirtualMemorySummary::record_uncommitted_memory(uncommitted_rgn.size(), flag()); // del_rgn contains crgn
return remove_uncommitted_region(head, uncommitted_rgn.base(), uncommitted_rgn.size()); if (del_rgn.contain_region(crgn->base(), crgn->size())) {
} else if (uncommitted_rgn.contain_region(crgn->base(), crgn->size())) {
// this committed region has been uncommitted
size_t exclude_size = crgn->end() - uncommitted_rgn.base();
uncommitted_rgn.exclude_region(uncommitted_rgn.base(), exclude_size);
VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag()); VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
LinkedListNode<CommittedMemoryRegion>* tmp = head;
head = head->next(); head = head->next();
_committed_regions.remove_after(prev); _committed_regions.remove_after(prev);
continue; continue; // don't update head or prev
} else if (crgn->contain_address(uncommitted_rgn.base())) {
size_t toUncommitted = crgn->end() - uncommitted_rgn.base();
crgn->exclude_region(uncommitted_rgn.base(), toUncommitted);
uncommitted_rgn.exclude_region(uncommitted_rgn.base(), toUncommitted);
VirtualMemorySummary::record_uncommitted_memory(toUncommitted, flag());
} else if (uncommitted_rgn.contain_address(crgn->base())) {
size_t toUncommitted = uncommitted_rgn.end() - crgn->base();
crgn->exclude_region(crgn->base(), toUncommitted);
uncommitted_rgn.exclude_region(uncommitted_rgn.end() - toUncommitted,
toUncommitted);
VirtualMemorySummary::record_uncommitted_memory(toUncommitted, flag());
} }
// Found addr in the current crgn. There are 2 subcases:
if (crgn->contain_address(addr)) {
// (1) Found addr+size in current crgn as well. (del_rgn is contained in crgn)
if (crgn->contain_address(end - 1)) {
VirtualMemorySummary::record_uncommitted_memory(sz, flag());
return remove_uncommitted_region(head, addr, sz); // done!
} else {
// (2) Did not find del_rgn's end in crgn.
size_t size = crgn->end() - del_rgn.base();
crgn->exclude_region(addr, size);
VirtualMemorySummary::record_uncommitted_memory(size, flag());
} }
} else if (crgn->contain_address(end - 1)) {
// Found del_rgn's end, but not its base addr.
size_t size = del_rgn.end() - crgn->base();
crgn->exclude_region(crgn->base(), size);
VirtualMemorySummary::record_uncommitted_memory(size, flag());
return true; // should be done if the list is sorted properly!
}
prev = head; prev = head;
head = head->next(); head = head->next();
} }
@ -386,7 +388,8 @@ bool VirtualMemoryTracker::add_committed_region(address addr, size_t size,
assert(reserved_rgn != NULL, "No reserved region"); assert(reserved_rgn != NULL, "No reserved region");
assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); assert(reserved_rgn->contain_region(addr, size), "Not completely contained");
return reserved_rgn->add_committed_region(addr, size, stack); bool result = reserved_rgn->add_committed_region(addr, size, stack);
return result;
} }
bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size) { bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size) {
@ -398,7 +401,8 @@ bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size)
ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
assert(reserved_rgn != NULL, "No reserved region"); assert(reserved_rgn != NULL, "No reserved region");
assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); assert(reserved_rgn->contain_region(addr, size), "Not completely contained");
return reserved_rgn->remove_uncommitted_region(addr, size); bool result = reserved_rgn->remove_uncommitted_region(addr, size);
return result;
} }
bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) { bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) {
@ -488,5 +492,3 @@ bool VirtualMemoryTracker::transition(NMT_TrackingLevel from, NMT_TrackingLevel
return true; return true;
} }

View File

@ -261,8 +261,7 @@ class CommittedMemoryRegion : public VirtualMemoryRegion {
VirtualMemoryRegion(addr, size), _stack(stack) { } VirtualMemoryRegion(addr, size), _stack(stack) { }
inline int compare(const CommittedMemoryRegion& rgn) const { inline int compare(const CommittedMemoryRegion& rgn) const {
if (overlap_region(rgn.base(), rgn.size()) || if (overlap_region(rgn.base(), rgn.size())) {
adjacent_to (rgn.base(), rgn.size())) {
return 0; return 0;
} else { } else {
if (base() == rgn.base()) { if (base() == rgn.base()) {

View File

@ -93,12 +93,12 @@ static void print_flag_error_message_if_needed(Flag::Error error, const char* na
// set a boolean global flag // set a boolean global flag
Flag::Error WriteableFlags::set_bool_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) { Flag::Error WriteableFlags::set_bool_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
int value = true; if ((strcasecmp(arg, "true") == 0) || (*arg == '1' && *(arg + 1) == 0)) {
return set_bool_flag(name, true, origin, err_msg);
if (sscanf(arg, "%d", &value)) { } else if ((strcasecmp(arg, "false") == 0) || (*arg == '0' && *(arg + 1) == 0)) {
return set_bool_flag(name, value != 0, origin, err_msg); return set_bool_flag(name, false, origin, err_msg);
} }
err_msg.print("flag value must be a boolean (1 or 0)"); err_msg.print("flag value must be a boolean (1/0 or true/false)");
return Flag::WRONG_FORMAT; return Flag::WRONG_FORMAT;
} }

View File

@ -383,6 +383,7 @@ template class BasicHashtable<mtClassShared>;
template class BasicHashtable<mtSymbol>; template class BasicHashtable<mtSymbol>;
template class BasicHashtable<mtCode>; template class BasicHashtable<mtCode>;
template class BasicHashtable<mtInternal>; template class BasicHashtable<mtInternal>;
template class BasicHashtable<mtModule>;
#if INCLUDE_TRACE #if INCLUDE_TRACE
template class Hashtable<Symbol*, mtTracing>; template class Hashtable<Symbol*, mtTracing>;
template class HashtableEntry<Symbol*, mtTracing>; template class HashtableEntry<Symbol*, mtTracing>;

View File

@ -259,6 +259,11 @@ template <class E, ResourceObj::allocation_type T = ResourceObj::C_HEAP,
virtual bool remove(LinkedListNode<E>* node) { virtual bool remove(LinkedListNode<E>* node) {
LinkedListNode<E>* p = this->head(); LinkedListNode<E>* p = this->head();
if (p == node) {
this->set_head(p->next());
delete_node(node);
return true;
}
while (p != NULL && p->next() != node) { while (p != NULL && p->next() != node) {
p = p->next(); p = p->next();
} }

View File

@ -306,7 +306,10 @@ ifdef TESTDIRS
endif endif
ifdef CONCURRENCY ifdef CONCURRENCY
EXTRA_JTREG_OPTIONS += -concurrency:$(CONCURRENCY) JTREG_BASIC_OPTIONS += -concurrency:$(CONCURRENCY)
endif
ifdef EXTRA_JTREG_OPTIONS
JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS)
endif endif
# Default JTREG to run # Default JTREG to run
@ -326,8 +329,6 @@ JTREG_BASIC_OPTIONS += $(JTREG_IGNORE_OPTION)
# Multiply by 4 the timeout factor # Multiply by 4 the timeout factor
JTREG_TIMEOUT_OPTION = -timeoutFactor:4 JTREG_TIMEOUT_OPTION = -timeoutFactor:4
JTREG_BASIC_OPTIONS += $(JTREG_TIMEOUT_OPTION) JTREG_BASIC_OPTIONS += $(JTREG_TIMEOUT_OPTION)
# Add any extra options
JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS)
# Set other vm and test options # Set other vm and test options
JTREG_TEST_OPTIONS = $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_OPTIONS:%=-vmoption:%) $(JAVA_VM_ARGS:%=-vmoption:%) JTREG_TEST_OPTIONS = $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_OPTIONS:%=-vmoption:%) $(JAVA_VM_ARGS:%=-vmoption:%)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,22 +23,15 @@
/** /**
* @test TestSmallHeap * @test TestSmallHeap
* @bug 8067438 * @bug 8067438 8152239
* @requires vm.gc=="null" * @requires vm.gc=="null"
* @requires (vm.opt.AggressiveOpts=="null") | (vm.opt.AggressiveOpts=="false")
* @requires vm.compMode != "Xcomp"
* @requires vm.opt.UseCompressedOops != false
* @summary Verify that starting the VM with a small heap works * @summary Verify that starting the VM with a small heap works
* @library /testlibrary /test/lib * @library /testlibrary /test/lib /test/lib/share/classes
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
* @modules java.management/sun.management * @modules java.management/sun.management
* @ignore 8076621
* @build TestSmallHeap * @build TestSmallHeap
* @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xmx2m -XX:+UseParallelGC TestSmallHeap * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI TestSmallHeap
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xmx2m -XX:+UseSerialGC TestSmallHeap
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xmx2m -XX:+UseG1GC TestSmallHeap
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xmx2m -XX:+UseConcMarkSweepGC TestSmallHeap
*/ */
/* Note: It would be nice to verify the minimal supported heap size (2m) here, /* Note: It would be nice to verify the minimal supported heap size (2m) here,
@ -60,23 +53,55 @@
* So, the expected heap size is page_size * 512. * So, the expected heap size is page_size * 512.
*/ */
import jdk.test.lib.*; import jdk.test.lib.Asserts;
import com.sun.management.HotSpotDiagnosticMXBean; import jdk.test.lib.process.OutputAnalyzer;
import java.lang.management.ManagementFactory; import jdk.test.lib.process.ProcessTools;
import static jdk.test.lib.Asserts.*;
import java.util.LinkedList;
import sun.hotspot.WhiteBox; import sun.hotspot.WhiteBox;
public class TestSmallHeap { public class TestSmallHeap {
public static void main(String[] args) { public static void main(String[] args) throws Exception {
// Do all work in the VM driving the test, the VM
// with the small heap size should do as little as
// possible to avoid hitting an OOME.
WhiteBox wb = WhiteBox.getWhiteBox(); WhiteBox wb = WhiteBox.getWhiteBox();
int pageSize = wb.getVMPageSize(); int pageSize = wb.getVMPageSize();
int heapBytesPerCard = 512; int heapBytesPerCard = 512;
long expectedMaxHeap = pageSize * heapBytesPerCard; long expectedMaxHeap = pageSize * heapBytesPerCard;
String maxHeap
= ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class) verifySmallHeapSize("-XX:+UseParallelGC", expectedMaxHeap);
.getVMOption("MaxHeapSize").getValue(); verifySmallHeapSize("-XX:+UseSerialGC", expectedMaxHeap);
assertEQ(Long.parseLong(maxHeap), expectedMaxHeap); verifySmallHeapSize("-XX:+UseG1GC", expectedMaxHeap);
verifySmallHeapSize("-XX:+UseConcMarkSweepGC", expectedMaxHeap);
}
private static void verifySmallHeapSize(String gc, long expectedMaxHeap) throws Exception {
LinkedList<String> vmOptions = new LinkedList<>();
vmOptions.add(gc);
vmOptions.add("-Xmx2m");
vmOptions.add("-XX:+PrintFlagsFinal");
vmOptions.add(VerifyHeapSize.class.getName());
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[0]));
OutputAnalyzer analyzer = new OutputAnalyzer(pb.start());
analyzer.shouldHaveExitValue(0);
long maxHeapSize = Long.parseLong(analyzer.firstMatch("MaxHeapSize.+=\\s+(\\d+)",1));
long actualHeapSize = Long.parseLong(analyzer.firstMatch(VerifyHeapSize.actualMsg + "(\\d+)",1));
Asserts.assertEQ(maxHeapSize, expectedMaxHeap);
Asserts.assertLessThanOrEqual(actualHeapSize, maxHeapSize);
}
}
class VerifyHeapSize {
public static final String actualMsg = "Actual heap size: ";
public static void main(String args[]) {
// Avoid string concatenation
System.out.print(actualMsg);
System.out.println(Runtime.getRuntime().maxMemory());
} }
} }

View File

@ -28,6 +28,7 @@
* @requires vm.gc=="G1" | vm.gc=="null" * @requires vm.gc=="G1" | vm.gc=="null"
* @requires vm.opt.FlightRecorder != true * @requires vm.opt.FlightRecorder != true
* @requires vm.opt.ExplicitGCInvokesConcurrent != true * @requires vm.opt.ExplicitGCInvokesConcurrent != true
* @requires vm.opt.MaxGCPauseMillis == "null"
* @library /testlibrary /test/lib / * @library /testlibrary /test/lib /
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
* @modules java.management * @modules java.management

View File

@ -25,6 +25,7 @@
* @test TestLogging * @test TestLogging
* @summary Check that a mixed GC is reflected in the gc logs * @summary Check that a mixed GC is reflected in the gc logs
* @requires vm.gc=="G1" | vm.gc=="null" * @requires vm.gc=="G1" | vm.gc=="null"
* @requires vm.opt.MaxGCPauseMillis == "null"
* @library /testlibrary /test/lib * @library /testlibrary /test/lib
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
* @modules java.management * @modules java.management

View File

@ -122,10 +122,7 @@ public class TestPLABPromotion {
List<String> options = PLABUtils.prepareOptions(testCase.toOptions()); List<String> options = PLABUtils.prepareOptions(testCase.toOptions());
options.add(AppPLABPromotion.class.getName()); options.add(AppPLABPromotion.class.getName());
OutputAnalyzer out = ProcessTools.executeTestJvm(options.toArray(new String[options.size()])); OutputAnalyzer out = ProcessTools.executeTestJvm(options.toArray(new String[options.size()]));
if (out.getExitValue() != 0) { PLABUtils.commonCheck(out);
System.out.println(out.getOutput());
throw new RuntimeException("Expect exit code 0.");
}
output = out.getOutput(); output = out.getOutput();
checkResults(testCase); checkResults(testCase);
} }

View File

@ -94,10 +94,7 @@ public class TestPLABResize {
List<String> options = PLABUtils.prepareOptions(testCase.toOptions()); List<String> options = PLABUtils.prepareOptions(testCase.toOptions());
options.add(AppPLABResize.class.getName()); options.add(AppPLABResize.class.getName());
OutputAnalyzer out = ProcessTools.executeTestJvm(options.toArray(new String[options.size()])); OutputAnalyzer out = ProcessTools.executeTestJvm(options.toArray(new String[options.size()]));
if (out.getExitValue() != 0) { PLABUtils.commonCheck(out);
System.out.println(out.getOutput());
throw new RuntimeException("Exit code is not 0");
}
checkResults(out.getOutput(), testCase); checkResults(out.getOutput(), testCase);
} }
} }
@ -124,6 +121,11 @@ public class TestPLABResize {
// The test case does 3 rounds of allocations. The second round of N allocations and GC's // The test case does 3 rounds of allocations. The second round of N allocations and GC's
// has a decreasing size of allocations so that iterations N to 2*N -1 will be of decreasing size. // has a decreasing size of allocations so that iterations N to 2*N -1 will be of decreasing size.
// The third round with iterations 2*N to 3*N -1 has increasing sizes of allocation. // The third round with iterations 2*N to 3*N -1 has increasing sizes of allocation.
if ( plabSizes.size() != testCase.iterations * 3 ) {
System.out.println(output);
throw new RuntimeException ("Expects for " + testCase.iterations * 3 + " PLAB entries in log, found " + plabSizes.size());
}
long startDesiredPLABSize = plabSizes.get(testCase.getIterations()); long startDesiredPLABSize = plabSizes.get(testCase.getIterations());
long endDesiredPLABSize = plabSizes.get(testCase.getIterations() * 2 - 1); long endDesiredPLABSize = plabSizes.get(testCase.getIterations() * 2 - 1);

View File

@ -169,7 +169,12 @@ final public class LogParser {
* @return * @return
**/ **/
public PlabInfo getSpecifiedStats(long specifiedGcId, LogParser.ReportType type, List<String> fieldsName) { public PlabInfo getSpecifiedStats(long specifiedGcId, LogParser.ReportType type, List<String> fieldsName) {
return getSpecifiedStats(Arrays.asList(specifiedGcId), type, fieldsName, true).get(specifiedGcId); PlabInfo info = getSpecifiedStats(Arrays.asList(specifiedGcId), type, fieldsName, true).get(specifiedGcId);
if (info == null) {
System.out.println(log);
throw new RuntimeException("Cannot find PLAB statistics in log ( GC_ID=" + specifiedGcId + " type=" + type + " )");
}
return info;
} }
/** /**

View File

@ -26,6 +26,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import jdk.test.lib.OutputAnalyzer;
import jdk.test.lib.Utils; import jdk.test.lib.Utils;
/** /**
@ -50,7 +51,7 @@ public class PLABUtils {
* GC logging options list. * GC logging options list.
*/ */
private final static String G1_PLAB_LOGGING_OPTIONS[] = { private final static String G1_PLAB_LOGGING_OPTIONS[] = {
"-Xlog:gc=debug,gc+plab=debug" "-Xlog:gc=debug,gc+plab=debug,gc+heap=debug"
}; };
/** /**
@ -81,4 +82,18 @@ public class PLABUtils {
executionOtions.addAll(options); executionOtions.addAll(options);
return executionOtions; return executionOtions;
} }
/**
* Common check for test PLAB application's results.
* @param out OutputAnalyzer for checking
* @throws RuntimeException
*/
public static void commonCheck(OutputAnalyzer out) throws RuntimeException {
if (out.getExitValue() != 0) {
System.out.println(out.getOutput());
throw new RuntimeException("Exit code is not 0");
}
// Test expects only WhiteBox initiated GC.
out.shouldNotContain("Pause Young (G1 Evacuation Pause)");
}
} }

View File

@ -33,6 +33,7 @@ import sun.hotspot.WhiteBox;
* @key stress * @key stress
* @requires vm.gc=="G1" | vm.gc=="null" * @requires vm.gc=="G1" | vm.gc=="null"
* @requires os.maxMemory > 2G * @requires os.maxMemory > 2G
* @requires vm.opt.MaxGCPauseMillis == "null"
* *
* @summary Stress G1 Remembered Set using multiple threads * @summary Stress G1 Remembered Set using multiple threads
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc

View File

@ -30,6 +30,7 @@ import sun.hotspot.WhiteBox;
* @bug 8146984 8147087 * @bug 8146984 8147087
* @requires vm.gc=="G1" | vm.gc=="null" * @requires vm.gc=="G1" | vm.gc=="null"
* @requires os.maxMemory > 3G * @requires os.maxMemory > 3G
* @requires vm.opt.MaxGCPauseMillis == "null"
* *
* @summary Stress G1 Remembered Set by creating a lot of cross region links * @summary Stress G1 Remembered Set by creating a lot of cross region links
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
@ -102,7 +103,7 @@ public class TestStressRSetCoarsening {
private static final WhiteBox WB = WhiteBox.getWhiteBox(); private static final WhiteBox WB = WhiteBox.getWhiteBox();
public final Object[][] storage; public final ObjStorage storage;
/** /**
* Number of objects per region. This is a test parameter. * Number of objects per region. This is a test parameter.
@ -161,6 +162,8 @@ public class TestStressRSetCoarsening {
long totalFree = rt.maxMemory() - used; long totalFree = rt.maxMemory() - used;
regionCount = (int) ((totalFree / regionSize) * heapFractionToAllocate); regionCount = (int) ((totalFree / regionSize) * heapFractionToAllocate);
long toAllocate = regionCount * regionSize; long toAllocate = regionCount * regionSize;
long freeMemoryLimit = totalFree - toAllocate;
System.out.println("%% Test parameters"); System.out.println("%% Test parameters");
System.out.println("%% Objects per region : " + K); System.out.println("%% Objects per region : " + K);
System.out.println("%% Heap fraction to allocate : " + (int) (heapFractionToAllocate * 100) + "%"); System.out.println("%% Heap fraction to allocate : " + (int) (heapFractionToAllocate * 100) + "%");
@ -212,9 +215,15 @@ public class TestStressRSetCoarsening {
" (sizeOf(new Object[" + N + "])"); " (sizeOf(new Object[" + N + "])");
System.out.println("%% Reference size : " + refSize); System.out.println("%% Reference size : " + refSize);
storage = new Object[regionCount * K][]; // Maximum number of objects to allocate is regionCount * K.
for (int i = 0; i < storage.length; i++) { storage = new ObjStorage(regionCount * K);
storage[i] = new Object[N];
// Add objects as long as there is space in the storage
// and we haven't used more memory than planned.
while (!storage.isFull() && (rt.maxMemory() - used) > freeMemoryLimit) {
storage.addArray(new Object[N]);
// Update used memory
used = rt.totalMemory() - rt.freeMemory();
} }
} }
@ -255,7 +264,7 @@ public class TestStressRSetCoarsening {
// The celebrity will be referred from all other regions. // The celebrity will be referred from all other regions.
// If the number of references after should be less than they // If the number of references after should be less than they
// were before, select NULL. // were before, select NULL.
Object celebrity = cur > pre ? storage[to * K] : null; Object celebrity = cur > pre ? storage.getArrayAt(to * K) : null;
for (int from = 0; from < regionCount; from++) { for (int from = 0; from < regionCount; from++) {
if (to == from) { if (to == from) {
continue; // no need to refer to itself continue; // no need to refer to itself
@ -263,7 +272,8 @@ public class TestStressRSetCoarsening {
int step = cur > pre ? +1 : -1; int step = cur > pre ? +1 : -1;
for (int rn = pre; rn != cur; rn += step) { for (int rn = pre; rn != cur; rn += step) {
storage[getY(to, from, rn)][getX(to, from, rn)] = celebrity; Object[] rnArray = storage.getArrayAt(getY(to, from, rn));
rnArray[getX(to, from, rn)] = celebrity;
if (System.currentTimeMillis() > finishAt) { if (System.currentTimeMillis() > finishAt) {
throw new TimeoutException(); throw new TimeoutException();
} }
@ -290,14 +300,15 @@ public class TestStressRSetCoarsening {
continue; // no need to refer to itself continue; // no need to refer to itself
} }
for (int rn = 0; rn <= cur; rn++) { for (int rn = 0; rn <= cur; rn++) {
storage[getY(to, from, rn)][getX(to, from, rn)] = null; Object[] rnArray = storage.getArrayAt(getY(to, from, rn));
rnArray[getX(to, from, rn)] = null;
} }
} }
// 'Refresh' storage elements for the region 'to' // 'Refresh' storage elements for the region 'to'
// After that loop all 'old' objects in the region 'to' // After that loop all 'old' objects in the region 'to'
// should become unreachable. // should become unreachable.
for (int k = 0; k < K; k++) { for (int k = 0; k < K; k++) {
storage[(to * K + k) % storage.length] = new Object[N]; storage.setArrayAt(to * K + k, new Object[N]);
} }
} }
} }
@ -340,3 +351,36 @@ public class TestStressRSetCoarsening {
} }
} }
//Helper class to encapsulate the object array storage.
class ObjStorage {
public final Object[][] storage;
public int usedCount;
ObjStorage(int size) {
storage = new Object[size][];
usedCount = 0;
}
public boolean isFull() {
return usedCount >= storage.length;
}
public void addArray(Object[] objects) {
if (isFull()) {
throw new IllegalStateException("Storage full maximum number of allowed elements: " + usedCount);
}
storage[usedCount++] = objects;
}
// Limit by usedCount since memory limits can cause the storage
// to have unused slots in the end.
public void setArrayAt(int i, Object[] objects) {
storage[i % usedCount] = objects;
}
// Limit by usedCount since memory limits can cause the storage
// to have unused slots in the end.
public Object[] getArrayAt(int i) {
return storage[i % usedCount];
}
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/* @test
* @summary a jtreg wrapper for gtest tests
* @library /test/lib/share/classes
* @modules java.base/jdk.internal.misc
* @run main/native GTestWrapper
*/
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import java.util.stream.Collectors;
import java.nio.file.Paths;
import java.nio.file.Path;
import jdk.test.lib.Platform;
import jdk.test.lib.Utils;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
public class GTestWrapper {
public static void main(String[] args) throws Throwable {
// gtestLauncher is located in <test_image>/hotspot/gtest/<vm_variant>/
// nativePath points either to <test_image>/hotspot/jtreg/native or to <test_image>/hotspot/gtest
Path nativePath = Paths.get(System.getProperty("test.nativepath"));
String jvmVariantDir = getJVMVariantSubDir();
// let's assume it's <test_image>/hotspot/gtest
Path path = nativePath.resolve(jvmVariantDir);
if (!path.toFile().exists()) {
// maybe it is <test_image>/hotspot/jtreg/native
path = nativePath.getParent()
.getParent()
.resolve("gtest")
.resolve(jvmVariantDir);
}
if (!path.toFile().exists()) {
throw new Error("TESTBUG: the library has not been found in " + nativePath);
}
path = path.resolve("gtestLauncher" + (Platform.isWindows() ? ".exe" : ""));
ProcessTools.executeCommand(new String[] {
path.toString(),
"-jdk",
System.getProperty("test.jdk")
}).shouldHaveExitValue(0);
}
private static String getJVMVariantSubDir() {
if (Platform.isServer()) {
return "server";
} else if (Platform.isClient()) {
return "client";
} else if (Platform.isMinimal()) {
return "minimal";
} else {
throw new Error("TESTBUG: unsuppported vm variant");
}
}
}

View File

@ -0,0 +1,254 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8087223
* @summary Adding constantTag to keep method call consistent with it.
* @library /testlibrary
* @modules java.base/jdk.internal.org.objectweb.asm
* java.base/jdk.internal.misc
* java.management
* @compile -XDignore.symbol.file BadMethodHandles.java
* @run main/othervm BadMethodHandles
*/
import jdk.internal.org.objectweb.asm.*;
import java.io.FileOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import static jdk.internal.org.objectweb.asm.Opcodes.*;
public class BadMethodHandles {
static byte[] dumpBadInterfaceMethodref() {
ClassWriter cw = new ClassWriter(0);
cw.visit(52, ACC_PUBLIC | ACC_SUPER, "BadInterfaceMethodref", null, "java/lang/Object", null);
Handle handle1 =
new Handle(Opcodes.H_INVOKEINTERFACE, "BadInterfaceMethodref", "m", "()V");
Handle handle2 =
new Handle(Opcodes.H_INVOKEINTERFACE, "BadInterfaceMethodref", "staticM", "()V");
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "m", "()V", null, null);
mv.visitCode();
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitLdcInsn("hello from m");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false/*intf*/);
mv.visitInsn(RETURN);
mv.visitMaxs(3, 1);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "staticM", "()V", null, null);
mv.visitCode();
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitLdcInsn("hello from staticM");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false/*intf*/);
mv.visitInsn(RETURN);
mv.visitMaxs(3, 1);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "runm", "()V", null, null);
mv.visitCode();
// REF_invokeStatic
mv.visitLdcInsn(handle1);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invoke", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "runStaticM", "()V", null, null);
mv.visitCode();
// REF_invokeStatic
mv.visitLdcInsn(handle2);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invoke", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
cw.visitEnd();
return cw.toByteArray();
}
static byte[] dumpIBad() {
ClassWriter cw = new ClassWriter(0);
cw.visit(52, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, "IBad", null, "java/lang/Object", null);
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "m", "()V", null, null);
mv.visitCode();
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitLdcInsn("hello from m");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false/*intf*/);
mv.visitInsn(RETURN);
mv.visitMaxs(3, 1);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "staticM", "()V", null, null);
mv.visitCode();
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitLdcInsn("hello from staticM");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false/*intf*/);
mv.visitInsn(RETURN);
mv.visitMaxs(3, 1);
mv.visitEnd();
}
cw.visitEnd();
return cw.toByteArray();
}
static byte[] dumpBadMethodref() {
ClassWriter cw = new ClassWriter(0);
cw.visit(52, ACC_PUBLIC | ACC_SUPER, "BadMethodref", null, "java/lang/Object", new String[]{"IBad"});
Handle handle1 =
new Handle(Opcodes.H_INVOKEINTERFACE, "BadMethodref", "m", "()V");
Handle handle2 =
new Handle(Opcodes.H_INVOKEINTERFACE, "BadMethodref", "staticM", "()V");
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "runm", "()V", null, null);
mv.visitCode();
// REF_invokeStatic
mv.visitLdcInsn(handle1);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invoke", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "runStaticM", "()V", null, null);
mv.visitCode();
// REF_invokeStatic
mv.visitLdcInsn(handle2);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invoke", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
cw.visitEnd();
return cw.toByteArray();
}
static class CL extends ClassLoader {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classBytes = null;
switch (name) {
case "BadInterfaceMethodref": classBytes = dumpBadInterfaceMethodref(); break;
case "BadMethodref" : classBytes = dumpBadMethodref(); break;
case "IBad" : classBytes = dumpIBad(); break;
default : throw new ClassNotFoundException(name);
}
return defineClass(name, classBytes, 0, classBytes.length);
}
}
public static void main(String[] args) throws Throwable {
try (FileOutputStream fos = new FileOutputStream("BadInterfaceMethodref.class")) {
fos.write(dumpBadInterfaceMethodref());
}
try (FileOutputStream fos = new FileOutputStream("IBad.class")) {
fos.write(dumpIBad());
}
try (FileOutputStream fos = new FileOutputStream("BadMethodref.class")) {
fos.write(dumpBadMethodref());
}
Class<?> cls = (new CL()).loadClass("BadInterfaceMethodref");
String[] methods = {"runm", "runStaticM"};
System.out.println("Test BadInterfaceMethodref:");
int success = 0;
for (String name : methods) {
try {
System.out.printf("invoke %s: \n", name);
cls.getMethod(name).invoke(cls.newInstance());
System.out.println("FAILED - ICCE should be thrown");
} catch (Throwable e) {
if (e instanceof InvocationTargetException && e.getCause() != null &&
e.getCause() instanceof IncompatibleClassChangeError) {
System.out.println("PASSED - expected ICCE thrown");
success++;
continue;
} else {
System.out.println("FAILED with wrong exception" + e);
throw e;
}
}
}
if (success != methods.length) {
throw new Exception("BadInterfaceMethodRef Failed to catch IncompatibleClassChangeError");
}
System.out.println("Test BadMethodref:");
cls = (new CL()).loadClass("BadMethodref");
success = 0;
for (String name : methods) {
try {
System.out.printf("invoke %s: \n", name);
cls.getMethod(name).invoke(cls.newInstance());
System.out.println("FAILED - ICCE should be thrown");
} catch (Throwable e) {
if (e instanceof InvocationTargetException && e.getCause() != null &&
e.getCause() instanceof IncompatibleClassChangeError) {
System.out.println("PASSED - expected ICCE thrown");
success++;
continue;
} else {
System.out.println("FAILED with wrong exception" + e);
throw e;
}
}
}
if (success != methods.length) {
throw new Exception("BadMethodRef Failed to catch IncompatibleClassChangeError");
}
}
}

View File

@ -0,0 +1,160 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* $bug 8087223
* @summary Adding constantTag to keep method call consistent with it.
* @library /testlibrary
* @modules java.base/jdk.internal.org.objectweb.asm
* java.base/jdk.internal.misc
* java.management
* @compile -XDignore.symbol.file IntfMethod.java
* @run main/othervm IntfMethod
* @run main/othervm -Xint IntfMethod
* @run main/othervm -Xcomp IntfMethod
*/
import jdk.internal.org.objectweb.asm.*;
import java.io.FileOutputStream;
import java.lang.reflect.InvocationTargetException;
import static jdk.internal.org.objectweb.asm.Opcodes.*;
public class IntfMethod {
static byte[] dumpC() {
ClassWriter cw = new ClassWriter(0);
cw.visit(52, ACC_PUBLIC | ACC_SUPER, "C", null, "java/lang/Object", new String[]{"I"});
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "testSpecialIntf", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "I", "f1", "()V", /*itf=*/false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "testStaticIntf", "()V", null, null);
mv.visitCode();
mv.visitMethodInsn(INVOKESTATIC, "I", "f2", "()V", /*itf=*/false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "testSpecialClass", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "C", "f1", "()V", /*itf=*/true);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "f2", "()V", null, null);
mv.visitCode();
mv.visitInsn(RETURN);
mv.visitMaxs(0, 1);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "testStaticClass", "()V", null, null);
mv.visitCode();
mv.visitMethodInsn(INVOKESTATIC, "C", "f2", "()V", /*itf=*/true);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
cw.visitEnd();
return cw.toByteArray();
}
static byte[] dumpI() {
ClassWriter cw = new ClassWriter(0);
cw.visit(52, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, "I", null, "java/lang/Object", null);
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "f1", "()V", null, null);
mv.visitCode();
mv.visitInsn(RETURN);
mv.visitMaxs(0, 1);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "f2", "()V", null, null);
mv.visitCode();
mv.visitInsn(RETURN);
mv.visitMaxs(0, 1);
mv.visitEnd();
}
cw.visitEnd();
return cw.toByteArray();
}
static class CL extends ClassLoader {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classFile;
switch (name) {
case "I": classFile = dumpI(); break;
case "C": classFile = dumpC(); break;
default:
throw new ClassNotFoundException(name);
}
return defineClass(name, classFile, 0, classFile.length);
}
}
public static void main(String[] args) throws Throwable {
Class<?> cls = (new CL()).loadClass("C");
try (FileOutputStream fos = new FileOutputStream("I.class")) { fos.write(dumpI()); }
try (FileOutputStream fos = new FileOutputStream("C.class")) { fos.write(dumpC()); }
int success = 0;
for (String name : new String[] { "testSpecialIntf", "testStaticIntf", "testSpecialClass", "testStaticClass"}) {
System.out.printf("%s: ", name);
try {
cls.getMethod(name).invoke(cls.newInstance());
System.out.println("FAILED - ICCE not thrown");
} catch (Throwable e) {
if (e instanceof InvocationTargetException &&
e.getCause() != null && e.getCause() instanceof IncompatibleClassChangeError) {
System.out.println("PASSED - expected ICCE thrown");
success++;
continue;
}
}
}
if (success != 4) throw new Exception("Failed to catch ICCE");
}
}

View File

@ -0,0 +1,144 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Test commits of overlapping regions of memory.
* @key nmt jcmd
* @library /testlibrary /test/lib
* @modules java.base/jdk.internal.misc
* java.management
* @build CommitOverlappingRegions
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail CommitOverlappingRegions
*/
import jdk.test.lib.*;
import sun.hotspot.WhiteBox;
public class CommitOverlappingRegions {
public static WhiteBox wb = WhiteBox.getWhiteBox();
public static void main(String args[]) throws Exception {
OutputAnalyzer output;
long size = 32 * 1024;
long addr = wb.NMTReserveMemory(8*size);
String pid = Long.toString(ProcessTools.getProcessId());
ProcessBuilder pb = new ProcessBuilder();
pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail"});
System.out.println("Address is " + Long.toHexString(addr));
// Start: . . . . . . . .
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB, committed=0KB)");
// Committing: * * * . . . . .
// Region: * * * . . . . .
// Expected Total: 3 x 32KB = 96KB
wb.NMTCommitMemory(addr + 0*size, 3*size);
// Committing: . . . . * * * .
// Region: * * * . * * * .
// Expected Total: 6 x 32KB = 192KB
wb.NMTCommitMemory(addr + 4*size, 3*size);
// Check output after first 2 commits.
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB, committed=192KB)");
// Committing: . . * * * . . .
// Region: * * * * * * * .
// Expected Total: 7 x 32KB = 224KB
wb.NMTCommitMemory(addr + 2*size, 3*size);
// Check output after overlapping commit.
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB, committed=224KB)");
// Uncommitting: * * * * * * * *
// Region: . . . . . . . .
// Expected Total: 0 x 32KB = 0KB
wb.NMTUncommitMemory(addr + 0*size, 8*size);
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB, committed=0KB)");
// Committing: * * . . . . . .
// Region: * * . . . . . .
// Expected Total: 2 x 32KB = 64KB
wb.NMTCommitMemory(addr + 0*size, 2*size);
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB, committed=64KB)");
// Committing: . * * * . . . .
// Region: * * * * . . . .
// Expected Total: 4 x 32KB = 128KB
wb.NMTCommitMemory(addr + 1*size, 3*size);
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB, committed=128KB)");
// Uncommitting: * * * . . . . .
// Region: . . . * . . . .
// Expected Total: 1 x 32KB = 32KB
wb.NMTUncommitMemory(addr + 0*size, 3*size);
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB, committed=32KB)");
// Committing: . . . * * . . .
// Region: . . . * * . . .
// Expected Total: 2 x 32KB = 64KB
wb.NMTCommitMemory(addr + 3*size, 2*size);
System.out.println("Address is " + Long.toHexString(addr + 3*size));
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB, committed=64KB)");
// Committing: . . . . * * . .
// Region: . . . * * * . .
// Expected Total: 3 x 32KB = 96KB
wb.NMTCommitMemory(addr + 4*size, 2*size);
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB, committed=96KB)");
// Committing: . . . . . * * .
// Region: . . . * * * * .
// Expected Total: 4 x 32KB = 128KB
wb.NMTCommitMemory(addr + 5*size, 2*size);
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB, committed=128KB)");
// Committing: . . . . . . * *
// Region: . . . * * * * *
// Expected Total: 5 x 32KB = 160KB
wb.NMTCommitMemory(addr + 6*size, 2*size);
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB, committed=160KB)");
// Uncommitting: * * * * * * * *
// Region: . . . . . . . .
// Expected Total: 0 x 32KB = 32KB
wb.NMTUncommitMemory(addr + 0*size, 8*size);
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB, committed=0KB)");
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -48,6 +48,9 @@ public class PrintNMTStatistics {
output_detail.shouldNotContain("error"); output_detail.shouldNotContain("error");
output_detail.shouldHaveExitValue(0); output_detail.shouldHaveExitValue(0);
// Make sure memory reserved for Module processing is recorded.
output_detail.shouldContain(" Module (reserved=");
ProcessBuilder pb1 = ProcessTools.createJavaProcessBuilder( ProcessBuilder pb1 = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockDiagnosticVMOptions",
"-XX:+PrintNMTStatistics", "-XX:+PrintNMTStatistics",

View File

@ -27,6 +27,7 @@
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
* @modules java.base/jdk.internal.vm.annotation * @modules java.base/jdk.internal.vm.annotation
* @build jdk.test.lib.* * @build jdk.test.lib.*
* @run main/othervm -Xint ReservedStackTest
* @run main/othervm -XX:-Inline -XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread ReservedStackTest * @run main/othervm -XX:-Inline -XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread ReservedStackTest
*/ */
@ -196,9 +197,12 @@ public class ReservedStackTest {
System.out.println("Test started execution at frame = " + (counter - deframe)); System.out.println("Test started execution at frame = " + (counter - deframe));
String result = test.getResult(); String result = test.getResult();
// The feature is not fully implemented on all platforms, // The feature is not fully implemented on all platforms,
// corruptions are still possible // corruptions are still possible.
boolean supportedPlatform = Platform.isSolaris() || Platform.isOSX() boolean supportedPlatform =
|| (Platform.isLinux() && (Platform.isX86() || Platform.isX64())); Platform.isAix() ||
(Platform.isLinux() && (Platform.isPPC() || Platform.isX64() || Platform.isX86())) ||
Platform.isOSX() ||
Platform.isSolaris();
if (supportedPlatform && !result.contains("PASSED")) { if (supportedPlatform && !result.contains("PASSED")) {
System.out.println(result); System.out.println(result);
throw new Error(result); throw new Error(result);

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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 ReservedStackTestCompiler
* @summary Run ReservedStackTest with dedicated compilers C1 and C2.
* @requires vm.flavor == "server"
* @library /testlibrary
* @modules java.base/jdk.internal.misc
* @modules java.base/jdk.internal.vm.annotation
* @build jdk.test.lib.* ReservedStackTest
* @run main/othervm -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -XX:-Inline -XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread ReservedStackTest
* @run main/othervm -XX:-TieredCompilation -XX:-Inline -XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread ReservedStackTest
*/
// Intentionally left blank. Just runs ReservedStackTest with @requires annotation.

View File

@ -72,6 +72,6 @@ class Clazz extends ClassConstruct {
public Clazz(String name, String extending, int access, int classFileVersion, int index, String... implementing) { public Clazz(String name, String extending, int access, int classFileVersion, int index, String... implementing) {
super(name, extending == null ? "java/lang/Object" : extending, access + ACC_SUPER, classFileVersion, index, implementing); super(name, extending == null ? "java/lang/Object" : extending, access + ACC_SUPER, classFileVersion, index, implementing);
// Add the default constructor // Add the default constructor
addMethod("<init>", "()V", ACC_PUBLIC).makeConstructor(extending); addMethod("<init>", "()V", ACC_PUBLIC).makeConstructor(extending, false);
} }
} }

View File

@ -59,14 +59,12 @@ class Method {
private final String ownerClassName; private final String ownerClassName;
private final ClassVisitor cv; private final ClassVisitor cv;
private final MethodVisitor mv; private final MethodVisitor mv;
private final boolean isInterface;
private final ClassBuilder.ExecutionMode execMode; private final ClassBuilder.ExecutionMode execMode;
public Method(ClassConstruct ownerClass, ClassVisitor cv, String name, String descriptor, int access, public Method(ClassConstruct ownerClass, ClassVisitor cv, String name, String descriptor, int access,
ClassBuilder.ExecutionMode execMode) { ClassBuilder.ExecutionMode execMode) {
this.ownerClassName = ownerClass.getName(); this.ownerClassName = ownerClass.getName();
this.ownerClass = ownerClass; this.ownerClass = ownerClass;
this.isInterface = ownerClass.isInterface();
this.execMode = execMode; this.execMode = execMode;
this.cv = cv; this.cv = cv;
mv = cv.visitMethod(access, name, descriptor, null, null); mv = cv.visitMethod(access, name, descriptor, null, null);
@ -91,12 +89,12 @@ class Method {
public void makeSuperCallMethod(int invokeInstruction, String className) { public void makeSuperCallMethod(int invokeInstruction, String className) {
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0);
makeCall(invokeInstruction, className); makeCall(invokeInstruction, className, false);
mv.visitInsn(POP); mv.visitInsn(POP);
done(); done();
} }
public void defaultInvoke(int instr, String className, String objectRef) { public void defaultInvoke(int instr, String className, String objectRef, boolean isInterface) {
switch (instr) { switch (instr) {
case INVOKEVIRTUAL: case INVOKEVIRTUAL:
defaultInvokeVirtual(className, objectRef); defaultInvokeVirtual(className, objectRef);
@ -105,10 +103,10 @@ class Method {
defaultInvokeInterface(className, objectRef); defaultInvokeInterface(className, objectRef);
break; break;
case INVOKESTATIC: case INVOKESTATIC:
defaultInvokeStatic(className); defaultInvokeStatic(className, isInterface);
break; break;
case INVOKESPECIAL: case INVOKESPECIAL:
defaultInvokeSpecial(className, objectRef); defaultInvokeSpecial(className, objectRef, isInterface);
break; break;
default: default:
break; break;
@ -118,30 +116,26 @@ class Method {
mv.visitEnd(); mv.visitEnd();
} }
public void defaultInvokeVirtual(String className, String objectRef) { private void defaultInvokeVirtual(String className, String objectRef) {
String objectRefPackageName = objectRef.substring(0, objectRef.lastIndexOf("/")); String objectRefPackageName = objectRef.substring(0, objectRef.lastIndexOf("/"));
makeNewObject(objectRef, objectRefPackageName); makeNewObject(objectRef, objectRefPackageName);
makeCall(INVOKEVIRTUAL, className, false); makeCall(INVOKEVIRTUAL, className, false);
} }
public void defaultInvokeInterface(String className, String objectRef) { private void defaultInvokeInterface(String className, String objectRef) {
String objectRefPackageName = objectRef.substring(0, objectRef.lastIndexOf("/")); String objectRefPackageName = objectRef.substring(0, objectRef.lastIndexOf("/"));
makeNewObject(objectRef, objectRefPackageName); makeNewObject(objectRef, objectRefPackageName);
makeCall(INVOKEINTERFACE, className, true); makeCall(INVOKEINTERFACE, className, true);
} }
public void defaultInvokeSpecial(String className, String objectRef) { private void defaultInvokeSpecial(String className, String objectRef, boolean isInterface) {
String objectRefPackageName = objectRef.substring(0, objectRef.lastIndexOf("/")); String objectRefPackageName = objectRef.substring(0, objectRef.lastIndexOf("/"));
makeNewObject(objectRef, objectRefPackageName); makeNewObject(objectRef, objectRefPackageName);
makeCall(INVOKESPECIAL, className, false); makeCall(INVOKESPECIAL, className, isInterface);
} }
public void defaultInvokeStatic(String className) { private void defaultInvokeStatic(String className, boolean isInterface) {
makeCall(INVOKESTATIC, className); makeCall(INVOKESTATIC, className, isInterface);
}
private Method makeCall(int invokeInstruction, String className) {
return makeCall(invokeInstruction, className, isInterface);
} }
private Method makeCall(int invokeInstruction, String className, boolean isInterface) { private Method makeCall(int invokeInstruction, String className, boolean isInterface) {
@ -219,7 +213,7 @@ class Method {
String className = objectRef.substring(objectRef.lastIndexOf("/") + 1); String className = objectRef.substring(objectRef.lastIndexOf("/") + 1);
makeStaticCall( objectRefPackageName + "/Helper", makeStaticCall( objectRefPackageName + "/Helper",
"get" + className, "get" + className,
"()L" + objectRef + ";"); "()L" + objectRef + ";", false);
mv.visitVarInsn(ASTORE, 1); mv.visitVarInsn(ASTORE, 1);
mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 1);
} }
@ -236,12 +230,12 @@ class Method {
mv.visitEnd(); mv.visitEnd();
} }
public Method makeStaticCall(String classname, String method, String descriptor) { public Method makeStaticCall(String classname, String method, String descriptor, boolean isInterface) {
mv.visitMethodInsn(INVOKESTATIC, classname, method, descriptor, isInterface); mv.visitMethodInsn(INVOKESTATIC, classname, method, descriptor, isInterface);
return this; return this;
} }
public void makeConstructor(String extending) { public void makeConstructor(String extending, boolean isInterface) {
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, extending == null ? "java/lang/Object" : extending, "<init>", "()V", isInterface); mv.visitMethodInsn(INVOKESPECIAL, extending == null ? "java/lang/Object" : extending, "<init>", "()V", isInterface);
mv.visitInsn(RETURN); mv.visitInsn(RETURN);

View File

@ -53,9 +53,10 @@ class TestBuilder extends Builder {
Method m = clazz.addMethod("test", "()Ljava/lang/Integer;", ACC_PUBLIC + ACC_STATIC, execMode); Method m = clazz.addMethod("test", "()Ljava/lang/Integer;", ACC_PUBLIC + ACC_STATIC, execMode);
m.defaultInvoke(getInvokeInstruction(testcase.invoke), m.defaultInvoke(getInvokeInstruction(testcase.invoke),
getName(testcase.methodref), getName(testcase.methodref),
getName(testcase.objectref)); getName(testcase.objectref),
testcase.hier.isInterface(testcase.methodref));
mainMethod.makeStaticCall(clazz.getName(), "test", "()Ljava/lang/Integer;").done(); mainMethod.makeStaticCall(clazz.getName(), "test", "()Ljava/lang/Integer;", false).done();
} }
private static int getInvokeInstruction(SelectionResolutionTestCase.InvokeInstruction instr) { private static int getInvokeInstruction(SelectionResolutionTestCase.InvokeInstruction instr) {

View File

@ -103,7 +103,7 @@ public class CheckRead {
// Resolves "m1" // Resolves "m1"
Configuration cf = Layer.boot() Configuration cf = Layer.boot()
.configuration() .configuration()
.resolveRequires(finder, ModuleFinder.empty(), Set.of("m1")); .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
// map each module to differing class loaders for this test // map each module to differing class loaders for this test
Map<String, ClassLoader> map = new HashMap<>(); Map<String, ClassLoader> map = new HashMap<>();

View File

@ -103,7 +103,7 @@ public class DiffCL_CheckRead {
// Resolves "m1" // Resolves "m1"
Configuration cf = Layer.boot() Configuration cf = Layer.boot()
.configuration() .configuration()
.resolveRequires(finder, ModuleFinder.empty(), Set.of("m1")); .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
// map each module to differing class loaders for this test // map each module to differing class loaders for this test
Map<String, ClassLoader> map = new HashMap<>(); Map<String, ClassLoader> map = new HashMap<>();

View File

@ -105,7 +105,7 @@ public class DiffCL_ExpQualOther {
// Resolves "m1" // Resolves "m1"
Configuration cf = Layer.boot() Configuration cf = Layer.boot()
.configuration() .configuration()
.resolveRequires(finder, ModuleFinder.empty(), Set.of("m1")); .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
// map each module to differing class loaders for this test // map each module to differing class loaders for this test
Map<String, ClassLoader> map = new HashMap<>(); Map<String, ClassLoader> map = new HashMap<>();

View File

@ -91,7 +91,7 @@ public class DiffCL_ExpQualToM1 {
// Resolves "m1" // Resolves "m1"
Configuration cf = Layer.boot() Configuration cf = Layer.boot()
.configuration() .configuration()
.resolveRequires(finder, ModuleFinder.empty(), Set.of("m1")); .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
// map each module to differing class loaders for this test // map each module to differing class loaders for this test
Map<String, ClassLoader> map = new HashMap<>(); Map<String, ClassLoader> map = new HashMap<>();

View File

@ -92,7 +92,7 @@ public class DiffCL_ExpUnqual {
// Resolves "m1" // Resolves "m1"
Configuration cf = Layer.boot() Configuration cf = Layer.boot()
.configuration() .configuration()
.resolveRequires(finder, ModuleFinder.empty(), Set.of("m1")); .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
// map each module to differing class loaders for this test // map each module to differing class loaders for this test
Map<String, ClassLoader> map = new HashMap<>(); Map<String, ClassLoader> map = new HashMap<>();

View File

@ -91,7 +91,7 @@ public class DiffCL_PkgNotExp {
// Resolves "m1" // Resolves "m1"
Configuration cf = Layer.boot() Configuration cf = Layer.boot()
.configuration() .configuration()
.resolveRequires(finder, ModuleFinder.empty(), Set.of("m1")); .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
// map each module to differing class loaders for this test // map each module to differing class loaders for this test
Map<String, ClassLoader> map = new HashMap<>(); Map<String, ClassLoader> map = new HashMap<>();

View File

@ -92,7 +92,7 @@ public class DiffCL_Umod {
// Resolves "m1" // Resolves "m1"
Configuration cf = Layer.boot() Configuration cf = Layer.boot()
.configuration() .configuration()
.resolveRequires(finder, ModuleFinder.empty(), Set.of("m1")); .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
MyDiffClassLoader.loader1 = new MyDiffClassLoader(); MyDiffClassLoader.loader1 = new MyDiffClassLoader();
MyDiffClassLoader.loader2 = new MyDiffClassLoader(); MyDiffClassLoader.loader2 = new MyDiffClassLoader();
@ -141,7 +141,7 @@ public class DiffCL_Umod {
// Resolves "m1" // Resolves "m1"
Configuration cf = Layer.boot() Configuration cf = Layer.boot()
.configuration() .configuration()
.resolveRequires(finder, ModuleFinder.empty(), Set.of("m1")); .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
MyDiffClassLoader.loader1 = new MyDiffClassLoader(); MyDiffClassLoader.loader1 = new MyDiffClassLoader();
MyDiffClassLoader.loader2 = new MyDiffClassLoader(); MyDiffClassLoader.loader2 = new MyDiffClassLoader();
@ -190,7 +190,7 @@ public class DiffCL_Umod {
// Resolves "m1" // Resolves "m1"
Configuration cf = Layer.boot() Configuration cf = Layer.boot()
.configuration() .configuration()
.resolveRequires(finder, ModuleFinder.empty(), Set.of("m1")); .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
MyDiffClassLoader.loader1 = new MyDiffClassLoader(); MyDiffClassLoader.loader1 = new MyDiffClassLoader();
MyDiffClassLoader.loader2 = new MyDiffClassLoader(); MyDiffClassLoader.loader2 = new MyDiffClassLoader();

Some files were not shown because too many files have changed in this diff Show More