This commit is contained in:
Phil Race 2014-09-12 10:33:32 -07:00
commit 1b9cab9346
1519 changed files with 54184 additions and 32131 deletions

View File

@ -269,3 +269,7 @@ c5495e25c7258ab5f96a1ae14610887d76d2be63 jdk9-b18
d9ce05f36ffec3e5e8af62a92455c1c66a63c320 jdk9-b24
13a5c76976fe48e55c9727c25fae2d2ce7c05da0 jdk9-b25
cd6f4557e7fea5799ff3762ed7a80a743e75d5fd jdk9-b26
d06a6d3c66c08293b2a9650f3cc01fd55c620e65 jdk9-b27
f4269e8f454eb77763ecee228a88ae102a9aef6e jdk9-b28
c36c0092693707a8255561433647e8c3cd724ccd jdk9-b29
b2287cac7813c70ed7f679d9a46fe774bd4005f8 jdk9-b30

View File

@ -269,3 +269,7 @@ ee4fd72b2ec3d92497f37163352f294aa695c6fb jdk9-b20
1d4a293fbec19dc2d5790bbb2c7dd0ed8f265484 jdk9-b24
aefd8899a8d6615fb34ba99b2e38996a7145baa8 jdk9-b25
d3ec8d048e6c3c46b6e0ee011cc551ad386dfba5 jdk9-b26
ba5645f2735b41ed085d07ba20fa7b322afff318 jdk9-b27
ea2f7981236f3812436958748ab3d26e80a35130 jdk9-b28
9e6581aeda388a23fbee021fc33e6aa152a60657 jdk9-b29
36e9bc875325813ac9c44ac0c617a463091fa9f5 jdk9-b30

View File

