Merge
This commit is contained in:
commit
1b9cab9346
4
.hgtags
4
.hgtags
@ -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
|
||||
|
@ -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
|
||||
|
24
Makefile
24
Makefile
@ -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)
|
||||
|
@ -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.])
|
||||
|
@ -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.
|
||||
|
@ -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])
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
|
||||
}
|
||||
|
@ -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])
|
||||
]
|
||||
)
|
||||
|
@ -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)
|
||||
|
@ -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@
|
||||
|
@ -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
|
||||
|
@ -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])
|
||||
|
@ -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
|
||||
|
@ -1,5 +1,6 @@
|
||||
^build/
|
||||
^dist/
|
||||
^webrev
|
||||
/nbproject/private/
|
||||
^.hgtip
|
||||
.DS_Store
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
################################################################################
|
||||
|
||||
|
@ -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>
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -1,5 +1,6 @@
|
||||
^build/
|
||||
^dist/
|
||||
^webrev
|
||||
/nbproject/private/
|
||||
^src/share/tools/hsdis/build/
|
||||
^src/share/tools/IdealGraphVisualizer/[a-zA-Z0-9]*/build/
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 = \
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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));}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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) :
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
%}
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
66
hotspot/src/cpu/x86/vm/interpreterGenerator_x86.cpp
Normal file
66
hotspot/src/cpu/x86/vm/interpreterGenerator_x86.cpp
Normal 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;
|
||||
}
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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 -
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -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) {
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user