@ -108,12 +108,23 @@ else
$(shell $(MKDIR) -p $(SJAVAC_SERVER_DIR) && $(RM) -rf $(SJAVAC_SERVER_DIR)/*)
endif
# Split out the targets requiring sequential execution. Run these targets separately
# from the rest so that the rest may still enjoy full parallel execution.
SEQUENTIAL_TARGETS := $(filter dist-clean clean% reconfigure, $(MAIN_TARGETS))
PARALLEL_TARGETS := $(filter-out $(SEQUENTIAL_TARGETS), $(MAIN_TARGETS))
main-wrapper:
@$(if $(findstring clean, $(MAIN_TARGETS)), , $(call AtMakeStart))
(cd $(root_dir)/make && $(BUILD_LOG_WRAPPER) $(MAKE) -f Main.gmk SPEC=$(SPEC) -j $(JOBS) \
$(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) $(MAIN_TARGETS) \
$(if $(filter true, $(OUTPUT_SYNC_SUPPORTED)), -O$(OUTPUT_SYNC)))
@$(if $(findstring clean, $(MAIN_TARGETS)), , $(call AtMakeEnd))
ifneq ($(SEQUENTIAL_TARGETS), )
(cd $(root_dir)/make && $(MAKE) -f Main.gmk SPEC=$(SPEC) -j 1 \
$(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) $(SEQUENTIAL_TARGETS))
endif
ifneq ($(PARALLEL_TARGETS), )
@$(call AtMakeStart)
(cd $(root_dir)/make && $(BUILD_LOG_WRAPPER) $(MAKE) -f Main.gmk SPEC=$(SPEC) -j $(JOBS) \
$(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) $(PARALLEL_TARGETS) \
$(if $(filter true, $(OUTPUT_SYNC_SUPPORTED)), -O$(OUTPUT_SYNC)))
@$(call AtMakeEnd)
endif
.PHONY: main-wrapper
@ -136,8 +147,9 @@ help:
$(info . make docs # Create all docs)
$(info . make docs-javadoc # Create just javadocs, depends on less than full docs)
$(info . make profiles # Create complete j2re compact profile images)
$(info . make bootcycle-images # Build images twice, second time with newly build JDK)
$(info . make bootcycle-images # Build images twice, second time with newly built JDK)
$(info . make install # Install the generated images locally)
$(info . make reconfigure # Rerun configure with the same arguments as last time)
$(info . make clean # Remove all files generated by make, but not those)
$(info . # generated by configure)
$(info . make dist-clean # Remove all files, including configuration)

View File

@ -377,7 +377,6 @@ AC_DEFUN_ONCE([BASIC_SETUP_FUNDAMENTAL_TOOLS],
BASIC_REQUIRE_PROGS(CMP, cmp)
BASIC_REQUIRE_PROGS(COMM, comm)
BASIC_REQUIRE_PROGS(CP, cp)
BASIC_REQUIRE_PROGS(CPIO, cpio)
BASIC_REQUIRE_PROGS(CUT, cut)
BASIC_REQUIRE_PROGS(DATE, date)
BASIC_REQUIRE_PROGS(DIFF, [gdiff diff])
@ -427,6 +426,7 @@ AC_DEFUN_ONCE([BASIC_SETUP_FUNDAMENTAL_TOOLS],
BASIC_PATH_PROGS(READLINK, [greadlink readlink])
BASIC_PATH_PROGS(DF, df)
BASIC_PATH_PROGS(SETFILE, SetFile)
BASIC_PATH_PROGS(CPIO, [cpio bsdcpio])
])
# Setup basic configuration paths, and platform-specific stuff related to PATHs.
@ -849,7 +849,12 @@ AC_DEFUN([BASIC_CHECK_FIND_DELETE],
if test -f $DELETEDIR/TestIfFindSupportsDelete; then
# No, it does not.
rm $DELETEDIR/TestIfFindSupportsDelete
FIND_DELETE="-exec rm \{\} \+"
if test "x$OPENJDK_TARGET_OS" = "xaix"; then
# AIX 'find' is buggy if called with '-exec {} \+' and an empty file list
FIND_DELETE="-print | xargs rm"
else
FIND_DELETE="-exec rm \{\} \+"
fi
AC_MSG_RESULT([no])
else
AC_MSG_RESULT([yes])
@ -954,7 +959,7 @@ AC_DEFUN([BASIC_CHECK_DIR_ON_LOCAL_DISK],
# not be the case in cygwin in certain conditions.
AC_DEFUN_ONCE([BASIC_CHECK_SRC_PERMS],
[
if test x"$OPENJDK_BUILD_OS" = xwindows; then
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
file_to_test="$SRC_ROOT/LICENSE"
if test `$STAT -c '%a' "$file_to_test"` -lt 400; then
AC_MSG_ERROR([Bad file permissions on src files. This is usually caused by cloning the repositories with a non cygwin hg in a directory not created in cygwin.])

View File

@ -266,6 +266,14 @@ AC_DEFUN([BASIC_FIXUP_EXECUTABLE_MSYS],
BASIC_WINDOWS_REWRITE_AS_UNIX_PATH(new_path)
new_path=`$WHICH "$new_path" 2> /dev/null`
# bat and cmd files are not always considered executable in MSYS causing which
# to not find them
if test "x$new_path" = x \
&& test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \
&& test "x`$LS \"$path\" 2>/dev/null`" != x; then
new_path="$path"
BASIC_WINDOWS_REWRITE_AS_UNIX_PATH(new_path)
fi
if test "x$new_path" = x; then
# It's still not found. Now this is an unrecoverable error.

View File

@ -370,18 +370,27 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS],
# Maximum amount of heap memory.
# Maximum stack size.
JVM_MAX_HEAP=`expr $MEMORY_SIZE / 2`
if test "x$BUILD_NUM_BITS" = x32; then
JVM_MAX_HEAP=1100M
if test "$JVM_MAX_HEAP" -gt "1100"; then
JVM_MAX_HEAP=1100
elif test "$JVM_MAX_HEAP" -lt "512"; then
JVM_MAX_HEAP=512
fi
STACK_SIZE=768
else
# Running Javac on a JVM on a 64-bit machine, takes more space since 64-bit
# pointers are used. Apparently, we need to increase the heap and stack
# space for the jvm. More specifically, when running javac to build huge
# jdk batch
JVM_MAX_HEAP=1600M
if test "$JVM_MAX_HEAP" -gt "1600"; then
JVM_MAX_HEAP=1600
elif test "$JVM_MAX_HEAP" -lt "512"; then
JVM_MAX_HEAP=512
fi
STACK_SIZE=1536
fi
ADD_JVM_ARG_IF_OK([-Xmx$JVM_MAX_HEAP],boot_jdk_jvmargs_big,[$JAVA])
ADD_JVM_ARG_IF_OK([-Xmx${JVM_MAX_HEAP}M],boot_jdk_jvmargs_big,[$JAVA])
ADD_JVM_ARG_IF_OK([-XX:ThreadStackSize=$STACK_SIZE],boot_jdk_jvmargs_big,[$JAVA])
AC_MSG_RESULT([$boot_jdk_jvmargs_big])

View File

@ -131,8 +131,8 @@ AC_DEFUN_ONCE([BPERF_SETUP_BUILD_JOBS],
if test "x$with_jobs" = x; then
# Number of jobs was not specified, calculate.
AC_MSG_CHECKING([for appropriate number of jobs to run in parallel])
# Approximate memory in GB, rounding up a bit.
memory_gb=`expr $MEMORY_SIZE / 1100`
# Approximate memory in GB.
memory_gb=`expr $MEMORY_SIZE / 1024`
# Pick the lowest of memory in gb and number of cores.
if test "$memory_gb" -lt "$NUM_CORES"; then
JOBS="$memory_gb"
@ -291,16 +291,11 @@ AC_DEFUN_ONCE([BPERF_SETUP_SMART_JAVAC],
AC_MSG_ERROR([Could not execute server java: $SJAVAC_SERVER_JAVA])
fi
else
SJAVAC_SERVER_JAVA=""
# Hotspot specific options.
ADD_JVM_ARG_IF_OK([-verbosegc],SJAVAC_SERVER_JAVA,[$JAVA])
# JRockit specific options.
ADD_JVM_ARG_IF_OK([-Xverbose:gc],SJAVAC_SERVER_JAVA,[$JAVA])
SJAVAC_SERVER_JAVA="$JAVA $SJAVAC_SERVER_JAVA"
SJAVAC_SERVER_JAVA="$JAVA"
fi
AC_SUBST(SJAVAC_SERVER_JAVA)
if test "$MEMORY_SIZE" -gt "2500"; then
if test "$MEMORY_SIZE" -gt "3000"; then
ADD_JVM_ARG_IF_OK([-d64],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
if test "$JVM_ARG_OK" = true; then
JVM_64BIT=true
@ -308,34 +303,33 @@ AC_DEFUN_ONCE([BPERF_SETUP_SMART_JAVAC],
fi
fi
MX_VALUE=`expr $MEMORY_SIZE / 2`
if test "$JVM_64BIT" = true; then
if test "$MEMORY_SIZE" -gt "17000"; then
ADD_JVM_ARG_IF_OK([-Xms10G -Xmx10G],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
# Set ms lower than mx since more than one instance of the server might
# get launched at the same time before they figure out which instance won.
MS_VALUE=512
if test "$MX_VALUE" -gt "2048"; then
MX_VALUE=2048
fi
if test "$MEMORY_SIZE" -gt "10000" && test "$JVM_ARG_OK" = false; then
ADD_JVM_ARG_IF_OK([-Xms6G -Xmx6G],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
fi
if test "$MEMORY_SIZE" -gt "5000" && test "$JVM_ARG_OK" = false; then
ADD_JVM_ARG_IF_OK([-Xms1G -Xmx3G],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
fi
if test "$MEMORY_SIZE" -gt "3800" && test "$JVM_ARG_OK" = false; then
ADD_JVM_ARG_IF_OK([-Xms1G -Xmx2500M],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
else
MS_VALUE=256
if test "$MX_VALUE" -gt "1500"; then
MX_VALUE=1500
fi
fi
if test "$MEMORY_SIZE" -gt "2500" && test "$JVM_ARG_OK" = false; then
ADD_JVM_ARG_IF_OK([-Xms1000M -Xmx1500M],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
fi
if test "$MEMORY_SIZE" -gt "1000" && test "$JVM_ARG_OK" = false; then
ADD_JVM_ARG_IF_OK([-Xms400M -Xmx1100M],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
fi
if test "$JVM_ARG_OK" = false; then
ADD_JVM_ARG_IF_OK([-Xms256M -Xmx512M],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
if test "$MX_VALUE" -lt "512"; then
MX_VALUE=512
fi
ADD_JVM_ARG_IF_OK([-Xms${MS_VALUE}M -Xmx${MX_VALUE}M],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
AC_MSG_CHECKING([whether to use sjavac])
AC_ARG_ENABLE([sjavac], [AS_HELP_STRING([--enable-sjavac],
[use sjavac to do fast incremental compiles @<:@disabled@:>@])],
[ENABLE_SJAVAC="${enableval}"], [ENABLE_SJAVAC='no'])
if test "x$JVM_ARG_OK" = "xfalse"; then
AC_MSG_WARN([Could not set -Xms${MS_VALUE}M -Xmx${MX_VALUE}M, disabling sjavac])
ENABLE_SJAVAC=no;
fi
AC_MSG_CHECKING([whether to use sjavac])
AC_MSG_RESULT([$ENABLE_SJAVAC])
AC_SUBST(ENABLE_SJAVAC)

View File

@ -54,6 +54,7 @@ m4_include([toolchain_windows.m4])
AC_DEFUN_ONCE([CUSTOM_EARLY_HOOK])
AC_DEFUN_ONCE([CUSTOM_LATE_HOOK])
AC_DEFUN_ONCE([CUSTOM_SUMMARY_AND_WARNINGS_HOOK])
# This line needs to be here, verbatim, after all includes and the dummy hook
# definitions. It is replaced with custom functionality when building
@ -142,7 +143,6 @@ JDKOPT_SETUP_JDK_VERSION_NUMBERS
###############################################################################
BOOTJDK_SETUP_BOOT_JDK
BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS
###############################################################################
#
@ -233,6 +233,9 @@ BPERF_SETUP_BUILD_CORES
BPERF_SETUP_BUILD_MEMORY
BPERF_SETUP_BUILD_JOBS
# Setup arguments for the boot jdk (after cores and memory have been setup)
BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS
# Setup smart javac (after cores and memory have been setup)
BPERF_SETUP_SMART_JAVAC
@ -271,3 +274,4 @@ $CHMOD +x $OUTPUT_ROOT/compare.sh
# Finally output some useful information to the user
HELP_PRINT_SUMMARY_AND_WARNINGS
CUSTOM_SUMMARY_AND_WARNINGS_HOOK

View File

@ -342,17 +342,15 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_OPTIMIZATION],
# no adjustment
;;
fastdebug )
# Add compile time bounds checks.
CFLAGS_DEBUG_OPTIONS="-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1"
CXXFLAGS_DEBUG_OPTIONS="-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1"
# no adjustment
;;
slowdebug )
# Add runtime bounds checks and symbol info.
CFLAGS_DEBUG_OPTIONS="-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-all --param ssp-buffer-size=1"
CXXFLAGS_DEBUG_OPTIONS="-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-all --param ssp-buffer-size=1"
# Add runtime stack smashing and undefined behavior checks
CFLAGS_DEBUG_OPTIONS="-fstack-protector-all --param ssp-buffer-size=1"
CXXFLAGS_DEBUG_OPTIONS="-fstack-protector-all --param ssp-buffer-size=1"
if test "x$HAS_CFLAG_DETECT_UNDEFINED_BEHAVIOR" = "xtrue"; then
CFLAGS_DEBUG_OPTIONS="$CFLAGS_DEBUG_OPTIONS $CFLAG_DETECT_UNDEFINED_BEHAVIOR_FLAG"
CXXFLAGS_DEBUG_OPTIONS="$CXXFLAGS_DEBUG_OPTIONS $CFLAG_DETECT_UNDEFINED_BEHAVIOR_FLAG"
CXXFLAGS_DEBUG_OPTIONS="$CXXFLAGS_DEBUG_OPTIONS $CFLAG_DETECT_UNDEFINED_BEHAVIsOR_FLAG"
fi
;;
esac
@ -900,7 +898,7 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_MISC],
case "${TOOLCHAIN_TYPE}" in
microsoft)
CFLAGS_WARNINGS_ARE_ERRORS="/WX"
CFLAGS_WARNINGS_ARE_ERRORS="-WX"
;;
solstudio)
CFLAGS_WARNINGS_ARE_ERRORS="-errtags -errwarn=%all"

File diff suppressed because it is too large Load Diff

View File

@ -75,20 +75,18 @@ cygwin_help() {
HELP_MSG="You might be able to fix this by running '$PKGHANDLER_COMMAND'."
;;
freetype)
if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then
HELP_MSG="To install freetype, run:
wget \"http://gnuwin32.sourceforge.net/downlinks/freetype.php\" -O /tmp/freetype-setup.exe
chmod +x /tmp/freetype-setup.exe
/tmp/freetype-setup.exe
Follow GUI prompts, and install to default directory \"C:\Program Files (x86)\GnuWin32\".
After installation, locate lib/libfreetype.dll.a and make a copy with the name freetype.dll."
else
HELP_MSG="You need to build a 64-bit version of freetype.
This is not readily available.
You can find source code and build instructions on
http://www.freetype.org/
If you put the resulting build in \"C:\Program Files\GnuWin32\", it will be found automatically."
fi
HELP_MSG="
The freetype library can now be build during the configure process.
Download the freetype sources and unpack them into an arbitrary directory:
wget http://download.savannah.gnu.org/releases/freetype/freetype-2.5.3.tar.gz
tar -xzf freetype-2.5.3.tar.gz
Then run configure with '--with-freetype-src=<freetype_src>'. This will
automatically build the freetype library into '<freetype_src>/lib64' for 64-bit
builds or into '<freetype_src>/lib32' for 32-bit builds.
Afterwards you can always use '--with-freetype-include=<freetype_src>/include'
and '--with-freetype-lib=<freetype_src>/lib[32|64]' for other builds."
;;
esac
}

View File

@ -247,12 +247,95 @@ AC_DEFUN_ONCE([LIB_SETUP_CUPS],
])
AC_DEFUN([LIB_BUILD_FREETYPE],
[
FREETYPE_SRC_PATH="$1"
BUILD_FREETYPE=yes
# Check if the freetype sources are acessible..
if ! test -d $FREETYPE_SRC_PATH; then
AC_MSG_WARN([--with-freetype-src specified, but can't find path "$FREETYPE_SRC_PATH" - ignoring --with-freetype-src])
BUILD_FREETYPE=no
fi
# ..and contain a vc2010 project file
vcxproj_path="$FREETYPE_SRC_PATH/builds/windows/vc2010/freetype.vcxproj"
if test "x$BUILD_FREETYPE" = xyes && ! test -s $vcxproj_path; then
AC_MSG_WARN([Can't find project file $vcxproj_path (you may try a newer freetype version) - ignoring --with-freetype-src])
BUILD_FREETYPE=no
fi
# Now check if configure found a version of 'msbuild.exe'
if test "x$BUILD_FREETYPE" = xyes && test "x$MSBUILD" == x ; then
AC_MSG_WARN([Can't find an msbuild.exe executable (you may try to install .NET 4.0) - ignoring --with-freetype-src])
BUILD_FREETYPE=no
fi
# Ready to go..
if test "x$BUILD_FREETYPE" = xyes; then
# msbuild requires trailing slashes for output directories
freetype_lib_path="$FREETYPE_SRC_PATH/lib$OPENJDK_TARGET_CPU_BITS/"
freetype_lib_path_unix="$freetype_lib_path"
freetype_obj_path="$FREETYPE_SRC_PATH/obj$OPENJDK_TARGET_CPU_BITS/"
BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH(vcxproj_path)
BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH(freetype_lib_path)
BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH(freetype_obj_path)
if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
freetype_platform=x64
else
freetype_platform=win32
fi
# The original freetype project file is for VS 2010 (i.e. 'v100'),
# so we have to adapt the toolset if building with any other toolsed (i.e. SDK).
# Currently 'PLATFORM_TOOLSET' is set in 'TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT'/
# 'TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT' in toolchain_windows.m4
AC_MSG_NOTICE([Trying to compile freetype sources with PlatformToolset=$PLATFORM_TOOLSET to $freetype_lib_path_unix ...])
# First we try to build the freetype.dll
$ECHO -e "@echo off\n"\
"$MSBUILD $vcxproj_path "\
"/p:PlatformToolset=$PLATFORM_TOOLSET "\
"/p:Configuration=\"Release Multithreaded\" "\
"/p:Platform=$freetype_platform "\
"/p:ConfigurationType=DynamicLibrary "\
"/p:TargetName=freetype "\
"/p:OutDir=\"$freetype_lib_path\" "\
"/p:IntDir=\"$freetype_obj_path\" > freetype.log" > freetype.bat
cmd /c freetype.bat
if test -s "$freetype_lib_path_unix/freetype.dll"; then
# If that succeeds we also build freetype.lib
$ECHO -e "@echo off\n"\
"$MSBUILD $vcxproj_path "\
"/p:PlatformToolset=$PLATFORM_TOOLSET "\
"/p:Configuration=\"Release Multithreaded\" "\
"/p:Platform=$freetype_platform "\
"/p:ConfigurationType=StaticLibrary "\
"/p:TargetName=freetype "\
"/p:OutDir=\"$freetype_lib_path\" "\
"/p:IntDir=\"$freetype_obj_path\" >> freetype.log" > freetype.bat
cmd /c freetype.bat
if test -s "$freetype_lib_path_unix/freetype.lib"; then
# Once we build both, lib and dll, set freetype lib and include path appropriately
POTENTIAL_FREETYPE_INCLUDE_PATH="$FREETYPE_SRC_PATH/include"
POTENTIAL_FREETYPE_LIB_PATH="$freetype_lib_path_unix"
AC_MSG_NOTICE([Compiling freetype sources succeeded! (see freetype.log for build results)])
else
BUILD_FREETYPE=no
fi
else
BUILD_FREETYPE=no
fi
fi
])
AC_DEFUN([LIB_CHECK_POTENTIAL_FREETYPE],
[
POTENTIAL_FREETYPE_INCLUDE_PATH="$1"
POTENTIAL_FREETYPE_LIB_PATH="$2"
METHOD="$3"
# First check if the files exists.
if test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then
# We found an arbitrary include file. That's a good sign.
@ -305,6 +388,8 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
[specify directory for the freetype include files])])
AC_ARG_WITH(freetype-lib, [AS_HELP_STRING([--with-freetype-lib],
[specify directory for the freetype library])])
AC_ARG_WITH(freetype-src, [AS_HELP_STRING([--with-freetype-src],
[specify directory with freetype sources to automatically build the library (experimental, Windows-only)])])
AC_ARG_ENABLE(freetype-bundling, [AS_HELP_STRING([--disable-freetype-bundling],
[disable bundling of the freetype library with the build result @<:@enabled on Windows or when using --with-freetype, disabled otherwise@:>@])])
@ -313,7 +398,7 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
FREETYPE_BUNDLE_LIB_PATH=
if test "x$FREETYPE_NOT_NEEDED" = xyes; then
if test "x$with_freetype" != x || test "x$with_freetype_include" != x || test "x$with_freetype_lib" != x; then
if test "x$with_freetype" != x || test "x$with_freetype_include" != x || test "x$with_freetype_lib" != x || test "x$with_freetype_src" != x; then
AC_MSG_WARN([freetype not used, so --with-freetype is ignored])
fi
if test "x$enable_freetype_bundling" != x; then
@ -324,6 +409,25 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
BUNDLE_FREETYPE="$enable_freetype_bundling"
if test "x$with_freetype_src" != x; then
if test "x$OPENJDK_TARGET_OS" = xwindows; then
# Try to build freetype if --with-freetype-src was given on Windows
LIB_BUILD_FREETYPE([$with_freetype_src])
if test "x$BUILD_FREETYPE" = xyes; then
# Okay, we built it. Check that it works.
LIB_CHECK_POTENTIAL_FREETYPE($POTENTIAL_FREETYPE_INCLUDE_PATH, $POTENTIAL_FREETYPE_LIB_PATH, [--with-freetype-src])
if test "x$FOUND_FREETYPE" != xyes; then
AC_MSG_ERROR([Can not use the built freetype at location given by --with-freetype-src])
fi
else
AC_MSG_NOTICE([User specified --with-freetype-src but building freetype failed. (see freetype.log for build results)])
AC_MSG_ERROR([Consider building freetype manually and using --with-freetype instead.])
fi
else
AC_MSG_WARN([--with-freetype-src is currently only supported on Windows - ignoring])
fi
fi
if test "x$with_freetype" != x || test "x$with_freetype_include" != x || test "x$with_freetype_lib" != x; then
# User has specified settings
@ -331,12 +435,12 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
# If not specified, default is to bundle freetype
BUNDLE_FREETYPE=yes
fi
if test "x$with_freetype" != x; then
POTENTIAL_FREETYPE_INCLUDE_PATH="$with_freetype/include"
POTENTIAL_FREETYPE_LIB_PATH="$with_freetype/lib"
fi
# Allow --with-freetype-lib and --with-freetype-include to override
if test "x$with_freetype_include" != x; then
POTENTIAL_FREETYPE_INCLUDE_PATH="$with_freetype_include"
@ -468,7 +572,7 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
FREETYPE_CFLAGS="-I$FREETYPE_INCLUDE_PATH"
fi
fi
if test "x$FREETYPE_LIBS" = x; then
BASIC_FIXUP_PATH(FREETYPE_LIB_PATH)
if test "x$OPENJDK_TARGET_OS" = xwindows; then
@ -484,7 +588,7 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
PREV_CXXCFLAGS="$CXXFLAGS"
PREV_LIBS="$LIBS"
PREV_CXX="$CXX"
CXXFLAGS="$CXXFLAGS $FREETYPE_CFLAGS"
CXXFLAGS="$CXXFLAGS $FREETYPE_CFLAGS"
LIBS="$LIBS $FREETYPE_LIBS"
CXX="$FIXPATH $CXX"
AC_LINK_IFELSE([AC_LANG_SOURCE([[
@ -502,9 +606,9 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
AC_MSG_RESULT([no])
AC_MSG_NOTICE([Could not compile and link with freetype. This might be a 32/64-bit mismatch.])
AC_MSG_NOTICE([Using FREETYPE_CFLAGS=$FREETYPE_CFLAGS and FREETYPE_LIBS=$FREETYPE_LIBS])
HELP_MSG_MISSING_DEPENDENCY([freetype])
AC_MSG_ERROR([Can not continue without freetype. $HELP_MSG])
]
)

View File

@ -173,6 +173,7 @@ AC_DEFUN([PLATFORM_EXTRACT_TARGET_AND_BUILD],
OPENJDK_BUILD_CPU_ENDIAN="$VAR_CPU_ENDIAN"
AC_SUBST(OPENJDK_BUILD_OS)
AC_SUBST(OPENJDK_BUILD_OS_API)
AC_SUBST(OPENJDK_BUILD_OS_ENV)
AC_SUBST(OPENJDK_BUILD_CPU)
AC_SUBST(OPENJDK_BUILD_CPU_ARCH)
AC_SUBST(OPENJDK_BUILD_CPU_BITS)
@ -194,6 +195,7 @@ AC_DEFUN([PLATFORM_EXTRACT_TARGET_AND_BUILD],
OPENJDK_TARGET_CPU_ENDIAN="$VAR_CPU_ENDIAN"
AC_SUBST(OPENJDK_TARGET_OS)
AC_SUBST(OPENJDK_TARGET_OS_API)
AC_SUBST(OPENJDK_TARGET_OS_ENV)
AC_SUBST(OPENJDK_TARGET_CPU)
AC_SUBST(OPENJDK_TARGET_CPU_ARCH)
AC_SUBST(OPENJDK_TARGET_CPU_BITS)

View File

@ -106,6 +106,7 @@ OPENJDK_TARGET_OS_EXPORT_DIR:=@OPENJDK_TARGET_OS_EXPORT_DIR@
# When not cross-compiling, it is the same as the target.
OPENJDK_BUILD_OS:=@OPENJDK_BUILD_OS@
OPENJDK_BUILD_OS_API:=@OPENJDK_BUILD_OS_API@
OPENJDK_BUILD_OS_ENV:=@OPENJDK_BUILD_OS_ENV@
OPENJDK_BUILD_CPU:=@OPENJDK_BUILD_CPU@
OPENJDK_BUILD_CPU_ARCH:=@OPENJDK_BUILD_CPU_ARCH@

View File

@ -557,6 +557,14 @@ AC_DEFUN_ONCE([TOOLCHAIN_DETECT_TOOLCHAIN_EXTRA],
BASIC_FIXUP_EXECUTABLE(RC)
AC_CHECK_PROG([DUMPBIN], [dumpbin], [dumpbin],,,)
BASIC_FIXUP_EXECUTABLE(DUMPBIN)
# We need to check for 'msbuild.exe' because at the place where we expect to
# find 'msbuild.exe' there's also a directory called 'msbuild' and configure
# won't find the 'msbuild.exe' executable in that case (and the
# 'ac_executable_extensions' is unusable due to performance reasons).
# Notice that we intentionally don't fix up the path to MSBUILD because we
# will call it in a DOS shell during freetype detection on Windows (see
# 'LIB_SETUP_FREETYPE' in "libraries.m4"
AC_CHECK_PROG([MSBUILD], [msbuild.exe], [msbuild.exe],,,)
fi
if test "x$OPENJDK_TARGET_OS" = xsolaris; then

View File

@ -33,6 +33,10 @@ AC_DEFUN([TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT],
if test -f "$VS100BASE/$VCVARSFILE"; then
AC_MSG_NOTICE([Found Visual Studio installation at $VS100BASE using $METHOD])
VS_ENV_CMD="$VS100BASE/$VCVARSFILE"
# PLATFORM_TOOLSET is used during the compilation of the freetype sources (see
# 'LIB_BUILD_FREETYPE' in libraries.m4) and must be one of 'v100', 'v110' or 'v120' for VS 2010, 2012 or VS2013
# TODO: improve detection for other versions of VS
PLATFORM_TOOLSET="v100"
else
AC_MSG_NOTICE([Found Visual Studio installation at $VS100BASE using $METHOD])
AC_MSG_NOTICE([Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring])
@ -61,6 +65,10 @@ AC_DEFUN([TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT],
else
VS_ENV_ARGS="/x64"
fi
# PLATFORM_TOOLSET is used during the compilation of the freetype sources (see
# 'LIB_BUILD_FREETYPE' in libraries.m4) and must be 'Windows7.1SDK' for Windows7.1SDK
# TODO: improve detection for other versions of SDK
PLATFORM_TOOLSET="Windows7.1SDK"
else
AC_MSG_NOTICE([Found Windows SDK installation at $WIN_SDK_BASE using $METHOD])
AC_MSG_NOTICE([Warning: Installation is broken, SetEnv.Cmd is missing. Ignoring])
@ -244,12 +252,22 @@ AC_DEFUN([TOOLCHAIN_CHECK_POSSIBLE_MSVCR_DLL],
# Need to check if the found msvcr is correct architecture
AC_MSG_CHECKING([found msvcr100.dll architecture])
MSVCR_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVCR_DLL"`
if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then
CORRECT_MSVCR_ARCH=386
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
# The MSYS 'file' command returns "PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit"
# on x32 and "PE32+ executable for MS Windows (DLL) (GUI) Mono/.Net assembly" on x64 systems.
if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then
CORRECT_MSVCR_ARCH="PE32 executable"
else
CORRECT_MSVCR_ARCH="PE32+ executable"
fi
else
CORRECT_MSVCR_ARCH=x86-64
if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then
CORRECT_MSVCR_ARCH=386
else
CORRECT_MSVCR_ARCH=x86-64
fi
fi
if $ECHO "$MSVCR_DLL_FILETYPE" | $GREP $CORRECT_MSVCR_ARCH 2>&1 > /dev/null; then
if $ECHO "$MSVCR_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then
AC_MSG_RESULT([ok])
MSVCR_DLL="$POSSIBLE_MSVCR_DLL"
AC_MSG_CHECKING([for msvcr100.dll])

View File

@ -77,6 +77,11 @@ do
shift
done
# debug mode
if [ "${HGFOREST_DEBUG:-false}" = "true" ] ; then
global_opts="${global_opts} --debug"
fi
# silence standard output?
if [ ${qflag} = "true" ] ; then
global_opts="${global_opts} -q"
@ -89,14 +94,26 @@ if [ ${vflag} = "true" ] ; then
fi
# Make sure we have a command.
if [ $# -lt 1 -o -z "${1:-}" ] ; then
echo "ERROR: No command to hg supplied!"
usage
if [ ${#} -lt 1 -o -z "${1:-}" ] ; then
echo "ERROR: No command to hg supplied!" > ${status_output}
usage > ${status_output}
fi
command="$1"; shift
# grab command
command="${1}"; shift
if [ ${vflag} = "true" ] ; then
echo "# Mercurial command: ${command}" > ${status_output}
fi
# capture command options and arguments (if any)
command_args="${@:-}"
if [ ${vflag} = "true" ] ; then
echo "# Mercurial command arguments: ${command_args}" > ${status_output}
fi
# Clean out the temporary directory that stores the pid files.
tmp=/tmp/forest.$$
rm -f -r ${tmp}
@ -104,7 +121,8 @@ mkdir -p ${tmp}
if [ "${HGFOREST_DEBUG:-false}" = "true" ] ; then
echo "DEBUG: temp files are in: ${tmp}"
# ignores redirection.
echo "DEBUG: temp files are in: ${tmp}" >&2
fi
# Check if we can use fifos for monitoring sub-process completion.
@ -377,21 +395,33 @@ else
fi
fi
done
if [ ${have_fifos} = "true" ]; then
# done with the fifo
exec 3>&-
fi
fi
# Wait for all subprocesses to complete
wait
# Terminate with exit 0 only if all subprocesses were successful
# Terminate with highest exit code of subprocesses
ec=0
if [ -d ${tmp} ]; then
rcfiles="`(ls -a ${tmp}/*.pid.rc 2> /dev/null) || echo ''`"
for rc in ${rcfiles} ; do
exit_code=`cat ${rc} | tr -d ' \n\r'`
if [ "${exit_code}" != "0" ] ; then
if [ ${exit_code} -gt 1 ]; then
# mercurial exit codes greater than "1" signal errors.
repo="`echo ${rc} | sed -e 's@^'${tmp}'@@' -e 's@/*\([^/]*\)\.pid\.rc$@\1@' -e 's@_@/@g'`"
echo "WARNING: ${repo} exited abnormally (${exit_code})" > ${status_output}
ec=1
fi
if [ ${exit_code} -gt ${ec} ]; then
# assume that larger exit codes are more significant
ec=${exit_code}
fi
fi
done
fi

View File

@ -1,5 +1,6 @@
^build/
^dist/
^webrev
/nbproject/private/
^.hgtip
.DS_Store

View File

@ -269,3 +269,7 @@ ddc07abf4307855c0dc904cc5c96cc764023a930 jdk9-b22
8a44142bb7fc8118f70f91a1b97c12dfc50563ee jdk9-b24
da08cca6b97f41b7081a3e176dcb400af6e4bb26 jdk9-b25
6c777df597bbf5abba3488d44c401edfe73c74af jdk9-b26
7e06bf1dcb0907b80ddf59315426ce9ce775e56d jdk9-b27
a00b04ef067e39f50b9a0fea6f1904e35d632a73 jdk9-b28
163a9cd806fd09970baf1f5f42b92a3cfe7ee945 jdk9-b29
98967ae6ae53ebf15615e07cd5a6b1ae04dfd84c jdk9-b30

View File

@ -50,8 +50,9 @@ $(eval $(call SetupJavaCompilation,BUILD_IDLJ, \
INCLUDES := com/sun/tools/corba/se/idl, \
EXCLUDE_FILES := ResourceBundleUtil.java))
# Force the language to english for predictable source code generation.
TOOL_IDLJ_CMD := $(JAVA) -cp $(CORBA_OUTPUTDIR)/idlj_classes \
com.sun.tools.corba.se.idl.toJavaPortable.Compile
-Duser.language=en com.sun.tools.corba.se.idl.toJavaPortable.Compile
################################################################################

View File

@ -38,11 +38,11 @@ package org.omg.CORBA;
* OMG specifications :
* <ul>
* <li> ORB core as defined by CORBA 2.3.1
* (<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
* (<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
* </li>
*
* <li> IDL/Java Language Mapping as defined in
* <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
* <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
* </li>
* </ul>
*/

View File

@ -67,7 +67,7 @@ if [ "x$hgwhere" = "x" ]; then
error "Could not locate Mercurial command"
fi
hgversion="`hg --version 2> /dev/null | sed -n -e 's@^Mercurial Distributed SCM (version \([^+]*\).*)\$@\1@p'`"
hgversion="`LANGUAGE=en hg --version 2> /dev/null | sed -n -e 's@^Mercurial Distributed SCM (version \([^+]*\).*)\$@\1@p'`"
if [ "x${hgversion}" = "x" ] ; then
error "Could not determine Mercurial version of $hgwhere"
fi

View File

@ -1,5 +1,6 @@
^build/
^dist/
^webrev
/nbproject/private/
^src/share/tools/hsdis/build/
^src/share/tools/IdealGraphVisualizer/[a-zA-Z0-9]*/build/

View File

@ -429,3 +429,7 @@ dd472cdacc32e3afc7c5bfa7ef16ea0e0befb7fa jdk9-b23
dde2d03b0ea46a27650839e3a1d212c7c1f7b4c8 jdk9-b24
6de94e8693240cec8aae11f6b42f43433456a733 jdk9-b25
48b95a073d752d6891cc0d1d2836b321ecf3ce0c jdk9-b26
f95347244306affc32ce3056f27ceff7b2100810 jdk9-b27
657294869d7ff063e055f5492cab7ce5612ca851 jdk9-b28
deb29e92f68ace2808a36ecfa18c7d61dcb645bb jdk9-b29
5c722dffbc0f34eb8d903dca7b261e52248fa17e jdk9-b30

View File

@ -64,7 +64,10 @@ static jmethodID listAdd_ID = 0;
#define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}
void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
(*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
jclass clazz;
clazz = (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException");
CHECK_EXCEPTION;
(*env)->ThrowNew(env, clazz, errMsg);
}
struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {
@ -149,11 +152,14 @@ static void fillThreadsAndLoadObjects(JNIEnv* env, jobject this_obj, struct ps_p
const char* name;
jobject loadObject;
jobject loadObjectList;
jstring str;
base = get_lib_base(ph, i);
name = get_lib_name(ph, i);
loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID,
(*env)->NewStringUTF(env, name), (jlong)0, (jlong)base);
str = (*env)->NewStringUTF(env, name);
CHECK_EXCEPTION;
loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID, str, (jlong)0, (jlong)base);
CHECK_EXCEPTION;
loadObjectList = (*env)->GetObjectField(env, this_obj, loadObjectList_ID);
CHECK_EXCEPTION;
@ -298,13 +304,18 @@ JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_l
JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByAddress0
(JNIEnv *env, jobject this_obj, jlong addr) {
uintptr_t offset;
jobject obj;
jstring str;
const char* sym = NULL;
struct ps_prochandle* ph = get_proc_handle(env, this_obj);
sym = symbol_for_pc(ph, (uintptr_t) addr, &offset);
if (sym == NULL) return 0;
return (*env)->CallObjectMethod(env, this_obj, createClosestSymbol_ID,
(*env)->NewStringUTF(env, sym), (jlong)offset);
str = (*env)->NewStringUTF(env, sym);
CHECK_EXCEPTION_(NULL);
obj = (*env)->CallObjectMethod(env, this_obj, createClosestSymbol_ID, str, (jlong)offset);
CHECK_EXCEPTION_(NULL);
return obj;
}
/*

View File

@ -90,7 +90,9 @@ struct DebuggerWith2Objects : DebuggerWithObject {
*/
static void throwNewDebuggerException(JNIEnv* env, const char* errMsg) {
env->ThrowNew(env->FindClass("sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
jclass clazz = env->FindClass("sun/jvm/hotspot/debugger/DebuggerException");
CHECK_EXCEPTION;
env->ThrowNew(clazz, errMsg);
}
// JNI ids for some fields, methods
@ -314,7 +316,7 @@ static void * pathmap_dlopen(const char * name, int mode) {
handle = dlopen(name, mode);
}
if (_libsaproc_debug) {
printf("libsaproc DEBUG: pathmap_dlopen %s return 0x%x\n", name, handle);
printf("libsaproc DEBUG: pathmap_dlopen %s return 0x%lx\n", name, (unsigned long) handle);
}
return handle;
}
@ -661,30 +663,30 @@ init_classsharing_workaround(void *cd, const prmap_t* pmap, const char* obj_name
// read FileMapHeader
size_t n = read(fd, pheader, sizeof(struct FileMapHeader));
if (n != sizeof(struct FileMapHeader)) {
free(pheader);
close(fd);
char errMsg[ERR_MSG_SIZE];
sprintf(errMsg, "unable to read shared archive file map header from %s", classes_jsa);
close(fd);
free(pheader);
THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
}
// check file magic
if (pheader->_magic != 0xf00baba2) {
free(pheader);
close(fd);
char errMsg[ERR_MSG_SIZE];
sprintf(errMsg, "%s has bad shared archive magic 0x%x, expecting 0xf00baba2",
classes_jsa, pheader->_magic);
close(fd);
free(pheader);
THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
}
// check version
if (pheader->_version != CURRENT_ARCHIVE_VERSION) {
free(pheader);
close(fd);
char errMsg[ERR_MSG_SIZE];
sprintf(errMsg, "%s has wrong shared archive version %d, expecting %d",
classes_jsa, pheader->_version, CURRENT_ARCHIVE_VERSION);
close(fd);
free(pheader);
THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
}
@ -962,6 +964,7 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLoca
CHECK_EXCEPTION_(0);
jboolean isCopy;
jlong* ptr = env->GetLongArrayElements(res, &isCopy);
CHECK_EXCEPTION_(NULL);
for (int i = 0; i < NPRGREG; i++) {
ptr[i] = (jlong) (uintptr_t) gregs[i];
}
@ -1253,6 +1256,7 @@ JNIEXPORT jstring JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_d
(JNIEnv *env, jobject this_object, jstring name) {
jboolean isCopy;
const char* ptr = env->GetStringUTFChars(name, &isCopy);
CHECK_EXCEPTION_(NULL);
char buf[2*SYMBOL_BUF_SIZE + 1];
jstring res = 0;
if (cplus_demangle((char*) ptr, buf, sizeof(buf)) != DEMANGLE_ESPACE) {
@ -1439,7 +1443,9 @@ JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_init
"createClosestSymbol", "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;");
CHECK_EXCEPTION;
listAdd_ID = env->GetMethodID(env->FindClass("java/util/List"), "add", "(Ljava/lang/Object;)Z");
jclass list_clazz = env->FindClass("java/util/List");
CHECK_EXCEPTION;
listAdd_ID = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z");
CHECK_EXCEPTION;
// part of the class sharing workaround

View File

@ -43,10 +43,10 @@ import sun.jvm.hotspot.types.TypeDataBase;
// Mirror class for G1CollectedHeap.
public class G1CollectedHeap extends SharedHeap {
// HeapRegionSeq _seq;
static private long hrsFieldOffset;
// MemRegion _g1_committed;
static private long g1CommittedFieldOffset;
// HeapRegionManager _hrm;
static private long hrmFieldOffset;
// MemRegion _g1_reserved;
static private long g1ReservedFieldOffset;
// size_t _summary_bytes_used;
static private CIntegerField summaryBytesUsedField;
// G1MonitoringSupport* _g1mm;
@ -67,8 +67,7 @@ public class G1CollectedHeap extends SharedHeap {
static private synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("G1CollectedHeap");
hrsFieldOffset = type.getField("_hrs").getOffset();
g1CommittedFieldOffset = type.getField("_g1_committed").getOffset();
hrmFieldOffset = type.getField("_hrm").getOffset();
summaryBytesUsedField = type.getCIntegerField("_summary_bytes_used");
g1mmField = type.getAddressField("_g1mm");
oldSetFieldOffset = type.getField("_old_set").getOffset();
@ -76,9 +75,7 @@ public class G1CollectedHeap extends SharedHeap {
}
public long capacity() {
Address g1CommittedAddr = addr.addOffsetTo(g1CommittedFieldOffset);
MemRegion g1Committed = new MemRegion(g1CommittedAddr);
return g1Committed.byteSize();
return hrm().capacity();
}
public long used() {
@ -86,13 +83,13 @@ public class G1CollectedHeap extends SharedHeap {
}
public long n_regions() {
return hrs().length();
return hrm().length();
}
private HeapRegionSeq hrs() {
Address hrsAddr = addr.addOffsetTo(hrsFieldOffset);
return (HeapRegionSeq) VMObjectFactory.newObject(HeapRegionSeq.class,
hrsAddr);
private HeapRegionManager hrm() {
Address hrmAddr = addr.addOffsetTo(hrmFieldOffset);
return (HeapRegionManager) VMObjectFactory.newObject(HeapRegionManager.class,
hrmAddr);
}
public G1MonitoringSupport g1mm() {
@ -113,7 +110,7 @@ public class G1CollectedHeap extends SharedHeap {
}
private Iterator<HeapRegion> heapRegionIterator() {
return hrs().heapRegionIterator();
return hrm().heapRegionIterator();
}
public void heapRegionIterate(SpaceClosure scl) {

View File

@ -93,19 +93,35 @@ public class G1HeapRegionTable extends VMObject {
private class HeapRegionIterator implements Iterator<HeapRegion> {
private long index;
private long length;
private HeapRegion next;
public HeapRegion positionToNext() {
HeapRegion result = next;
while (index < length && at(index) == null) {
index++;
}
if (index < length) {
next = at(index);
index++; // restart search at next element
} else {
next = null;
}
return result;
}
@Override
public boolean hasNext() { return index < length; }
public boolean hasNext() { return next != null; }
@Override
public HeapRegion next() { return at(index++); }
public HeapRegion next() { return positionToNext(); }
@Override
public void remove() { /* not supported */ }
public void remove() { /* not supported */ }
HeapRegionIterator(long committedLength) {
HeapRegionIterator(long totalLength) {
index = 0;
length = committedLength;
length = totalLength;
positionToNext();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -37,13 +37,13 @@ import sun.jvm.hotspot.types.CIntegerField;
import sun.jvm.hotspot.types.Type;
import sun.jvm.hotspot.types.TypeDataBase;
// Mirror class for HeapRegionSeq. It essentially encapsulates the G1HeapRegionTable.
// Mirror class for HeapRegionManager.
public class HeapRegionSeq extends VMObject {
public class HeapRegionManager extends VMObject {
// G1HeapRegionTable _regions
static private long regionsFieldOffset;
// uint _committed_length
static private CIntegerField committedLengthField;
static private CIntegerField numCommittedField;
static {
VM.registerVMInitializedObserver(new Observer() {
@ -54,10 +54,10 @@ public class HeapRegionSeq extends VMObject {
}
static private synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("HeapRegionSeq");
Type type = db.lookupType("HeapRegionManager");
regionsFieldOffset = type.getField("_regions").getOffset();
committedLengthField = type.getCIntegerField("_committed_length");
numCommittedField = type.getCIntegerField("_num_committed");
}
private G1HeapRegionTable regions() {
@ -66,19 +66,23 @@ public class HeapRegionSeq extends VMObject {
regionsAddr);
}
public long capacity() {
return length() * HeapRegion.grainBytes();
}
public long length() {
return regions().length();
}
public long committedLength() {
return committedLengthField.getValue(addr);
return numCommittedField.getValue(addr);
}
public Iterator<HeapRegion> heapRegionIterator() {
return regions().heapRegionIterator(committedLength());
return regions().heapRegionIterator(length());
}
public HeapRegionSeq(Address addr) {
public HeapRegionManager(Address addr) {
super(addr);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -49,7 +49,6 @@ public class ArrayKlass extends Klass {
higherDimension = new MetadataField(type.getAddressField("_higher_dimension"), 0);
lowerDimension = new MetadataField(type.getAddressField("_lower_dimension"), 0);
vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), 0);
componentMirror = new OopField(type.getOopField("_component_mirror"), 0);
javaLangCloneableName = null;
javaLangObjectName = null;
javaIoSerializableName = null;
@ -63,7 +62,6 @@ public class ArrayKlass extends Klass {
private static MetadataField higherDimension;
private static MetadataField lowerDimension;
private static CIntField vtableLen;
private static OopField componentMirror;
public Klass getJavaSuper() {
SystemDictionary sysDict = VM.getVM().getSystemDictionary();
@ -74,7 +72,6 @@ public class ArrayKlass extends Klass {
public Klass getHigherDimension() { return (Klass) higherDimension.getValue(this); }
public Klass getLowerDimension() { return (Klass) lowerDimension.getValue(this); }
public long getVtableLen() { return vtableLen.getValue(this); }
public Oop getComponentMirror() { return componentMirror.getValue(this); }
// constant class names - javaLangCloneable, javaIoSerializable, javaLangObject
// Initialized lazily to avoid initialization ordering dependencies between ArrayKlass and SymbolTable
@ -144,6 +141,5 @@ public class ArrayKlass extends Klass {
visitor.doMetadata(higherDimension, true);
visitor.doMetadata(lowerDimension, true);
visitor.doCInt(vtableLen, true);
visitor.doOop(componentMirror, true);
}
}

View File

@ -337,7 +337,7 @@ export_optimized:
export_product_jdk::
$(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) generic_export
export_optimized_jdk::
$(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) generic_export
$(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) generic_export
export_fastdebug_jdk::
$(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) generic_export
export_debug_jdk::
@ -721,6 +721,19 @@ copy_debug_jdk::
($(CD) $(JDK_IMAGE_DIR)/debug && $(TAR) -xf -) ; \
fi
copy_optimized_jdk::
$(RM) -r $(JDK_IMAGE_DIR)/optimized
$(MKDIR) -p $(JDK_IMAGE_DIR)/optimized
if [ -d $(JDK_IMPORT_PATH)/optimized ] ; then \
($(CD) $(JDK_IMPORT_PATH)/optimized && \
$(TAR) -cf - $(JDK_DIRS)) | \
($(CD) $(JDK_IMAGE_DIR)/optimized && $(TAR) -xf -) ; \
else \
($(CD) $(JDK_IMPORT_PATH) && \
$(TAR) -cf - $(JDK_DIRS)) | \
($(CD) $(JDK_IMAGE_DIR)/optimized && $(TAR) -xf -) ; \
fi
#
# Check target
#

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -125,7 +125,6 @@ SUNWprivate_1.1 {
JVM_GetClassSignature;
JVM_GetClassSigners;
JVM_GetClassTypeAnnotations;
JVM_GetComponentType;
JVM_GetDeclaredClasses;
JVM_GetDeclaringClass;
JVM_GetEnclosingMethodInfo;

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -125,7 +125,6 @@ SUNWprivate_1.1 {
JVM_GetClassSignature;
JVM_GetClassSigners;
JVM_GetClassTypeAnnotations;
JVM_GetComponentType;
JVM_GetDeclaredClasses;
JVM_GetDeclaringClass;
JVM_GetEnclosingMethodInfo;

View File

@ -325,6 +325,10 @@ ifeq ($(USE_CLANG), true)
else ifeq ($(shell expr $(CC_VER_MAJOR) = 5 \& $(CC_VER_MINOR) = 1), 1)
OPT_CFLAGS/loopTransform.o += $(OPT_CFLAGS/NOOPT)
OPT_CFLAGS/unsafe.o += -O1
# Clang 6.0
else ifeq ($(shell expr $(CC_VER_MAJOR) = 6 \& $(CC_VER_MINOR) = 0), 1)
OPT_CFLAGS/loopTransform.o += $(OPT_CFLAGS/NOOPT)
OPT_CFLAGS/unsafe.o += -O1
else
$(error "Update compiler workarounds for Clang $(CC_VER_MAJOR).$(CC_VER_MINOR)")
endif
@ -508,13 +512,9 @@ endif
ifeq ($(USE_CLANG),)
# Enable bounds checking.
# _FORTIFY_SOURCE appears in GCC 4.0+
ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) )" "1"
# compile time size bounds checks
FASTDEBUG_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
# and runtime size bounds checks and paranoid stack smashing checks.
DEBUG_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-all --param ssp-buffer-size=1
# stack smashing checks.
DEBUG_CFLAGS += -fstack-protector-all --param ssp-buffer-size=1
endif
endif

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -123,7 +123,6 @@
_JVM_GetClassSignature
_JVM_GetClassSigners
_JVM_GetClassTypeAnnotations
_JVM_GetComponentType
_JVM_GetDeclaredClasses
_JVM_GetDeclaringClass
_JVM_GetEnclosingMethodInfo

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -123,7 +123,6 @@
_JVM_GetClassSignature
_JVM_GetClassSigners
_JVM_GetClassTypeAnnotations
_JVM_GetComponentType
_JVM_GetDeclaredClasses
_JVM_GetDeclaringClass
_JVM_GetEnclosingMethodInfo

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -125,7 +125,6 @@ SUNWprivate_1.1 {
JVM_GetClassSignature;
JVM_GetClassSigners;
JVM_GetClassTypeAnnotations;
JVM_GetComponentType;
JVM_GetDeclaredClasses;
JVM_GetDeclaringClass;
JVM_GetEnclosingMethodInfo;

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -125,7 +125,6 @@ SUNWprivate_1.1 {
JVM_GetClassSignature;
JVM_GetClassSigners;
JVM_GetClassTypeAnnotations;
JVM_GetComponentType;
JVM_GetDeclaredClasses;
JVM_GetDeclaringClass;
JVM_GetEnclosingMethodInfo;

View File

@ -70,7 +70,8 @@ ifeq ($(INCLUDE_CDS), false)
CXXFLAGS += -DINCLUDE_CDS=0
CFLAGS += -DINCLUDE_CDS=0
Src_Files_EXCLUDE += filemap.cpp metaspaceShared.cpp
Src_Files_EXCLUDE += filemap.cpp metaspaceShared*.cpp sharedPathsMiscInfo.cpp \
systemDictionaryShared.cpp classLoaderExt.cpp sharedClassUtil.cpp
endif
ifeq ($(INCLUDE_ALL_GCS), false)
@ -119,8 +120,8 @@ ifeq ($(INCLUDE_NMT), false)
CFLAGS += -DINCLUDE_NMT=0
Src_Files_EXCLUDE += \
memBaseline.cpp memPtr.cpp memRecorder.cpp memReporter.cpp memSnapshot.cpp memTrackWorker.cpp \
memTracker.cpp nmtDCmd.cpp
memBaseline.cpp memReporter.cpp mallocTracker.cpp virtualMemoryTracker.cpp nmtCommon.cpp \
memTracker.cpp nmtDCmd.cpp mallocSiteTable.cpp
endif
-include $(HS_ALT_MAKE)/excludeSrc.make

View File

@ -42,6 +42,9 @@ jprt_build_debugEmb:
jprt_build_fastdebugEmb:
$(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_fastdebug
jprt_build_optimizedEmb:
$(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_optimized
jprt_build_productOpen:
$(MAKE) OPENJDK=true jprt_build_product
@ -51,6 +54,9 @@ jprt_build_debugOpen:
jprt_build_fastdebugOpen:
$(MAKE) OPENJDK=true jprt_build_fastdebug
jprt_build_optimizedOpen:
$(MAKE) OPENJDK=true jprt_build_optimized
jprt_build_product: all_product copy_product_jdk export_product_jdk
( $(CD) $(JDK_IMAGE_DIR) && \
$(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
@ -63,5 +69,9 @@ jprt_build_debug: all_debug copy_debug_jdk export_debug_jdk
( $(CD) $(JDK_IMAGE_DIR)/debug && \
$(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
.PHONY: jprt_build_product jprt_build_fastdebug jprt_build_debug
jprt_build_optimized: all_optimized copy_optimized_jdk export_optimized_jdk
( $(CD) $(JDK_IMAGE_DIR)/optimized && \
$(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
.PHONY: jprt_build_product jprt_build_fastdebug jprt_build_debug jprt_build_optimized

View File

@ -93,13 +93,13 @@ jprt.my.windows.x64=${jprt.my.windows.x64.${jprt.tools.default.release}}
# Standard list of jprt build targets for this source tree
jprt.build.targets.standard= \
${jprt.my.solaris.sparcv9}-{product|fastdebug|optimized}, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}, \
${jprt.my.solaris.x64}-{product|fastdebug}, \
${jprt.my.linux.i586}-{product|fastdebug}, \
${jprt.my.linux.x64}-{product|fastdebug|optimized}, \
${jprt.my.linux.x64}-{product|fastdebug}, \
${jprt.my.macosx.x64}-{product|fastdebug}, \
${jprt.my.windows.i586}-{product|fastdebug}, \
${jprt.my.windows.x64}-{product|fastdebug|optimized}, \
${jprt.my.windows.x64}-{product|fastdebug}, \
${jprt.my.linux.armvh}-{product|fastdebug}
jprt.build.targets.open= \
@ -356,14 +356,15 @@ jprt.make.rule.test.targets.standard.internalvmtests = \
${jprt.my.windows.x64}-fastdebug-c2-internalvmtests
jprt.make.rule.test.targets.standard.reg.group = \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GROUP, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GROUP, \
${jprt.my.linux.i586}-{product|fastdebug}-c2-GROUP, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GROUP, \
${jprt.my.windows.i586}-{product|fastdebug}-c2-GROUP, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GROUP, \
${jprt.my.linux.i586}-{product|fastdebug}-c1-GROUP, \
${jprt.my.windows.i586}-{product|fastdebug}-c1-GROUP
${jprt.my.solaris.sparcv9}-fastdebug-c2-GROUP, \
${jprt.my.solaris.x64}-fastdebug-c2-GROUP, \
${jprt.my.linux.i586}-fastdebug-c2-GROUP, \
${jprt.my.linux.x64}-fastdebug-c2-GROUP, \
${jprt.my.macosx.x64}-fastdebug-c2-GROUP, \
${jprt.my.windows.i586}-fastdebug-c2-GROUP, \
${jprt.my.windows.x64}-fastdebug-c2-GROUP, \
${jprt.my.linux.i586}-fastdebug-c1-GROUP, \
${jprt.my.windows.i586}-fastdebug-c1-GROUP
jprt.make.rule.test.targets.standard = \
${jprt.make.rule.test.targets.standard.client}, \
@ -373,6 +374,7 @@ jprt.make.rule.test.targets.standard = \
${jprt.make.rule.test.targets.standard.reg.group:GROUP=hotspot_compiler}, \
${jprt.make.rule.test.targets.standard.reg.group:GROUP=hotspot_gc}, \
${jprt.make.rule.test.targets.standard.reg.group:GROUP=hotspot_runtime}, \
${jprt.make.rule.test.targets.standard.reg.group:GROUP=hotspot_runtime_closed}, \
${jprt.make.rule.test.targets.standard.reg.group:GROUP=hotspot_serviceability}
jprt.make.rule.test.targets.embedded = \

View File

@ -365,16 +365,13 @@ endif
ifeq ($(USE_CLANG),)
# Enable bounds checking.
# _FORTIFY_SOURCE appears in GCC 4.0+
ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) )" "1"
# compile time size bounds checks
FASTDEBUG_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
# and runtime size bounds checks and paranoid stack smashing checks.
DEBUG_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-all --param ssp-buffer-size=1
# stack smashing checks.
DEBUG_CFLAGS += -fstack-protector-all --param ssp-buffer-size=1
endif
endif
# If we are building HEADLESS, pass on to VM
# so it can set the java.awt.headless property
ifdef HEADLESS

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -125,7 +125,6 @@ SUNWprivate_1.1 {
JVM_GetClassSignature;
JVM_GetClassSigners;
JVM_GetClassTypeAnnotations;
JVM_GetComponentType;
JVM_GetDeclaredClasses;
JVM_GetDeclaringClass;
JVM_GetEnclosingMethodInfo;

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -125,7 +125,6 @@ SUNWprivate_1.1 {
JVM_GetClassSignature;
JVM_GetClassSigners;
JVM_GetClassTypeAnnotations;
JVM_GetComponentType;
JVM_GetDeclaredClasses;
JVM_GetDeclaringClass;
JVM_GetEnclosingMethodInfo;

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -58,6 +58,8 @@ DTRACE_SRCDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/dtrace
DTRACE_COMMON_SRCDIR = $(GAMMADIR)/src/os/posix/dtrace
DTRACE = dtrace
DTRACE.o = $(DTRACE).o
DTRACE_JHELPER = dtrace_jhelper
DTRACE_JHELPER.o = $(DTRACE_JHELPER).o
# to remove '-g' option which causes link problems
# also '-z nodefs' is used as workaround
@ -255,7 +257,10 @@ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
endif
$(DTRACE).d: $(DTRACE_COMMON_SRCDIR)/hotspot.d $(DTRACE_COMMON_SRCDIR)/hotspot_jni.d \
$(DTRACE_COMMON_SRCDIR)/hs_private.d $(DTRACE_SRCDIR)/jhelper.d
$(DTRACE_COMMON_SRCDIR)/hs_private.d
$(QUIETLY) cat $^ > $@
$(DTRACE_JHELPER).d: $(DTRACE_SRCDIR)/jhelper.d
$(QUIETLY) cat $^ > $@
DTraced_Files = ciEnv.o \
@ -280,7 +285,7 @@ DTraced_Files = ciEnv.o \
vmGCOperations.o \
# Dtrace is available, so we build $(DTRACE.o)
$(DTRACE.o): $(DTRACE).d $(JVMOFFS).h $(JVMOFFS)Index.h $(DTraced_Files)
$(DTRACE.o): $(DTRACE).d $(DTraced_Files)
@echo Compiling $(DTRACE).d
$(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -G -xlazyload -o $@ -s $(DTRACE).d \
@ -344,6 +349,11 @@ $(DtraceOutDir)/hs_private.h: $(DTRACE_COMMON_SRCDIR)/hs_private.d | $(DtraceOut
dtrace_gen_headers: $(DtraceOutDir)/hotspot.h $(DtraceOutDir)/hotspot_jni.h $(DtraceOutDir)/hs_private.h
# The jhelper.d and hotspot probes are separated into two different SUNW_dof sections.
# Now the jhelper.d is built without the -Xlazyload flag.
$(DTRACE_JHELPER.o) : $(DTRACE_JHELPER).d $(JVMOFFS).h $(JVMOFFS)Index.h
@echo Compiling $(DTRACE_JHELPER).d
$(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -G -o $@ -s $(DTRACE_JHELPER).d
.PHONY: dtraceCheck
@ -372,7 +382,7 @@ endif # ifneq ("$(patchDtraceFound)", "")
ifneq ("${DTRACE_PROG}", "")
ifeq ("${HOTSPOT_DISABLE_DTRACE_PROBES}", "")
DTRACE_OBJS = $(DTRACE.o) $(JVMOFFS.o)
DTRACE_OBJS = $(DTRACE.o) $(JVMOFFS.o) $(DTRACE_JHELPER.o)
CFLAGS += $(DTRACE_INCL) -DDTRACE_ENABLED
MAPFILE_DTRACE_OPT = $(MAPFILE_DTRACE)

View File

@ -240,11 +240,7 @@ ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
endif
# Enable bounds checking.
# _FORTIFY_SOURCE appears in GCC 4.0+
ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) )" "1"
# compile time size bounds checks
FASTDEBUG_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
# and runtime size bounds checks and paranoid stack smashing checks.
DEBUG_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-all --param ssp-buffer-size=1
# stack smashing checks.
DEBUG_CFLAGS += -fstack-protector-all --param ssp-buffer-size=1
endif

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -124,7 +124,6 @@ SUNWprivate_1.1 {
JVM_GetClassNameUTF;
JVM_GetClassSignature;
JVM_GetClassSigners;
JVM_GetComponentType;
JVM_GetClassTypeAnnotations;
JVM_GetDeclaredClasses;
JVM_GetDeclaringClass;

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -53,9 +53,9 @@ ifeq ($(JRE_RELEASE_VER),1.6.0)
VALIDATED_COMPILER_REVS := 5.8
VALIDATED_CC_COMPILER_REVS := 5.8
else
# Validated compiler for JDK7 is SS12 update 1 + patches (5.10)
VALIDATED_COMPILER_REVS := 5.10
VALIDATED_CC_COMPILER_REVS := 5.10
# Validated compiler for JDK9 is SS12.3 (5.12)
VALIDATED_COMPILER_REVS := 5.12
VALIDATED_CC_COMPILER_REVS := 5.12
endif
# Warning messages about not using the above validated versions

View File

@ -34,6 +34,9 @@ ALTSRC=$(WorkSpace)\src\closed
CXX_FLAGS=$(CXX_FLAGS) /D "PRODUCT"
!else
CXX_FLAGS=$(CXX_FLAGS) /D "ASSERT"
!if "$(BUILDARCH)" == "amd64"
CXX_FLAGS=$(CXX_FLAGS) /homeparams
!endif
!endif
!if "$(Variant)" == "compiler1"

View File

@ -298,6 +298,7 @@ class Assembler : public AbstractAssembler {
LWZ_OPCODE = (32u << OPCODE_SHIFT),
LWZX_OPCODE = (31u << OPCODE_SHIFT | 23u << 1),
LWZU_OPCODE = (33u << OPCODE_SHIFT),
LWBRX_OPCODE = (31u << OPCODE_SHIFT | 534 << 1),
LHA_OPCODE = (42u << OPCODE_SHIFT),
LHAX_OPCODE = (31u << OPCODE_SHIFT | 343u << 1),
@ -306,6 +307,7 @@ class Assembler : public AbstractAssembler {
LHZ_OPCODE = (40u << OPCODE_SHIFT),
LHZX_OPCODE = (31u << OPCODE_SHIFT | 279u << 1),
LHZU_OPCODE = (41u << OPCODE_SHIFT),
LHBRX_OPCODE = (31u << OPCODE_SHIFT | 790 << 1),
LBZ_OPCODE = (34u << OPCODE_SHIFT),
LBZX_OPCODE = (31u << OPCODE_SHIFT | 87u << 1),
@ -1364,11 +1366,17 @@ class Assembler : public AbstractAssembler {
inline void lwax( Register d, Register s1, Register s2);
inline void lwa( Register d, int si16, Register s1);
// 4 bytes reversed
inline void lwbrx( Register d, Register s1, Register s2);
// 2 bytes
inline void lhzx( Register d, Register s1, Register s2);
inline void lhz( Register d, int si16, Register s1);
inline void lhzu( Register d, int si16, Register s1);
// 2 bytes reversed
inline void lhbrx( Register d, Register s1, Register s2);
// 2 bytes
inline void lhax( Register d, Register s1, Register s2);
inline void lha( Register d, int si16, Register s1);
@ -1858,10 +1866,12 @@ class Assembler : public AbstractAssembler {
inline void lwz( Register d, int si16);
inline void lwax( Register d, Register s2);
inline void lwa( Register d, int si16);
inline void lwbrx(Register d, Register s2);
inline void lhzx( Register d, Register s2);
inline void lhz( Register d, int si16);
inline void lhax( Register d, Register s2);
inline void lha( Register d, int si16);
inline void lhbrx(Register d, Register s2);
inline void lbzx( Register d, Register s2);
inline void lbz( Register d, int si16);
inline void ldx( Register d, Register s2);

View File

@ -263,10 +263,14 @@ inline void Assembler::lwzu( Register d, int si16, Register s1) { assert(d !=
inline void Assembler::lwax( Register d, Register s1, Register s2) { emit_int32(LWAX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::lwa( Register d, int si16, Register s1) { emit_int32(LWA_OPCODE | rt(d) | ds(si16) | ra0mem(s1));}
inline void Assembler::lwbrx( Register d, Register s1, Register s2) { emit_int32(LWBRX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::lhzx( Register d, Register s1, Register s2) { emit_int32(LHZX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::lhz( Register d, int si16, Register s1) { emit_int32(LHZ_OPCODE | rt(d) | d1(si16) | ra0mem(s1));}
inline void Assembler::lhzu( Register d, int si16, Register s1) { assert(d != s1, "according to ibm manual"); emit_int32(LHZU_OPCODE | rt(d) | d1(si16) | rta0mem(s1));}
inline void Assembler::lhbrx( Register d, Register s1, Register s2) { emit_int32(LHBRX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::lhax( Register d, Register s1, Register s2) { emit_int32(LHAX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::lha( Register d, int si16, Register s1) { emit_int32(LHA_OPCODE | rt(d) | d1(si16) | ra0mem(s1));}
inline void Assembler::lhau( Register d, int si16, Register s1) { assert(d != s1, "according to ibm manual"); emit_int32(LHAU_OPCODE | rt(d) | d1(si16) | rta0mem(s1));}
@ -736,10 +740,12 @@ inline void Assembler::lwzx( Register d, Register s2) { emit_int32( LWZX_OPCODE
inline void Assembler::lwz( Register d, int si16 ) { emit_int32( LWZ_OPCODE | rt(d) | d1(si16));}
inline void Assembler::lwax( Register d, Register s2) { emit_int32( LWAX_OPCODE | rt(d) | rb(s2));}
inline void Assembler::lwa( Register d, int si16 ) { emit_int32( LWA_OPCODE | rt(d) | ds(si16));}
inline void Assembler::lwbrx(Register d, Register s2) { emit_int32( LWBRX_OPCODE| rt(d) | rb(s2));}
inline void Assembler::lhzx( Register d, Register s2) { emit_int32( LHZX_OPCODE | rt(d) | rb(s2));}
inline void Assembler::lhz( Register d, int si16 ) { emit_int32( LHZ_OPCODE | rt(d) | d1(si16));}
inline void Assembler::lhax( Register d, Register s2) { emit_int32( LHAX_OPCODE | rt(d) | rb(s2));}
inline void Assembler::lha( Register d, int si16 ) { emit_int32( LHA_OPCODE | rt(d) | d1(si16));}
inline void Assembler::lhbrx(Register d, Register s2) { emit_int32( LHBRX_OPCODE| rt(d) | rb(s2));}
inline void Assembler::lbzx( Register d, Register s2) { emit_int32( LBZX_OPCODE | rt(d) | rb(s2));}
inline void Assembler::lbz( Register d, int si16 ) { emit_int32( LBZ_OPCODE | rt(d) | d1(si16));}
inline void Assembler::ld( Register d, int si16 ) { emit_int32( LD_OPCODE | rt(d) | ds(si16));}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012, 2013 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -26,8 +26,9 @@
#ifndef CPU_PPC_VM_CPPINTERPRETERGENERATOR_PPC_HPP
#define CPU_PPC_VM_CPPINTERPRETERGENERATOR_PPC_HPP
address generate_normal_entry(void);
address generate_native_entry(void);
address generate_normal_entry(bool synchronized);
address generate_native_entry(bool synchronized);
address generate_math_entry(AbstractInterpreter::MethodKind kind) { return NULL; }
void lock_method(void);
void unlock_method(void);

View File

@ -938,8 +938,9 @@ void CppInterpreterGenerator::generate_counter_incr(Label& overflow) {
// Interpreter stub for calling a native method. (C++ interpreter)
// This sets up a somewhat different looking stack for calling the native method
// than the typical interpreter frame setup.
// The synchronized parameter is ignored.
//
address CppInterpreterGenerator::generate_native_entry(void) {
address CppInterpreterGenerator::generate_native_entry(bool synchronized) {
if (native_entry != NULL) return native_entry;
address entry = __ pc();
@ -1729,7 +1730,8 @@ void CppInterpreterGenerator::generate_more_monitors() {
__ std(R0, BasicObjectLock::obj_offset_in_bytes(), stack_base); // Mark lock as unused
}
address CppInterpreterGenerator::generate_normal_entry(void) {
// The synchronized parameter is ignored
address CppInterpreterGenerator::generate_normal_entry(bool synchronized) {
if (interpreter_frame_manager != NULL) return interpreter_frame_manager;
address entry = __ pc();
@ -2789,38 +2791,6 @@ address CppInterpreterGenerator::generate_normal_entry(void) {
return interpreter_frame_manager;
}
// Generate code for various sorts of method entries
//
address AbstractInterpreterGenerator::generate_method_entry(AbstractInterpreter::MethodKind kind) {
address entry_point = NULL;
switch (kind) {
case Interpreter::zerolocals : break;
case Interpreter::zerolocals_synchronized : break;
case Interpreter::native : // Fall thru
case Interpreter::native_synchronized : entry_point = ((CppInterpreterGenerator*)this)->generate_native_entry(); break;
case Interpreter::empty : break;
case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break;
case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break;
// These are special interpreter intrinsics which we don't support so far.
case Interpreter::java_lang_math_sin : break;
case Interpreter::java_lang_math_cos : break;
case Interpreter::java_lang_math_tan : break;
case Interpreter::java_lang_math_abs : break;
case Interpreter::java_lang_math_log : break;
case Interpreter::java_lang_math_log10 : break;
case Interpreter::java_lang_math_sqrt : break;
case Interpreter::java_lang_math_pow : break;
case Interpreter::java_lang_math_exp : break;
case Interpreter::java_lang_ref_reference_get: entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
default : ShouldNotReachHere(); break;
}
if (entry_point) {
return entry_point;
}
return ((InterpreterGenerator*)this)->generate_normal_entry();
}
InterpreterGenerator::InterpreterGenerator(StubQueue* code)
: CppInterpreterGenerator(code) {

View File

@ -119,9 +119,15 @@ void InterpreterMacroAssembler::check_and_handle_popframe(Register scratch_reg)
// Call the Interpreter::remove_activation_preserving_args_entry()
// func to get the address of the same-named entrypoint in the
// generated interpreter code.
#if defined(ABI_ELFv2)
call_c(CAST_FROM_FN_PTR(address,
Interpreter::remove_activation_preserving_args_entry),
relocInfo::none);
#else
call_c(CAST_FROM_FN_PTR(FunctionDescriptor*,
Interpreter::remove_activation_preserving_args_entry),
relocInfo::none);
#endif
// Jump to Interpreter::_remove_activation_preserving_args_entry.
mtctr(R3_RET);
@ -331,29 +337,40 @@ void InterpreterMacroAssembler::empty_expression_stack() {
void InterpreterMacroAssembler::get_2_byte_integer_at_bcp(int bcp_offset,
Register Rdst,
signedOrNot is_signed) {
#if defined(VM_LITTLE_ENDIAN)
if (bcp_offset) {
load_const_optimized(Rdst, bcp_offset);
lhbrx(Rdst, R14_bcp, Rdst);
} else {
lhbrx(Rdst, R14_bcp);
}
if (is_signed == Signed) {
extsh(Rdst, Rdst);
}
#else
// Read Java big endian format.
if (is_signed == Signed) {
lha(Rdst, bcp_offset, R14_bcp);
} else {
lhz(Rdst, bcp_offset, R14_bcp);
}
#if 0
assert(Rtmp != Rdst, "need separate temp register");
Register Rfirst = Rtmp;
lbz(Rfirst, bcp_offset, R14_bcp); // first byte
lbz(Rdst, bcp_offset+1, R14_bcp); // second byte
// Rdst = ((Rfirst<<8) & 0xFF00) | (Rdst &~ 0xFF00)
rldimi(/*RA=*/Rdst, /*RS=*/Rfirst, /*sh=*/8, /*mb=*/48);
if (is_signed == Signed) {
extsh(Rdst, Rdst);
}
#endif
}
void InterpreterMacroAssembler::get_4_byte_integer_at_bcp(int bcp_offset,
Register Rdst,
signedOrNot is_signed) {
#if defined(VM_LITTLE_ENDIAN)
if (bcp_offset) {
load_const_optimized(Rdst, bcp_offset);
lwbrx(Rdst, R14_bcp, Rdst);
} else {
lwbrx(Rdst, R14_bcp);
}
if (is_signed == Signed) {
extsw(Rdst, Rdst);
}
#else
// Read Java big endian format.
if (bcp_offset & 3) { // Offset unaligned?
load_const_optimized(Rdst, bcp_offset);
@ -369,18 +386,26 @@ void InterpreterMacroAssembler::get_4_byte_integer_at_bcp(int bcp_offset
lwz(Rdst, bcp_offset, R14_bcp);
}
}
#endif
}
// Load the constant pool cache index from the bytecode stream.
//
// Kills / writes:
// - Rdst, Rscratch
void InterpreterMacroAssembler::get_cache_index_at_bcp(Register Rdst, int bcp_offset, size_t index_size) {
assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
// Cache index is always in the native format, courtesy of Rewriter.
if (index_size == sizeof(u2)) {
get_2_byte_integer_at_bcp(bcp_offset, Rdst, Unsigned);
lhz(Rdst, bcp_offset, R14_bcp);
} else if (index_size == sizeof(u4)) {
get_4_byte_integer_at_bcp(bcp_offset, Rdst, Signed);
if (bcp_offset & 3) {
load_const_optimized(Rdst, bcp_offset);
lwax(Rdst, R14_bcp, Rdst);
} else {
lwa(Rdst, bcp_offset, R14_bcp);
}
assert(ConstantPool::decode_invokedynamic_index(~123) == 123, "else change next line");
nand(Rdst, Rdst, Rdst); // convert to plain index
} else if (index_size == sizeof(u1)) {
@ -397,6 +422,29 @@ void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, int b
add(cache, R27_constPoolCache, cache);
}
// Load 4-byte signed or unsigned integer in Java format (that is, big-endian format)
// from (Rsrc)+offset.
void InterpreterMacroAssembler::get_u4(Register Rdst, Register Rsrc, int offset,
signedOrNot is_signed) {
#if defined(VM_LITTLE_ENDIAN)
if (offset) {
load_const_optimized(Rdst, offset);
lwbrx(Rdst, Rdst, Rsrc);
} else {
lwbrx(Rdst, Rsrc);
}
if (is_signed == Signed) {
extsw(Rdst, Rdst);
}
#else
if (is_signed == Signed) {
lwa(Rdst, offset, Rsrc);
} else {
lwz(Rdst, offset, Rsrc);
}
#endif
}
// Load object from cpool->resolved_references(index).
void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result, Register index) {
assert_different_registers(result, index);

View File

@ -130,6 +130,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
void get_cache_and_index_at_bcp(Register cache, int bcp_offset, size_t index_size = sizeof(u2));
void get_u4(Register Rdst, Register Rsrc, int offset, signedOrNot is_signed);
// common code

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012, 2013 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -31,7 +31,12 @@
private:
address generate_abstract_entry(void);
address generate_accessor_entry(void);
address generate_jump_to_normal_entry(void);
address generate_accessor_entry(void) { return generate_jump_to_normal_entry(); }
address generate_empty_entry(void) { return generate_jump_to_normal_entry(); }
address generate_Reference_get_entry(void);
// Not supported
address generate_CRC32_update_entry() { return NULL; }
address generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) { return NULL; }
#endif // CPU_PPC_VM_INTERPRETERGENERATOR_PPC_HPP

View File

@ -428,6 +428,19 @@ address AbstractInterpreterGenerator::generate_result_handler_for(BasicType type
return entry;
}
// Call an accessor method (assuming it is resolved, otherwise drop into
// vanilla (slow path) entry.
address InterpreterGenerator::generate_jump_to_normal_entry(void) {
address entry = __ pc();
address normal_entry = Interpreter::entry_for_kind(Interpreter::zerolocals);
assert(normal_entry != NULL, "should already be generated.");
__ branch_to_entry(normal_entry, R11_scratch1);
__ flush();
return entry;
}
// Abstract method entry.
//
address InterpreterGenerator::generate_abstract_entry(void) {
@ -485,203 +498,6 @@ address InterpreterGenerator::generate_abstract_entry(void) {
return entry;
}
// Call an accessor method (assuming it is resolved, otherwise drop into
// vanilla (slow path) entry.
address InterpreterGenerator::generate_accessor_entry(void) {
if (!UseFastAccessorMethods && (!FLAG_IS_ERGO(UseFastAccessorMethods))) {
return NULL;
}
Label Lslow_path, Lacquire;
const Register
Rclass_or_obj = R3_ARG1,
Rconst_method = R4_ARG2,
Rcodes = Rconst_method,
Rcpool_cache = R5_ARG3,
Rscratch = R11_scratch1,
Rjvmti_mode = Rscratch,
Roffset = R12_scratch2,
Rflags = R6_ARG4,
Rbtable = R7_ARG5;
static address branch_table[number_of_states];
address entry = __ pc();
// Check for safepoint:
// Ditch this, real man don't need safepoint checks.
// Also check for JVMTI mode
// Check for null obj, take slow path if so.
__ ld(Rclass_or_obj, Interpreter::stackElementSize, CC_INTERP_ONLY(R17_tos) NOT_CC_INTERP(R15_esp));
__ lwz(Rjvmti_mode, thread_(interp_only_mode));
__ cmpdi(CCR1, Rclass_or_obj, 0);
__ cmpwi(CCR0, Rjvmti_mode, 0);
__ crorc(/*CCR0 eq*/2, /*CCR1 eq*/4+2, /*CCR0 eq*/2);
__ beq(CCR0, Lslow_path); // this==null or jvmti_mode!=0
// Do 2 things in parallel:
// 1. Load the index out of the first instruction word, which looks like this:
// <0x2a><0xb4><index (2 byte, native endianess)>.
// 2. Load constant pool cache base.
__ ld(Rconst_method, in_bytes(Method::const_offset()), R19_method);
__ ld(Rcpool_cache, in_bytes(ConstMethod::constants_offset()), Rconst_method);
__ lhz(Rcodes, in_bytes(ConstMethod::codes_offset()) + 2, Rconst_method); // Lower half of 32 bit field.
__ ld(Rcpool_cache, ConstantPool::cache_offset_in_bytes(), Rcpool_cache);
// Get the const pool entry by means of <index>.
const int codes_shift = exact_log2(in_words(ConstantPoolCacheEntry::size()) * BytesPerWord);
__ slwi(Rscratch, Rcodes, codes_shift); // (codes&0xFFFF)<<codes_shift
__ add(Rcpool_cache, Rscratch, Rcpool_cache);
// Check if cpool cache entry is resolved.
// We are resolved if the indices offset contains the current bytecode.
ByteSize cp_base_offset = ConstantPoolCache::base_offset();
// Big Endian:
__ lbz(Rscratch, in_bytes(cp_base_offset) + in_bytes(ConstantPoolCacheEntry::indices_offset()) + 7 - 2, Rcpool_cache);
__ cmpwi(CCR0, Rscratch, Bytecodes::_getfield);
__ bne(CCR0, Lslow_path);
__ isync(); // Order succeeding loads wrt. load of _indices field from cpool_cache.
// Finally, start loading the value: Get cp cache entry into regs.
__ ld(Rflags, in_bytes(cp_base_offset) + in_bytes(ConstantPoolCacheEntry::flags_offset()), Rcpool_cache);
__ ld(Roffset, in_bytes(cp_base_offset) + in_bytes(ConstantPoolCacheEntry::f2_offset()), Rcpool_cache);
// Following code is from templateTable::getfield_or_static
// Load pointer to branch table
__ load_const_optimized(Rbtable, (address)branch_table, Rscratch);
// Get volatile flag
__ rldicl(Rscratch, Rflags, 64-ConstantPoolCacheEntry::is_volatile_shift, 63); // extract volatile bit
// note: sync is needed before volatile load on PPC64
// Check field type
__ rldicl(Rflags, Rflags, 64-ConstantPoolCacheEntry::tos_state_shift, 64-ConstantPoolCacheEntry::tos_state_bits);
#ifdef ASSERT
Label LFlagInvalid;
__ cmpldi(CCR0, Rflags, number_of_states);
__ bge(CCR0, LFlagInvalid);
__ ld(R9_ARG7, 0, R1_SP);
__ ld(R10_ARG8, 0, R21_sender_SP);
__ cmpd(CCR0, R9_ARG7, R10_ARG8);
__ asm_assert_eq("backlink", 0x543);
#endif // ASSERT
__ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.
// Load from branch table and dispatch (volatile case: one instruction ahead)
__ sldi(Rflags, Rflags, LogBytesPerWord);
__ cmpwi(CCR6, Rscratch, 1); // volatile?
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ sldi(Rscratch, Rscratch, exact_log2(BytesPerInstWord)); // volatile ? size of 1 instruction : 0
}
__ ldx(Rbtable, Rbtable, Rflags);
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ subf(Rbtable, Rscratch, Rbtable); // point to volatile/non-volatile entry point
}
__ mtctr(Rbtable);
__ bctr();
#ifdef ASSERT
__ bind(LFlagInvalid);
__ stop("got invalid flag", 0x6541);
bool all_uninitialized = true,
all_initialized = true;
for (int i = 0; i<number_of_states; ++i) {
all_uninitialized = all_uninitialized && (branch_table[i] == NULL);
all_initialized = all_initialized && (branch_table[i] != NULL);
}
assert(all_uninitialized != all_initialized, "consistency"); // either or
__ fence(); // volatile entry point (one instruction before non-volatile_entry point)
if (branch_table[vtos] == 0) branch_table[vtos] = __ pc(); // non-volatile_entry point
if (branch_table[dtos] == 0) branch_table[dtos] = __ pc(); // non-volatile_entry point
if (branch_table[ftos] == 0) branch_table[ftos] = __ pc(); // non-volatile_entry point
__ stop("unexpected type", 0x6551);
#endif
if (branch_table[itos] == 0) { // generate only once
__ align(32, 28, 28); // align load
__ fence(); // volatile entry point (one instruction before non-volatile_entry point)
branch_table[itos] = __ pc(); // non-volatile_entry point
__ lwax(R3_RET, Rclass_or_obj, Roffset);
__ beq(CCR6, Lacquire);
__ blr();
}
if (branch_table[ltos] == 0) { // generate only once
__ align(32, 28, 28); // align load
__ fence(); // volatile entry point (one instruction before non-volatile_entry point)
branch_table[ltos] = __ pc(); // non-volatile_entry point
__ ldx(R3_RET, Rclass_or_obj, Roffset);
__ beq(CCR6, Lacquire);
__ blr();
}
if (branch_table[btos] == 0) { // generate only once
__ align(32, 28, 28); // align load
__ fence(); // volatile entry point (one instruction before non-volatile_entry point)
branch_table[btos] = __ pc(); // non-volatile_entry point
__ lbzx(R3_RET, Rclass_or_obj, Roffset);
__ extsb(R3_RET, R3_RET);
__ beq(CCR6, Lacquire);
__ blr();
}
if (branch_table[ctos] == 0) { // generate only once
__ align(32, 28, 28); // align load
__ fence(); // volatile entry point (one instruction before non-volatile_entry point)
branch_table[ctos] = __ pc(); // non-volatile_entry point
__ lhzx(R3_RET, Rclass_or_obj, Roffset);
__ beq(CCR6, Lacquire);
__ blr();
}
if (branch_table[stos] == 0) { // generate only once
__ align(32, 28, 28); // align load
__ fence(); // volatile entry point (one instruction before non-volatile_entry point)
branch_table[stos] = __ pc(); // non-volatile_entry point
__ lhax(R3_RET, Rclass_or_obj, Roffset);
__ beq(CCR6, Lacquire);
__ blr();
}
if (branch_table[atos] == 0) { // generate only once
__ align(32, 28, 28); // align load
__ fence(); // volatile entry point (one instruction before non-volatile_entry point)
branch_table[atos] = __ pc(); // non-volatile_entry point
__ load_heap_oop(R3_RET, (RegisterOrConstant)Roffset, Rclass_or_obj);
__ verify_oop(R3_RET);
//__ dcbt(R3_RET); // prefetch
__ beq(CCR6, Lacquire);
__ blr();
}
__ align(32, 12);
__ bind(Lacquire);
__ twi_0(R3_RET);
__ isync(); // acquire
__ blr();
#ifdef ASSERT
for (int i = 0; i<number_of_states; ++i) {
assert(branch_table[i], "accessor_entry initialization");
//tty->print_cr("accessor_entry: branch_table[%d] = 0x%llx (opcode 0x%llx)", i, branch_table[i], *((unsigned int*)branch_table[i]));
}
#endif
__ bind(Lslow_path);
__ branch_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals), Rscratch);
__ flush();
return entry;
}
// Interpreter intrinsic for WeakReference.get().
// 1. Don't push a full blown frame and go on dispatching, but fetch the value
// into R8 and return quickly
@ -713,7 +529,6 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
// and so we don't need to call the G1 pre-barrier. Thus we can use the
// regular method entry code to generate the NPE.
//
// This code is based on generate_accessor_enty.
address entry = __ pc();
@ -768,7 +583,7 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
return entry;
} else {
return generate_accessor_entry();
return generate_jump_to_normal_entry();
}
}

View File

@ -1283,8 +1283,6 @@ int Compile::ConstantTable::calculate_table_base_offset() const {
bool MachConstantBaseNode::requires_postalloc_expand() const { return true; }
void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
Compile *C = ra_->C;
iRegPdstOper *op_dst = new iRegPdstOper();
MachNode *m1 = new loadToc_hiNode();
MachNode *m2 = new loadToc_loNode();
@ -2229,7 +2227,7 @@ const bool Matcher::isSimpleConstant64(jlong value) {
}
/* TODO: PPC port
// Make a new machine dependent decode node (with its operands).
MachTypeNode *Matcher::make_decode_node(Compile *C) {
MachTypeNode *Matcher::make_decode_node() {
assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0,
"This method is only implemented for unscaled cOops mode so far");
MachTypeNode *decode = new decodeN_unscaledNode();
@ -2593,7 +2591,7 @@ typedef struct {
MachNode *_last;
} loadConLNodesTuple;
loadConLNodesTuple loadConLNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
OptoReg::Name reg_second, OptoReg::Name reg_first) {
loadConLNodesTuple nodes;
@ -2669,7 +2667,7 @@ encode %{
enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{
// Create new nodes.
loadConLNodesTuple loadConLNodes =
loadConLNodesTuple_create(C, ra_, n_toc, op_src,
loadConLNodesTuple_create(ra_, n_toc, op_src,
ra_->get_reg_second(this), ra_->get_reg_first(this));
// Push new nodes.
@ -3391,7 +3389,7 @@ encode %{
immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
loadConLNodesTuple loadConLNodes =
loadConLNodesTuple_create(C, ra_, n_toc, op_repl,
loadConLNodesTuple_create(ra_, n_toc, op_repl,
ra_->get_reg_second(this), ra_->get_reg_first(this));
// Push new nodes.
@ -3611,7 +3609,7 @@ encode %{
// Create the nodes for loading the IC from the TOC.
loadConLNodesTuple loadConLNodes_IC =
loadConLNodesTuple_create(C, ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()),
loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()),
OptoReg::Name(R19_H_num), OptoReg::Name(R19_num));
// Create the call node.
@ -3765,7 +3763,7 @@ encode %{
#if defined(ABI_ELFv2)
jlong entry_address = (jlong) this->entry_point();
assert(entry_address, "need address here");
loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new immLOper(entry_address),
loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
#else
// Get the struct that describes the function we are about to call.
@ -3777,13 +3775,13 @@ encode %{
loadConLNodesTuple loadConLNodes_Toc;
// Create nodes and operands for loading the entry point.
loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new immLOper(entry_address),
loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
// Create nodes and operands for loading the env pointer.
if (fd->env() != NULL) {
loadConLNodes_Env = loadConLNodesTuple_create(C, ra_, n_toc, new immLOper((jlong) fd->env()),
loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()),
OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
} else {
loadConLNodes_Env._large_hi = NULL;
@ -3796,7 +3794,7 @@ encode %{
}
// Create nodes and operands for loading the Toc point.
loadConLNodes_Toc = loadConLNodesTuple_create(C, ra_, n_toc, new immLOper((jlong) fd->toc()),
loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()),
OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
#endif // ABI_ELFv2
// mtctr node

View File

@ -30,7 +30,6 @@
address generate_normal_entry(bool synchronized);
address generate_native_entry(bool synchronized);
address generate_math_entry(AbstractInterpreter::MethodKind kind);
address generate_empty_entry(void);
void lock_method(Register Rflags, Register Rscratch1, Register Rscratch2, bool flags_preloaded=false);
void unlock_method(bool check_exceptions = true);

View File

@ -176,8 +176,12 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
const Register size = R12_scratch2;
__ get_cache_and_index_at_bcp(cache, 1, index_size);
// Big Endian (get least significant byte of 64 bit value):
// Get least significant byte of 64 bit value:
#if defined(VM_LITTLE_ENDIAN)
__ lbz(size, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()), cache);
#else
__ lbz(size, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()) + 7, cache);
#endif
__ sldi(size, size, Interpreter::logStackElementSize);
__ add(R15_esp, R15_esp, size);
__ dispatch_next(state, step);
@ -598,48 +602,6 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist
// End of helpers
// ============================================================================
// Various method entries
//
// Empty method, generate a very fast return. We must skip this entry if
// someone's debugging, indicated by the flag
// "interp_mode" in the Thread obj.
// Note: empty methods are generated mostly methods that do assertions, which are
// disabled in the "java opt build".
address TemplateInterpreterGenerator::generate_empty_entry(void) {
if (!UseFastEmptyMethods) {
NOT_PRODUCT(__ should_not_reach_here();)
return Interpreter::entry_for_kind(Interpreter::zerolocals);
}
Label Lslow_path;
const Register Rjvmti_mode = R11_scratch1;
address entry = __ pc();
__ lwz(Rjvmti_mode, thread_(interp_only_mode));
__ cmpwi(CCR0, Rjvmti_mode, 0);
__ bne(CCR0, Lslow_path); // jvmti_mode!=0
// Noone's debuggin: Simply return.
// Pop c2i arguments (if any) off when we return.
#ifdef ASSERT
__ ld(R9_ARG7, 0, R1_SP);
__ ld(R10_ARG8, 0, R21_sender_SP);
__ cmpd(CCR0, R9_ARG7, R10_ARG8);
__ asm_assert_eq("backlink", 0x545);
#endif // ASSERT
__ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.
// And we're done.
__ blr();
__ bind(Lslow_path);
__ branch_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals), R11_scratch1);
__ flush();
return entry;
}
// Support abs and sqrt like in compiler.
// For others we can use a normal (native) entry.
@ -858,7 +820,9 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// Our signature handlers copy required arguments to the C stack
// (outgoing C args), R3_ARG1 to R10_ARG8, and FARG1 to FARG13.
__ mr(R3_ARG1, R18_locals);
#if !defined(ABI_ELFv2)
__ ld(signature_handler_fd, 0, signature_handler_fd);
#endif
__ call_stub(signature_handler_fd);
@ -1020,8 +984,13 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// native result across the call. No oop is present.
__ mr(R3_ARG1, R16_thread);
#if defined(ABI_ELFv2)
__ call_c(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans),
relocInfo::none);
#else
__ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, JavaThread::check_special_condition_for_native_trans),
relocInfo::none);
#endif
__ bind(sync_check_done);
@ -1278,45 +1247,6 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
return entry;
}
// =============================================================================
// Entry points
address AbstractInterpreterGenerator::generate_method_entry(
AbstractInterpreter::MethodKind kind) {
// Determine code generation flags.
bool synchronized = false;
address entry_point = NULL;
switch (kind) {
case Interpreter::zerolocals : break;
case Interpreter::zerolocals_synchronized: synchronized = true; break;
case Interpreter::native : entry_point = ((InterpreterGenerator*) this)->generate_native_entry(false); break;
case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*) this)->generate_native_entry(true); break;
case Interpreter::empty : entry_point = ((InterpreterGenerator*) this)->generate_empty_entry(); break;
case Interpreter::accessor : entry_point = ((InterpreterGenerator*) this)->generate_accessor_entry(); break;
case Interpreter::abstract : entry_point = ((InterpreterGenerator*) this)->generate_abstract_entry(); break;
case Interpreter::java_lang_math_sin : // fall thru
case Interpreter::java_lang_math_cos : // fall thru
case Interpreter::java_lang_math_tan : // fall thru
case Interpreter::java_lang_math_abs : // fall thru
case Interpreter::java_lang_math_log : // fall thru
case Interpreter::java_lang_math_log10 : // fall thru
case Interpreter::java_lang_math_sqrt : // fall thru
case Interpreter::java_lang_math_pow : // fall thru
case Interpreter::java_lang_math_exp : entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind); break;
case Interpreter::java_lang_ref_reference_get
: entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
default : ShouldNotReachHere(); break;
}
if (entry_point) {
return entry_point;
}
return ((InterpreterGenerator*) this)->generate_normal_entry(synchronized);
}
// These should never be compiled since the interpreter will prefer
// the compiled version to the intrinsic version.
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
@ -1344,7 +1274,7 @@ int AbstractInterpreter::size_activation(int max_stack,
int callee_locals,
bool is_top_frame) {
// Note: This calculation must exactly parallel the frame setup
// in AbstractInterpreterGenerator::generate_method_entry.
// in InterpreterGenerator::generate_fixed_frame.
assert(Interpreter::stackElementWords == 1, "sanity");
const int max_alignment_space = StackAlignmentInBytes / Interpreter::stackElementSize;
const int abi_scratch = is_top_frame ? (frame::abi_reg_args_size / Interpreter::stackElementSize) :

View File

@ -189,8 +189,12 @@ void TemplateTable::patch_bytecode(Bytecodes::Code new_bc, Register Rnew_bc, Reg
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
assert(load_bc_into_bc_reg, "we use bc_reg as temp");
__ get_cache_and_index_at_bcp(Rtemp /* dst = cache */, 1);
// Big Endian: ((*(cache+indices))>>((1+byte_no)*8))&0xFF
// ((*(cache+indices))>>((1+byte_no)*8))&0xFF:
#if defined(VM_LITTLE_ENDIAN)
__ lbz(Rnew_bc, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + 1 + byte_no, Rtemp);
#else
__ lbz(Rnew_bc, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + 7 - (1 + byte_no), Rtemp);
#endif
__ cmpwi(CCR0, Rnew_bc, 0);
__ li(Rnew_bc, (unsigned int)(unsigned char)new_bc);
__ beq(CCR0, L_patch_done);
@ -1839,8 +1843,8 @@ void TemplateTable::tableswitch() {
__ clrrdi(Rdef_offset_addr, Rdef_offset_addr, log2_long((jlong)BytesPerInt));
// Load lo & hi.
__ lwz(Rlow_byte, BytesPerInt, Rdef_offset_addr);
__ lwz(Rhigh_byte, BytesPerInt * 2, Rdef_offset_addr);
__ get_u4(Rlow_byte, Rdef_offset_addr, BytesPerInt, InterpreterMacroAssembler::Unsigned);
__ get_u4(Rhigh_byte, Rdef_offset_addr, 2 *BytesPerInt, InterpreterMacroAssembler::Unsigned);
// Check for default case (=index outside [low,high]).
__ cmpw(CCR0, R17_tos, Rlow_byte);
@ -1854,12 +1858,17 @@ void TemplateTable::tableswitch() {
__ profile_switch_case(Rindex, Rhigh_byte /* scratch */, Rscratch1, Rscratch2);
__ sldi(Rindex, Rindex, LogBytesPerInt);
__ addi(Rindex, Rindex, 3 * BytesPerInt);
#if defined(VM_LITTLE_ENDIAN)
__ lwbrx(Roffset, Rdef_offset_addr, Rindex);
__ extsw(Roffset, Roffset);
#else
__ lwax(Roffset, Rdef_offset_addr, Rindex);
#endif
__ b(Ldispatch);
__ bind(Ldefault_case);
__ profile_switch_default(Rhigh_byte, Rscratch1);
__ lwa(Roffset, 0, Rdef_offset_addr);
__ get_u4(Roffset, Rdef_offset_addr, 0, InterpreterMacroAssembler::Signed);
__ bind(Ldispatch);
@ -1875,12 +1884,11 @@ void TemplateTable::lookupswitch() {
// Table switch using linear search through cases.
// Bytecode stream format:
// Bytecode (1) | 4-byte padding | default offset (4) | count (4) | value/offset pair1 (8) | value/offset pair2 (8) | ...
// Note: Everything is big-endian format here. So on little endian machines, we have to revers offset and count and cmp value.
// Note: Everything is big-endian format here.
void TemplateTable::fast_linearswitch() {
transition(itos, vtos);
Label Lloop_entry, Lsearch_loop, Lfound, Lcontinue_execution, Ldefault_case;
Label Lloop_entry, Lsearch_loop, Lcontinue_execution, Ldefault_case;
Register Rcount = R3_ARG1,
Rcurrent_pair = R4_ARG2,
Rdef_offset_addr = R5_ARG3, // Is going to contain address of default offset.
@ -1894,47 +1902,40 @@ void TemplateTable::fast_linearswitch() {
__ clrrdi(Rdef_offset_addr, Rdef_offset_addr, log2_long((jlong)BytesPerInt));
// Setup loop counter and limit.
__ lwz(Rcount, BytesPerInt, Rdef_offset_addr); // Load count.
__ get_u4(Rcount, Rdef_offset_addr, BytesPerInt, InterpreterMacroAssembler::Unsigned);
__ addi(Rcurrent_pair, Rdef_offset_addr, 2 * BytesPerInt); // Rcurrent_pair now points to first pair.
// Set up search loop.
__ cmpwi(CCR0, Rcount, 0);
__ beq(CCR0, Ldefault_case);
__ mtctr(Rcount);
__ cmpwi(CCR0, Rcount, 0);
__ bne(CCR0, Lloop_entry);
// linear table search
__ bind(Lsearch_loop);
__ lwz(Rvalue, 0, Rcurrent_pair);
__ lwa(Roffset, 1 * BytesPerInt, Rcurrent_pair);
__ cmpw(CCR0, Rvalue, Rcmp_value);
__ beq(CCR0, Lfound);
__ addi(Rcurrent_pair, Rcurrent_pair, 2 * BytesPerInt);
__ bdnz(Lsearch_loop);
// default case
// Default case
__ bind(Ldefault_case);
__ lwa(Roffset, 0, Rdef_offset_addr);
__ get_u4(Roffset, Rdef_offset_addr, 0, InterpreterMacroAssembler::Signed);
if (ProfileInterpreter) {
__ profile_switch_default(Rdef_offset_addr, Rcount/* scratch */);
__ b(Lcontinue_execution);
}
__ b(Lcontinue_execution);
// Next iteration
__ bind(Lsearch_loop);
__ bdz(Ldefault_case);
__ addi(Rcurrent_pair, Rcurrent_pair, 2 * BytesPerInt);
__ bind(Lloop_entry);
__ get_u4(Rvalue, Rcurrent_pair, 0, InterpreterMacroAssembler::Unsigned);
__ cmpw(CCR0, Rvalue, Rcmp_value);
__ bne(CCR0, Lsearch_loop);
// Found, load offset.
__ get_u4(Roffset, Rcurrent_pair, BytesPerInt, InterpreterMacroAssembler::Signed);
// Calculate case index and profile
__ mfctr(Rcurrent_pair);
if (ProfileInterpreter) {
__ sub(Rcurrent_pair, Rcount, Rcurrent_pair);
__ profile_switch_case(Rcurrent_pair, Rcount /*scratch*/, Rdef_offset_addr/*scratch*/, Rscratch);
}
// Entry found, skip Roffset bytecodes and continue.
__ bind(Lfound);
if (ProfileInterpreter) {
// Calc the num of the pair we hit. Careful, Rcurrent_pair points 2 ints
// beyond the actual current pair due to the auto update load above!
__ sub(Rcurrent_pair, Rcurrent_pair, Rdef_offset_addr);
__ addi(Rcurrent_pair, Rcurrent_pair, - 2 * BytesPerInt);
__ srdi(Rcurrent_pair, Rcurrent_pair, LogBytesPerInt + 1);
__ profile_switch_case(Rcurrent_pair, Rcount /*scratch*/, Rdef_offset_addr/*scratch*/, Rscratch);
__ bind(Lcontinue_execution);
}
__ bind(Lcontinue_execution);
__ add(R14_bcp, Roffset, R14_bcp);
__ dispatch_next(vtos);
}
@ -1990,7 +1991,7 @@ void TemplateTable::fast_binaryswitch() {
// initialize i & j
__ li(Ri,0);
__ lwz(Rj, -BytesPerInt, Rarray);
__ get_u4(Rj, Rarray, -BytesPerInt, InterpreterMacroAssembler::Unsigned);
// and start.
Label entry;
@ -2007,7 +2008,11 @@ void TemplateTable::fast_binaryswitch() {
// i = h;
// }
__ sldi(Rscratch, Rh, log_entry_size);
#if defined(VM_LITTLE_ENDIAN)
__ lwbrx(Rscratch, Rscratch, Rarray);
#else
__ lwzx(Rscratch, Rscratch, Rarray);
#endif
// if (key < current value)
// Rh = Rj
@ -2039,20 +2044,20 @@ void TemplateTable::fast_binaryswitch() {
// Ri = value offset
__ sldi(Ri, Ri, log_entry_size);
__ add(Ri, Ri, Rarray);
__ lwz(Rscratch, 0, Ri);
__ get_u4(Rscratch, Ri, 0, InterpreterMacroAssembler::Unsigned);
Label not_found;
// Ri = offset offset
__ cmpw(CCR0, Rkey, Rscratch);
__ beq(CCR0, not_found);
// entry not found -> j = default offset
__ lwz(Rj, -2 * BytesPerInt, Rarray);
__ get_u4(Rj, Rarray, -2 * BytesPerInt, InterpreterMacroAssembler::Unsigned);
__ b(default_case);
__ bind(not_found);
// entry found -> j = offset
__ profile_switch_case(Rh, Rj, Rscratch, Rkey);
__ lwz(Rj, BytesPerInt, Ri);
__ get_u4(Rj, Ri, BytesPerInt, InterpreterMacroAssembler::Unsigned);
if (ProfileInterpreter) {
__ b(continue_execution);
@ -2147,8 +2152,11 @@ void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Regist
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
// We are resolved if the indices offset contains the current bytecode.
// Big Endian:
#if defined(VM_LITTLE_ENDIAN)
__ lbz(Rscratch, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + byte_no + 1, Rcache);
#else
__ lbz(Rscratch, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + 7 - (byte_no + 1), Rcache);
#endif
// Acquire by cmp-br-isync (see below).
__ cmpdi(CCR0, Rscratch, (int)bytecode());
__ beq(CCR0, Lresolved);

View File

@ -29,6 +29,7 @@
#include "compiler/disassembler.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/java.hpp"
#include "runtime/os.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "utilities/defaultStream.hpp"
#include "vm_version_ppc.hpp"
@ -108,7 +109,7 @@ void VM_Version::initialize() {
(has_vand() ? " vand" : "")
// Make sure number of %s matches num_features!
);
_features_str = strdup(buf);
_features_str = os::strdup(buf);
NOT_PRODUCT(if (Verbose) print_features(););
// PPC64 supports 8-byte compare-exchange operations (see

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,7 @@
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterGenerator.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "interpreter/interp_masm.hpp"
#include "oops/arrayOop.hpp"
#include "oops/methodData.hpp"
#include "oops/method.hpp"
@ -68,9 +69,7 @@ bool CppInterpreter::contains(address pc) {
#define STATE(field_name) Lstate, in_bytes(byte_offset_of(BytecodeInterpreter, field_name))
#define __ _masm->
Label frame_manager_entry;
Label fast_accessor_slow_entry_path; // fast accessor methods need to be able to jmp to unsynchronized
// c++ interpreter entry point this holds that entry point label.
Label frame_manager_entry; // c++ interpreter entry point this holds that entry point label.
static address unctrap_frame_manager_entry = NULL;
@ -452,110 +451,6 @@ address InterpreterGenerator::generate_empty_entry(void) {
return NULL;
}
// Call an accessor method (assuming it is resolved, otherwise drop into
// vanilla (slow path) entry
// Generates code to elide accessor methods
// Uses G3_scratch and G1_scratch as scratch
address InterpreterGenerator::generate_accessor_entry(void) {
// Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites thereof;
// parameter size = 1
// Note: We can only use this code if the getfield has been resolved
// and if we don't have a null-pointer exception => check for
// these conditions first and use slow path if necessary.
address entry = __ pc();
Label slow_path;
if ( UseFastAccessorMethods) {
// Check if we need to reach a safepoint and generate full interpreter
// frame if so.
AddressLiteral sync_state(SafepointSynchronize::address_of_state());
__ load_contents(sync_state, G3_scratch);
__ cmp(G3_scratch, SafepointSynchronize::_not_synchronized);
__ br(Assembler::notEqual, false, Assembler::pn, slow_path);
__ delayed()->nop();
// Check if local 0 != NULL
__ ld_ptr(Gargs, G0, Otos_i ); // get local 0
__ tst(Otos_i); // check if local 0 == NULL and go the slow path
__ brx(Assembler::zero, false, Assembler::pn, slow_path);
__ delayed()->nop();
// read first instruction word and extract bytecode @ 1 and index @ 2
// get first 4 bytes of the bytecodes (big endian!)
__ ld_ptr(Address(G5_method, in_bytes(Method::const_offset())), G1_scratch);
__ ld(Address(G1_scratch, in_bytes(ConstMethod::codes_offset())), G1_scratch);
// move index @ 2 far left then to the right most two bytes.
__ sll(G1_scratch, 2*BitsPerByte, G1_scratch);
__ srl(G1_scratch, 2*BitsPerByte - exact_log2(in_words(
ConstantPoolCacheEntry::size()) * BytesPerWord), G1_scratch);
// get constant pool cache
__ ld_ptr(G5_method, in_bytes(Method::const_offset()), G3_scratch);
__ ld_ptr(G3_scratch, in_bytes(ConstMethod::constants_offset()), G3_scratch);
__ ld_ptr(G3_scratch, ConstantPool::cache_offset_in_bytes(), G3_scratch);
// get specific constant pool cache entry
__ add(G3_scratch, G1_scratch, G3_scratch);
// Check the constant Pool cache entry to see if it has been resolved.
// If not, need the slow path.
ByteSize cp_base_offset = ConstantPoolCache::base_offset();
__ ld_ptr(G3_scratch, in_bytes(cp_base_offset + ConstantPoolCacheEntry::indices_offset()), G1_scratch);
__ srl(G1_scratch, 2*BitsPerByte, G1_scratch);
__ and3(G1_scratch, 0xFF, G1_scratch);
__ cmp(G1_scratch, Bytecodes::_getfield);
__ br(Assembler::notEqual, false, Assembler::pn, slow_path);
__ delayed()->nop();
// Get the type and return field offset from the constant pool cache
__ ld_ptr(G3_scratch, in_bytes(cp_base_offset + ConstantPoolCacheEntry::flags_offset()), G1_scratch);
__ ld_ptr(G3_scratch, in_bytes(cp_base_offset + ConstantPoolCacheEntry::f2_offset()), G3_scratch);
Label xreturn_path;
// Need to differentiate between igetfield, agetfield, bgetfield etc.
// because they are different sizes.
// Get the type from the constant pool cache
__ srl(G1_scratch, ConstantPoolCacheEntry::tos_state_shift, G1_scratch);
// Make sure we don't need to mask G1_scratch after the above shift
ConstantPoolCacheEntry::verify_tos_state_shift();
__ cmp(G1_scratch, atos );
__ br(Assembler::equal, true, Assembler::pt, xreturn_path);
__ delayed()->ld_ptr(Otos_i, G3_scratch, Otos_i);
__ cmp(G1_scratch, itos);
__ br(Assembler::equal, true, Assembler::pt, xreturn_path);
__ delayed()->ld(Otos_i, G3_scratch, Otos_i);
__ cmp(G1_scratch, stos);
__ br(Assembler::equal, true, Assembler::pt, xreturn_path);
__ delayed()->ldsh(Otos_i, G3_scratch, Otos_i);
__ cmp(G1_scratch, ctos);
__ br(Assembler::equal, true, Assembler::pt, xreturn_path);
__ delayed()->lduh(Otos_i, G3_scratch, Otos_i);
#ifdef ASSERT
__ cmp(G1_scratch, btos);
__ br(Assembler::equal, true, Assembler::pt, xreturn_path);
__ delayed()->ldsb(Otos_i, G3_scratch, Otos_i);
__ should_not_reach_here();
#endif
__ ldsb(Otos_i, G3_scratch, Otos_i);
__ bind(xreturn_path);
// _ireturn/_areturn
__ retl(); // return from leaf routine
__ delayed()->mov(O5_savedSP, SP);
// Generate regular method entry
__ bind(slow_path);
__ ba(fast_accessor_slow_entry_path);
__ delayed()->nop();
return entry;
}
return NULL;
}
address InterpreterGenerator::generate_Reference_get_entry(void) {
#if INCLUDE_ALL_GCS
if (UseG1GC) {
@ -573,7 +468,7 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
// If G1 is not enabled then attempt to go through the accessor entry point
// Reference.get is an accessor
return generate_accessor_entry();
return generate_jump_to_normal_entry();
}
//
@ -1870,23 +1765,6 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
__ ba(call_interpreter_2);
__ delayed()->st_ptr(O1, STATE(_stack));
// Fast accessor methods share this entry point.
// This works because frame manager is in the same codelet
// This can either be an entry via call_stub/c1/c2 or a recursive interpreter call
// we need to do a little register fixup here once we distinguish the two of them
if (UseFastAccessorMethods && !synchronized) {
// Call stub_return address still in O7
__ bind(fast_accessor_slow_entry_path);
__ set((intptr_t)return_from_native_method - 8, Gtmp1);
__ cmp(Gtmp1, O7); // returning to interpreter?
__ brx(Assembler::equal, true, Assembler::pt, re_dispatch); // yep
__ delayed()->nop();
__ ba(re_dispatch);
__ delayed()->mov(G0, prevState); // initial entry
}
// interpreter returning to native code (call_stub/c1/c2)
// convert result and unwind initial activation
// L2_scratch - scaled result type index

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -32,9 +32,11 @@
address generate_normal_entry(bool synchronized);
address generate_native_entry(bool synchronized);
address generate_abstract_entry(void);
address generate_math_entry(AbstractInterpreter::MethodKind kind);
address generate_empty_entry(void);
address generate_accessor_entry(void);
// there are no math intrinsics on sparc
address generate_math_entry(AbstractInterpreter::MethodKind kind) { return NULL; }
address generate_jump_to_normal_entry(void);
address generate_accessor_entry(void) { return generate_jump_to_normal_entry(); }
address generate_empty_entry(void) { return generate_jump_to_normal_entry(); }
address generate_Reference_get_entry(void);
void lock_method(void);
void save_native_result(void);
@ -43,4 +45,7 @@
void generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue);
void generate_counter_overflow(Label& Lcontinue);
// Not supported
address generate_CRC32_update_entry() { return NULL; }
address generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) { return NULL; }
#endif // CPU_SPARC_VM_INTERPRETERGENERATOR_SPARC_HPP

View File

@ -241,6 +241,15 @@ void InterpreterGenerator::generate_counter_overflow(Label& Lcontinue) {
// Various method entries
address InterpreterGenerator::generate_jump_to_normal_entry(void) {
address entry = __ pc();
assert(Interpreter::entry_for_kind(Interpreter::zerolocals) != NULL, "should already be generated");
AddressLiteral al(Interpreter::entry_for_kind(Interpreter::zerolocals));
__ jump_to(al, G3_scratch);
__ delayed()->nop();
return entry;
}
// Abstract method entry
// Attempt to execute abstract method. Throw exception
//
@ -255,159 +264,6 @@ address InterpreterGenerator::generate_abstract_entry(void) {
}
//----------------------------------------------------------------------------------------------------
// Entry points & stack frame layout
//
// Here we generate the various kind of entries into the interpreter.
// The two main entry type are generic bytecode methods and native call method.
// These both come in synchronized and non-synchronized versions but the
// frame layout they create is very similar. The other method entry
// types are really just special purpose entries that are really entry
// and interpretation all in one. These are for trivial methods like
// accessor, empty, or special math methods.
//
// When control flow reaches any of the entry types for the interpreter
// the following holds ->
//
// C2 Calling Conventions:
//
// The entry code below assumes that the following registers are set
// when coming in:
// G5_method: holds the Method* of the method to call
// Lesp: points to the TOS of the callers expression stack
// after having pushed all the parameters
//
// The entry code does the following to setup an interpreter frame
// pop parameters from the callers stack by adjusting Lesp
// set O0 to Lesp
// compute X = (max_locals - num_parameters)
// bump SP up by X to accomadate the extra locals
// compute X = max_expression_stack
// + vm_local_words
// + 16 words of register save area
// save frame doing a save sp, -X, sp growing towards lower addresses
// set Lbcp, Lmethod, LcpoolCache
// set Llocals to i0
// set Lmonitors to FP - rounded_vm_local_words
// set Lesp to Lmonitors - 4
//
// The frame has now been setup to do the rest of the entry code
// Try this optimization: Most method entries could live in a
// "one size fits all" stack frame without all the dynamic size
// calculations. It might be profitable to do all this calculation
// statically and approximately for "small enough" methods.
//-----------------------------------------------------------------------------------------------
// C1 Calling conventions
//
// Upon method entry, the following registers are setup:
//
// g2 G2_thread: current thread
// g5 G5_method: method to activate
// g4 Gargs : pointer to last argument
//
//
// Stack:
//
// +---------------+ <--- sp
// | |
// : reg save area :
// | |
// +---------------+ <--- sp + 0x40
// | |
// : extra 7 slots : note: these slots are not really needed for the interpreter (fix later)
// | |
// +---------------+ <--- sp + 0x5c
// | |
// : free :
// | |
// +---------------+ <--- Gargs
// | |
// : arguments :
// | |
// +---------------+
// | |
//
//
//
// AFTER FRAME HAS BEEN SETUP for method interpretation the stack looks like:
//
// +---------------+ <--- sp
// | |
// : reg save area :
// | |
// +---------------+ <--- sp + 0x40
// | |
// : extra 7 slots : note: these slots are not really needed for the interpreter (fix later)
// | |
// +---------------+ <--- sp + 0x5c
// | |
// : :
// | | <--- Lesp
// +---------------+ <--- Lmonitors (fp - 0x18)
// | VM locals |
// +---------------+ <--- fp
// | |
// : reg save area :
// | |
// +---------------+ <--- fp + 0x40
// | |
// : extra 7 slots : note: these slots are not really needed for the interpreter (fix later)
// | |
// +---------------+ <--- fp + 0x5c
// | |
// : free :
// | |
// +---------------+
// | |
// : nonarg locals :
// | |
// +---------------+
// | |
// : arguments :
// | | <--- Llocals
// +---------------+ <--- Gargs
// | |
address AbstractInterpreterGenerator::generate_method_entry(AbstractInterpreter::MethodKind kind) {
// determine code generation flags
bool synchronized = false;
address entry_point = NULL;
switch (kind) {
case Interpreter::zerolocals : break;
case Interpreter::zerolocals_synchronized: synchronized = true; break;
case Interpreter::native : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break;
case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true); break;
case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break;
case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break;
case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break;
case Interpreter::java_lang_math_sin : break;
case Interpreter::java_lang_math_cos : break;
case Interpreter::java_lang_math_tan : break;
case Interpreter::java_lang_math_sqrt : break;
case Interpreter::java_lang_math_abs : break;
case Interpreter::java_lang_math_log : break;
case Interpreter::java_lang_math_log10 : break;
case Interpreter::java_lang_math_pow : break;
case Interpreter::java_lang_math_exp : break;
case Interpreter::java_lang_ref_reference_get
: entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
default:
fatal(err_msg("unexpected method kind: %d", kind));
break;
}
if (entry_point) return entry_point;
return ((InterpreterGenerator*)this)->generate_normal_entry(synchronized);
}
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
// No special entry points that preclude compilation
return true;

View File

@ -6184,7 +6184,11 @@ instruct loadConP_no_oop_cheap(iRegP dst, immP_no_oop_cheap con) %{
ins_cost(DEFAULT_COST * 3/2);
format %{ "SET $con,$dst\t! non-oop ptr" %}
ins_encode %{
__ set($con$$constant, $dst$$Register);
if (_opnds[1]->constant_reloc() == relocInfo::metadata_type) {
__ set_metadata_constant((Metadata*)$con$$constant, $dst$$Register);
} else {
__ set($con$$constant, $dst$$Register);
}
%}
ins_pipe(loadConP);
%}

View File

@ -456,6 +456,115 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rframe
// Generate a fixed interpreter frame. This is identical setup for interpreted
// methods and for native methods hence the shared code.
//----------------------------------------------------------------------------------------------------
// Stack frame layout
//
// When control flow reaches any of the entry types for the interpreter
// the following holds ->
//
// C2 Calling Conventions:
//
// The entry code below assumes that the following registers are set
// when coming in:
// G5_method: holds the Method* of the method to call
// Lesp: points to the TOS of the callers expression stack
// after having pushed all the parameters
//
// The entry code does the following to setup an interpreter frame
// pop parameters from the callers stack by adjusting Lesp
// set O0 to Lesp
// compute X = (max_locals - num_parameters)
// bump SP up by X to accomadate the extra locals
// compute X = max_expression_stack
// + vm_local_words
// + 16 words of register save area
// save frame doing a save sp, -X, sp growing towards lower addresses
// set Lbcp, Lmethod, LcpoolCache
// set Llocals to i0
// set Lmonitors to FP - rounded_vm_local_words
// set Lesp to Lmonitors - 4
//
// The frame has now been setup to do the rest of the entry code
// Try this optimization: Most method entries could live in a
// "one size fits all" stack frame without all the dynamic size
// calculations. It might be profitable to do all this calculation
// statically and approximately for "small enough" methods.
//-----------------------------------------------------------------------------------------------
// C1 Calling conventions
//
// Upon method entry, the following registers are setup:
//
// g2 G2_thread: current thread
// g5 G5_method: method to activate
// g4 Gargs : pointer to last argument
//
//
// Stack:
//
// +---------------+ <--- sp
// | |
// : reg save area :
// | |
// +---------------+ <--- sp + 0x40
// | |
// : extra 7 slots : note: these slots are not really needed for the interpreter (fix later)
// | |
// +---------------+ <--- sp + 0x5c
// | |
// : free :
// | |
// +---------------+ <--- Gargs
// | |
// : arguments :
// | |
// +---------------+
// | |
//
//
//
// AFTER FRAME HAS BEEN SETUP for method interpretation the stack looks like:
//
// +---------------+ <--- sp
// | |
// : reg save area :
// | |
// +---------------+ <--- sp + 0x40
// | |
// : extra 7 slots : note: these slots are not really needed for the interpreter (fix later)
// | |
// +---------------+ <--- sp + 0x5c
// | |
// : :
// | | <--- Lesp
// +---------------+ <--- Lmonitors (fp - 0x18)
// | VM locals |
// +---------------+ <--- fp
// | |
// : reg save area :
// | |
// +---------------+ <--- fp + 0x40
// | |
// : extra 7 slots : note: these slots are not really needed for the interpreter (fix later)
// | |
// +---------------+ <--- fp + 0x5c
// | |
// : free :
// | |
// +---------------+
// | |
// : nonarg locals :
// | |
// +---------------+
// | |
// : arguments :
// | | <--- Llocals
// +---------------+ <--- Gargs
// | |
void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
//
//
@ -599,136 +708,6 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
}
// Empty method, generate a very fast return.
address InterpreterGenerator::generate_empty_entry(void) {
// A method that does nother but return...
address entry = __ pc();
Label slow_path;
// do nothing for empty methods (do not even increment invocation counter)
if ( UseFastEmptyMethods) {
// If we need a safepoint check, generate full interpreter entry.
AddressLiteral sync_state(SafepointSynchronize::address_of_state());
__ set(sync_state, G3_scratch);
__ cmp_and_br_short(G3_scratch, SafepointSynchronize::_not_synchronized, Assembler::notEqual, Assembler::pn, slow_path);
// Code: _return
__ retl();
__ delayed()->mov(O5_savedSP, SP);
__ bind(slow_path);
(void) generate_normal_entry(false);
return entry;
}
return NULL;
}
// Call an accessor method (assuming it is resolved, otherwise drop into
// vanilla (slow path) entry
// Generates code to elide accessor methods
// Uses G3_scratch and G1_scratch as scratch
address InterpreterGenerator::generate_accessor_entry(void) {
// Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites thereof;
// parameter size = 1
// Note: We can only use this code if the getfield has been resolved
// and if we don't have a null-pointer exception => check for
// these conditions first and use slow path if necessary.
address entry = __ pc();
Label slow_path;
// XXX: for compressed oops pointer loading and decoding doesn't fit in
// delay slot and damages G1
if ( UseFastAccessorMethods && !UseCompressedOops ) {
// Check if we need to reach a safepoint and generate full interpreter
// frame if so.
AddressLiteral sync_state(SafepointSynchronize::address_of_state());
__ load_contents(sync_state, G3_scratch);
__ cmp(G3_scratch, SafepointSynchronize::_not_synchronized);
__ cmp_and_br_short(G3_scratch, SafepointSynchronize::_not_synchronized, Assembler::notEqual, Assembler::pn, slow_path);
// Check if local 0 != NULL
__ ld_ptr(Gargs, G0, Otos_i ); // get local 0
// check if local 0 == NULL and go the slow path
__ br_null_short(Otos_i, Assembler::pn, slow_path);
// read first instruction word and extract bytecode @ 1 and index @ 2
// get first 4 bytes of the bytecodes (big endian!)
__ ld_ptr(G5_method, Method::const_offset(), G1_scratch);
__ ld(G1_scratch, ConstMethod::codes_offset(), G1_scratch);
// move index @ 2 far left then to the right most two bytes.
__ sll(G1_scratch, 2*BitsPerByte, G1_scratch);
__ srl(G1_scratch, 2*BitsPerByte - exact_log2(in_words(
ConstantPoolCacheEntry::size()) * BytesPerWord), G1_scratch);
// get constant pool cache
__ ld_ptr(G5_method, Method::const_offset(), G3_scratch);
__ ld_ptr(G3_scratch, ConstMethod::constants_offset(), G3_scratch);
__ ld_ptr(G3_scratch, ConstantPool::cache_offset_in_bytes(), G3_scratch);
// get specific constant pool cache entry
__ add(G3_scratch, G1_scratch, G3_scratch);
// Check the constant Pool cache entry to see if it has been resolved.
// If not, need the slow path.
ByteSize cp_base_offset = ConstantPoolCache::base_offset();
__ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::indices_offset(), G1_scratch);
__ srl(G1_scratch, 2*BitsPerByte, G1_scratch);
__ and3(G1_scratch, 0xFF, G1_scratch);
__ cmp_and_br_short(G1_scratch, Bytecodes::_getfield, Assembler::notEqual, Assembler::pn, slow_path);
// Get the type and return field offset from the constant pool cache
__ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::flags_offset(), G1_scratch);
__ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::f2_offset(), G3_scratch);
Label xreturn_path;
// Need to differentiate between igetfield, agetfield, bgetfield etc.
// because they are different sizes.
// Get the type from the constant pool cache
__ srl(G1_scratch, ConstantPoolCacheEntry::tos_state_shift, G1_scratch);
// Make sure we don't need to mask G1_scratch after the above shift
ConstantPoolCacheEntry::verify_tos_state_shift();
__ cmp(G1_scratch, atos );
__ br(Assembler::equal, true, Assembler::pt, xreturn_path);
__ delayed()->ld_ptr(Otos_i, G3_scratch, Otos_i);
__ cmp(G1_scratch, itos);
__ br(Assembler::equal, true, Assembler::pt, xreturn_path);
__ delayed()->ld(Otos_i, G3_scratch, Otos_i);
__ cmp(G1_scratch, stos);
__ br(Assembler::equal, true, Assembler::pt, xreturn_path);
__ delayed()->ldsh(Otos_i, G3_scratch, Otos_i);
__ cmp(G1_scratch, ctos);
__ br(Assembler::equal, true, Assembler::pt, xreturn_path);
__ delayed()->lduh(Otos_i, G3_scratch, Otos_i);
#ifdef ASSERT
__ cmp(G1_scratch, btos);
__ br(Assembler::equal, true, Assembler::pt, xreturn_path);
__ delayed()->ldsb(Otos_i, G3_scratch, Otos_i);
__ should_not_reach_here();
#endif
__ ldsb(Otos_i, G3_scratch, Otos_i);
__ bind(xreturn_path);
// _ireturn/_areturn
__ retl(); // return from leaf routine
__ delayed()->mov(O5_savedSP, SP);
// Generate regular method entry
__ bind(slow_path);
(void) generate_normal_entry(false);
return entry;
}
return NULL;
}
// Method entry for java.lang.ref.Reference.get.
address InterpreterGenerator::generate_Reference_get_entry(void) {
#if INCLUDE_ALL_GCS
@ -806,7 +785,7 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
// If G1 is not enabled then attempt to go through the accessor entry point
// Reference.get is an accessor
return generate_accessor_entry();
return generate_jump_to_normal_entry();
}
//
@ -1242,8 +1221,6 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
// Generic method entry to (asm) interpreter
//------------------------------------------------------------------------------------------------------------------------
//
address InterpreterGenerator::generate_normal_entry(bool synchronized) {
address entry = __ pc();
@ -1410,123 +1387,6 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
return entry;
}
//----------------------------------------------------------------------------------------------------
// Entry points & stack frame layout
//
// Here we generate the various kind of entries into the interpreter.
// The two main entry type are generic bytecode methods and native call method.
// These both come in synchronized and non-synchronized versions but the
// frame layout they create is very similar. The other method entry
// types are really just special purpose entries that are really entry
// and interpretation all in one. These are for trivial methods like
// accessor, empty, or special math methods.
//
// When control flow reaches any of the entry types for the interpreter
// the following holds ->
//
// C2 Calling Conventions:
//
// The entry code below assumes that the following registers are set
// when coming in:
// G5_method: holds the Method* of the method to call
// Lesp: points to the TOS of the callers expression stack
// after having pushed all the parameters
//
// The entry code does the following to setup an interpreter frame
// pop parameters from the callers stack by adjusting Lesp
// set O0 to Lesp
// compute X = (max_locals - num_parameters)
// bump SP up by X to accomadate the extra locals
// compute X = max_expression_stack
// + vm_local_words
// + 16 words of register save area
// save frame doing a save sp, -X, sp growing towards lower addresses
// set Lbcp, Lmethod, LcpoolCache
// set Llocals to i0
// set Lmonitors to FP - rounded_vm_local_words
// set Lesp to Lmonitors - 4
//
// The frame has now been setup to do the rest of the entry code
// Try this optimization: Most method entries could live in a
// "one size fits all" stack frame without all the dynamic size
// calculations. It might be profitable to do all this calculation
// statically and approximately for "small enough" methods.
//-----------------------------------------------------------------------------------------------
// C1 Calling conventions
//
// Upon method entry, the following registers are setup:
//
// g2 G2_thread: current thread
// g5 G5_method: method to activate
// g4 Gargs : pointer to last argument
//
//
// Stack:
//
// +---------------+ <--- sp
// | |
// : reg save area :
// | |
// +---------------+ <--- sp + 0x40
// | |
// : extra 7 slots : note: these slots are not really needed for the interpreter (fix later)
// | |
// +---------------+ <--- sp + 0x5c
// | |
// : free :
// | |
// +---------------+ <--- Gargs
// | |
// : arguments :
// | |
// +---------------+
// | |
//
//
//
// AFTER FRAME HAS BEEN SETUP for method interpretation the stack looks like:
//
// +---------------+ <--- sp
// | |
// : reg save area :
// | |
// +---------------+ <--- sp + 0x40
// | |
// : extra 7 slots : note: these slots are not really needed for the interpreter (fix later)
// | |
// +---------------+ <--- sp + 0x5c
// | |
// : :
// | | <--- Lesp
// +---------------+ <--- Lmonitors (fp - 0x18)
// | VM locals |
// +---------------+ <--- fp
// | |
// : reg save area :
// | |
// +---------------+ <--- fp + 0x40
// | |
// : extra 7 slots : note: these slots are not really needed for the interpreter (fix later)
// | |
// +---------------+ <--- fp + 0x5c
// | |
// : free :
// | |
// +---------------+
// | |
// : nonarg locals :
// | |
// +---------------+
// | |
// : arguments :
// | | <--- Llocals
// +---------------+ <--- Gargs
// | |
static int size_activation_helper(int callee_extra_locals, int max_stack, int monitor_size) {
// Figure out the size of an interpreter frame (in words) given that we have a fully allocated

View File

@ -26,6 +26,7 @@
#include "asm/macroAssembler.inline.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/java.hpp"
#include "runtime/os.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "vm_version_sparc.hpp"
@ -249,7 +250,7 @@ void VM_Version::initialize() {
(!has_hardware_fsmuld() ? ", no-fsmuld" : ""));
// buf is started with ", " or is empty
_features_str = strdup(strlen(buf) > 2 ? buf + 2 : buf);
_features_str = os::strdup(strlen(buf) > 2 ? buf + 2 : buf);
// There are three 64-bit SPARC families that do not overlap, e.g.,
// both is_ultra3() and is_sparc64() cannot be true at the same time.

View File

@ -3853,6 +3853,15 @@ void Assembler::vpbroadcastd(XMMRegister dst, XMMRegister src) {
emit_int8((unsigned char)(0xC0 | encode));
}
// Carry-Less Multiplication Quadword
void Assembler::pclmulqdq(XMMRegister dst, XMMRegister src, int mask) {
assert(VM_Version::supports_clmul(), "");
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A);
emit_int8(0x44);
emit_int8((unsigned char)(0xC0 | encode));
emit_int8((unsigned char)mask);
}
// Carry-Less Multiplication Quadword
void Assembler::vpclmulqdq(XMMRegister dst, XMMRegister nds, XMMRegister src, int mask) {
assert(VM_Version::supports_avx() && VM_Version::supports_clmul(), "");
@ -4928,6 +4937,26 @@ void Assembler::addq(Register dst, Register src) {
emit_arith(0x03, 0xC0, dst, src);
}
void Assembler::adcxq(Register dst, Register src) {
//assert(VM_Version::supports_adx(), "adx instructions not supported");
emit_int8((unsigned char)0x66);
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
emit_int8(0x0F);
emit_int8(0x38);
emit_int8((unsigned char)0xF6);
emit_int8((unsigned char)(0xC0 | encode));
}
void Assembler::adoxq(Register dst, Register src) {
//assert(VM_Version::supports_adx(), "adx instructions not supported");
emit_int8((unsigned char)0xF3);
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
emit_int8(0x0F);
emit_int8(0x38);
emit_int8((unsigned char)0xF6);
emit_int8((unsigned char)(0xC0 | encode));
}
void Assembler::andq(Address dst, int32_t imm32) {
InstructionMark im(this);
prefixq(dst);
@ -5435,6 +5464,26 @@ void Assembler::movzwq(Register dst, Register src) {
emit_int8((unsigned char)(0xC0 | encode));
}
void Assembler::mulq(Address src) {
InstructionMark im(this);
prefixq(src);
emit_int8((unsigned char)0xF7);
emit_operand(rsp, src);
}
void Assembler::mulq(Register src) {
int encode = prefixq_and_encode(src->encoding());
emit_int8((unsigned char)0xF7);
emit_int8((unsigned char)(0xE0 | encode));
}
void Assembler::mulxq(Register dst1, Register dst2, Register src) {
assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
int encode = vex_prefix_and_encode(dst1->encoding(), dst2->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38, true, false);
emit_int8((unsigned char)0xF6);
emit_int8((unsigned char)(0xC0 | encode));
}
void Assembler::negq(Register dst) {
int encode = prefixq_and_encode(dst->encoding());
emit_int8((unsigned char)0xF7);
@ -5563,6 +5612,28 @@ void Assembler::rclq(Register dst, int imm8) {
emit_int8(imm8);
}
}
void Assembler::rorq(Register dst, int imm8) {
assert(isShiftCount(imm8 >> 1), "illegal shift count");
int encode = prefixq_and_encode(dst->encoding());
if (imm8 == 1) {
emit_int8((unsigned char)0xD1);
emit_int8((unsigned char)(0xC8 | encode));
} else {
emit_int8((unsigned char)0xC1);
emit_int8((unsigned char)(0xc8 | encode));
emit_int8(imm8);
}
}
void Assembler::rorxq(Register dst, Register src, int imm8) {
assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_3A, true, false);
emit_int8((unsigned char)0xF0);
emit_int8((unsigned char)(0xC0 | encode));
emit_int8(imm8);
}
void Assembler::sarq(Register dst, int imm8) {
assert(isShiftCount(imm8 >> 1), "illegal shift count");
int encode = prefixq_and_encode(dst->encoding());

View File

@ -888,6 +888,14 @@ private:
void addq(Register dst, Address src);
void addq(Register dst, Register src);
#ifdef _LP64
//Add Unsigned Integers with Carry Flag
void adcxq(Register dst, Register src);
//Add Unsigned Integers with Overflow Flag
void adoxq(Register dst, Register src);
#endif
void addr_nop_4();
void addr_nop_5();
void addr_nop_7();
@ -1204,19 +1212,20 @@ private:
void idivl(Register src);
void divl(Register src); // Unsigned division
#ifdef _LP64
void idivq(Register src);
#endif
void imull(Register dst, Register src);
void imull(Register dst, Register src, int value);
void imull(Register dst, Address src);
#ifdef _LP64
void imulq(Register dst, Register src);
void imulq(Register dst, Register src, int value);
#ifdef _LP64
void imulq(Register dst, Address src);
#endif
// jcc is the generic conditional branch generator to run-
// time routines, jcc is used for branches to labels. jcc
// takes a branch opcode (cc) and a label (L) and generates
@ -1408,9 +1417,16 @@ private:
void movzwq(Register dst, Register src);
#endif
// Unsigned multiply with RAX destination register
void mull(Address src);
void mull(Register src);
#ifdef _LP64
void mulq(Address src);
void mulq(Register src);
void mulxq(Register dst1, Register dst2, Register src);
#endif
// Multiply Scalar Double-Precision Floating-Point Values
void mulsd(XMMRegister dst, Address src);
void mulsd(XMMRegister dst, XMMRegister src);
@ -1541,6 +1557,11 @@ private:
void ret(int imm16);
#ifdef _LP64
void rorq(Register dst, int imm8);
void rorxq(Register dst, Register src, int imm8);
#endif
void sahf();
void sarl(Register dst, int imm8);
@ -1837,6 +1858,7 @@ private:
void vpbroadcastd(XMMRegister dst, XMMRegister src);
// Carry-Less Multiplication Quadword
void pclmulqdq(XMMRegister dst, XMMRegister src, int mask);
void vpclmulqdq(XMMRegister dst, XMMRegister nds, XMMRegister src, int mask);
// AVX instruction which is used to clear upper 128 bits of YMM registers and

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,21 +27,6 @@
protected:
#if 0
address generate_asm_interpreter_entry(bool synchronized);
address generate_native_entry(bool synchronized);
address generate_abstract_entry(void);
address generate_math_entry(AbstractInterpreter::MethodKind kind);
address generate_empty_entry(void);
address generate_accessor_entry(void);
address generate_Reference_get_entry(void);
void lock_method(void);
void generate_stack_overflow_check(void);
void generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue);
void generate_counter_overflow(Label* do_continue);
#endif
void generate_more_monitors();
void generate_deopt_handling();
address generate_interpreter_frame_manager(bool synchronized); // C++ interpreter only

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -66,9 +66,6 @@ extern "C" void RecursiveInterpreterActivation(interpreterState istate )
#define __ _masm->
#define STATE(field_name) (Address(state, byte_offset_of(BytecodeInterpreter, field_name)))
Label fast_accessor_slow_entry_path; // fast accessor methods need to be able to jmp to unsynchronized
// c++ interpreter entry point this holds that entry point label.
// default registers for state and sender_sp
// state and sender_sp are the same on 32bit because we have no choice.
// state could be rsi on 64bit but it is an arg reg and not callee save
@ -660,7 +657,6 @@ void InterpreterGenerator::generate_stack_overflow_check(void) {
// generate_method_entry) so the guard should work for them too.
//
// monitor entry size: see picture of stack set (generate_method_entry) and frame_i486.hpp
const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
// total overhead size: entry_size + (saved rbp, thru expr stack bottom).
@ -794,156 +790,6 @@ void InterpreterGenerator::lock_method(void) {
__ lock_object(monitor);
}
// Call an accessor method (assuming it is resolved, otherwise drop into vanilla (slow path) entry
address InterpreterGenerator::generate_accessor_entry(void) {
// rbx: Method*
// rsi/r13: senderSP must preserved for slow path, set SP to it on fast path
Label xreturn_path;
// do fastpath for resolved accessor methods
if (UseFastAccessorMethods) {
address entry_point = __ pc();
Label slow_path;
// If we need a safepoint check, generate full interpreter entry.
ExternalAddress state(SafepointSynchronize::address_of_state());
__ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
SafepointSynchronize::_not_synchronized);
__ jcc(Assembler::notEqual, slow_path);
// ASM/C++ Interpreter
// Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites thereof; parameter size = 1
// Note: We can only use this code if the getfield has been resolved
// and if we don't have a null-pointer exception => check for
// these conditions first and use slow path if necessary.
// rbx,: method
// rcx: receiver
__ movptr(rax, Address(rsp, wordSize));
// check if local 0 != NULL and read field
__ testptr(rax, rax);
__ jcc(Assembler::zero, slow_path);
// read first instruction word and extract bytecode @ 1 and index @ 2
__ movptr(rdx, Address(rbx, Method::const_offset()));
__ movptr(rdi, Address(rdx, ConstMethod::constants_offset()));
__ movl(rdx, Address(rdx, ConstMethod::codes_offset()));
// Shift codes right to get the index on the right.
// The bytecode fetched looks like <index><0xb4><0x2a>
__ shrl(rdx, 2*BitsPerByte);
__ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size())));
__ movptr(rdi, Address(rdi, ConstantPool::cache_offset_in_bytes()));
// rax,: local 0
// rbx,: method
// rcx: receiver - do not destroy since it is needed for slow path!
// rcx: scratch
// rdx: constant pool cache index
// rdi: constant pool cache
// rsi/r13: sender sp
// check if getfield has been resolved and read constant pool cache entry
// check the validity of the cache entry by testing whether _indices field
// contains Bytecode::_getfield in b1 byte.
assert(in_words(ConstantPoolCacheEntry::size()) == 4, "adjust shift below");
__ movl(rcx,
Address(rdi,
rdx,
Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()));
__ shrl(rcx, 2*BitsPerByte);
__ andl(rcx, 0xFF);
__ cmpl(rcx, Bytecodes::_getfield);
__ jcc(Assembler::notEqual, slow_path);
// Note: constant pool entry is not valid before bytecode is resolved
__ movptr(rcx,
Address(rdi,
rdx,
Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f2_offset()));
__ movl(rdx,
Address(rdi,
rdx,
Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
Label notByte, notShort, notChar;
const Address field_address (rax, rcx, Address::times_1);
// Need to differentiate between igetfield, agetfield, bgetfield etc.
// because they are different sizes.
// Use the type from the constant pool cache
__ shrl(rdx, ConstantPoolCacheEntry::tos_state_shift);
// Make sure we don't need to mask rdx after the above shift
ConstantPoolCacheEntry::verify_tos_state_shift();
#ifdef _LP64
Label notObj;
__ cmpl(rdx, atos);
__ jcc(Assembler::notEqual, notObj);
// atos
__ movptr(rax, field_address);
__ jmp(xreturn_path);
__ bind(notObj);
#endif // _LP64
__ cmpl(rdx, btos);
__ jcc(Assembler::notEqual, notByte);
__ load_signed_byte(rax, field_address);
__ jmp(xreturn_path);
__ bind(notByte);
__ cmpl(rdx, stos);
__ jcc(Assembler::notEqual, notShort);
__ load_signed_short(rax, field_address);
__ jmp(xreturn_path);
__ bind(notShort);
__ cmpl(rdx, ctos);
__ jcc(Assembler::notEqual, notChar);
__ load_unsigned_short(rax, field_address);
__ jmp(xreturn_path);
__ bind(notChar);
#ifdef ASSERT
Label okay;
#ifndef _LP64
__ cmpl(rdx, atos);
__ jcc(Assembler::equal, okay);
#endif // _LP64
__ cmpl(rdx, itos);
__ jcc(Assembler::equal, okay);
__ stop("what type is this?");
__ bind(okay);
#endif // ASSERT
// All the rest are a 32 bit wordsize
__ movl(rax, field_address);
__ bind(xreturn_path);
// _ireturn/_areturn
__ pop(rdi); // get return address
__ mov(rsp, sender_sp_on_entry); // set sp to sender sp
__ jmp(rdi);
// generate a vanilla interpreter entry as the slow path
__ bind(slow_path);
// We will enter c++ interpreter looking like it was
// called by the call_stub this will cause it to return
// a tosca result to the invoker which might have been
// the c++ interpreter itself.
__ jmp(fast_accessor_slow_entry_path);
return entry_point;
} else {
return NULL;
}
}
address InterpreterGenerator::generate_Reference_get_entry(void) {
#if INCLUDE_ALL_GCS
if (UseG1GC) {
@ -961,7 +807,7 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
// If G1 is not enabled then attempt to go through the accessor entry point
// Reference.get is an accessor
return generate_accessor_entry();
return generate_jump_to_normal_entry();
}
//
@ -1670,10 +1516,6 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
address entry_point = __ pc();
// Fast accessor methods share this entry point.
// This works because frame manager is in the same codelet
if (UseFastAccessorMethods && !synchronized) __ bind(fast_accessor_slow_entry_path);
Label dispatch_entry_2;
__ movptr(rcx, sender_sp_on_entry);
__ movptr(state, (int32_t)NULL_WORD); // no current activation
@ -2212,40 +2054,6 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
return entry_point;
}
address AbstractInterpreterGenerator::generate_method_entry(AbstractInterpreter::MethodKind kind) {
// determine code generation flags
bool synchronized = false;
address entry_point = NULL;
switch (kind) {
case Interpreter::zerolocals : break;
case Interpreter::zerolocals_synchronized: synchronized = true; break;
case Interpreter::native : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break;
case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true); break;
case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break;
case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break;
case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break;
case Interpreter::java_lang_math_sin : // fall thru
case Interpreter::java_lang_math_cos : // fall thru
case Interpreter::java_lang_math_tan : // fall thru
case Interpreter::java_lang_math_abs : // fall thru
case Interpreter::java_lang_math_log : // fall thru
case Interpreter::java_lang_math_log10 : // fall thru
case Interpreter::java_lang_math_sqrt : // fall thru
case Interpreter::java_lang_math_pow : // fall thru
case Interpreter::java_lang_math_exp : // fall thru
entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind); break;
case Interpreter::java_lang_ref_reference_get
: entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
default : ShouldNotReachHere(); break;
}
if (entry_point) return entry_point;
return ((InterpreterGenerator*)this)->generate_normal_entry(synchronized);
}
InterpreterGenerator::InterpreterGenerator(StubQueue* code)
: CppInterpreterGenerator(code) {

View File

@ -176,6 +176,8 @@ define_pd_global(uintx, TypeProfileLevel, 111);
"Use count trailing zeros instruction") \
\
product(bool, UseBMI1Instructions, false, \
"Use BMI instructions")
"Use BMI1 instructions") \
\
product(bool, UseBMI2Instructions, false, \
"Use BMI2 instructions")
#endif // CPU_X86_VM_GLOBALS_X86_HPP

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterGenerator.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "interpreter/interp_masm.hpp"
#define __ _masm->
// Jump into normal path for accessor and empty entry to jump to normal entry
// The "fast" optimization don't update compilation count therefore can disable inlining
// for these functions that should be inlined.
address InterpreterGenerator::generate_jump_to_normal_entry(void) {
address entry_point = __ pc();
assert(Interpreter::entry_for_kind(Interpreter::zerolocals) != NULL, "should already be generated");
__ jump(RuntimeAddress(Interpreter::entry_for_kind(Interpreter::zerolocals)));
return entry_point;
}
// Abstract method entry
// Attempt to execute abstract method. Throw exception
address InterpreterGenerator::generate_abstract_entry(void) {
address entry_point = __ pc();
// abstract method entry
#ifndef CC_INTERP
// pop return address, reset last_sp to NULL
__ empty_expression_stack();
__ restore_bcp(); // rsi must be correct for exception handler (was destroyed)
__ restore_locals(); // make sure locals pointer is correct as well (was destroyed)
#endif
// throw exception
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
// the call_VM checks for exception, so we should never return here.
__ should_not_reach_here();
return entry_point;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -36,8 +36,9 @@
address generate_native_entry(bool synchronized);
address generate_abstract_entry(void);
address generate_math_entry(AbstractInterpreter::MethodKind kind);
address generate_empty_entry(void);
address generate_accessor_entry(void);
address generate_jump_to_normal_entry(void);
address generate_accessor_entry(void) { return generate_jump_to_normal_entry(); }
address generate_empty_entry(void) { return generate_jump_to_normal_entry(); }
address generate_Reference_get_entry();
address generate_CRC32_update_entry();
address generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind);

View File

@ -67,45 +67,6 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() {
}
//
// Various method entries (that c++ and asm interpreter agree upon)
//------------------------------------------------------------------------------------------------------------------------
//
//
// Empty method, generate a very fast return.
address InterpreterGenerator::generate_empty_entry(void) {
// rbx,: Method*
// rcx: receiver (unused)
// rsi: previous interpreter state (C++ interpreter) must preserve
// rsi: sender sp must set sp to this value on return
if (!UseFastEmptyMethods) return NULL;
address entry_point = __ pc();
// If we need a safepoint check, generate full interpreter entry.
Label slow_path;
ExternalAddress state(SafepointSynchronize::address_of_state());
__ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
SafepointSynchronize::_not_synchronized);
__ jcc(Assembler::notEqual, slow_path);
// do nothing for empty methods (do not even increment invocation counter)
// Code: _return
// _return
// return w/o popping parameters
__ pop(rax);
__ mov(rsp, rsi);
__ jmp(rax);
__ bind(slow_path);
(void) generate_normal_entry(false);
return entry_point;
}
address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
// rbx,: Method*
@ -216,36 +177,6 @@ address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKin
}
// Abstract method entry
// Attempt to execute abstract method. Throw exception
address InterpreterGenerator::generate_abstract_entry(void) {
// rbx,: Method*
// rcx: receiver (unused)
// rsi: previous interpreter state (C++ interpreter) must preserve
// rsi: sender SP
address entry_point = __ pc();
// abstract method entry
#ifndef CC_INTERP
// pop return address, reset last_sp to NULL
__ empty_expression_stack();
__ restore_bcp(); // rsi must be correct for exception handler (was destroyed)
__ restore_locals(); // make sure locals pointer is correct as well (was destroyed)
#endif
// throw exception
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
// the call_VM checks for exception, so we should never return here.
__ should_not_reach_here();
return entry_point;
}
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in

View File

@ -301,66 +301,6 @@ address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKin
return entry_point;
}
// Abstract method entry
// Attempt to execute abstract method. Throw exception
address InterpreterGenerator::generate_abstract_entry(void) {
// rbx: Method*
// r13: sender SP
address entry_point = __ pc();
// abstract method entry
#ifndef CC_INTERP
// pop return address, reset last_sp to NULL
__ empty_expression_stack();
__ restore_bcp(); // rsi must be correct for exception handler (was destroyed)
__ restore_locals(); // make sure locals pointer is correct as well (was destroyed)
#endif
// throw exception
__ call_VM(noreg, CAST_FROM_FN_PTR(address,
InterpreterRuntime::throw_AbstractMethodError));
// the call_VM checks for exception, so we should never return here.
__ should_not_reach_here();
return entry_point;
}
// Empty method, generate a very fast return.
address InterpreterGenerator::generate_empty_entry(void) {
// rbx: Method*
// r13: sender sp must set sp to this value on return
if (!UseFastEmptyMethods) {
return NULL;
}
address entry_point = __ pc();
// If we need a safepoint check, generate full interpreter entry.
Label slow_path;
__ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
SafepointSynchronize::_not_synchronized);
__ jcc(Assembler::notEqual, slow_path);
// do nothing for empty methods (do not even increment invocation counter)
// Code: _return
// _return
// return w/o popping parameters
__ pop(rax);
__ mov(rsp, r13);
__ jmp(rax);
__ bind(slow_path);
(void) generate_normal_entry(false);
return entry_point;
}
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in

View File

@ -7293,6 +7293,467 @@ void MacroAssembler::encode_iso_array(Register src, Register dst, Register len,
bind(L_done);
}
#ifdef _LP64
/**
* Helper for multiply_to_len().
*/
void MacroAssembler::add2_with_carry(Register dest_hi, Register dest_lo, Register src1, Register src2) {
addq(dest_lo, src1);
adcq(dest_hi, 0);
addq(dest_lo, src2);
adcq(dest_hi, 0);
}
/**
* Multiply 64 bit by 64 bit first loop.
*/
void MacroAssembler::multiply_64_x_64_loop(Register x, Register xstart, Register x_xstart,
Register y, Register y_idx, Register z,
Register carry, Register product,
Register idx, Register kdx) {
//
// jlong carry, x[], y[], z[];
// for (int idx=ystart, kdx=ystart+1+xstart; idx >= 0; idx-, kdx--) {
// huge_128 product = y[idx] * x[xstart] + carry;
// z[kdx] = (jlong)product;
// carry = (jlong)(product >>> 64);
// }
// z[xstart] = carry;
//
Label L_first_loop, L_first_loop_exit;
Label L_one_x, L_one_y, L_multiply;
decrementl(xstart);
jcc(Assembler::negative, L_one_x);
movq(x_xstart, Address(x, xstart, Address::times_4, 0));
rorq(x_xstart, 32); // convert big-endian to little-endian
bind(L_first_loop);
decrementl(idx);
jcc(Assembler::negative, L_first_loop_exit);
decrementl(idx);
jcc(Assembler::negative, L_one_y);
movq(y_idx, Address(y, idx, Address::times_4, 0));
rorq(y_idx, 32); // convert big-endian to little-endian
bind(L_multiply);
movq(product, x_xstart);
mulq(y_idx); // product(rax) * y_idx -> rdx:rax
addq(product, carry);
adcq(rdx, 0);
subl(kdx, 2);
movl(Address(z, kdx, Address::times_4, 4), product);
shrq(product, 32);
movl(Address(z, kdx, Address::times_4, 0), product);
movq(carry, rdx);
jmp(L_first_loop);
bind(L_one_y);
movl(y_idx, Address(y, 0));
jmp(L_multiply);
bind(L_one_x);
movl(x_xstart, Address(x, 0));
jmp(L_first_loop);
bind(L_first_loop_exit);
}
/**
* Multiply 64 bit by 64 bit and add 128 bit.
*/
void MacroAssembler::multiply_add_128_x_128(Register x_xstart, Register y, Register z,
Register yz_idx, Register idx,
Register carry, Register product, int offset) {
// huge_128 product = (y[idx] * x_xstart) + z[kdx] + carry;
// z[kdx] = (jlong)product;
movq(yz_idx, Address(y, idx, Address::times_4, offset));
rorq(yz_idx, 32); // convert big-endian to little-endian
movq(product, x_xstart);
mulq(yz_idx); // product(rax) * yz_idx -> rdx:product(rax)
movq(yz_idx, Address(z, idx, Address::times_4, offset));
rorq(yz_idx, 32); // convert big-endian to little-endian
add2_with_carry(rdx, product, carry, yz_idx);
movl(Address(z, idx, Address::times_4, offset+4), product);
shrq(product, 32);
movl(Address(z, idx, Address::times_4, offset), product);
}
/**
* Multiply 128 bit by 128 bit. Unrolled inner loop.
*/
void MacroAssembler::multiply_128_x_128_loop(Register x_xstart, Register y, Register z,
Register yz_idx, Register idx, Register jdx,
Register carry, Register product,
Register carry2) {
// jlong carry, x[], y[], z[];
// int kdx = ystart+1;
// for (int idx=ystart-2; idx >= 0; idx -= 2) { // Third loop
// huge_128 product = (y[idx+1] * x_xstart) + z[kdx+idx+1] + carry;
// z[kdx+idx+1] = (jlong)product;
// jlong carry2 = (jlong)(product >>> 64);
// product = (y[idx] * x_xstart) + z[kdx+idx] + carry2;
// z[kdx+idx] = (jlong)product;
// carry = (jlong)(product >>> 64);
// }
// idx += 2;
// if (idx > 0) {
// product = (y[idx] * x_xstart) + z[kdx+idx] + carry;
// z[kdx+idx] = (jlong)product;
// carry = (jlong)(product >>> 64);
// }
//
Label L_third_loop, L_third_loop_exit, L_post_third_loop_done;
movl(jdx, idx);
andl(jdx, 0xFFFFFFFC);
shrl(jdx, 2);
bind(L_third_loop);
subl(jdx, 1);
jcc(Assembler::negative, L_third_loop_exit);
subl(idx, 4);
multiply_add_128_x_128(x_xstart, y, z, yz_idx, idx, carry, product, 8);
movq(carry2, rdx);
multiply_add_128_x_128(x_xstart, y, z, yz_idx, idx, carry2, product, 0);
movq(carry, rdx);
jmp(L_third_loop);
bind (L_third_loop_exit);
andl (idx, 0x3);
jcc(Assembler::zero, L_post_third_loop_done);
Label L_check_1;
subl(idx, 2);
jcc(Assembler::negative, L_check_1);
multiply_add_128_x_128(x_xstart, y, z, yz_idx, idx, carry, product, 0);
movq(carry, rdx);
bind (L_check_1);
addl (idx, 0x2);
andl (idx, 0x1);
subl(idx, 1);
jcc(Assembler::negative, L_post_third_loop_done);
movl(yz_idx, Address(y, idx, Address::times_4, 0));
movq(product, x_xstart);
mulq(yz_idx); // product(rax) * yz_idx -> rdx:product(rax)
movl(yz_idx, Address(z, idx, Address::times_4, 0));
add2_with_carry(rdx, product, yz_idx, carry);
movl(Address(z, idx, Address::times_4, 0), product);
shrq(product, 32);
shlq(rdx, 32);
orq(product, rdx);
movq(carry, product);
bind(L_post_third_loop_done);
}
/**
* Multiply 128 bit by 128 bit using BMI2. Unrolled inner loop.
*
*/
void MacroAssembler::multiply_128_x_128_bmi2_loop(Register y, Register z,
Register carry, Register carry2,
Register idx, Register jdx,
Register yz_idx1, Register yz_idx2,
Register tmp, Register tmp3, Register tmp4) {
assert(UseBMI2Instructions, "should be used only when BMI2 is available");
// jlong carry, x[], y[], z[];
// int kdx = ystart+1;
// for (int idx=ystart-2; idx >= 0; idx -= 2) { // Third loop
// huge_128 tmp3 = (y[idx+1] * rdx) + z[kdx+idx+1] + carry;
// jlong carry2 = (jlong)(tmp3 >>> 64);
// huge_128 tmp4 = (y[idx] * rdx) + z[kdx+idx] + carry2;
// carry = (jlong)(tmp4 >>> 64);
// z[kdx+idx+1] = (jlong)tmp3;
// z[kdx+idx] = (jlong)tmp4;
// }
// idx += 2;
// if (idx > 0) {
// yz_idx1 = (y[idx] * rdx) + z[kdx+idx] + carry;
// z[kdx+idx] = (jlong)yz_idx1;
// carry = (jlong)(yz_idx1 >>> 64);
// }
//
Label L_third_loop, L_third_loop_exit, L_post_third_loop_done;
movl(jdx, idx);
andl(jdx, 0xFFFFFFFC);
shrl(jdx, 2);
bind(L_third_loop);
subl(jdx, 1);
jcc(Assembler::negative, L_third_loop_exit);
subl(idx, 4);
movq(yz_idx1, Address(y, idx, Address::times_4, 8));
rorxq(yz_idx1, yz_idx1, 32); // convert big-endian to little-endian
movq(yz_idx2, Address(y, idx, Address::times_4, 0));
rorxq(yz_idx2, yz_idx2, 32);
mulxq(tmp4, tmp3, yz_idx1); // yz_idx1 * rdx -> tmp4:tmp3
mulxq(carry2, tmp, yz_idx2); // yz_idx2 * rdx -> carry2:tmp
movq(yz_idx1, Address(z, idx, Address::times_4, 8));
rorxq(yz_idx1, yz_idx1, 32);
movq(yz_idx2, Address(z, idx, Address::times_4, 0));
rorxq(yz_idx2, yz_idx2, 32);
if (VM_Version::supports_adx()) {
adcxq(tmp3, carry);
adoxq(tmp3, yz_idx1);
adcxq(tmp4, tmp);
adoxq(tmp4, yz_idx2);
movl(carry, 0); // does not affect flags
adcxq(carry2, carry);
adoxq(carry2, carry);
} else {
add2_with_carry(tmp4, tmp3, carry, yz_idx1);
add2_with_carry(carry2, tmp4, tmp, yz_idx2);
}
movq(carry, carry2);
movl(Address(z, idx, Address::times_4, 12), tmp3);
shrq(tmp3, 32);
movl(Address(z, idx, Address::times_4, 8), tmp3);
movl(Address(z, idx, Address::times_4, 4), tmp4);
shrq(tmp4, 32);
movl(Address(z, idx, Address::times_4, 0), tmp4);
jmp(L_third_loop);
bind (L_third_loop_exit);
andl (idx, 0x3);
jcc(Assembler::zero, L_post_third_loop_done);
Label L_check_1;
subl(idx, 2);
jcc(Assembler::negative, L_check_1);
movq(yz_idx1, Address(y, idx, Address::times_4, 0));
rorxq(yz_idx1, yz_idx1, 32);
mulxq(tmp4, tmp3, yz_idx1); // yz_idx1 * rdx -> tmp4:tmp3
movq(yz_idx2, Address(z, idx, Address::times_4, 0));
rorxq(yz_idx2, yz_idx2, 32);
add2_with_carry(tmp4, tmp3, carry, yz_idx2);
movl(Address(z, idx, Address::times_4, 4), tmp3);
shrq(tmp3, 32);
movl(Address(z, idx, Address::times_4, 0), tmp3);
movq(carry, tmp4);
bind (L_check_1);
addl (idx, 0x2);
andl (idx, 0x1);
subl(idx, 1);
jcc(Assembler::negative, L_post_third_loop_done);
movl(tmp4, Address(y, idx, Address::times_4, 0));
mulxq(carry2, tmp3, tmp4); // tmp4 * rdx -> carry2:tmp3
movl(tmp4, Address(z, idx, Address::times_4, 0));
add2_with_carry(carry2, tmp3, tmp4, carry);
movl(Address(z, idx, Address::times_4, 0), tmp3);
shrq(tmp3, 32);
shlq(carry2, 32);
orq(tmp3, carry2);
movq(carry, tmp3);
bind(L_post_third_loop_done);
}
/**
* Code for BigInteger::multiplyToLen() instrinsic.
*
* rdi: x
* rax: xlen
* rsi: y
* rcx: ylen
* r8: z
* r11: zlen
* r12: tmp1
* r13: tmp2
* r14: tmp3
* r15: tmp4
* rbx: tmp5
*
*/
void MacroAssembler::multiply_to_len(Register x, Register xlen, Register y, Register ylen, Register z, Register zlen,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5) {
ShortBranchVerifier sbv(this);
assert_different_registers(x, xlen, y, ylen, z, zlen, tmp1, tmp2, tmp3, tmp4, tmp5, rdx);
push(tmp1);
push(tmp2);
push(tmp3);
push(tmp4);
push(tmp5);
push(xlen);
push(zlen);
const Register idx = tmp1;
const Register kdx = tmp2;
const Register xstart = tmp3;
const Register y_idx = tmp4;
const Register carry = tmp5;
const Register product = xlen;
const Register x_xstart = zlen; // reuse register
// First Loop.
//
// final static long LONG_MASK = 0xffffffffL;
// int xstart = xlen - 1;
// int ystart = ylen - 1;
// long carry = 0;
// for (int idx=ystart, kdx=ystart+1+xstart; idx >= 0; idx-, kdx--) {
// long product = (y[idx] & LONG_MASK) * (x[xstart] & LONG_MASK) + carry;
// z[kdx] = (int)product;
// carry = product >>> 32;
// }
// z[xstart] = (int)carry;
//
movl(idx, ylen); // idx = ylen;
movl(kdx, zlen); // kdx = xlen+ylen;
xorq(carry, carry); // carry = 0;
Label L_done;
movl(xstart, xlen);
decrementl(xstart);
jcc(Assembler::negative, L_done);
multiply_64_x_64_loop(x, xstart, x_xstart, y, y_idx, z, carry, product, idx, kdx);
Label L_second_loop;
testl(kdx, kdx);
jcc(Assembler::zero, L_second_loop);
Label L_carry;
subl(kdx, 1);
jcc(Assembler::zero, L_carry);
movl(Address(z, kdx, Address::times_4, 0), carry);
shrq(carry, 32);
subl(kdx, 1);
bind(L_carry);
movl(Address(z, kdx, Address::times_4, 0), carry);
// Second and third (nested) loops.
//
// for (int i = xstart-1; i >= 0; i--) { // Second loop
// carry = 0;
// for (int jdx=ystart, k=ystart+1+i; jdx >= 0; jdx--, k--) { // Third loop
// long product = (y[jdx] & LONG_MASK) * (x[i] & LONG_MASK) +
// (z[k] & LONG_MASK) + carry;
// z[k] = (int)product;
// carry = product >>> 32;
// }
// z[i] = (int)carry;
// }
//
// i = xlen, j = tmp1, k = tmp2, carry = tmp5, x[i] = rdx
const Register jdx = tmp1;
bind(L_second_loop);
xorl(carry, carry); // carry = 0;
movl(jdx, ylen); // j = ystart+1
subl(xstart, 1); // i = xstart-1;
jcc(Assembler::negative, L_done);
push (z);
Label L_last_x;
lea(z, Address(z, xstart, Address::times_4, 4)); // z = z + k - j
subl(xstart, 1); // i = xstart-1;
jcc(Assembler::negative, L_last_x);
if (UseBMI2Instructions) {
movq(rdx, Address(x, xstart, Address::times_4, 0));
rorxq(rdx, rdx, 32); // convert big-endian to little-endian
} else {
movq(x_xstart, Address(x, xstart, Address::times_4, 0));
rorq(x_xstart, 32); // convert big-endian to little-endian
}
Label L_third_loop_prologue;
bind(L_third_loop_prologue);
push (x);
push (xstart);
push (ylen);
if (UseBMI2Instructions) {
multiply_128_x_128_bmi2_loop(y, z, carry, x, jdx, ylen, product, tmp2, x_xstart, tmp3, tmp4);
} else { // !UseBMI2Instructions
multiply_128_x_128_loop(x_xstart, y, z, y_idx, jdx, ylen, carry, product, x);
}
pop(ylen);
pop(xlen);
pop(x);
pop(z);
movl(tmp3, xlen);
addl(tmp3, 1);
movl(Address(z, tmp3, Address::times_4, 0), carry);
subl(tmp3, 1);
jccb(Assembler::negative, L_done);
shrq(carry, 32);
movl(Address(z, tmp3, Address::times_4, 0), carry);
jmp(L_second_loop);
// Next infrequent code is moved outside loops.
bind(L_last_x);
if (UseBMI2Instructions) {
movl(rdx, Address(x, 0));
} else {
movl(x_xstart, Address(x, 0));
}
jmp(L_third_loop_prologue);
bind(L_done);
pop(zlen);
pop(xlen);
pop(tmp5);
pop(tmp4);
pop(tmp3);
pop(tmp2);
pop(tmp1);
}
#endif
/**
* Emits code to update CRC-32 with a byte value according to constants in table
*
@ -7316,17 +7777,34 @@ void MacroAssembler::update_byte_crc32(Register crc, Register val, Register tabl
* Fold 128-bit data chunk
*/
void MacroAssembler::fold_128bit_crc32(XMMRegister xcrc, XMMRegister xK, XMMRegister xtmp, Register buf, int offset) {
vpclmulhdq(xtmp, xK, xcrc); // [123:64]
vpclmulldq(xcrc, xK, xcrc); // [63:0]
vpxor(xcrc, xcrc, Address(buf, offset), false /* vector256 */);
pxor(xcrc, xtmp);
if (UseAVX > 0) {
vpclmulhdq(xtmp, xK, xcrc); // [123:64]
vpclmulldq(xcrc, xK, xcrc); // [63:0]
vpxor(xcrc, xcrc, Address(buf, offset), false /* vector256 */);
pxor(xcrc, xtmp);
} else {
movdqa(xtmp, xcrc);
pclmulhdq(xtmp, xK); // [123:64]
pclmulldq(xcrc, xK); // [63:0]
pxor(xcrc, xtmp);
movdqu(xtmp, Address(buf, offset));
pxor(xcrc, xtmp);
}
}
void MacroAssembler::fold_128bit_crc32(XMMRegister xcrc, XMMRegister xK, XMMRegister xtmp, XMMRegister xbuf) {
vpclmulhdq(xtmp, xK, xcrc);
vpclmulldq(xcrc, xK, xcrc);
pxor(xcrc, xbuf);
pxor(xcrc, xtmp);
if (UseAVX > 0) {
vpclmulhdq(xtmp, xK, xcrc);
vpclmulldq(xcrc, xK, xcrc);
pxor(xcrc, xbuf);
pxor(xcrc, xtmp);
} else {
movdqa(xtmp, xcrc);
pclmulhdq(xtmp, xK);
pclmulldq(xcrc, xK);
pxor(xcrc, xbuf);
pxor(xcrc, xtmp);
}
}
/**
@ -7444,9 +7922,17 @@ void MacroAssembler::kernel_crc32(Register crc, Register buf, Register len, Regi
// Fold 128 bits in xmm1 down into 32 bits in crc register.
BIND(L_fold_128b);
movdqu(xmm0, ExternalAddress(StubRoutines::x86::crc_by128_masks_addr()));
vpclmulqdq(xmm2, xmm0, xmm1, 0x1);
vpand(xmm3, xmm0, xmm2, false /* vector256 */);
vpclmulqdq(xmm0, xmm0, xmm3, 0x1);
if (UseAVX > 0) {
vpclmulqdq(xmm2, xmm0, xmm1, 0x1);
vpand(xmm3, xmm0, xmm2, false /* vector256 */);
vpclmulqdq(xmm0, xmm0, xmm3, 0x1);
} else {
movdqa(xmm2, xmm0);
pclmulqdq(xmm2, xmm1, 0x1);
movdqa(xmm3, xmm0);
pand(xmm3, xmm2);
pclmulqdq(xmm0, xmm3, 0x1);
}
psrldq(xmm1, 8);
psrldq(xmm2, 4);
pxor(xmm0, xmm1);

View File

@ -966,6 +966,16 @@ public:
void mulss(XMMRegister dst, Address src) { Assembler::mulss(dst, src); }
void mulss(XMMRegister dst, AddressLiteral src);
// Carry-Less Multiplication Quadword
void pclmulldq(XMMRegister dst, XMMRegister src) {
// 0x00 - multiply lower 64 bits [0:63]
Assembler::pclmulqdq(dst, src, 0x00);
}
void pclmulhdq(XMMRegister dst, XMMRegister src) {
// 0x11 - multiply upper 64 bits [64:127]
Assembler::pclmulqdq(dst, src, 0x11);
}
void sqrtsd(XMMRegister dst, XMMRegister src) { Assembler::sqrtsd(dst, src); }
void sqrtsd(XMMRegister dst, Address src) { Assembler::sqrtsd(dst, src); }
void sqrtsd(XMMRegister dst, AddressLiteral src);
@ -1211,6 +1221,28 @@ public:
XMMRegister tmp1, XMMRegister tmp2, XMMRegister tmp3,
XMMRegister tmp4, Register tmp5, Register result);
#ifdef _LP64
void add2_with_carry(Register dest_hi, Register dest_lo, Register src1, Register src2);
void multiply_64_x_64_loop(Register x, Register xstart, Register x_xstart,
Register y, Register y_idx, Register z,
Register carry, Register product,
Register idx, Register kdx);
void multiply_add_128_x_128(Register x_xstart, Register y, Register z,
Register yz_idx, Register idx,
Register carry, Register product, int offset);
void multiply_128_x_128_bmi2_loop(Register y, Register z,
Register carry, Register carry2,
Register idx, Register jdx,
Register yz_idx1, Register yz_idx2,
Register tmp, Register tmp3, Register tmp4);
void multiply_128_x_128_loop(Register x_xstart, Register y, Register z,
Register yz_idx, Register idx, Register jdx,
Register carry, Register product,
Register carry2);
void multiply_to_len(Register x, Register xlen, Register y, Register ylen, Register z, Register zlen,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5);
#endif
// CRC32 code for java.util.zip.CRC32::updateBytes() instrinsic.
void update_byte_crc32(Register crc, Register val, Register table);
void kernel_crc32(Register crc, Register buf, Register len, Register table, Register tmp);

View File

@ -3677,6 +3677,70 @@ class StubGenerator: public StubCodeGenerator {
return start;
}
/**
* Arguments:
*
* Input:
* c_rarg0 - x address
* c_rarg1 - x length
* c_rarg2 - y address
* c_rarg3 - y lenth
* not Win64
* c_rarg4 - z address
* c_rarg5 - z length
* Win64
* rsp+40 - z address
* rsp+48 - z length
*/
address generate_multiplyToLen() {
__ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", "multiplyToLen");
address start = __ pc();
// Win64: rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...)
// Unix: rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...)
const Register x = rdi;
const Register xlen = rax;
const Register y = rsi;
const Register ylen = rcx;
const Register z = r8;
const Register zlen = r11;
// Next registers will be saved on stack in multiply_to_len().
const Register tmp1 = r12;
const Register tmp2 = r13;
const Register tmp3 = r14;
const Register tmp4 = r15;
const Register tmp5 = rbx;
BLOCK_COMMENT("Entry:");
__ enter(); // required for proper stackwalking of RuntimeStub frame
#ifndef _WIN64
__ movptr(zlen, r9); // Save r9 in r11 - zlen
#endif
setup_arg_regs(4); // x => rdi, xlen => rsi, y => rdx
// ylen => rcx, z => r8, zlen => r11
// r9 and r10 may be used to save non-volatile registers
#ifdef _WIN64
// last 2 arguments (#4, #5) are on stack on Win64
__ movptr(z, Address(rsp, 6 * wordSize));
__ movptr(zlen, Address(rsp, 7 * wordSize));
#endif
__ movptr(xlen, rsi);
__ movptr(y, rdx);
__ multiply_to_len(x, xlen, y, ylen, z, zlen, tmp1, tmp2, tmp3, tmp4, tmp5);
restore_arg_regs();
__ leave(); // required for proper stackwalking of RuntimeStub frame
__ ret(0);
return start;
}
#undef __
#define __ masm->
@ -3917,6 +3981,11 @@ class StubGenerator: public StubCodeGenerator {
generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry,
&StubRoutines::_safefetchN_fault_pc,
&StubRoutines::_safefetchN_continuation_pc);
#ifdef COMPILER2
if (UseMultiplyToLenIntrinsic) {
StubRoutines::_multiplyToLen = generate_multiplyToLen();
}
#endif
}
public:

View File

@ -38,7 +38,7 @@ int AbstractInterpreter::size_activation(int max_stack,
int callee_locals,
bool is_top_frame) {
// Note: This calculation must exactly parallel the frame setup
// in AbstractInterpreterGenerator::generate_method_entry.
// in InterpreterGenerator::generate_fixed_frame.
// fixed size of an interpreter frame:
int overhead = frame::sender_sp_offset -

View File

@ -468,10 +468,10 @@ void InterpreterGenerator::generate_stack_overflow_check(void) {
// rax,
// NOTE: since the additional locals are also always pushed (wasn't obvious in
// generate_method_entry) so the guard should work for them too.
// generate_fixed_frame) so the guard should work for them too.
//
// monitor entry size: see picture of stack set (generate_method_entry) and frame_x86.hpp
// monitor entry size: see picture of stack in frame_x86.hpp
const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
// total overhead size: entry_size + (saved rbp, thru expr stack bottom).
@ -633,145 +633,6 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
__ movptr(Address(rsp, 0), rsp); // set expression stack bottom
}
// End of helpers
//
// Various method entries
//------------------------------------------------------------------------------------------------------------------------
//
//
// Call an accessor method (assuming it is resolved, otherwise drop into vanilla (slow path) entry
address InterpreterGenerator::generate_accessor_entry(void) {
// rbx,: Method*
// rcx: receiver (preserve for slow entry into asm interpreter)
// rsi: senderSP must preserved for slow path, set SP to it on fast path
address entry_point = __ pc();
Label xreturn_path;
// do fastpath for resolved accessor methods
if (UseFastAccessorMethods) {
Label slow_path;
// If we need a safepoint check, generate full interpreter entry.
ExternalAddress state(SafepointSynchronize::address_of_state());
__ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
SafepointSynchronize::_not_synchronized);
__ jcc(Assembler::notEqual, slow_path);
// ASM/C++ Interpreter
// Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites thereof; parameter size = 1
// Note: We can only use this code if the getfield has been resolved
// and if we don't have a null-pointer exception => check for
// these conditions first and use slow path if necessary.
// rbx,: method
// rcx: receiver
__ movptr(rax, Address(rsp, wordSize));
// check if local 0 != NULL and read field
__ testptr(rax, rax);
__ jcc(Assembler::zero, slow_path);
// read first instruction word and extract bytecode @ 1 and index @ 2
__ movptr(rdx, Address(rbx, Method::const_offset()));
__ movptr(rdi, Address(rdx, ConstMethod::constants_offset()));
__ movl(rdx, Address(rdx, ConstMethod::codes_offset()));
// Shift codes right to get the index on the right.
// The bytecode fetched looks like <index><0xb4><0x2a>
__ shrl(rdx, 2*BitsPerByte);
__ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size())));
__ movptr(rdi, Address(rdi, ConstantPool::cache_offset_in_bytes()));
// rax,: local 0
// rbx,: method
// rcx: receiver - do not destroy since it is needed for slow path!
// rcx: scratch
// rdx: constant pool cache index
// rdi: constant pool cache
// rsi: sender sp
// check if getfield has been resolved and read constant pool cache entry
// check the validity of the cache entry by testing whether _indices field
// contains Bytecode::_getfield in b1 byte.
assert(in_words(ConstantPoolCacheEntry::size()) == 4, "adjust shift below");
__ movl(rcx,
Address(rdi,
rdx,
Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()));
__ shrl(rcx, 2*BitsPerByte);
__ andl(rcx, 0xFF);
__ cmpl(rcx, Bytecodes::_getfield);
__ jcc(Assembler::notEqual, slow_path);
// Note: constant pool entry is not valid before bytecode is resolved
__ movptr(rcx,
Address(rdi,
rdx,
Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f2_offset()));
__ movl(rdx,
Address(rdi,
rdx,
Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
Label notByte, notShort, notChar;
const Address field_address (rax, rcx, Address::times_1);
// Need to differentiate between igetfield, agetfield, bgetfield etc.
// because they are different sizes.
// Use the type from the constant pool cache
__ shrl(rdx, ConstantPoolCacheEntry::tos_state_shift);
// Make sure we don't need to mask rdx after the above shift
ConstantPoolCacheEntry::verify_tos_state_shift();
__ cmpl(rdx, btos);
__ jcc(Assembler::notEqual, notByte);
__ load_signed_byte(rax, field_address);
__ jmp(xreturn_path);
__ bind(notByte);
__ cmpl(rdx, stos);
__ jcc(Assembler::notEqual, notShort);
__ load_signed_short(rax, field_address);
__ jmp(xreturn_path);
__ bind(notShort);
__ cmpl(rdx, ctos);
__ jcc(Assembler::notEqual, notChar);
__ load_unsigned_short(rax, field_address);
__ jmp(xreturn_path);
__ bind(notChar);
#ifdef ASSERT
Label okay;
__ cmpl(rdx, atos);
__ jcc(Assembler::equal, okay);
__ cmpl(rdx, itos);
__ jcc(Assembler::equal, okay);
__ stop("what type is this?");
__ bind(okay);
#endif // ASSERT
// All the rest are a 32 bit wordsize
// This is ok for now. Since fast accessors should be going away
__ movptr(rax, field_address);
__ bind(xreturn_path);
// _ireturn/_areturn
__ pop(rdi); // get return address
__ mov(rsp, rsi); // set sp to sender sp
__ jmp(rdi);
// generate a vanilla interpreter entry as the slow path
__ bind(slow_path);
(void) generate_normal_entry(false);
return entry_point;
}
return NULL;
}
// Method entry for java.lang.ref.Reference.get.
address InterpreterGenerator::generate_Reference_get_entry(void) {
@ -862,7 +723,7 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
// If G1 is not enabled then attempt to go through the accessor entry point
// Reference.get is an accessor
return generate_accessor_entry();
return generate_jump_to_normal_entry();
}
/**
@ -1557,100 +1418,6 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
return entry_point;
}
//------------------------------------------------------------------------------------------------------------------------
// Entry points
//
// Here we generate the various kind of entries into the interpreter.
// The two main entry type are generic bytecode methods and native call method.
// These both come in synchronized and non-synchronized versions but the
// frame layout they create is very similar. The other method entry
// types are really just special purpose entries that are really entry
// and interpretation all in one. These are for trivial methods like
// accessor, empty, or special math methods.
//
// When control flow reaches any of the entry types for the interpreter
// the following holds ->
//
// Arguments:
//
// rbx,: Method*
// rcx: receiver
//
//
// Stack layout immediately at entry
//
// [ return address ] <--- rsp
// [ parameter n ]
// ...
// [ parameter 1 ]
// [ expression stack ] (caller's java expression stack)
// Assuming that we don't go to one of the trivial specialized
// entries the stack will look like below when we are ready to execute
// the first bytecode (or call the native routine). The register usage
// will be as the template based interpreter expects (see interpreter_x86.hpp).
//
// local variables follow incoming parameters immediately; i.e.
// the return address is moved to the end of the locals).
//
// [ monitor entry ] <--- rsp
// ...
// [ monitor entry ]
// [ expr. stack bottom ]
// [ saved rsi ]
// [ current rdi ]
// [ Method* ]
// [ saved rbp, ] <--- rbp,
// [ return address ]
// [ local variable m ]
// ...
// [ local variable 1 ]
// [ parameter n ]
// ...
// [ parameter 1 ] <--- rdi
address AbstractInterpreterGenerator::generate_method_entry(AbstractInterpreter::MethodKind kind) {
// determine code generation flags
bool synchronized = false;
address entry_point = NULL;
InterpreterGenerator* ig_this = (InterpreterGenerator*)this;
switch (kind) {
case Interpreter::zerolocals : break;
case Interpreter::zerolocals_synchronized: synchronized = true; break;
case Interpreter::native : entry_point = ig_this->generate_native_entry(false); break;
case Interpreter::native_synchronized : entry_point = ig_this->generate_native_entry(true); break;
case Interpreter::empty : entry_point = ig_this->generate_empty_entry(); break;
case Interpreter::accessor : entry_point = ig_this->generate_accessor_entry(); break;
case Interpreter::abstract : entry_point = ig_this->generate_abstract_entry(); break;
case Interpreter::java_lang_math_sin : // fall thru
case Interpreter::java_lang_math_cos : // fall thru
case Interpreter::java_lang_math_tan : // fall thru
case Interpreter::java_lang_math_abs : // fall thru
case Interpreter::java_lang_math_log : // fall thru
case Interpreter::java_lang_math_log10 : // fall thru
case Interpreter::java_lang_math_sqrt : // fall thru
case Interpreter::java_lang_math_pow : // fall thru
case Interpreter::java_lang_math_exp : entry_point = ig_this->generate_math_entry(kind); break;
case Interpreter::java_lang_ref_reference_get
: entry_point = ig_this->generate_Reference_get_entry(); break;
case Interpreter::java_util_zip_CRC32_update
: entry_point = ig_this->generate_CRC32_update_entry(); break;
case Interpreter::java_util_zip_CRC32_updateBytes
: // fall thru
case Interpreter::java_util_zip_CRC32_updateByteBuffer
: entry_point = ig_this->generate_CRC32_updateBytes_entry(kind); break;
default:
fatal(err_msg("unexpected method kind: %d", kind));
break;
}
if (entry_point) return entry_point;
return ig_this->generate_normal_entry(synchronized);
}
// These should never be compiled since the interpreter will prefer
// the compiled version to the intrinsic version.

View File

@ -400,7 +400,7 @@ void InterpreterGenerator::generate_counter_overflow(Label* do_continue) {
// page mechanism will work for that.
//
// NOTE: Since the additional locals are also always pushed (wasn't
// obvious in generate_method_entry) so the guard should work for them
// obvious in generate_fixed_frame) so the guard should work for them
// too.
//
// Args:
@ -411,8 +411,7 @@ void InterpreterGenerator::generate_counter_overflow(Label* do_continue) {
// rax
void InterpreterGenerator::generate_stack_overflow_check(void) {
// monitor entry size: see picture of stack set
// (generate_method_entry) and frame_amd64.hpp
// monitor entry size: see picture of stack in frame_x86.hpp
const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
// total overhead size: entry_size + (saved rbp through expr stack
@ -600,153 +599,6 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
// End of helpers
// Various method entries
//------------------------------------------------------------------------------------------------------------------------
//
//
// Call an accessor method (assuming it is resolved, otherwise drop
// into vanilla (slow path) entry
address InterpreterGenerator::generate_accessor_entry(void) {
// rbx: Method*
// r13: senderSP must preserver for slow path, set SP to it on fast path
address entry_point = __ pc();
Label xreturn_path;
// do fastpath for resolved accessor methods
if (UseFastAccessorMethods) {
// Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites
// thereof; parameter size = 1
// Note: We can only use this code if the getfield has been resolved
// and if we don't have a null-pointer exception => check for
// these conditions first and use slow path if necessary.
Label slow_path;
// If we need a safepoint check, generate full interpreter entry.
__ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
SafepointSynchronize::_not_synchronized);
__ jcc(Assembler::notEqual, slow_path);
// rbx: method
__ movptr(rax, Address(rsp, wordSize));
// check if local 0 != NULL and read field
__ testptr(rax, rax);
__ jcc(Assembler::zero, slow_path);
// read first instruction word and extract bytecode @ 1 and index @ 2
__ movptr(rdx, Address(rbx, Method::const_offset()));
__ movptr(rdi, Address(rdx, ConstMethod::constants_offset()));
__ movl(rdx, Address(rdx, ConstMethod::codes_offset()));
// Shift codes right to get the index on the right.
// The bytecode fetched looks like <index><0xb4><0x2a>
__ shrl(rdx, 2 * BitsPerByte);
__ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size())));
__ movptr(rdi, Address(rdi, ConstantPool::cache_offset_in_bytes()));
// rax: local 0
// rbx: method
// rdx: constant pool cache index
// rdi: constant pool cache
// check if getfield has been resolved and read constant pool cache entry
// check the validity of the cache entry by testing whether _indices field
// contains Bytecode::_getfield in b1 byte.
assert(in_words(ConstantPoolCacheEntry::size()) == 4,
"adjust shift below");
__ movl(rcx,
Address(rdi,
rdx,
Address::times_8,
ConstantPoolCache::base_offset() +
ConstantPoolCacheEntry::indices_offset()));
__ shrl(rcx, 2 * BitsPerByte);
__ andl(rcx, 0xFF);
__ cmpl(rcx, Bytecodes::_getfield);
__ jcc(Assembler::notEqual, slow_path);
// Note: constant pool entry is not valid before bytecode is resolved
__ movptr(rcx,
Address(rdi,
rdx,
Address::times_8,
ConstantPoolCache::base_offset() +
ConstantPoolCacheEntry::f2_offset()));
// edx: flags
__ movl(rdx,
Address(rdi,
rdx,
Address::times_8,
ConstantPoolCache::base_offset() +
ConstantPoolCacheEntry::flags_offset()));
Label notObj, notInt, notByte, notShort;
const Address field_address(rax, rcx, Address::times_1);
// Need to differentiate between igetfield, agetfield, bgetfield etc.
// because they are different sizes.
// Use the type from the constant pool cache
__ shrl(rdx, ConstantPoolCacheEntry::tos_state_shift);
// Make sure we don't need to mask edx after the above shift
ConstantPoolCacheEntry::verify_tos_state_shift();
__ cmpl(rdx, atos);
__ jcc(Assembler::notEqual, notObj);
// atos
__ load_heap_oop(rax, field_address);
__ jmp(xreturn_path);
__ bind(notObj);
__ cmpl(rdx, itos);
__ jcc(Assembler::notEqual, notInt);
// itos
__ movl(rax, field_address);
__ jmp(xreturn_path);
__ bind(notInt);
__ cmpl(rdx, btos);
__ jcc(Assembler::notEqual, notByte);
// btos
__ load_signed_byte(rax, field_address);
__ jmp(xreturn_path);
__ bind(notByte);
__ cmpl(rdx, stos);
__ jcc(Assembler::notEqual, notShort);
// stos
__ load_signed_short(rax, field_address);
__ jmp(xreturn_path);
__ bind(notShort);
#ifdef ASSERT
Label okay;
__ cmpl(rdx, ctos);
__ jcc(Assembler::equal, okay);
__ stop("what type is this?");
__ bind(okay);
#endif
// ctos
__ load_unsigned_short(rax, field_address);
__ bind(xreturn_path);
// _ireturn/_areturn
__ pop(rdi);
__ mov(rsp, r13);
__ jmp(rdi);
__ ret(0);
// generate a vanilla interpreter entry as the slow path
__ bind(slow_path);
(void) generate_normal_entry(false);
} else {
(void) generate_normal_entry(false);
}
return entry_point;
}
// Method entry for java.lang.ref.Reference.get.
address InterpreterGenerator::generate_Reference_get_entry(void) {
#if INCLUDE_ALL_GCS
@ -773,8 +625,6 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
// and so we don't need to call the G1 pre-barrier. Thus we can use the
// regular method entry code to generate the NPE.
//
// This code is based on generate_accessor_enty.
//
// rbx: Method*
// r13: senderSP must preserve for slow path, set SP to it on fast path
@ -832,7 +682,7 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
// If G1 is not enabled then attempt to go through the accessor entry point
// Reference.get is an accessor
return generate_accessor_entry();
return generate_jump_to_normal_entry();
}
/**
@ -1566,100 +1416,6 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
return entry_point;
}
// Entry points
//
// Here we generate the various kind of entries into the interpreter.
// The two main entry type are generic bytecode methods and native
// call method. These both come in synchronized and non-synchronized
// versions but the frame layout they create is very similar. The
// other method entry types are really just special purpose entries
// that are really entry and interpretation all in one. These are for
// trivial methods like accessor, empty, or special math methods.
//
// When control flow reaches any of the entry types for the interpreter
// the following holds ->
//
// Arguments:
//
// rbx: Method*
//
// Stack layout immediately at entry
//
// [ return address ] <--- rsp
// [ parameter n ]
// ...
// [ parameter 1 ]
// [ expression stack ] (caller's java expression stack)
// Assuming that we don't go to one of the trivial specialized entries
// the stack will look like below when we are ready to execute the
// first bytecode (or call the native routine). The register usage
// will be as the template based interpreter expects (see
// interpreter_amd64.hpp).
//
// local variables follow incoming parameters immediately; i.e.
// the return address is moved to the end of the locals).
//
// [ monitor entry ] <--- rsp
// ...
// [ monitor entry ]
// [ expr. stack bottom ]
// [ saved r13 ]
// [ current r14 ]
// [ Method* ]
// [ saved ebp ] <--- rbp
// [ return address ]
// [ local variable m ]
// ...
// [ local variable 1 ]
// [ parameter n ]
// ...
// [ parameter 1 ] <--- r14
address AbstractInterpreterGenerator::generate_method_entry(
AbstractInterpreter::MethodKind kind) {
// determine code generation flags
bool synchronized = false;
address entry_point = NULL;
InterpreterGenerator* ig_this = (InterpreterGenerator*)this;
switch (kind) {
case Interpreter::zerolocals : break;
case Interpreter::zerolocals_synchronized: synchronized = true; break;
case Interpreter::native : entry_point = ig_this->generate_native_entry(false); break;
case Interpreter::native_synchronized : entry_point = ig_this->generate_native_entry(true); break;
case Interpreter::empty : entry_point = ig_this->generate_empty_entry(); break;
case Interpreter::accessor : entry_point = ig_this->generate_accessor_entry(); break;
case Interpreter::abstract : entry_point = ig_this->generate_abstract_entry(); break;
case Interpreter::java_lang_math_sin : // fall thru
case Interpreter::java_lang_math_cos : // fall thru
case Interpreter::java_lang_math_tan : // fall thru
case Interpreter::java_lang_math_abs : // fall thru
case Interpreter::java_lang_math_log : // fall thru
case Interpreter::java_lang_math_log10 : // fall thru
case Interpreter::java_lang_math_sqrt : // fall thru
case Interpreter::java_lang_math_pow : // fall thru
case Interpreter::java_lang_math_exp : entry_point = ig_this->generate_math_entry(kind); break;
case Interpreter::java_lang_ref_reference_get
: entry_point = ig_this->generate_Reference_get_entry(); break;
case Interpreter::java_util_zip_CRC32_update
: entry_point = ig_this->generate_CRC32_update_entry(); break;
case Interpreter::java_util_zip_CRC32_updateBytes
: // fall thru
case Interpreter::java_util_zip_CRC32_updateByteBuffer
: entry_point = ig_this->generate_CRC32_updateBytes_entry(kind); break;
default:
fatal(err_msg("unexpected method kind: %d", kind));
break;
}
if (entry_point) {
return entry_point;
}
return ig_this->generate_normal_entry(synchronized);
}
// These should never be compiled since the interpreter will prefer
// the compiled version to the intrinsic version.

View File

@ -27,6 +27,7 @@
#include "asm/macroAssembler.inline.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/java.hpp"
#include "runtime/os.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "vm_version_x86.hpp"
@ -484,7 +485,7 @@ void VM_Version::get_processor_features() {
}
char buf[256];
jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
cores_per_cpu(), threads_per_core(),
cpu_family(), _model, _stepping,
(supports_cmov() ? ", cmov" : ""),
@ -513,8 +514,9 @@ void VM_Version::get_processor_features() {
(supports_tscinv_bit() ? ", tscinvbit": ""),
(supports_tscinv() ? ", tscinv": ""),
(supports_bmi1() ? ", bmi1" : ""),
(supports_bmi2() ? ", bmi2" : ""));
_features_str = strdup(buf);
(supports_bmi2() ? ", bmi2" : ""),
(supports_adx() ? ", adx" : ""));
_features_str = os::strdup(buf);
// UseSSE is set to the smaller of what hardware supports and what
// the command line requires. I.e., you cannot set UseSSE to 2 on
@ -559,13 +561,13 @@ void VM_Version::get_processor_features() {
FLAG_SET_DEFAULT(UseCLMUL, false);
}
if (UseCLMUL && (UseAVX > 0) && (UseSSE > 2)) {
if (UseCLMUL && (UseSSE > 2)) {
if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) {
UseCRC32Intrinsics = true;
}
} else if (UseCRC32Intrinsics) {
if (!FLAG_IS_DEFAULT(UseCRC32Intrinsics))
warning("CRC32 Intrinsics requires AVX and CLMUL instructions (not available on this CPU)");
warning("CRC32 Intrinsics requires CLMUL instructions (not available on this CPU)");
FLAG_SET_DEFAULT(UseCRC32Intrinsics, false);
}
@ -603,6 +605,17 @@ void VM_Version::get_processor_features() {
#if INCLUDE_RTM_OPT
if (UseRTMLocking) {
if (is_intel_family_core()) {
if ((_model == CPU_MODEL_HASWELL_E3) ||
(_model == CPU_MODEL_HASWELL_E7 && _stepping < 3) ||
(_model == CPU_MODEL_BROADWELL && _stepping < 4)) {
if (!UnlockExperimentalVMOptions) {
vm_exit_during_initialization("UseRTMLocking is only available as experimental option on this platform. It must be enabled via -XX:+UnlockExperimentalVMOptions flag.");
} else {
warning("UseRTMLocking is only available as experimental option on this platform.");
}
}
}
if (!FLAG_IS_CMDLINE(UseRTMLocking)) {
// RTM locking should be used only for applications with
// high lock contention. For now we do not use it by default.
@ -677,7 +690,20 @@ void VM_Version::get_processor_features() {
}
#endif
}
#ifdef _LP64
if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
UseMultiplyToLenIntrinsic = true;
}
#else
if (UseMultiplyToLenIntrinsic) {
if (!FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
warning("multiplyToLen intrinsic is not available in 32-bit VM");
}
FLAG_SET_DEFAULT(UseMultiplyToLenIntrinsic, false);
}
#endif
#endif // COMPILER2
// On new cpus instructions which update whole XMM register should be used
// to prevent partial register stall due to dependencies on high half.
@ -805,6 +831,24 @@ void VM_Version::get_processor_features() {
}
}
}
if ((cpu_family() == 0x06) &&
((extended_cpu_model() == 0x36) || // Centerton
(extended_cpu_model() == 0x37) || // Silvermont
(extended_cpu_model() == 0x4D))) {
#ifdef COMPILER2
if (FLAG_IS_DEFAULT(OptoScheduling)) {
OptoScheduling = true;
}
#endif
if (supports_sse4_2()) { // Silvermont
if (FLAG_IS_DEFAULT(UseUnalignedLoadStores)) {
UseUnalignedLoadStores = true; // use movdqu on newest Intel cpus
}
}
}
if(FLAG_IS_DEFAULT(AllocatePrefetchInstr) && supports_3dnow_prefetch()) {
AllocatePrefetchInstr = 3;
}
}
// Use count leading zeros count instruction if available.
@ -817,25 +861,37 @@ void VM_Version::get_processor_features() {
FLAG_SET_DEFAULT(UseCountLeadingZerosInstruction, false);
}
if (supports_bmi1()) {
if (FLAG_IS_DEFAULT(UseBMI1Instructions)) {
UseBMI1Instructions = true;
}
} else if (UseBMI1Instructions) {
warning("BMI1 instructions are not available on this CPU");
FLAG_SET_DEFAULT(UseBMI1Instructions, false);
}
// Use count trailing zeros instruction if available
if (supports_bmi1()) {
// tzcnt does not require VEX prefix
if (FLAG_IS_DEFAULT(UseCountTrailingZerosInstruction)) {
UseCountTrailingZerosInstruction = UseBMI1Instructions;
UseCountTrailingZerosInstruction = true;
}
} else if (UseCountTrailingZerosInstruction) {
warning("tzcnt instruction is not available on this CPU");
FLAG_SET_DEFAULT(UseCountTrailingZerosInstruction, false);
}
// BMI instructions use an encoding with VEX prefix.
// VEX prefix is generated only when AVX > 0.
if (supports_bmi1() && supports_avx()) {
if (FLAG_IS_DEFAULT(UseBMI1Instructions)) {
UseBMI1Instructions = true;
}
} else if (UseBMI1Instructions) {
warning("BMI1 instructions are not available on this CPU (AVX is also required)");
FLAG_SET_DEFAULT(UseBMI1Instructions, false);
}
if (supports_bmi2() && supports_avx()) {
if (FLAG_IS_DEFAULT(UseBMI2Instructions)) {
UseBMI2Instructions = true;
}
} else if (UseBMI2Instructions) {
warning("BMI2 instructions are not available on this CPU (AVX is also required)");
FLAG_SET_DEFAULT(UseBMI2Instructions, false);
}
// Use population count instruction if available.
if (supports_popcnt()) {
if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
@ -892,23 +948,25 @@ void VM_Version::get_processor_features() {
AllocatePrefetchDistance = allocate_prefetch_distance();
AllocatePrefetchStyle = allocate_prefetch_style();
if( is_intel() && cpu_family() == 6 && supports_sse3() ) {
if( AllocatePrefetchStyle == 2 ) { // watermark prefetching on Core
if (is_intel() && cpu_family() == 6 && supports_sse3()) {
if (AllocatePrefetchStyle == 2) { // watermark prefetching on Core
#ifdef _LP64
AllocatePrefetchDistance = 384;
#else
AllocatePrefetchDistance = 320;
#endif
}
if( supports_sse4_2() && supports_ht() ) { // Nehalem based cpus
if (supports_sse4_2() && supports_ht()) { // Nehalem based cpus
AllocatePrefetchDistance = 192;
AllocatePrefetchLines = 4;
}
#ifdef COMPILER2
if (AggressiveOpts && FLAG_IS_DEFAULT(UseFPUForSpilling)) {
if (supports_sse4_2()) {
if (FLAG_IS_DEFAULT(UseFPUForSpilling)) {
FLAG_SET_DEFAULT(UseFPUForSpilling, true);
}
#endif
}
#endif
}
assert(AllocatePrefetchDistance % AllocatePrefetchStepSize == 0, "invalid value");

View File

@ -209,7 +209,9 @@ public:
erms : 1,
: 1,
rtm : 1,
: 20;
: 7,
adx : 1,
: 12;
} bits;
};
@ -260,7 +262,8 @@ protected:
CPU_CLMUL = (1 << 21), // carryless multiply for CRC
CPU_BMI1 = (1 << 22),
CPU_BMI2 = (1 << 23),
CPU_RTM = (1 << 24) // Restricted Transactional Memory instructions
CPU_RTM = (1 << 24), // Restricted Transactional Memory instructions
CPU_ADX = (1 << 25)
} cpuFeatureFlags;
enum {
@ -276,7 +279,10 @@ protected:
CPU_MODEL_WESTMERE_EX = 0x2f,
CPU_MODEL_SANDYBRIDGE = 0x2a,
CPU_MODEL_SANDYBRIDGE_EP = 0x2d,
CPU_MODEL_IVYBRIDGE_EP = 0x3a
CPU_MODEL_IVYBRIDGE_EP = 0x3a,
CPU_MODEL_HASWELL_E3 = 0x3c,
CPU_MODEL_HASWELL_E7 = 0x3f,
CPU_MODEL_BROADWELL = 0x3d
} cpuExtendedFamily;
// cpuid information block. All info derived from executing cpuid with
@ -462,10 +468,16 @@ protected:
}
// Intel features.
if(is_intel()) {
if(_cpuid_info.sef_cpuid7_ebx.bits.adx != 0)
result |= CPU_ADX;
if(_cpuid_info.sef_cpuid7_ebx.bits.bmi2 != 0)
result |= CPU_BMI2;
if(_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0)
result |= CPU_LZCNT;
// for Intel, ecx.bits.misalignsse bit (bit 8) indicates support for prefetchw
if (_cpuid_info.ext_cpuid1_ecx.bits.misalignsse != 0) {
result |= CPU_3DNOW_PREFETCH;
}
}
return result;
@ -622,6 +634,7 @@ public:
static bool supports_rtm() { return (_cpuFeatures & CPU_RTM) != 0; }
static bool supports_bmi1() { return (_cpuFeatures & CPU_BMI1) != 0; }
static bool supports_bmi2() { return (_cpuFeatures & CPU_BMI2) != 0; }
static bool supports_adx() { return (_cpuFeatures & CPU_ADX) != 0; }
// Intel features
static bool is_intel_family_core() { return is_intel() &&
extended_cpu_family() == CPU_FAMILY_INTEL_CORE; }

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -731,7 +731,7 @@ InterpreterFrame *InterpreterFrame::build(Method* const method, TRAPS) {
if (method->is_static())
object = method->constants()->pool_holder()->java_mirror();
else
object = (oop) locals[0];
object = (oop) (void*)locals[0];
monitor->set_obj(object);
}
@ -831,60 +831,6 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
return generate_entry((address) CppInterpreter::normal_entry);
}
address AbstractInterpreterGenerator::generate_method_entry(
AbstractInterpreter::MethodKind kind) {
address entry_point = NULL;
switch (kind) {
case Interpreter::zerolocals:
case Interpreter::zerolocals_synchronized:
break;
case Interpreter::native:
entry_point = ((InterpreterGenerator*) this)->generate_native_entry(false);
break;
case Interpreter::native_synchronized:
entry_point = ((InterpreterGenerator*) this)->generate_native_entry(false);
break;
case Interpreter::empty:
entry_point = ((InterpreterGenerator*) this)->generate_empty_entry();
break;
case Interpreter::accessor:
entry_point = ((InterpreterGenerator*) this)->generate_accessor_entry();
break;
case Interpreter::abstract:
entry_point = ((InterpreterGenerator*) this)->generate_abstract_entry();
break;
case Interpreter::java_lang_math_sin:
case Interpreter::java_lang_math_cos:
case Interpreter::java_lang_math_tan:
case Interpreter::java_lang_math_abs:
case Interpreter::java_lang_math_log:
case Interpreter::java_lang_math_log10:
case Interpreter::java_lang_math_sqrt:
case Interpreter::java_lang_math_pow:
case Interpreter::java_lang_math_exp:
entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind);
break;
case Interpreter::java_lang_ref_reference_get:
entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry();
break;
default:
ShouldNotReachHere();
}
if (entry_point == NULL)
entry_point = ((InterpreterGenerator*) this)->generate_normal_entry(false);
return entry_point;
}
InterpreterGenerator::InterpreterGenerator(StubQueue* code)
: CppInterpreterGenerator(code) {

View File

@ -26,6 +26,8 @@
#ifndef CPU_ZERO_VM_FRAME_ZERO_INLINE_HPP
#define CPU_ZERO_VM_FRAME_ZERO_INLINE_HPP
#include "code/codeCache.hpp"
// Constructors
inline frame::frame() {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -61,6 +61,12 @@ define_pd_global(uintx, CMSYoungGenPerWorker, 16*M); // default max size of CMS
define_pd_global(uintx, TypeProfileLevel, 0);
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct)
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
product(bool, UseFastEmptyMethods, true, \
"Use fast method entry code for empty methods") \
\
product(bool, UseFastAccessorMethods, true, \
"Use fast method entry code for accessor methods") \
\
#endif // CPU_ZERO_VM_GLOBALS_ZERO_HPP

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -39,4 +39,7 @@
address generate_accessor_entry();
address generate_Reference_get_entry();
// Not supported
address generate_CRC32_update_entry() { return NULL; }
address generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) { return NULL; }
#endif // CPU_ZERO_VM_INTERPRETERGENERATOR_ZERO_HPP

View File

@ -58,6 +58,7 @@
#include "runtime/mutexLocker.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/os.hpp"
#include "runtime/osThread.hpp"
#include "runtime/perfMemory.hpp"
#include "runtime/sharedRuntime.hpp"
@ -378,10 +379,10 @@ void os::Aix::query_multipage_support() {
// default should be 4K.
size_t data_page_size = SIZE_4K;
{
void* p = ::malloc(SIZE_16M);
void* p = os::malloc(SIZE_16M, mtInternal);
guarantee(p != NULL, "malloc failed");
data_page_size = os::Aix::query_pagesize(p);
::free(p);
os::free(p);
}
// query default shm page size (LDR_CNTRL SHMPSIZE)

View File

@ -24,6 +24,8 @@
#include "asm/assembler.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
#include "runtime/os.hpp"
#include "loadlib_aix.hpp"
#include "porting_aix.hpp"
#include "utilities/debug.hpp"
@ -83,7 +85,7 @@ class fixed_strings {
while (n) {
node* p = n;
n = n->next;
free(p->v);
os::free(p->v);
delete p;
}
}
@ -95,7 +97,7 @@ class fixed_strings {
}
}
node* p = new node;
p->v = strdup(s);
p->v = os::strdup_check_oom(s);
p->next = first;
first = p;
return p->v;

View File

@ -1678,14 +1678,9 @@ void os::print_dll_info(outputStream *st) {
dlclose(handle);
#elif defined(__APPLE__)
uint32_t count;
uint32_t i;
count = _dyld_image_count();
for (i = 1; i < count; i++) {
const char *name = _dyld_get_image_name(i);
intptr_t slide = _dyld_get_image_vmaddr_slide(i);
st->print_cr(PTR_FORMAT " \t%s", slide, name);
for (uint32_t i = 1; i < _dyld_image_count(); i++) {
st->print_cr(PTR_FORMAT " \t%s", _dyld_get_image_header(i),
_dyld_get_image_name(i));
}
#else
st->print_cr("Error: Cannot print dynamic libraries.");
@ -2439,23 +2434,25 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr,
}
// The memory is committed
MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, mtNone, CALLER_PC);
MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, CALLER_PC);
return addr;
}
bool os::release_memory_special(char* base, size_t bytes) {
MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
// detaching the SHM segment will also delete it, see reserve_memory_special()
int rslt = shmdt(base);
if (rslt == 0) {
tkr.record((address)base, bytes);
return true;
if (MemTracker::tracking_level() > NMT_minimal) {
Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
// detaching the SHM segment will also delete it, see reserve_memory_special()
int rslt = shmdt(base);
if (rslt == 0) {
tkr.record((address)base, bytes);
return true;
} else {
return false;
}
} else {
tkr.discard();
return false;
return shmdt(base) == 0;
}
}
size_t os::large_page_size() {

View File

@ -753,7 +753,7 @@ static char* mmap_create_shared(size_t size) {
(void)::memset((void*) mapAddress, 0, size);
// it does not go through os api, the operation has to record from here
MemTracker::record_virtual_memory_reserve((address)mapAddress, size, mtInternal, CURRENT_PC);
MemTracker::record_virtual_memory_reserve_and_commit((address)mapAddress, size, CURRENT_PC, mtInternal);
return mapAddress;
}
@ -918,7 +918,7 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
}
// it does not go through os api, the operation has to record from here
MemTracker::record_virtual_memory_reserve((address)mapAddress, size, mtInternal, CURRENT_PC);
MemTracker::record_virtual_memory_reserve_and_commit((address)mapAddress, size, CURRENT_PC, mtInternal);
*addr = mapAddress;
*sizep = size;

View File

@ -2246,7 +2246,7 @@ void os::print_siginfo(outputStream* st, void* siginfo) {
const siginfo_t* si = (const siginfo_t*)siginfo;
os::Posix::print_siginfo_brief(st, si);
#if INCLUDE_CDS
if (si && (si->si_signo == SIGBUS || si->si_signo == SIGSEGV) &&
UseSharedSpaces) {
FileMapInfo* mapinfo = FileMapInfo::current_info();
@ -2256,6 +2256,7 @@ void os::print_siginfo(outputStream* st, void* siginfo) {
" possible disk/network problem.");
}
}
#endif
st->cr();
}
@ -3504,9 +3505,12 @@ char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes, size_t al
assert(is_ptr_aligned(start, alignment), "Must be");
// os::reserve_memory_special will record this memory area.
// Need to release it here to prevent overlapping reservations.
MemTracker::record_virtual_memory_release((address)start, bytes);
if (MemTracker::tracking_level() > NMT_minimal) {
// os::reserve_memory_special will record this memory area.
// Need to release it here to prevent overlapping reservations.
Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
tkr.record((address)start, bytes);
}
char* end = start + bytes;
@ -3601,7 +3605,7 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr,
}
// The memory is committed
MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, mtNone, CALLER_PC);
MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, CALLER_PC);
}
return addr;
@ -3617,24 +3621,30 @@ bool os::Linux::release_memory_special_huge_tlbfs(char* base, size_t bytes) {
}
bool os::release_memory_special(char* base, size_t bytes) {
assert(UseLargePages, "only for large pages");
MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
bool res;
if (MemTracker::tracking_level() > NMT_minimal) {
Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
res = os::Linux::release_memory_special_impl(base, bytes);
if (res) {
tkr.record((address)base, bytes);
}
} else {
res = os::Linux::release_memory_special_impl(base, bytes);
}
return res;
}
bool os::Linux::release_memory_special_impl(char* base, size_t bytes) {
assert(UseLargePages, "only for large pages");
bool res;
if (UseSHM) {
res = os::Linux::release_memory_special_shm(base, bytes);
} else {
assert(UseHugeTLBFS, "must be");
res = os::Linux::release_memory_special_huge_tlbfs(base, bytes);
}
if (res) {
tkr.record((address)base, bytes);
} else {
tkr.discard();
}
return res;
}

View File

@ -108,6 +108,7 @@ class Linux {
static char* reserve_memory_special_huge_tlbfs_only(size_t bytes, char* req_addr, bool exec);
static char* reserve_memory_special_huge_tlbfs_mixed(size_t bytes, size_t alignment, char* req_addr, bool exec);
static bool release_memory_special_impl(char* base, size_t bytes);
static bool release_memory_special_shm(char* base, size_t bytes);
static bool release_memory_special_huge_tlbfs(char* base, size_t bytes);

View File

@ -753,7 +753,7 @@ static char* mmap_create_shared(size_t size) {
(void)::memset((void*) mapAddress, 0, size);
// it does not go through os api, the operation has to record from here
MemTracker::record_virtual_memory_reserve((address)mapAddress, size, mtInternal, CURRENT_PC);
MemTracker::record_virtual_memory_reserve_and_commit((address)mapAddress, size, CURRENT_PC, mtInternal);
return mapAddress;
}
@ -924,7 +924,7 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
}
// it does not go through os api, the operation has to record from here
MemTracker::record_virtual_memory_reserve((address)mapAddress, size, mtInternal, CURRENT_PC);
MemTracker::record_virtual_memory_reserve_and_commit((address)mapAddress, size, CURRENT_PC, mtInternal);
*addr = mapAddress;
*sizep = size;

View File

@ -75,21 +75,41 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
VMError::report_coredump_status(buffer, success);
}
address os::get_caller_pc(int n) {
int os::get_native_stack(address* stack, int frames, int toSkip) {
#ifdef _NMT_NOINLINE_
n ++;
toSkip++;
#endif
int frame_idx = 0;
int num_of_frames; // number of frames captured
frame fr = os::current_frame();
while (n > 0 && fr.pc() &&
!os::is_first_C_frame(&fr) && fr.sender_pc()) {
fr = os::get_sender_for_C_frame(&fr);
n --;
while (fr.pc() && frame_idx < frames) {
if (toSkip > 0) {
toSkip --;
} else {
stack[frame_idx ++] = fr.pc();
}
if (fr.fp() == NULL || os::is_first_C_frame(&fr)
||fr.sender_pc() == NULL || fr.cb() != NULL) break;
if (fr.sender_pc() && !os::is_first_C_frame(&fr)) {
fr = os::get_sender_for_C_frame(&fr);
} else {
break;
}
}
if (n == 0) {
return fr.pc();
} else {
return NULL;
num_of_frames = frame_idx;
for (; frame_idx < frames; frame_idx ++) {
stack[frame_idx] = NULL;
}
return num_of_frames;
}
bool os::unsetenv(const char* name) {
assert(name != NULL, "Null pointer");
return (::unsetenv(name) == 0);
}
int os::get_last_error() {

View File

@ -199,23 +199,29 @@ class ArgumentIterator : public StackObj {
// Calls from the door function to check that the client credentials
// match this process. Returns 0 if credentials okay, otherwise -1.
static int check_credentials() {
door_cred_t cred_info;
ucred_t *cred_info = NULL;
int ret = -1; // deny by default
// get client credentials
if (door_cred(&cred_info) == -1) {
return -1; // unable to get them
if (door_ucred(&cred_info) == -1) {
return -1; // unable to get them, deny
}
// get our euid/eguid (probably could cache these)
uid_t euid = geteuid();
gid_t egid = getegid();
// check that the effective uid/gid matches - discuss this with Jeff.
if (cred_info.dc_euid == euid && cred_info.dc_egid == egid) {
return 0; // okay
} else {
return -1; // denied
// get euid/egid from ucred_free
uid_t ucred_euid = ucred_geteuid(cred_info);
gid_t ucred_egid = ucred_getegid(cred_info);
// check that the effective uid/gid matches
if (ucred_euid == euid && ucred_egid == egid) {
ret = 0; // allow
}
ucred_free(cred_info);
return ret;
}

View File

@ -770,7 +770,8 @@ static char* mmap_create_shared(size_t size) {
(void)::memset((void*) mapAddress, 0, size);
// it does not go through os api, the operation has to record from here
MemTracker::record_virtual_memory_reserve((address)mapAddress, size, mtInternal, CURRENT_PC);
MemTracker::record_virtual_memory_reserve_and_commit((address)mapAddress,
size, CURRENT_PC, mtInternal);
return mapAddress;
}
@ -941,7 +942,8 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
}
// it does not go through os api, the operation has to record from here
MemTracker::record_virtual_memory_reserve((address)mapAddress, size, mtInternal, CURRENT_PC);
MemTracker::record_virtual_memory_reserve_and_commit((address)mapAddress,
size, CURRENT_PC, mtInternal);
*addr = mapAddress;
*sizep = size;

View File

@ -135,12 +135,6 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
if (ForceTimeHighResolution)
timeEndPeriod(1L);
// Workaround for issue when a custom launcher doesn't call
// DestroyJavaVM and NMT is trying to track memory when free is
// called from a static destructor
if (MemTracker::is_on()) {
MemTracker::shutdown(MemTracker::NMT_normal);
}
break;
default:
break;
@ -163,6 +157,10 @@ bool os::getenv(const char* name, char* buffer, int len) {
return result > 0 && result < len;
}
bool os::unsetenv(const char* name) {
assert(name != NULL, "Null pointer");
return (SetEnvironmentVariable(name, NULL) == TRUE);
}
// No setuid programs under Windows.
bool os::have_special_privileges() {
@ -319,15 +317,16 @@ extern "C" void breakpoint() {
* So far, this method is only used by Native Memory Tracking, which is
* only supported on Windows XP or later.
*/
address os::get_caller_pc(int n) {
int os::get_native_stack(address* stack, int frames, int toSkip) {
#ifdef _NMT_NOINLINE_
n++;
toSkip ++;
#endif
address pc;
if (os::Kernel32Dll::RtlCaptureStackBackTrace(n + 1, 1, (PVOID*)&pc, NULL) == 1) {
return pc;
int captured = Kernel32Dll::RtlCaptureStackBackTrace(toSkip + 1, frames,
(PVOID*)stack, NULL);
for (int index = captured; index < frames; index ++) {
stack[index] = NULL;
}
return NULL;
return captured;
}
@ -410,6 +409,8 @@ struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo);
extern jint volatile vm_getting_terminated;
// Thread start routine for all new Java threads
static unsigned __stdcall java_start(Thread* thread) {
// Try to randomize the cache line index of hot stack frames.
@ -431,9 +432,17 @@ static unsigned __stdcall java_start(Thread* thread) {
}
}
// Diagnostic code to investigate JDK-6573254 (Part I)
unsigned res = 90115; // non-java thread
if (thread->is_Java_thread()) {
JavaThread* java_thread = (JavaThread*)thread;
res = java_lang_Thread::is_daemon(java_thread->threadObj())
? 70115 // java daemon thread
: 80115; // java non-daemon thread
}
// Install a win32 structured exception handler around every thread created
// by VM, so VM can genrate error dump when an exception occurred in non-
// by VM, so VM can generate error dump when an exception occurred in non-
// Java thread (e.g. VM thread).
__try {
thread->run();
@ -449,6 +458,11 @@ static unsigned __stdcall java_start(Thread* thread) {
Atomic::dec_ptr((intptr_t*)&os::win32::_os_thread_count);
}
// Diagnostic code to investigate JDK-6573254 (Part II)
if (OrderAccess::load_acquire(&vm_getting_terminated)) {
return res;
}
return 0;
}
@ -2901,7 +2915,7 @@ static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags,
PAGE_READWRITE);
// If reservation failed, return NULL
if (p_buf == NULL) return NULL;
MemTracker::record_virtual_memory_reserve((address)p_buf, size_of_reserve, mtNone, CALLER_PC);
MemTracker::record_virtual_memory_reserve((address)p_buf, size_of_reserve, CALLER_PC);
os::release_memory(p_buf, bytes + chunk_size);
// we still need to round up to a page boundary (in case we are using large pages)
@ -2967,7 +2981,7 @@ static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags,
// need to create a dummy 'reserve' record to match
// the release.
MemTracker::record_virtual_memory_reserve((address)p_buf,
bytes_to_release, mtNone, CALLER_PC);
bytes_to_release, CALLER_PC);
os::release_memory(p_buf, bytes_to_release);
}
#ifdef ASSERT
@ -2986,11 +3000,10 @@ static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags,
}
// Although the memory is allocated individually, it is returned as one.
// NMT records it as one block.
address pc = CALLER_PC;
if ((flags & MEM_COMMIT) != 0) {
MemTracker::record_virtual_memory_reserve_and_commit((address)p_buf, bytes, mtNone, pc);
MemTracker::record_virtual_memory_reserve_and_commit((address)p_buf, bytes, CALLER_PC);
} else {
MemTracker::record_virtual_memory_reserve((address)p_buf, bytes, mtNone, pc);
MemTracker::record_virtual_memory_reserve((address)p_buf, bytes, CALLER_PC);
}
// made it this far, success
@ -3188,8 +3201,7 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr, boo
DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
char * res = (char *)VirtualAlloc(addr, bytes, flag, prot);
if (res != NULL) {
address pc = CALLER_PC;
MemTracker::record_virtual_memory_reserve_and_commit((address)res, bytes, mtNone, pc);
MemTracker::record_virtual_memory_reserve_and_commit((address)res, bytes, CALLER_PC);
}
return res;

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