mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-16 21:35:25 +00:00
Merge
This commit is contained in:
commit
92d4547bee
2
.hgtags
2
.hgtags
@ -234,3 +234,5 @@ af9a674e12a16da1a4bd53e4990ddb1121a21ef1 jdk8-b109
|
||||
b5d2bf482a3ea1cca08c994512804ffbc73de0a1 jdk8-b110
|
||||
b9a0f6c693f347a6f4b9bb994957f4eaa05bdedd jdk8-b111
|
||||
ad67c34f79c28a8e755f4a49f313868619d6702c jdk8-b112
|
||||
4a4dbcf7cb7d3e1a81beaa3b11cd909f69ebc79a jdk8-b113
|
||||
dfa34ab293faad9b543a24646dbb381bc3ab5586 jdk8-b114
|
||||
|
||||
@ -234,3 +234,5 @@ b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103
|
||||
4faa09c7fe555de086dd9048d3c5cc92317d6f45 jdk8-b110
|
||||
d086227bfc45d124f09b3bd72a07956b4073bf71 jdk8-b111
|
||||
547316ea137d83d9c63083a9b83db64198fe0c81 jdk8-b112
|
||||
6ba4c7cb623ec612031e05cf8bf279d8f407bd1e jdk8-b113
|
||||
4f2011496393a26dcfd7b1f7787a3673ddd32599 jdk8-b114
|
||||
|
||||
@ -514,7 +514,7 @@ AC_DEFUN([BASIC_CHECK_MAKE_VERSION],
|
||||
if test "x$IS_GNU_MAKE" = x; then
|
||||
AC_MSG_NOTICE([Found potential make at $MAKE_CANDIDATE, however, this is not GNU Make. Ignoring.])
|
||||
else
|
||||
IS_MODERN_MAKE=`$ECHO $MAKE_VERSION_STRING | $GREP '\(3\.8[[12]]\)\|\(4\.\)'`
|
||||
IS_MODERN_MAKE=`$ECHO $MAKE_VERSION_STRING | $GREP -e '3\.8[[12]]' -e '4\.'`
|
||||
if test "x$IS_MODERN_MAKE" = x; then
|
||||
AC_MSG_NOTICE([Found GNU make at $MAKE_CANDIDATE, however this is not version 3.81 or later. (it is: $MAKE_VERSION_STRING). Ignoring.])
|
||||
else
|
||||
@ -656,7 +656,7 @@ AC_DEFUN_ONCE([BASIC_SETUP_COMPLEX_TOOLS],
|
||||
fi
|
||||
|
||||
if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
|
||||
BASIC_REQUIRE_PROG(DSYMUTIL, dsymutil)
|
||||
BASIC_REQUIRE_PROG(DSYMUTIL, dsymutil)
|
||||
BASIC_REQUIRE_PROG(XATTR, xattr)
|
||||
AC_PATH_PROG(CODESIGN, codesign)
|
||||
if test "x$CODESIGN" != "x"; then
|
||||
|
||||
@ -869,6 +869,7 @@ SRC_ROOT
|
||||
ZERO_ARCHDEF
|
||||
DEFINE_CROSS_COMPILE_ARCH
|
||||
LP64
|
||||
OPENJDK_TARGET_OS_EXPORT_DIR
|
||||
OPENJDK_TARGET_OS_API_DIR
|
||||
OPENJDK_TARGET_CPU_JLI_CFLAGS
|
||||
OPENJDK_TARGET_CPU_OSARCH
|
||||
@ -3864,7 +3865,7 @@ fi
|
||||
#CUSTOM_AUTOCONF_INCLUDE
|
||||
|
||||
# Do not change or remove the following line, it is needed for consistency checks:
|
||||
DATE_WHEN_GENERATED=1382540536
|
||||
DATE_WHEN_GENERATED=1383151988
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
@ -7149,6 +7150,13 @@ $as_echo "$COMPILE_TYPE" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
|
||||
OPENJDK_TARGET_OS_EXPORT_DIR=macosx
|
||||
else
|
||||
OPENJDK_TARGET_OS_EXPORT_DIR=${OPENJDK_TARGET_OS_API_DIR}
|
||||
fi
|
||||
|
||||
|
||||
if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
|
||||
A_LP64="LP64:="
|
||||
# -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
|
||||
@ -8315,7 +8323,7 @@ $as_echo "$as_me: Testing potential make at $MAKE_CANDIDATE, found using $DESCRI
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Found potential make at $MAKE_CANDIDATE, however, this is not GNU Make. Ignoring." >&5
|
||||
$as_echo "$as_me: Found potential make at $MAKE_CANDIDATE, however, this is not GNU Make. Ignoring." >&6;}
|
||||
else
|
||||
IS_MODERN_MAKE=`$ECHO $MAKE_VERSION_STRING | $GREP '\(3\.8[12]\)\|\(4\.\)'`
|
||||
IS_MODERN_MAKE=`$ECHO $MAKE_VERSION_STRING | $GREP -e '3\.8[12]' -e '4\.'`
|
||||
if test "x$IS_MODERN_MAKE" = x; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Found GNU make at $MAKE_CANDIDATE, however this is not version 3.81 or later. (it is: $MAKE_VERSION_STRING). Ignoring." >&5
|
||||
$as_echo "$as_me: Found GNU make at $MAKE_CANDIDATE, however this is not version 3.81 or later. (it is: $MAKE_VERSION_STRING). Ignoring." >&6;}
|
||||
@ -8672,7 +8680,7 @@ $as_echo "$as_me: Testing potential make at $MAKE_CANDIDATE, found using $DESCRI
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Found potential make at $MAKE_CANDIDATE, however, this is not GNU Make. Ignoring." >&5
|
||||
$as_echo "$as_me: Found potential make at $MAKE_CANDIDATE, however, this is not GNU Make. Ignoring." >&6;}
|
||||
else
|
||||
IS_MODERN_MAKE=`$ECHO $MAKE_VERSION_STRING | $GREP '\(3\.8[12]\)\|\(4\.\)'`
|
||||
IS_MODERN_MAKE=`$ECHO $MAKE_VERSION_STRING | $GREP -e '3\.8[12]' -e '4\.'`
|
||||
if test "x$IS_MODERN_MAKE" = x; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Found GNU make at $MAKE_CANDIDATE, however this is not version 3.81 or later. (it is: $MAKE_VERSION_STRING). Ignoring." >&5
|
||||
$as_echo "$as_me: Found GNU make at $MAKE_CANDIDATE, however this is not version 3.81 or later. (it is: $MAKE_VERSION_STRING). Ignoring." >&6;}
|
||||
@ -9026,7 +9034,7 @@ $as_echo "$as_me: Testing potential make at $MAKE_CANDIDATE, found using $DESCRI
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Found potential make at $MAKE_CANDIDATE, however, this is not GNU Make. Ignoring." >&5
|
||||
$as_echo "$as_me: Found potential make at $MAKE_CANDIDATE, however, this is not GNU Make. Ignoring." >&6;}
|
||||
else
|
||||
IS_MODERN_MAKE=`$ECHO $MAKE_VERSION_STRING | $GREP '\(3\.8[12]\)\|\(4\.\)'`
|
||||
IS_MODERN_MAKE=`$ECHO $MAKE_VERSION_STRING | $GREP -e '3\.8[12]' -e '4\.'`
|
||||
if test "x$IS_MODERN_MAKE" = x; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Found GNU make at $MAKE_CANDIDATE, however this is not version 3.81 or later. (it is: $MAKE_VERSION_STRING). Ignoring." >&5
|
||||
$as_echo "$as_me: Found GNU make at $MAKE_CANDIDATE, however this is not version 3.81 or later. (it is: $MAKE_VERSION_STRING). Ignoring." >&6;}
|
||||
@ -9385,7 +9393,7 @@ $as_echo "$as_me: Testing potential make at $MAKE_CANDIDATE, found using $DESCRI
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Found potential make at $MAKE_CANDIDATE, however, this is not GNU Make. Ignoring." >&5
|
||||
$as_echo "$as_me: Found potential make at $MAKE_CANDIDATE, however, this is not GNU Make. Ignoring." >&6;}
|
||||
else
|
||||
IS_MODERN_MAKE=`$ECHO $MAKE_VERSION_STRING | $GREP '\(3\.8[12]\)\|\(4\.\)'`
|
||||
IS_MODERN_MAKE=`$ECHO $MAKE_VERSION_STRING | $GREP -e '3\.8[12]' -e '4\.'`
|
||||
if test "x$IS_MODERN_MAKE" = x; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Found GNU make at $MAKE_CANDIDATE, however this is not version 3.81 or later. (it is: $MAKE_VERSION_STRING). Ignoring." >&5
|
||||
$as_echo "$as_me: Found GNU make at $MAKE_CANDIDATE, however this is not version 3.81 or later. (it is: $MAKE_VERSION_STRING). Ignoring." >&6;}
|
||||
@ -9738,7 +9746,7 @@ $as_echo "$as_me: Testing potential make at $MAKE_CANDIDATE, found using $DESCRI
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Found potential make at $MAKE_CANDIDATE, however, this is not GNU Make. Ignoring." >&5
|
||||
$as_echo "$as_me: Found potential make at $MAKE_CANDIDATE, however, this is not GNU Make. Ignoring." >&6;}
|
||||
else
|
||||
IS_MODERN_MAKE=`$ECHO $MAKE_VERSION_STRING | $GREP '\(3\.8[12]\)\|\(4\.\)'`
|
||||
IS_MODERN_MAKE=`$ECHO $MAKE_VERSION_STRING | $GREP -e '3\.8[12]' -e '4\.'`
|
||||
if test "x$IS_MODERN_MAKE" = x; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Found GNU make at $MAKE_CANDIDATE, however this is not version 3.81 or later. (it is: $MAKE_VERSION_STRING). Ignoring." >&5
|
||||
$as_echo "$as_me: Found GNU make at $MAKE_CANDIDATE, however this is not version 3.81 or later. (it is: $MAKE_VERSION_STRING). Ignoring." >&6;}
|
||||
@ -29638,7 +29646,7 @@ fi
|
||||
-I${JDK_OUTPUTDIR}/include \
|
||||
-I${JDK_OUTPUTDIR}/include/$OPENJDK_TARGET_OS \
|
||||
-I${JDK_TOPDIR}/src/share/javavm/export \
|
||||
-I${JDK_TOPDIR}/src/$OPENJDK_TARGET_OS_API_DIR/javavm/export \
|
||||
-I${JDK_TOPDIR}/src/$OPENJDK_TARGET_OS_EXPORT_DIR/javavm/export \
|
||||
-I${JDK_TOPDIR}/src/share/native/common \
|
||||
-I${JDK_TOPDIR}/src/$OPENJDK_TARGET_OS_API_DIR/native/common"
|
||||
|
||||
@ -29905,11 +29913,11 @@ $as_echo_n "checking if we should generate debug symbols... " >&6; }
|
||||
elif test "x$enable_debug_symbols" = "xno"; then
|
||||
ENABLE_DEBUG_SYMBOLS=false
|
||||
else
|
||||
# Default is on if objcopy is found
|
||||
if test "x$OBJCOPY" != x; then
|
||||
ENABLE_DEBUG_SYMBOLS=true
|
||||
# MacOS X and Windows don't use objcopy but default is on for those OSes
|
||||
elif test "x$OPENJDK_TARGET_OS" = xmacosx || test "x$OPENJDK_TARGET_OS" = xwindows; then
|
||||
# Default is on if objcopy is found
|
||||
if test "x$OBJCOPY" != x; then
|
||||
ENABLE_DEBUG_SYMBOLS=true
|
||||
# MacOS X and Windows don't use objcopy but default is on for those OSes
|
||||
elif test "x$OPENJDK_TARGET_OS" = xmacosx || test "x$OPENJDK_TARGET_OS" = xwindows; then
|
||||
ENABLE_DEBUG_SYMBOLS=true
|
||||
else
|
||||
ENABLE_DEBUG_SYMBOLS=false
|
||||
@ -34245,10 +34253,10 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
|
||||
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
|
||||
PREV_CXXCFLAGS="$CXXFLAGS"
|
||||
PREV_LDFLAGS="$LDFLAGS"
|
||||
PREV_LIBS="$LIBS"
|
||||
PREV_CXX="$CXX"
|
||||
CXXFLAGS="$CXXFLAGS $FREETYPE_CFLAGS"
|
||||
LDFLAGS="$LDFLAGS $FREETYPE_LIBS"
|
||||
LIBS="$LIBS $FREETYPE_LIBS"
|
||||
CXX="$FIXPATH $CXX"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
@ -34315,7 +34323,7 @@ fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
CXXCFLAGS="$PREV_CXXFLAGS"
|
||||
LDFLAGS="$PREV_LDFLAGS"
|
||||
LIBS="$PREV_LIBS"
|
||||
CXX="$PREV_CXX"
|
||||
ac_ext=cpp
|
||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
|
||||
@ -516,11 +516,11 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_DEBUG_SYMBOLS],
|
||||
elif test "x$enable_debug_symbols" = "xno"; then
|
||||
ENABLE_DEBUG_SYMBOLS=false
|
||||
else
|
||||
# Default is on if objcopy is found
|
||||
if test "x$OBJCOPY" != x; then
|
||||
ENABLE_DEBUG_SYMBOLS=true
|
||||
# MacOS X and Windows don't use objcopy but default is on for those OSes
|
||||
elif test "x$OPENJDK_TARGET_OS" = xmacosx || test "x$OPENJDK_TARGET_OS" = xwindows; then
|
||||
# Default is on if objcopy is found
|
||||
if test "x$OBJCOPY" != x; then
|
||||
ENABLE_DEBUG_SYMBOLS=true
|
||||
# MacOS X and Windows don't use objcopy but default is on for those OSes
|
||||
elif test "x$OPENJDK_TARGET_OS" = xmacosx || test "x$OPENJDK_TARGET_OS" = xwindows; then
|
||||
ENABLE_DEBUG_SYMBOLS=true
|
||||
else
|
||||
ENABLE_DEBUG_SYMBOLS=false
|
||||
|
||||
@ -481,10 +481,10 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
|
||||
AC_MSG_CHECKING([if we can compile and link with freetype])
|
||||
AC_LANG_PUSH(C++)
|
||||
PREV_CXXCFLAGS="$CXXFLAGS"
|
||||
PREV_LDFLAGS="$LDFLAGS"
|
||||
PREV_LIBS="$LIBS"
|
||||
PREV_CXX="$CXX"
|
||||
CXXFLAGS="$CXXFLAGS $FREETYPE_CFLAGS"
|
||||
LDFLAGS="$LDFLAGS $FREETYPE_LIBS"
|
||||
LIBS="$LIBS $FREETYPE_LIBS"
|
||||
CXX="$FIXPATH $CXX"
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[
|
||||
#include<ft2build.h>
|
||||
@ -508,7 +508,7 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
|
||||
]
|
||||
)
|
||||
CXXCFLAGS="$PREV_CXXFLAGS"
|
||||
LDFLAGS="$PREV_LDFLAGS"
|
||||
LIBS="$PREV_LIBS"
|
||||
CXX="$PREV_CXX"
|
||||
AC_LANG_POP(C++)
|
||||
|
||||
|
||||
@ -327,6 +327,13 @@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS],
|
||||
fi
|
||||
AC_SUBST(OPENJDK_TARGET_OS_API_DIR)
|
||||
|
||||
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
|
||||
OPENJDK_TARGET_OS_EXPORT_DIR=macosx
|
||||
else
|
||||
OPENJDK_TARGET_OS_EXPORT_DIR=${OPENJDK_TARGET_OS_API_DIR}
|
||||
fi
|
||||
AC_SUBST(OPENJDK_TARGET_OS_EXPORT_DIR)
|
||||
|
||||
if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
|
||||
A_LP64="LP64:="
|
||||
# -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
|
||||
|
||||
@ -92,6 +92,7 @@ OPENJDK_TARGET_CPU_LEGACY_LIB:=@OPENJDK_TARGET_CPU_LEGACY_LIB@
|
||||
OPENJDK_TARGET_CPU_OSARCH:=@OPENJDK_TARGET_CPU_OSARCH@
|
||||
OPENJDK_TARGET_CPU_JLI_CFLAGS:=@OPENJDK_TARGET_CPU_JLI_CFLAGS@
|
||||
OPENJDK_TARGET_OS_API_DIR:=@OPENJDK_TARGET_OS_API_DIR@
|
||||
OPENJDK_TARGET_OS_EXPORT_DIR:=@OPENJDK_TARGET_OS_EXPORT_DIR@
|
||||
|
||||
# We are building on this build system.
|
||||
# When not cross-compiling, it is the same as the target.
|
||||
|
||||
@ -942,7 +942,7 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_COMPILER_FLAGS_FOR_JDK],
|
||||
-I${JDK_OUTPUTDIR}/include \
|
||||
-I${JDK_OUTPUTDIR}/include/$OPENJDK_TARGET_OS \
|
||||
-I${JDK_TOPDIR}/src/share/javavm/export \
|
||||
-I${JDK_TOPDIR}/src/$OPENJDK_TARGET_OS_API_DIR/javavm/export \
|
||||
-I${JDK_TOPDIR}/src/$OPENJDK_TARGET_OS_EXPORT_DIR/javavm/export \
|
||||
-I${JDK_TOPDIR}/src/share/native/common \
|
||||
-I${JDK_TOPDIR}/src/$OPENJDK_TARGET_OS_API_DIR/native/common"
|
||||
|
||||
|
||||
@ -506,30 +506,30 @@ define SetupJavaCompilation
|
||||
|
||||
$$($1_BIN)/javac_state: $$($1_SRCS) $$($1_DEPENDS)
|
||||
$(MKDIR) -p $$(@D)
|
||||
$$(call ListPathsSafely,$1_SRCS,\n, >> $$($1_BIN)/_the.batch.tmp)
|
||||
$$(call ListPathsSafely,$1_SRCS,\n, >> $$($1_BIN)/_the.$1_batch.tmp)
|
||||
$(ECHO) Compiling $1
|
||||
($$($1_JVM) $$($1_SJAVAC) \
|
||||
$$($1_REMOTE) \
|
||||
-j $(JOBS) \
|
||||
--permit-unidentified-artifacts \
|
||||
--permit-sources-without-package \
|
||||
--compare-found-sources $$($1_BIN)/_the.batch.tmp \
|
||||
--compare-found-sources $$($1_BIN)/_the.$1_batch.tmp \
|
||||
--log=$(LOG_LEVEL) \
|
||||
$$($1_SJAVAC_ARGS) \
|
||||
$$($1_FLAGS) \
|
||||
$$($1_HEADERS_ARG) \
|
||||
-d $$($1_BIN) && \
|
||||
$(MV) $$($1_BIN)/_the.batch.tmp $$($1_BIN)/_the.batch)
|
||||
$(MV) $$($1_BIN)/_the.$1_batch.tmp $$($1_BIN)/_the.$1_batch)
|
||||
else
|
||||
# Using plain javac to batch compile everything.
|
||||
$1 := $$($1_ALL_COPY_TARGETS) $$($1_ALL_COPY_CLEAN_TARGETS) $$($1_BIN)/_the.batch
|
||||
$1 := $$($1_ALL_COPY_TARGETS) $$($1_ALL_COPY_CLEAN_TARGETS) $$($1_BIN)/_the.$1_batch
|
||||
|
||||
# When building in batch, put headers in a temp dir to filter out those that actually
|
||||
# changed before copying them to the real header dir.
|
||||
ifneq (,$$($1_HEADERS))
|
||||
$1_HEADERS_ARG := -h $$($1_HEADERS).tmp
|
||||
|
||||
$$($1_HEADERS)/_the.headers: $$($1_BIN)/_the.batch
|
||||
$$($1_HEADERS)/_the.$1_headers: $$($1_BIN)/_the.$1_batch
|
||||
$(MKDIR) -p $$(@D)
|
||||
for f in `ls $$($1_HEADERS).tmp`; do \
|
||||
if [ ! -f "$$($1_HEADERS)/$$$$f" ] || [ "`$(DIFF) $$($1_HEADERS)/$$$$f $$($1_HEADERS).tmp/$$$$f`" != "" ]; then \
|
||||
@ -539,19 +539,19 @@ define SetupJavaCompilation
|
||||
$(RM) -r $$($1_HEADERS).tmp
|
||||
$(TOUCH) $$@
|
||||
|
||||
$1 += $$($1_HEADERS)/_the.headers
|
||||
$1 += $$($1_HEADERS)/_the.$1_headers
|
||||
endif
|
||||
|
||||
# When not using sjavac, pass along all sources to javac using an @file.
|
||||
$$($1_BIN)/_the.batch: $$($1_SRCS) $$($1_DEPENDS)
|
||||
$$($1_BIN)/_the.$1_batch: $$($1_SRCS) $$($1_DEPENDS)
|
||||
$(MKDIR) -p $$(@D)
|
||||
$(RM) $$($1_BIN)/_the.batch $$($1_BIN)/_the.batch.tmp
|
||||
$$(call ListPathsSafely,$1_SRCS,\n, >> $$($1_BIN)/_the.batch.tmp)
|
||||
$(ECHO) Compiling `$(WC) $$($1_BIN)/_the.batch.tmp | $(TR) -s ' ' | $(CUT) -f 2 -d ' '` files for $1
|
||||
$(RM) $$($1_BIN)/_the.$1_batch $$($1_BIN)/_the.$1_batch.tmp
|
||||
$$(call ListPathsSafely,$1_SRCS,\n, >> $$($1_BIN)/_the.$1_batch.tmp)
|
||||
$(ECHO) Compiling `$(WC) $$($1_BIN)/_the.$1_batch.tmp | $(TR) -s ' ' | $(CUT) -f 2 -d ' '` files for $1
|
||||
($$($1_JVM) $$($1_JAVAC) $$($1_FLAGS) \
|
||||
-implicit:none -sourcepath "$$($1_SRCROOTSC)" \
|
||||
-d $$($1_BIN) $$($1_HEADERS_ARG) @$$($1_BIN)/_the.batch.tmp && \
|
||||
$(MV) $$($1_BIN)/_the.batch.tmp $$($1_BIN)/_the.batch)
|
||||
-d $$($1_BIN) $$($1_HEADERS_ARG) @$$($1_BIN)/_the.$1_batch.tmp && \
|
||||
$(MV) $$($1_BIN)/_the.$1_batch.tmp $$($1_BIN)/_the.$1_batch)
|
||||
|
||||
endif
|
||||
|
||||
|
||||
@ -435,36 +435,36 @@ define SetupNativeCompilation
|
||||
$(CP) $$< $$@
|
||||
endif
|
||||
|
||||
ifneq ($(OPENJDK_TARGET_OS), macosx) # OBJCOPY is not used on MacOS X
|
||||
ifneq ($(OPENJDK_TARGET_OS), windows) # nor on Windows
|
||||
ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
|
||||
# Use $(FIX_EMPTY_SEC_HDR_FLAGS) to clear the SHF_ALLOC flag (if set) from
|
||||
# empty section headers until a fixed $(OBJCOPY) is available.
|
||||
# An empty section header has sh_addr == 0 and sh_size == 0.
|
||||
# This problem has only been seen on Solaris X64, but we call this tool
|
||||
# on all Solaris builds just in case.
|
||||
#
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
|
||||
# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
|
||||
$$($1_OBJECT_DIR)/$$(LIBRARY_PREFIX)$$($1_LIBRARY).debuginfo : $$($1_TARGET) \
|
||||
$(FIX_EMPTY_SEC_HDR_FLAGS) $(ADD_GNU_DEBUGLINK)
|
||||
$(RM) $$@
|
||||
$(FIX_EMPTY_SEC_HDR_FLAGS) $(LOG_INFO) $$<
|
||||
$(OBJCOPY) --only-keep-debug $$< $$@
|
||||
$(CD) $$(@D) && $(ADD_GNU_DEBUGLINK) $(LOG_INFO) $$(@F) $$<
|
||||
else # not solaris
|
||||
$$($1_OBJECT_DIR)/$$(LIBRARY_PREFIX)$$($1_LIBRARY).debuginfo : $$($1_TARGET)
|
||||
$(RM) $$@
|
||||
$(OBJCOPY) --only-keep-debug $$< $$@
|
||||
$(CD) $$(@D) && $(OBJCOPY) --add-gnu-debuglink=$$(@F) $$<
|
||||
endif # Touch to not retrigger rule on rebuild
|
||||
ifneq ($(OPENJDK_TARGET_OS), macosx) # OBJCOPY is not used on MacOS X
|
||||
ifneq ($(OPENJDK_TARGET_OS), windows) # nor on Windows
|
||||
ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
|
||||
# Use $(FIX_EMPTY_SEC_HDR_FLAGS) to clear the SHF_ALLOC flag (if set) from
|
||||
# empty section headers until a fixed $(OBJCOPY) is available.
|
||||
# An empty section header has sh_addr == 0 and sh_size == 0.
|
||||
# This problem has only been seen on Solaris X64, but we call this tool
|
||||
# on all Solaris builds just in case.
|
||||
#
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
|
||||
# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
|
||||
$$($1_OBJECT_DIR)/$$(LIBRARY_PREFIX)$$($1_LIBRARY).debuginfo : $$($1_TARGET) \
|
||||
$(FIX_EMPTY_SEC_HDR_FLAGS) $(ADD_GNU_DEBUGLINK)
|
||||
$(RM) $$@
|
||||
$(FIX_EMPTY_SEC_HDR_FLAGS) $(LOG_INFO) $$<
|
||||
$(OBJCOPY) --only-keep-debug $$< $$@
|
||||
$(CD) $$(@D) && $(ADD_GNU_DEBUGLINK) $(LOG_INFO) $$(@F) $$<
|
||||
else # not solaris
|
||||
$$($1_OBJECT_DIR)/$$(LIBRARY_PREFIX)$$($1_LIBRARY).debuginfo : $$($1_TARGET)
|
||||
$(RM) $$@
|
||||
$(OBJCOPY) --only-keep-debug $$< $$@
|
||||
$(CD) $$(@D) && $(OBJCOPY) --add-gnu-debuglink=$$(@F) $$<
|
||||
endif # Touch to not retrigger rule on rebuild
|
||||
$(TOUCH) $$@
|
||||
endif # !windows
|
||||
endif # !macosx
|
||||
endif # !windows
|
||||
endif # !macosx
|
||||
|
||||
ifeq ($(ZIP_DEBUGINFO_FILES), true)
|
||||
ifneq ($(OPENJDK_TARGET_OS), macosx) # no MacOS X support yet
|
||||
ifneq ($(OPENJDK_TARGET_OS), macosx) # no MacOS X support yet
|
||||
$1 += $$($1_OUTPUT_DIR)/$$(LIBRARY_PREFIX)$$($1_LIBRARY).diz
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
@ -477,12 +477,12 @@ define SetupNativeCompilation
|
||||
$(CD) $$($1_OBJECT_DIR) \
|
||||
&& $(ZIP) -q $$@ $$(LIBRARY_PREFIX)$$($1_LIBRARY).debuginfo
|
||||
endif
|
||||
endif # no MacOS X support yet
|
||||
endif # no MacOS X support yet
|
||||
else
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
$1 += $$($1_OUTPUT_DIR)/$$($1_LIBRARY).map \
|
||||
$$($1_OUTPUT_DIR)/$$($1_LIBRARY).pdb
|
||||
else ifneq ($(OPENJDK_TARGET_OS), macosx) # MacOS X does not use .debuginfo files
|
||||
else ifneq ($(OPENJDK_TARGET_OS), macosx) # MacOS X does not use .debuginfo files
|
||||
$1 += $$($1_OUTPUT_DIR)/$$(LIBRARY_PREFIX)$$($1_LIBRARY).debuginfo
|
||||
endif
|
||||
endif
|
||||
@ -519,36 +519,36 @@ define SetupNativeCompilation
|
||||
$(CP) $$< $$@
|
||||
endif
|
||||
|
||||
ifneq ($(OPENJDK_TARGET_OS), macosx) # OBJCOPY is not used on MacOS X
|
||||
ifneq ($(OPENJDK_TARGET_OS), windows) # nor on Windows
|
||||
ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
|
||||
# Use $(FIX_EMPTY_SEC_HDR_FLAGS) to clear the SHF_ALLOC flag (if set) from
|
||||
# empty section headers until a fixed $(OBJCOPY) is available.
|
||||
# An empty section header has sh_addr == 0 and sh_size == 0.
|
||||
# This problem has only been seen on Solaris X64, but we call this tool
|
||||
# on all Solaris builds just in case.
|
||||
#
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
|
||||
# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
|
||||
$$($1_OBJECT_DIR)/$$($1_PROGRAM).debuginfo : $$($1_TARGET) \
|
||||
$(FIX_EMPTY_SEC_HDR_FLAGS) $(ADD_GNU_DEBUGLINK)
|
||||
$(RM) $$@
|
||||
$(FIX_EMPTY_SEC_HDR_FLAGS) $(LOG_INFO) $$<
|
||||
$(OBJCOPY) --only-keep-debug $$< $$@
|
||||
$(CD) $$(@D) && $(ADD_GNU_DEBUGLINK) $(LOG_INFO) $$(@F) $$<
|
||||
else # not solaris
|
||||
$$($1_OBJECT_DIR)/$$($1_PROGRAM).debuginfo : $$($1_TARGET)
|
||||
$(RM) $$@
|
||||
$(OBJCOPY) --only-keep-debug $$< $$@
|
||||
$(CD) $$(@D) && $(OBJCOPY) --add-gnu-debuglink=$$(@F) $$<
|
||||
endif
|
||||
$(TOUCH) $$@
|
||||
endif # !windows
|
||||
endif # !macosx
|
||||
ifneq ($(OPENJDK_TARGET_OS), macosx) # OBJCOPY is not used on MacOS X
|
||||
ifneq ($(OPENJDK_TARGET_OS), windows) # nor on Windows
|
||||
ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
|
||||
# Use $(FIX_EMPTY_SEC_HDR_FLAGS) to clear the SHF_ALLOC flag (if set) from
|
||||
# empty section headers until a fixed $(OBJCOPY) is available.
|
||||
# An empty section header has sh_addr == 0 and sh_size == 0.
|
||||
# This problem has only been seen on Solaris X64, but we call this tool
|
||||
# on all Solaris builds just in case.
|
||||
#
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
|
||||
# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
|
||||
$$($1_OBJECT_DIR)/$$($1_PROGRAM).debuginfo : $$($1_TARGET) \
|
||||
$(FIX_EMPTY_SEC_HDR_FLAGS) $(ADD_GNU_DEBUGLINK)
|
||||
$(RM) $$@
|
||||
$(FIX_EMPTY_SEC_HDR_FLAGS) $(LOG_INFO) $$<
|
||||
$(OBJCOPY) --only-keep-debug $$< $$@
|
||||
$(CD) $$(@D) && $(ADD_GNU_DEBUGLINK) $(LOG_INFO) $$(@F) $$<
|
||||
else # not solaris
|
||||
$$($1_OBJECT_DIR)/$$($1_PROGRAM).debuginfo : $$($1_TARGET)
|
||||
$(RM) $$@
|
||||
$(OBJCOPY) --only-keep-debug $$< $$@
|
||||
$(CD) $$(@D) && $(OBJCOPY) --add-gnu-debuglink=$$(@F) $$<
|
||||
endif
|
||||
$(TOUCH) $$@
|
||||
endif # !windows
|
||||
endif # !macosx
|
||||
|
||||
ifeq ($(ZIP_DEBUGINFO_FILES), true)
|
||||
ifneq ($(OPENJDK_TARGET_OS), macosx) # no MacOS X support yet
|
||||
ifneq ($(OPENJDK_TARGET_OS), macosx) # no MacOS X support yet
|
||||
$1 += $$($1_OUTPUT_DIR)/$$($1_PROGRAM).diz
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
@ -561,12 +561,12 @@ define SetupNativeCompilation
|
||||
$(CD) $$($1_OBJECT_DIR) \
|
||||
&& $(ZIP) -q $$@ $$($1_PROGRAM).debuginfo
|
||||
endif
|
||||
endif # no MacOS X support yet
|
||||
endif # no MacOS X support yet
|
||||
else
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
$1 += $$($1_OUTPUT_DIR)/$$($1_PROGRAM).map \
|
||||
$$($1_OUTPUT_DIR)/$$($1_PROGRAM).pdb
|
||||
else ifneq ($(OPENJDK_TARGET_OS), macosx) # MacOS X does not use .debuginfo files
|
||||
else ifneq ($(OPENJDK_TARGET_OS), macosx) # MacOS X does not use .debuginfo files
|
||||
$1 += $$($1_OUTPUT_DIR)/$$($1_PROGRAM).debuginfo
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -234,3 +234,5 @@ a4bb3b4500164748a9c33b2283cfda76d89f25ab jdk8-b108
|
||||
3d2b7ce93c5c2e3db748f29c3d29620a8b3b748a jdk8-b110
|
||||
85c1c94e723582f9a1dd0251502c42b73d6deea7 jdk8-b111
|
||||
43cec76d1d62587a07af07e2d9bec93aba2a506b jdk8-b112
|
||||
a259ff3e42d91da68f4d4f09d7eb9dc22bc024fc jdk8-b113
|
||||
0bbccf77c23e566170b88b52c2cf28e5d31ce927 jdk8-b114
|
||||
|
||||
@ -580,7 +580,7 @@ public class AnyImpl extends Any
|
||||
java.lang.Object[] objholder = new java.lang.Object[1];
|
||||
objholder[0] = object;
|
||||
long[] longholder = new long[1];
|
||||
TCUtility.unmarshalIn(in, typeCode, longholder, objholder);
|
||||
TCUtility.unmarshalIn(in, realType(), longholder, objholder);
|
||||
value = longholder[0];
|
||||
object = objholder[0];
|
||||
stream = null;
|
||||
|
||||
@ -61,13 +61,11 @@ public abstract class Stub extends ObjectImpl
|
||||
private transient StubDelegate stubDelegate = null;
|
||||
private static Class stubDelegateClass = null;
|
||||
private static final String StubClassKey = "javax.rmi.CORBA.StubClass";
|
||||
private static final String defaultStubImplName = "com.sun.corba.se.impl.javax.rmi.CORBA.StubDelegateImpl";
|
||||
|
||||
static {
|
||||
Object stubDelegateInstance = (Object) createDelegateIfSpecified(StubClassKey, defaultStubImplName);
|
||||
Object stubDelegateInstance = createDelegate(StubClassKey);
|
||||
if (stubDelegateInstance != null)
|
||||
stubDelegateClass = stubDelegateInstance.getClass();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -207,7 +205,7 @@ public abstract class Stub extends ObjectImpl
|
||||
// are in different packages and the visibility needs to be package for
|
||||
// security reasons. If you know a better solution how to share this code
|
||||
// then remove it from PortableRemoteObject. Also in Util.java
|
||||
private static Object createDelegateIfSpecified(String classKey, String defaultClassName) {
|
||||
private static Object createDelegate(String classKey) {
|
||||
String className = (String)
|
||||
AccessController.doPrivileged(new GetPropertyAction(classKey));
|
||||
if (className == null) {
|
||||
@ -218,7 +216,7 @@ public abstract class Stub extends ObjectImpl
|
||||
}
|
||||
|
||||
if (className == null) {
|
||||
className = defaultClassName;
|
||||
return new com.sun.corba.se.impl.javax.rmi.CORBA.StubDelegateImpl();
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@ -60,14 +60,11 @@ import com.sun.corba.se.impl.orbutil.GetPropertyAction;
|
||||
public class Util {
|
||||
|
||||
// This can only be set at static initialization time (no sync necessary).
|
||||
private static javax.rmi.CORBA.UtilDelegate utilDelegate = null;
|
||||
private static final javax.rmi.CORBA.UtilDelegate utilDelegate;
|
||||
private static final String UtilClassKey = "javax.rmi.CORBA.UtilClass";
|
||||
private static final String defaultUtilImplName =
|
||||
"com.sun.corba.se.impl.javax.rmi.CORBA.Util";
|
||||
|
||||
static {
|
||||
utilDelegate = (javax.rmi.CORBA.UtilDelegate)
|
||||
createDelegateIfSpecified(UtilClassKey, defaultUtilImplName);
|
||||
utilDelegate = (javax.rmi.CORBA.UtilDelegate)createDelegate(UtilClassKey);
|
||||
}
|
||||
|
||||
private Util(){}
|
||||
@ -338,9 +335,7 @@ Tie#deactivate}
|
||||
// are in different packages and the visibility needs to be package for
|
||||
// security reasons. If you know a better solution how to share this code
|
||||
// then remove it from PortableRemoteObject. Also in Stub.java
|
||||
private static Object createDelegateIfSpecified(String classKey,
|
||||
String defaultClassName)
|
||||
{
|
||||
private static Object createDelegate(String classKey) {
|
||||
String className = (String)
|
||||
AccessController.doPrivileged(new GetPropertyAction(classKey));
|
||||
if (className == null) {
|
||||
@ -351,7 +346,7 @@ Tie#deactivate}
|
||||
}
|
||||
|
||||
if (className == null) {
|
||||
className = defaultClassName;
|
||||
return new com.sun.corba.se.impl.javax.rmi.CORBA.Util();
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@ -65,17 +65,14 @@ import com.sun.corba.se.impl.orbutil.GetPropertyAction;
|
||||
*/
|
||||
public class PortableRemoteObject {
|
||||
|
||||
private static javax.rmi.CORBA.PortableRemoteObjectDelegate proDelegate = null;
|
||||
private static final javax.rmi.CORBA.PortableRemoteObjectDelegate proDelegate;
|
||||
|
||||
private static final String PortableRemoteObjectClassKey =
|
||||
"javax.rmi.CORBA.PortableRemoteObjectClass";
|
||||
|
||||
private static final String defaultPortableRemoteObjectImplName =
|
||||
"com.sun.corba.se.impl.javax.rmi.PortableRemoteObject";
|
||||
|
||||
static {
|
||||
proDelegate = (javax.rmi.CORBA.PortableRemoteObjectDelegate)
|
||||
createDelegateIfSpecified(PortableRemoteObjectClassKey);
|
||||
createDelegate(PortableRemoteObjectClassKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -181,7 +178,7 @@ public class PortableRemoteObject {
|
||||
// are in different packages and the visibility needs to be package for
|
||||
// security reasons. If you know a better solution how to share this code
|
||||
// then remove it from here.
|
||||
private static Object createDelegateIfSpecified(String classKey) {
|
||||
private static Object createDelegate(String classKey) {
|
||||
String className = (String)
|
||||
AccessController.doPrivileged(new GetPropertyAction(classKey));
|
||||
if (className == null) {
|
||||
@ -191,7 +188,7 @@ public class PortableRemoteObject {
|
||||
}
|
||||
}
|
||||
if (className == null) {
|
||||
className = defaultPortableRemoteObjectImplName;
|
||||
return new com.sun.corba.se.impl.javax.rmi.PortableRemoteObject();
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@ -173,15 +173,6 @@ abstract public class ORB {
|
||||
private static final String ORBClassKey = "org.omg.CORBA.ORBClass";
|
||||
private static final String ORBSingletonClassKey = "org.omg.CORBA.ORBSingletonClass";
|
||||
|
||||
//
|
||||
// The last resort fallback ORB implementation classes in case
|
||||
// no ORB implementation class is dynamically configured through
|
||||
// properties or applet parameters. Change these values to
|
||||
// vendor-specific class names.
|
||||
//
|
||||
private static final String defaultORB = "com.sun.corba.se.impl.orb.ORBImpl";
|
||||
private static final String defaultORBSingleton = "com.sun.corba.se.impl.orb.ORBSingleton";
|
||||
|
||||
//
|
||||
// The global instance of the singleton ORB implementation which
|
||||
// acts as a factory for typecodes for generated Helper classes.
|
||||
@ -294,10 +285,11 @@ abstract public class ORB {
|
||||
String className = getSystemProperty(ORBSingletonClassKey);
|
||||
if (className == null)
|
||||
className = getPropertyFromFile(ORBSingletonClassKey);
|
||||
if (className == null)
|
||||
className = defaultORBSingleton;
|
||||
|
||||
singleton = create_impl(className);
|
||||
if (className == null) {
|
||||
singleton = new com.sun.corba.se.impl.orb.ORBSingleton();
|
||||
} else {
|
||||
singleton = create_impl(className);
|
||||
}
|
||||
}
|
||||
return singleton;
|
||||
}
|
||||
@ -347,10 +339,12 @@ abstract public class ORB {
|
||||
className = getSystemProperty(ORBClassKey);
|
||||
if (className == null)
|
||||
className = getPropertyFromFile(ORBClassKey);
|
||||
if (className == null)
|
||||
className = defaultORB;
|
||||
if (className == null) {
|
||||
orb = new com.sun.corba.se.impl.orb.ORBImpl();
|
||||
} else {
|
||||
orb = create_impl(className);
|
||||
}
|
||||
|
||||
orb = create_impl(className);
|
||||
orb.set_parameters(args, props);
|
||||
return orb;
|
||||
}
|
||||
@ -375,10 +369,12 @@ abstract public class ORB {
|
||||
className = getSystemProperty(ORBClassKey);
|
||||
if (className == null)
|
||||
className = getPropertyFromFile(ORBClassKey);
|
||||
if (className == null)
|
||||
className = defaultORB;
|
||||
if (className == null) {
|
||||
orb = new com.sun.corba.se.impl.orb.ORBImpl();
|
||||
} else {
|
||||
orb = create_impl(className);
|
||||
}
|
||||
|
||||
orb = create_impl(className);
|
||||
orb.set_parameters(app, props);
|
||||
return orb;
|
||||
}
|
||||
|
||||
@ -387,3 +387,7 @@ f6962730bbde82f279a0ae3a1c14bc5e58096c6e jdk8-b111
|
||||
4a845c7a463844cead9e1e1641d6bcfb8a77f1c7 hs25-b54
|
||||
0ed9a90f45e1b392c671005f9ee22ce1acf02984 jdk8-b112
|
||||
23b8db5ea31d3079f1326afde4cd5c67b1dac49c hs25-b55
|
||||
4589b398ab03aba6a5da8c06ff53603488d1b8f4 jdk8-b113
|
||||
82a9cdbf683e374a76f2009352de53e16bed5a91 hs25-b56
|
||||
7fd913010dbbf75260688fd2fa8964763fa49a09 jdk8-b114
|
||||
3b32d287da89a47a45d16f6d9ba5bd3cd9bf4b3e hs25-b57
|
||||
|
||||
@ -131,7 +131,7 @@ static bool process_get_lwp_info(struct ps_prochandle *ph, lwpid_t lwp_id, void
|
||||
|
||||
static bool ptrace_continue(pid_t pid, int signal) {
|
||||
// pass the signal to the process so we don't swallow it
|
||||
if (ptrace(PTRACE_CONT, pid, NULL, signal) < 0) {
|
||||
if (ptrace(PT_CONTINUE, pid, NULL, signal) < 0) {
|
||||
print_debug("ptrace(PTRACE_CONT, ..) failed for %d\n", pid);
|
||||
return false;
|
||||
}
|
||||
@ -434,7 +434,6 @@ static ps_prochandle_ops process_ops = {
|
||||
// attach to the process. One and only one exposed stuff
|
||||
struct ps_prochandle* Pgrab(pid_t pid) {
|
||||
struct ps_prochandle* ph = NULL;
|
||||
thread_info* thr = NULL;
|
||||
|
||||
if ( (ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle))) == NULL) {
|
||||
print_debug("can't allocate memory for ps_prochandle\n");
|
||||
|
||||
@ -719,7 +719,7 @@ static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* li
|
||||
ELF_PHDR* phbuf;
|
||||
ELF_PHDR* lib_php = NULL;
|
||||
|
||||
int page_size=sysconf(_SC_PAGE_SIZE);
|
||||
int page_size = sysconf(_SC_PAGE_SIZE);
|
||||
|
||||
if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) {
|
||||
return false;
|
||||
@ -736,26 +736,29 @@ static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* li
|
||||
|
||||
if (existing_map == NULL){
|
||||
if (add_map_info(ph, lib_fd, lib_php->p_offset,
|
||||
target_vaddr, lib_php->p_filesz) == NULL) {
|
||||
target_vaddr, lib_php->p_memsz) == NULL) {
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
// Coredump stores value of p_memsz elf field
|
||||
// rounded up to page boundary.
|
||||
|
||||
if ((existing_map->memsz != page_size) &&
|
||||
(existing_map->fd != lib_fd) &&
|
||||
(existing_map->memsz != lib_php->p_filesz)){
|
||||
(ROUNDUP(existing_map->memsz, page_size) != ROUNDUP(lib_php->p_memsz, page_size))) {
|
||||
|
||||
print_debug("address conflict @ 0x%lx (size = %ld, flags = %d\n)",
|
||||
target_vaddr, lib_php->p_filesz, lib_php->p_flags);
|
||||
print_debug("address conflict @ 0x%lx (existing map size = %ld, size = %ld, flags = %d)\n",
|
||||
target_vaddr, existing_map->memsz, lib_php->p_memsz, lib_php->p_flags);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* replace PT_LOAD segment with library segment */
|
||||
print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n",
|
||||
existing_map->memsz, lib_php->p_filesz);
|
||||
existing_map->memsz, ROUNDUP(lib_php->p_memsz, page_size));
|
||||
|
||||
existing_map->fd = lib_fd;
|
||||
existing_map->offset = lib_php->p_offset;
|
||||
existing_map->memsz = lib_php->p_filesz;
|
||||
existing_map->memsz = ROUNDUP(lib_php->p_memsz, page_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -51,6 +51,7 @@ public class ConstMethod extends VMObject {
|
||||
private static int HAS_GENERIC_SIGNATURE;
|
||||
private static int HAS_METHOD_ANNOTATIONS;
|
||||
private static int HAS_PARAMETER_ANNOTATIONS;
|
||||
private static int HAS_METHOD_PARAMETERS;
|
||||
private static int HAS_DEFAULT_ANNOTATIONS;
|
||||
private static int HAS_TYPE_ANNOTATIONS;
|
||||
|
||||
@ -70,6 +71,7 @@ public class ConstMethod extends VMObject {
|
||||
HAS_GENERIC_SIGNATURE = db.lookupIntConstant("ConstMethod::_has_generic_signature").intValue();
|
||||
HAS_METHOD_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_method_annotations").intValue();
|
||||
HAS_PARAMETER_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_parameter_annotations").intValue();
|
||||
HAS_METHOD_PARAMETERS = db.lookupIntConstant("ConstMethod::_has_method_parameters").intValue();
|
||||
HAS_DEFAULT_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_default_annotations").intValue();
|
||||
HAS_TYPE_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_type_annotations").intValue();
|
||||
|
||||
@ -85,6 +87,9 @@ public class ConstMethod extends VMObject {
|
||||
// start of byte code
|
||||
bytecodeOffset = type.getSize();
|
||||
|
||||
type = db.lookupType("MethodParametersElement");
|
||||
methodParametersElementSize = type.getSize();
|
||||
|
||||
type = db.lookupType("CheckedExceptionElement");
|
||||
checkedExceptionElementSize = type.getSize();
|
||||
|
||||
@ -113,7 +118,7 @@ public class ConstMethod extends VMObject {
|
||||
|
||||
// start of bytecode
|
||||
private static long bytecodeOffset;
|
||||
|
||||
private static long methodParametersElementSize;
|
||||
private static long checkedExceptionElementSize;
|
||||
private static long localVariableTableElementSize;
|
||||
private static long exceptionTableElementSize;
|
||||
@ -387,6 +392,10 @@ public class ConstMethod extends VMObject {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private boolean hasMethodParameters() {
|
||||
return (getFlags() & HAS_METHOD_PARAMETERS) != 0;
|
||||
}
|
||||
|
||||
private boolean hasGenericSignature() {
|
||||
return (getFlags() & HAS_GENERIC_SIGNATURE) != 0;
|
||||
}
|
||||
@ -442,11 +451,41 @@ public class ConstMethod extends VMObject {
|
||||
return offsetOfLastU2Element();
|
||||
}
|
||||
|
||||
private long offsetOfCheckedExceptionsLength() {
|
||||
private long offsetOfMethodParametersLength() {
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(hasMethodParameters(), "should only be called if table is present");
|
||||
}
|
||||
return hasGenericSignature() ? offsetOfLastU2Element() - sizeofShort :
|
||||
offsetOfLastU2Element();
|
||||
}
|
||||
|
||||
private int getMethodParametersLength() {
|
||||
if (hasMethodParameters())
|
||||
return (int) getAddress().getCIntegerAt(offsetOfMethodParametersLength(), 2, true);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Offset of start of checked exceptions
|
||||
private long offsetOfMethodParameters() {
|
||||
long offset = offsetOfMethodParametersLength();
|
||||
long length = getMethodParametersLength();
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(length > 0, "should only be called if method parameter information is present");
|
||||
}
|
||||
offset -= length * methodParametersElementSize;
|
||||
return offset;
|
||||
}
|
||||
|
||||
private long offsetOfCheckedExceptionsLength() {
|
||||
if (hasMethodParameters())
|
||||
return offsetOfMethodParameters() - sizeofShort;
|
||||
else {
|
||||
return hasGenericSignature() ? offsetOfLastU2Element() - sizeofShort :
|
||||
offsetOfLastU2Element();
|
||||
}
|
||||
}
|
||||
|
||||
private int getCheckedExceptionsLength() {
|
||||
if (hasCheckedExceptions()) {
|
||||
return (int) getAddress().getCIntegerAt(offsetOfCheckedExceptionsLength(), 2, true);
|
||||
@ -496,6 +535,8 @@ public class ConstMethod extends VMObject {
|
||||
return offsetOfExceptionTable() - sizeofShort;
|
||||
} else if (hasCheckedExceptions()) {
|
||||
return offsetOfCheckedExceptions() - sizeofShort;
|
||||
} else if (hasMethodParameters()) {
|
||||
return offsetOfMethodParameters() - sizeofShort;
|
||||
} else {
|
||||
return hasGenericSignature() ? offsetOfLastU2Element() - sizeofShort :
|
||||
offsetOfLastU2Element();
|
||||
@ -526,6 +567,8 @@ public class ConstMethod extends VMObject {
|
||||
}
|
||||
if (hasCheckedExceptions()) {
|
||||
return offsetOfCheckedExceptions() - sizeofShort;
|
||||
} else if (hasMethodParameters()) {
|
||||
return offsetOfMethodParameters() - sizeofShort;
|
||||
} else {
|
||||
return hasGenericSignature() ? offsetOfLastU2Element() - sizeofShort :
|
||||
offsetOfLastU2Element();
|
||||
|
||||
@ -51,8 +51,7 @@ public class ClassLoaderStats extends Tool {
|
||||
|
||||
public static void main(String[] args) {
|
||||
ClassLoaderStats cls = new ClassLoaderStats();
|
||||
cls.start(args);
|
||||
cls.stop();
|
||||
cls.execute(args);
|
||||
}
|
||||
|
||||
private static class ClassData {
|
||||
|
||||
@ -54,8 +54,7 @@ public class FinalizerInfo extends Tool {
|
||||
|
||||
public static void main(String[] args) {
|
||||
FinalizerInfo finfo = new FinalizerInfo();
|
||||
finfo.start(args);
|
||||
finfo.stop();
|
||||
finfo.execute(args);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
@ -54,7 +54,6 @@ public class FlagDumper extends Tool {
|
||||
|
||||
public static void main(String[] args) {
|
||||
FlagDumper fd = new FlagDumper();
|
||||
fd.start(args);
|
||||
fd.stop();
|
||||
fd.execute(args);
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,8 +80,7 @@ public class HeapDumper extends Tool {
|
||||
}
|
||||
|
||||
HeapDumper dumper = new HeapDumper(file);
|
||||
dumper.start(args);
|
||||
dumper.stop();
|
||||
dumper.execute(args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -46,8 +46,7 @@ public class HeapSummary extends Tool {
|
||||
|
||||
public static void main(String[] args) {
|
||||
HeapSummary hs = new HeapSummary();
|
||||
hs.start(args);
|
||||
hs.stop();
|
||||
hs.execute(args);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
@ -134,8 +134,7 @@ public class JInfo extends Tool {
|
||||
}
|
||||
|
||||
JInfo jinfo = new JInfo(mode);
|
||||
jinfo.start(args);
|
||||
jinfo.stop();
|
||||
jinfo.execute(args);
|
||||
}
|
||||
|
||||
private void printVMFlags() {
|
||||
|
||||
@ -136,7 +136,9 @@ public class JMap extends Tool {
|
||||
mode = MODE_HEAP_GRAPH_GXL;
|
||||
} else {
|
||||
System.err.println("unknown heap format:" + format);
|
||||
return;
|
||||
|
||||
// Exit with error status
|
||||
System.exit(1);
|
||||
}
|
||||
} else {
|
||||
copyArgs = false;
|
||||
@ -153,8 +155,7 @@ public class JMap extends Tool {
|
||||
}
|
||||
|
||||
JMap jmap = new JMap(mode);
|
||||
jmap.start(args);
|
||||
jmap.stop();
|
||||
jmap.execute(args);
|
||||
}
|
||||
|
||||
public boolean writeHeapHprofBin(String fileName) {
|
||||
|
||||
@ -64,7 +64,6 @@ public class JSnap extends Tool {
|
||||
|
||||
public static void main(String[] args) {
|
||||
JSnap js = new JSnap();
|
||||
js.start(args);
|
||||
js.stop();
|
||||
js.execute(args);
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,8 +89,7 @@ public class JStack extends Tool {
|
||||
}
|
||||
|
||||
JStack jstack = new JStack(mixedMode, concurrentLocks);
|
||||
jstack.start(args);
|
||||
jstack.stop();
|
||||
jstack.execute(args);
|
||||
}
|
||||
|
||||
private boolean mixedMode;
|
||||
|
||||
@ -61,7 +61,6 @@ public class ObjectHistogram extends Tool {
|
||||
|
||||
public static void main(String[] args) {
|
||||
ObjectHistogram oh = new ObjectHistogram();
|
||||
oh.start(args);
|
||||
oh.stop();
|
||||
oh.execute(args);
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +69,6 @@ public class PMap extends Tool {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
PMap t = new PMap();
|
||||
t.start(args);
|
||||
t.stop();
|
||||
t.execute(args);
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,8 +182,7 @@ public class PStack extends Tool {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
PStack t = new PStack();
|
||||
t.start(args);
|
||||
t.stop();
|
||||
t.execute(args);
|
||||
}
|
||||
|
||||
// -- Internals only below this point
|
||||
|
||||
@ -137,8 +137,7 @@ public class StackTrace extends Tool {
|
||||
|
||||
public static void main(String[] args) {
|
||||
StackTrace st = new StackTrace();
|
||||
st.start(args);
|
||||
st.stop();
|
||||
st.execute(args);
|
||||
}
|
||||
|
||||
private boolean verbose;
|
||||
|
||||
@ -58,7 +58,6 @@ public class SysPropsDumper extends Tool {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SysPropsDumper pd = new SysPropsDumper();
|
||||
pd.start(args);
|
||||
pd.stop();
|
||||
pd.execute(args);
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ package sun.jvm.hotspot.tools;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import sun.jvm.hotspot.*;
|
||||
import sun.jvm.hotspot.runtime.*;
|
||||
import sun.jvm.hotspot.debugger.*;
|
||||
@ -105,26 +106,44 @@ public abstract class Tool implements Runnable {
|
||||
|
||||
public static void main(String[] args) {
|
||||
<derived class> obj = new <derived class>;
|
||||
obj.start(args);
|
||||
obj.execute(args);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
protected void stop() {
|
||||
protected void execute(String[] args) {
|
||||
int returnStatus = 1;
|
||||
|
||||
try {
|
||||
returnStatus = start(args);
|
||||
} finally {
|
||||
stop();
|
||||
}
|
||||
|
||||
// Exit with 0 or 1
|
||||
System.exit(returnStatus);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (agent != null) {
|
||||
agent.detach();
|
||||
}
|
||||
}
|
||||
|
||||
protected void start(String[] args) {
|
||||
private int start(String[] args) {
|
||||
|
||||
if ((args.length < 1) || (args.length > 2)) {
|
||||
usage();
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Attempt to handle -h or -help or some invalid flag
|
||||
if (args[0].startsWith("-")) {
|
||||
if (args[0].startsWith("-h")) {
|
||||
usage();
|
||||
return 0;
|
||||
} else if (args[0].startsWith("-")) {
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintStream err = System.err;
|
||||
@ -154,6 +173,7 @@ public abstract class Tool implements Runnable {
|
||||
|
||||
default:
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
agent = new HotSpotAgent();
|
||||
@ -191,15 +211,16 @@ public abstract class Tool implements Runnable {
|
||||
break;
|
||||
}
|
||||
if (e.getMessage() != null) {
|
||||
err.print(e.getMessage());
|
||||
err.println(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
err.println();
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
err.println("Debugger attached successfully.");
|
||||
startInternal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// When using an existing JVMDebugger.
|
||||
|
||||
@ -177,7 +177,6 @@ public class ClassDump extends Tool {
|
||||
public static void main(String[] args) {
|
||||
|
||||
ClassDump cd = new ClassDump();
|
||||
cd.start(args);
|
||||
cd.stop();
|
||||
cd.execute(args);
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,8 +42,7 @@ public class JSDB extends Tool {
|
||||
|
||||
public static void main(String[] args) {
|
||||
JSDB jsdb = new JSDB();
|
||||
jsdb.start(args);
|
||||
jsdb.stop();
|
||||
jsdb.execute(args);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
@ -40,8 +40,7 @@ import sun.jvm.hotspot.utilities.soql.*;
|
||||
public class SOQL extends Tool {
|
||||
public static void main(String[] args) {
|
||||
SOQL soql = new SOQL();
|
||||
soql.start(args);
|
||||
soql.stop();
|
||||
soql.execute(args);
|
||||
}
|
||||
|
||||
public SOQL() {
|
||||
|
||||
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
|
||||
|
||||
HS_MAJOR_VER=25
|
||||
HS_MINOR_VER=0
|
||||
HS_BUILD_NUMBER=55
|
||||
HS_BUILD_NUMBER=57
|
||||
|
||||
JDK_MAJOR_VER=1
|
||||
JDK_MINOR_VER=8
|
||||
|
||||
@ -24,12 +24,7 @@
|
||||
|
||||
# Properties for jprt
|
||||
|
||||
# All build result bundles are full jdks, so the 64bit testing does not
|
||||
# need the 32bit sibling bundle installed.
|
||||
# Note: If the hotspot/make/Makefile changed to only bundle the 64bit files
|
||||
# when bundling 64bit, and stripped out the 64bit files from any 32bit
|
||||
# bundles, then this setting would be need to be "true".
|
||||
|
||||
# All build result bundles are full jdks.
|
||||
jprt.need.sibling.build=false
|
||||
|
||||
# At submit time, the release supplied will be in jprt.submit.release
|
||||
@ -52,21 +47,11 @@ jprt.sync.push=false
|
||||
# sparc etc.
|
||||
|
||||
# Define the Solaris platforms we want for the various releases
|
||||
jprt.my.solaris.sparc.jdk8=solaris_sparc_5.10
|
||||
jprt.my.solaris.sparc.jdk7=solaris_sparc_5.10
|
||||
jprt.my.solaris.sparc.jdk7u8=${jprt.my.solaris.sparc.jdk7}
|
||||
jprt.my.solaris.sparc=${jprt.my.solaris.sparc.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.solaris.sparcv9.jdk8=solaris_sparcv9_5.10
|
||||
jprt.my.solaris.sparcv9.jdk7=solaris_sparcv9_5.10
|
||||
jprt.my.solaris.sparcv9.jdk7u8=${jprt.my.solaris.sparcv9.jdk7}
|
||||
jprt.my.solaris.sparcv9=${jprt.my.solaris.sparcv9.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.solaris.i586.jdk8=solaris_i586_5.10
|
||||
jprt.my.solaris.i586.jdk7=solaris_i586_5.10
|
||||
jprt.my.solaris.i586.jdk7u8=${jprt.my.solaris.i586.jdk7}
|
||||
jprt.my.solaris.i586=${jprt.my.solaris.i586.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.solaris.x64.jdk8=solaris_x64_5.10
|
||||
jprt.my.solaris.x64.jdk7=solaris_x64_5.10
|
||||
jprt.my.solaris.x64.jdk7u8=${jprt.my.solaris.x64.jdk7}
|
||||
@ -133,9 +118,7 @@ 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.sparc}-{product|fastdebug}, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug|optimized}, \
|
||||
${jprt.my.solaris.i586}-{product|fastdebug}, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug|optimized}, \
|
||||
@ -145,7 +128,6 @@ jprt.build.targets.standard= \
|
||||
${jprt.my.linux.armvh}-{product|fastdebug}
|
||||
|
||||
jprt.build.targets.open= \
|
||||
${jprt.my.solaris.i586}-{productOpen}, \
|
||||
${jprt.my.solaris.x64}-{debugOpen}, \
|
||||
${jprt.my.linux.x64}-{productOpen}
|
||||
|
||||
@ -168,31 +150,6 @@ jprt.build.targets=${jprt.build.targets.${jprt.tools.default.release}}
|
||||
|
||||
# Subset lists of test targets for this source tree
|
||||
|
||||
jprt.my.solaris.sparc.test.targets= \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jvm98, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-c2-jvm98_nontiered, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-scimark, \
|
||||
${jprt.my.solaris.sparc}-product-{c1|c2}-runThese, \
|
||||
${jprt.my.solaris.sparc}-fastdebug-c1-runThese_Xshare, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_G1, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_SerialGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_ParallelGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_ParNewGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_CMS, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_G1, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_ParOldGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-c2-jbb_default_nontiered, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_SerialGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_ParallelGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_CMS, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_G1, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_ParOldGC
|
||||
|
||||
jprt.my.solaris.sparcv9.test.targets= \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jvm98, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jvm98_nontiered, \
|
||||
@ -242,37 +199,6 @@ jprt.my.solaris.x64.test.targets= \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_G1, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParOldGC
|
||||
|
||||
jprt.my.solaris.i586.test.targets= \
|
||||
${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
|
||||
${jprt.my.solaris.i586}-{product|fastdebug}-c2-jvm98_nontiered, \
|
||||
${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-scimark, \
|
||||
${jprt.my.solaris.i586}-product-{c1|c2}-runThese_Xcomp, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c1-runThese_Xcomp, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c1-runThese_Xshare, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCBasher_SerialGC, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCBasher_ParallelGC, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCBasher_ParNewGC, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCBasher_CMS, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCBasher_G1, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCBasher_ParOldGC, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_SerialGC, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_ParallelGC, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_ParNewGC, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_CMS, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_G1, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_ParOldGC, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCOld_SerialGC, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCOld_ParallelGC, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCOld_ParNewGC, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCOld_CMS, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCOld_G1, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCOld_ParOldGC, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-jbb_default_nontiered, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-jbb_ParallelGC, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-jbb_CMS, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-jbb_G1, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-jbb_ParOldGC
|
||||
|
||||
jprt.my.linux.i586.test.targets = \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-c2-jvm98_nontiered, \
|
||||
@ -395,7 +321,6 @@ jprt.my.windows.x64.test.targets = \
|
||||
# Some basic "smoke" tests for OpenJDK builds
|
||||
jprt.test.targets.open = \
|
||||
${jprt.my.solaris.x64}-{productOpen|fastdebugOpen}-c2-jvm98, \
|
||||
${jprt.my.solaris.i586}-{productOpen|fastdebugOpen}-c2-jvm98, \
|
||||
${jprt.my.linux.x64}-{productOpen|fastdebugOpen}-c2-jvm98
|
||||
|
||||
# Testing for actual embedded builds is different to standard
|
||||
@ -407,9 +332,7 @@ jprt.my.linux.i586.test.targets.embedded = \
|
||||
|
||||
jprt.test.targets.standard = \
|
||||
${jprt.my.linux.i586.test.targets.embedded}, \
|
||||
${jprt.my.solaris.sparc.test.targets}, \
|
||||
${jprt.my.solaris.sparcv9.test.targets}, \
|
||||
${jprt.my.solaris.i586.test.targets}, \
|
||||
${jprt.my.solaris.x64.test.targets}, \
|
||||
${jprt.my.linux.i586.test.targets}, \
|
||||
${jprt.my.linux.x64.test.targets}, \
|
||||
@ -420,15 +343,12 @@ jprt.test.targets.standard = \
|
||||
|
||||
jprt.test.targets.embedded= \
|
||||
${jprt.my.linux.i586.test.targets.embedded}, \
|
||||
${jprt.my.solaris.sparc.test.targets}, \
|
||||
${jprt.my.solaris.sparcv9.test.targets}, \
|
||||
${jprt.my.solaris.i586.test.targets}, \
|
||||
${jprt.my.solaris.x64.test.targets}, \
|
||||
${jprt.my.linux.x64.test.targets}, \
|
||||
${jprt.my.windows.i586.test.targets}, \
|
||||
${jprt.my.windows.x64.test.targets}
|
||||
|
||||
|
||||
jprt.test.targets.jdk8=${jprt.test.targets.standard}
|
||||
jprt.test.targets.jdk7=${jprt.test.targets.standard}
|
||||
jprt.test.targets.jdk7u8=${jprt.test.targets.jdk7}
|
||||
@ -439,15 +359,11 @@ jprt.test.targets=${jprt.test.targets.${jprt.tools.default.release}}
|
||||
#jprt.make.rule.test.targets=*-product-*-packtest
|
||||
|
||||
jprt.make.rule.test.targets.standard.client = \
|
||||
${jprt.my.solaris.sparc}-*-c1-clienttest, \
|
||||
${jprt.my.solaris.i586}-*-c1-clienttest, \
|
||||
${jprt.my.linux.i586}-*-c1-clienttest, \
|
||||
${jprt.my.windows.i586}-*-c1-clienttest
|
||||
|
||||
jprt.make.rule.test.targets.standard.server = \
|
||||
${jprt.my.solaris.sparc}-*-c2-servertest, \
|
||||
${jprt.my.solaris.sparcv9}-*-c2-servertest, \
|
||||
${jprt.my.solaris.i586}-*-c2-servertest, \
|
||||
${jprt.my.solaris.x64}-*-c2-servertest, \
|
||||
${jprt.my.linux.i586}-*-c2-servertest, \
|
||||
${jprt.my.linux.x64}-*-c2-servertest, \
|
||||
@ -456,9 +372,7 @@ jprt.make.rule.test.targets.standard.server = \
|
||||
${jprt.my.windows.x64}-*-c2-servertest
|
||||
|
||||
jprt.make.rule.test.targets.standard.internalvmtests = \
|
||||
${jprt.my.solaris.sparc}-fastdebug-c2-internalvmtests, \
|
||||
${jprt.my.solaris.sparcv9}-fastdebug-c2-internalvmtests, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-internalvmtests, \
|
||||
${jprt.my.solaris.x64}-fastdebug-c2-internalvmtests, \
|
||||
${jprt.my.linux.i586}-fastdebug-c2-internalvmtests, \
|
||||
${jprt.my.linux.x64}-fastdebug-c2-internalvmtests, \
|
||||
@ -467,16 +381,12 @@ jprt.make.rule.test.targets.standard.internalvmtests = \
|
||||
${jprt.my.windows.x64}-fastdebug-c2-internalvmtests
|
||||
|
||||
jprt.make.rule.test.targets.standard.wbapi = \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.solaris.i586}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.windows.i586}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-c1-wbapitest, \
|
||||
${jprt.my.solaris.i586}-{product|fastdebug}-c1-wbapitest, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-c1-wbapitest, \
|
||||
${jprt.my.windows.i586}-{product|fastdebug}-c1-wbapitest
|
||||
|
||||
|
||||
@ -40,8 +40,7 @@ TraceGeneratedNames = \
|
||||
traceEventIds.hpp \
|
||||
traceTypes.hpp
|
||||
|
||||
|
||||
!if "$(OPENJDK)" != "true"
|
||||
!if EXISTS($(TraceAltSrcDir))
|
||||
TraceGeneratedNames = $(TraceGeneratedNames) \
|
||||
traceRequestables.hpp \
|
||||
traceEventControl.hpp \
|
||||
@ -56,7 +55,7 @@ TraceGeneratedFiles = \
|
||||
$(TraceOutDir)/traceEventIds.hpp \
|
||||
$(TraceOutDir)/traceTypes.hpp
|
||||
|
||||
!if "$(OPENJDK)" != "true"
|
||||
!if EXISTS($(TraceAltSrcDir))
|
||||
TraceGeneratedFiles = $(TraceGeneratedFiles) \
|
||||
$(TraceOutDir)/traceRequestables.hpp \
|
||||
$(TraceOutDir)/traceEventControl.hpp \
|
||||
@ -68,7 +67,7 @@ XSLT = $(QUIETLY) $(REMOTE) $(RUN_JAVA) -classpath $(JvmtiOutDir) jvmtiGen
|
||||
XML_DEPS = $(TraceSrcDir)/trace.xml $(TraceSrcDir)/tracetypes.xml \
|
||||
$(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
|
||||
|
||||
!if "$(OPENJDK)" != "true"
|
||||
!if EXISTS($(TraceAltSrcDir))
|
||||
XML_DEPS = $(XML_DEPS) $(TraceAltSrcDir)/traceevents.xml
|
||||
!endif
|
||||
|
||||
@ -87,7 +86,7 @@ $(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceType
|
||||
@echo Generating $@
|
||||
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceTypes.xsl -OUT $(TraceOutDir)/traceTypes.hpp
|
||||
|
||||
!if "$(OPENJDK)" == "true"
|
||||
!if !EXISTS($(TraceAltSrcDir))
|
||||
|
||||
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
|
||||
@echo Generating OpenJDK $@
|
||||
|
||||
@ -53,6 +53,8 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool outgoing) {
|
||||
opr = as_long_opr(reg);
|
||||
} else if (type == T_OBJECT || type == T_ARRAY) {
|
||||
opr = as_oop_opr(reg);
|
||||
} else if (type == T_METADATA) {
|
||||
opr = as_metadata_opr(reg);
|
||||
} else {
|
||||
opr = as_opr(reg);
|
||||
}
|
||||
|
||||
@ -2565,7 +2565,7 @@ void LIR_Assembler::type_profile_helper(Register mdo, int mdo_offset_bias,
|
||||
Address receiver_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) -
|
||||
mdo_offset_bias);
|
||||
__ ld_ptr(receiver_addr, tmp1);
|
||||
__ verify_oop(tmp1);
|
||||
__ verify_klass_ptr(tmp1);
|
||||
__ cmp_and_brx_short(recv, tmp1, Assembler::notEqual, Assembler::pt, next_test);
|
||||
Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) -
|
||||
mdo_offset_bias);
|
||||
|
||||
@ -404,7 +404,9 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
if (id == fast_new_instance_init_check_id) {
|
||||
// make sure the klass is initialized
|
||||
__ ldub(G5_klass, in_bytes(InstanceKlass::init_state_offset()), G3_t1);
|
||||
__ cmp_and_br_short(G3_t1, InstanceKlass::fully_initialized, Assembler::notEqual, Assembler::pn, slow_path);
|
||||
__ cmp(G3_t1, InstanceKlass::fully_initialized);
|
||||
__ br(Assembler::notEqual, false, Assembler::pn, slow_path);
|
||||
__ delayed()->nop();
|
||||
}
|
||||
#ifdef ASSERT
|
||||
// assert object can be fast path allocated
|
||||
@ -515,7 +517,9 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
|
||||
// check that array length is small enough for fast path
|
||||
__ set(C1_MacroAssembler::max_array_allocation_length, G3_t1);
|
||||
__ cmp_and_br_short(G4_length, G3_t1, Assembler::greaterUnsigned, Assembler::pn, slow_path);
|
||||
__ cmp(G4_length, G3_t1);
|
||||
__ br(Assembler::greaterUnsigned, false, Assembler::pn, slow_path);
|
||||
__ delayed()->nop();
|
||||
|
||||
// if we got here then the TLAB allocation failed, so try
|
||||
// refilling the TLAB or allocating directly from eden.
|
||||
|
||||
@ -365,7 +365,7 @@ address CppInterpreterGenerator::generate_stack_to_native_abi_converter(BasicTyp
|
||||
return entry;
|
||||
}
|
||||
|
||||
address CppInterpreter::return_entry(TosState state, int length) {
|
||||
address CppInterpreter::return_entry(TosState state, int length, Bytecodes::Code code) {
|
||||
// make it look good in the debugger
|
||||
return CAST_FROM_FN_PTR(address, RecursiveInterpreterActivation) + frame::pc_return_offset;
|
||||
}
|
||||
|
||||
@ -3333,7 +3333,8 @@ void MacroAssembler::tlab_refill(Label& retry, Label& try_eden, Label& slow_case
|
||||
|
||||
if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) {
|
||||
// No allocation in the shared eden.
|
||||
ba_short(slow_case);
|
||||
ba(slow_case);
|
||||
delayed()->nop();
|
||||
}
|
||||
|
||||
ld_ptr(G2_thread, in_bytes(JavaThread::tlab_top_offset()), top);
|
||||
@ -3358,7 +3359,8 @@ void MacroAssembler::tlab_refill(Label& retry, Label& try_eden, Label& slow_case
|
||||
add(t2, 1, t2);
|
||||
stw(t2, G2_thread, in_bytes(JavaThread::tlab_slow_allocations_offset()));
|
||||
}
|
||||
ba_short(try_eden);
|
||||
ba(try_eden);
|
||||
delayed()->nop();
|
||||
|
||||
bind(discard_tlab);
|
||||
if (TLABStats) {
|
||||
@ -3420,7 +3422,8 @@ void MacroAssembler::tlab_refill(Label& retry, Label& try_eden, Label& slow_case
|
||||
sub(top, ThreadLocalAllocBuffer::alignment_reserve_in_bytes(), top);
|
||||
st_ptr(top, G2_thread, in_bytes(JavaThread::tlab_end_offset()));
|
||||
verify_tlab();
|
||||
ba_short(retry);
|
||||
ba(retry);
|
||||
delayed()->nop();
|
||||
}
|
||||
|
||||
void MacroAssembler::incr_allocated_bytes(RegisterOrConstant size_in_bytes,
|
||||
@ -4096,15 +4099,19 @@ void MacroAssembler::decode_heap_oop_not_null(Register src, Register dst) {
|
||||
|
||||
void MacroAssembler::encode_klass_not_null(Register r) {
|
||||
assert (UseCompressedClassPointers, "must be compressed");
|
||||
assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
|
||||
assert(r != G6_heapbase, "bad register choice");
|
||||
set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
|
||||
sub(r, G6_heapbase, r);
|
||||
if (Universe::narrow_klass_shift() != 0) {
|
||||
assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
|
||||
srlx(r, LogKlassAlignmentInBytes, r);
|
||||
if (Universe::narrow_klass_base() != NULL) {
|
||||
assert(r != G6_heapbase, "bad register choice");
|
||||
set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
|
||||
sub(r, G6_heapbase, r);
|
||||
if (Universe::narrow_klass_shift() != 0) {
|
||||
assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
|
||||
srlx(r, LogKlassAlignmentInBytes, r);
|
||||
}
|
||||
reinit_heapbase();
|
||||
} else {
|
||||
assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift() || Universe::narrow_klass_shift() == 0, "decode alg wrong");
|
||||
srlx(r, Universe::narrow_klass_shift(), r);
|
||||
}
|
||||
reinit_heapbase();
|
||||
}
|
||||
|
||||
void MacroAssembler::encode_klass_not_null(Register src, Register dst) {
|
||||
@ -4112,11 +4119,16 @@ void MacroAssembler::encode_klass_not_null(Register src, Register dst) {
|
||||
encode_klass_not_null(src);
|
||||
} else {
|
||||
assert (UseCompressedClassPointers, "must be compressed");
|
||||
assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
|
||||
set((intptr_t)Universe::narrow_klass_base(), dst);
|
||||
sub(src, dst, dst);
|
||||
if (Universe::narrow_klass_shift() != 0) {
|
||||
srlx(dst, LogKlassAlignmentInBytes, dst);
|
||||
if (Universe::narrow_klass_base() != NULL) {
|
||||
set((intptr_t)Universe::narrow_klass_base(), dst);
|
||||
sub(src, dst, dst);
|
||||
if (Universe::narrow_klass_shift() != 0) {
|
||||
srlx(dst, LogKlassAlignmentInBytes, dst);
|
||||
}
|
||||
} else {
|
||||
// shift src into dst
|
||||
assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift() || Universe::narrow_klass_shift() == 0, "decode alg wrong");
|
||||
srlx(src, Universe::narrow_klass_shift(), dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4126,14 +4138,16 @@ void MacroAssembler::encode_klass_not_null(Register src, Register dst) {
|
||||
// the instructions they generate change, then this method needs to be updated.
|
||||
int MacroAssembler::instr_size_for_decode_klass_not_null() {
|
||||
assert (UseCompressedClassPointers, "only for compressed klass ptrs");
|
||||
// set + add + set
|
||||
int num_instrs = insts_for_internal_set((intptr_t)Universe::narrow_klass_base()) + 1 +
|
||||
insts_for_internal_set((intptr_t)Universe::narrow_ptrs_base());
|
||||
if (Universe::narrow_klass_shift() == 0) {
|
||||
return num_instrs * BytesPerInstWord;
|
||||
} else { // sllx
|
||||
return (num_instrs + 1) * BytesPerInstWord;
|
||||
int num_instrs = 1; // shift src,dst or add
|
||||
if (Universe::narrow_klass_base() != NULL) {
|
||||
// set + add + set
|
||||
num_instrs += insts_for_internal_set((intptr_t)Universe::narrow_klass_base()) +
|
||||
insts_for_internal_set((intptr_t)Universe::narrow_ptrs_base());
|
||||
if (Universe::narrow_klass_shift() != 0) {
|
||||
num_instrs += 1; // sllx
|
||||
}
|
||||
}
|
||||
return num_instrs * BytesPerInstWord;
|
||||
}
|
||||
|
||||
// !!! If the instructions that get generated here change then function
|
||||
@ -4142,13 +4156,17 @@ void MacroAssembler::decode_klass_not_null(Register r) {
|
||||
// Do not add assert code to this unless you change vtableStubs_sparc.cpp
|
||||
// pd_code_size_limit.
|
||||
assert (UseCompressedClassPointers, "must be compressed");
|
||||
assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
|
||||
assert(r != G6_heapbase, "bad register choice");
|
||||
set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
|
||||
if (Universe::narrow_klass_shift() != 0)
|
||||
sllx(r, LogKlassAlignmentInBytes, r);
|
||||
add(r, G6_heapbase, r);
|
||||
reinit_heapbase();
|
||||
if (Universe::narrow_klass_base() != NULL) {
|
||||
assert(r != G6_heapbase, "bad register choice");
|
||||
set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
|
||||
if (Universe::narrow_klass_shift() != 0)
|
||||
sllx(r, LogKlassAlignmentInBytes, r);
|
||||
add(r, G6_heapbase, r);
|
||||
reinit_heapbase();
|
||||
} else {
|
||||
assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift() || Universe::narrow_klass_shift() == 0, "decode alg wrong");
|
||||
sllx(r, Universe::narrow_klass_shift(), r);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::decode_klass_not_null(Register src, Register dst) {
|
||||
@ -4158,16 +4176,21 @@ void MacroAssembler::decode_klass_not_null(Register src, Register dst) {
|
||||
// Do not add assert code to this unless you change vtableStubs_sparc.cpp
|
||||
// pd_code_size_limit.
|
||||
assert (UseCompressedClassPointers, "must be compressed");
|
||||
assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
|
||||
if (Universe::narrow_klass_shift() != 0) {
|
||||
assert((src != G6_heapbase) && (dst != G6_heapbase), "bad register choice");
|
||||
set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
|
||||
sllx(src, LogKlassAlignmentInBytes, dst);
|
||||
add(dst, G6_heapbase, dst);
|
||||
reinit_heapbase();
|
||||
if (Universe::narrow_klass_base() != NULL) {
|
||||
if (Universe::narrow_klass_shift() != 0) {
|
||||
assert((src != G6_heapbase) && (dst != G6_heapbase), "bad register choice");
|
||||
set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
|
||||
sllx(src, LogKlassAlignmentInBytes, dst);
|
||||
add(dst, G6_heapbase, dst);
|
||||
reinit_heapbase();
|
||||
} else {
|
||||
set((intptr_t)Universe::narrow_klass_base(), dst);
|
||||
add(src, dst, dst);
|
||||
}
|
||||
} else {
|
||||
set((intptr_t)Universe::narrow_klass_base(), dst);
|
||||
add(src, dst, dst);
|
||||
// shift/mov src into dst.
|
||||
assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift() || Universe::narrow_klass_shift() == 0, "decode alg wrong");
|
||||
sllx(src, Universe::narrow_klass_shift(), dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1660,12 +1660,16 @@ void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
|
||||
if (UseCompressedClassPointers) {
|
||||
assert(Universe::heap() != NULL, "java heap should be initialized");
|
||||
st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check - compressed klass");
|
||||
st->print_cr("\tSET Universe::narrow_klass_base,R_G6_heap_base");
|
||||
if (Universe::narrow_klass_shift() != 0) {
|
||||
st->print_cr("\tSLL R_G5,3,R_G5");
|
||||
if (Universe::narrow_klass_base() != 0) {
|
||||
st->print_cr("\tSET Universe::narrow_klass_base,R_G6_heap_base");
|
||||
if (Universe::narrow_klass_shift() != 0) {
|
||||
st->print_cr("\tSLL R_G5,Universe::narrow_klass_shift,R_G5");
|
||||
}
|
||||
st->print_cr("\tADD R_G5,R_G6_heap_base,R_G5");
|
||||
st->print_cr("\tSET Universe::narrow_ptrs_base,R_G6_heap_base");
|
||||
} else {
|
||||
st->print_cr("\tSLL R_G5,Universe::narrow_klass_shift,R_G5");
|
||||
}
|
||||
st->print_cr("\tADD R_G5,R_G6_heap_base,R_G5");
|
||||
st->print_cr("\tSET Universe::narrow_ptrs_base,R_G6_heap_base");
|
||||
} else {
|
||||
st->print_cr("\tLDX [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check");
|
||||
}
|
||||
@ -2022,6 +2026,10 @@ const RegMask Matcher::mathExactI_result_proj_mask() {
|
||||
return G1_REGI_mask();
|
||||
}
|
||||
|
||||
const RegMask Matcher::mathExactL_result_proj_mask() {
|
||||
return G1_REGL_mask();
|
||||
}
|
||||
|
||||
const RegMask Matcher::mathExactI_flags_proj_mask() {
|
||||
return INT_FLAGS_mask();
|
||||
}
|
||||
|
||||
@ -153,13 +153,9 @@ address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
|
||||
}
|
||||
|
||||
|
||||
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) {
|
||||
TosState incoming_state = state;
|
||||
|
||||
Label cont;
|
||||
address compiled_entry = __ pc();
|
||||
|
||||
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {
|
||||
address entry = __ pc();
|
||||
|
||||
#if !defined(_LP64) && defined(COMPILER2)
|
||||
// All return values are where we want them, except for Longs. C2 returns
|
||||
// longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1.
|
||||
@ -170,14 +166,12 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
||||
// do this here. Unfortunately if we did a rethrow we'd see an machepilog node
|
||||
// first which would move g1 -> O0/O1 and destroy the exception we were throwing.
|
||||
|
||||
if (incoming_state == ltos) {
|
||||
if (state == ltos) {
|
||||
__ srl (G1, 0, O1);
|
||||
__ srlx(G1, 32, O0);
|
||||
}
|
||||
#endif // !_LP64 && COMPILER2
|
||||
|
||||
__ bind(cont);
|
||||
|
||||
// The callee returns with the stack possibly adjusted by adapter transition
|
||||
// We remove that possible adjustment here.
|
||||
// All interpreter local registers are untouched. Any result is passed back
|
||||
@ -186,28 +180,17 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
||||
|
||||
__ mov(Llast_SP, SP); // Remove any adapter added stack space.
|
||||
|
||||
Label L_got_cache, L_giant_index;
|
||||
const Register cache = G3_scratch;
|
||||
const Register size = G1_scratch;
|
||||
if (EnableInvokeDynamic) {
|
||||
__ ldub(Address(Lbcp, 0), G1_scratch); // Load current bytecode.
|
||||
__ cmp_and_br_short(G1_scratch, Bytecodes::_invokedynamic, Assembler::equal, Assembler::pn, L_giant_index);
|
||||
}
|
||||
__ get_cache_and_index_at_bcp(cache, G1_scratch, 1);
|
||||
__ bind(L_got_cache);
|
||||
__ ld_ptr(cache, ConstantPoolCache::base_offset() +
|
||||
ConstantPoolCacheEntry::flags_offset(), size);
|
||||
__ and3(size, 0xFF, size); // argument size in words
|
||||
__ sll(size, Interpreter::logStackElementSize, size); // each argument size in bytes
|
||||
__ add(Lesp, size, Lesp); // pop arguments
|
||||
__ dispatch_next(state, step);
|
||||
const Register index = G1_scratch;
|
||||
__ get_cache_and_index_at_bcp(cache, index, 1, index_size);
|
||||
|
||||
// out of the main line of code...
|
||||
if (EnableInvokeDynamic) {
|
||||
__ bind(L_giant_index);
|
||||
__ get_cache_and_index_at_bcp(cache, G1_scratch, 1, sizeof(u4));
|
||||
__ ba_short(L_got_cache);
|
||||
}
|
||||
const Register flags = cache;
|
||||
__ ld_ptr(cache, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset(), flags);
|
||||
const Register parameter_size = flags;
|
||||
__ and3(flags, ConstantPoolCacheEntry::parameter_size_mask, parameter_size); // argument size in words
|
||||
__ sll(parameter_size, Interpreter::logStackElementSize, parameter_size); // each argument size in bytes
|
||||
__ add(Lesp, parameter_size, Lesp); // pop arguments
|
||||
__ dispatch_next(state, step);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
@ -2932,9 +2932,7 @@ void TemplateTable::prepare_invoke(int byte_no,
|
||||
ConstantPoolCacheEntry::verify_tos_state_shift();
|
||||
// load return address
|
||||
{
|
||||
const address table_addr = (is_invokeinterface || is_invokedynamic) ?
|
||||
(address)Interpreter::return_5_addrs_by_index_table() :
|
||||
(address)Interpreter::return_3_addrs_by_index_table();
|
||||
const address table_addr = (address) Interpreter::invoke_return_entry_table_for(code);
|
||||
AddressLiteral table(table_addr);
|
||||
__ set(table, temp);
|
||||
__ sll(ra, LogBytesPerWord, ra);
|
||||
@ -2984,7 +2982,7 @@ void TemplateTable::invokevirtual(int byte_no) {
|
||||
__ verify_oop(O0_recv);
|
||||
|
||||
// get return address
|
||||
AddressLiteral table(Interpreter::return_3_addrs_by_index_table());
|
||||
AddressLiteral table(Interpreter::invoke_return_entry_table());
|
||||
__ set(table, Rtemp);
|
||||
__ srl(Rret, ConstantPoolCacheEntry::tos_state_shift, Rret); // get return type
|
||||
// Make sure we don't need to mask Rret after the above shift
|
||||
@ -3026,7 +3024,7 @@ void TemplateTable::invokevfinal_helper(Register Rscratch, Register Rret) {
|
||||
__ profile_final_call(O4);
|
||||
|
||||
// get return address
|
||||
AddressLiteral table(Interpreter::return_3_addrs_by_index_table());
|
||||
AddressLiteral table(Interpreter::invoke_return_entry_table());
|
||||
__ set(table, Rtemp);
|
||||
__ srl(Rret, ConstantPoolCacheEntry::tos_state_shift, Rret); // get return type
|
||||
// Make sure we don't need to mask Rret after the above shift
|
||||
|
||||
@ -1405,6 +1405,15 @@ void Assembler::imull(Register dst, Register src, int value) {
|
||||
}
|
||||
}
|
||||
|
||||
void Assembler::imull(Register dst, Address src) {
|
||||
InstructionMark im(this);
|
||||
prefix(src, dst);
|
||||
emit_int8(0x0F);
|
||||
emit_int8((unsigned char) 0xAF);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::incl(Address dst) {
|
||||
// Don't use it directly. Use MacroAssembler::increment() instead.
|
||||
InstructionMark im(this);
|
||||
@ -5024,6 +5033,14 @@ void Assembler::imulq(Register dst, Register src, int value) {
|
||||
}
|
||||
}
|
||||
|
||||
void Assembler::imulq(Register dst, Address src) {
|
||||
InstructionMark im(this);
|
||||
prefixq(src, dst);
|
||||
emit_int8(0x0F);
|
||||
emit_int8((unsigned char) 0xAF);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::incl(Register dst) {
|
||||
// Don't use it directly. Use MacroAssembler::incrementl() instead.
|
||||
// Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
|
||||
|
||||
@ -1162,9 +1162,13 @@ private:
|
||||
|
||||
void imull(Register dst, Register src);
|
||||
void imull(Register dst, Register src, int value);
|
||||
void imull(Register dst, Address src);
|
||||
|
||||
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-
|
||||
|
||||
@ -40,11 +40,8 @@
|
||||
#include "runtime/synchronizer.hpp"
|
||||
#include "runtime/vframeArray.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#ifdef TARGET_ARCH_MODEL_x86_32
|
||||
# include "interp_masm_x86_32.hpp"
|
||||
#endif
|
||||
#ifdef TARGET_ARCH_MODEL_x86_64
|
||||
# include "interp_masm_x86_64.hpp"
|
||||
#ifdef TARGET_ARCH_x86
|
||||
# include "interp_masm_x86.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef CC_INTERP
|
||||
|
||||
@ -52,6 +52,8 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool) {
|
||||
#endif // _LP64
|
||||
} else if (type == T_OBJECT || type == T_ARRAY) {
|
||||
opr = as_oop_opr(reg);
|
||||
} else if (type == T_METADATA) {
|
||||
opr = as_metadata_opr(reg);
|
||||
} else {
|
||||
opr = as_opr(reg);
|
||||
}
|
||||
|
||||
@ -432,15 +432,16 @@ int LIR_Assembler::emit_unwind_handler() {
|
||||
int offset = code_offset();
|
||||
|
||||
// Fetch the exception from TLS and clear out exception related thread state
|
||||
__ get_thread(rsi);
|
||||
__ movptr(rax, Address(rsi, JavaThread::exception_oop_offset()));
|
||||
__ movptr(Address(rsi, JavaThread::exception_oop_offset()), (intptr_t)NULL_WORD);
|
||||
__ movptr(Address(rsi, JavaThread::exception_pc_offset()), (intptr_t)NULL_WORD);
|
||||
Register thread = NOT_LP64(rsi) LP64_ONLY(r15_thread);
|
||||
NOT_LP64(__ get_thread(rsi));
|
||||
__ movptr(rax, Address(thread, JavaThread::exception_oop_offset()));
|
||||
__ movptr(Address(thread, JavaThread::exception_oop_offset()), (intptr_t)NULL_WORD);
|
||||
__ movptr(Address(thread, JavaThread::exception_pc_offset()), (intptr_t)NULL_WORD);
|
||||
|
||||
__ bind(_unwind_handler_entry);
|
||||
__ verify_not_null_oop(rax);
|
||||
if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {
|
||||
__ mov(rsi, rax); // Preserve the exception
|
||||
__ mov(rbx, rax); // Preserve the exception (rbx is always callee-saved)
|
||||
}
|
||||
|
||||
// Preform needed unlocking
|
||||
@ -448,19 +449,24 @@ int LIR_Assembler::emit_unwind_handler() {
|
||||
if (method()->is_synchronized()) {
|
||||
monitor_address(0, FrameMap::rax_opr);
|
||||
stub = new MonitorExitStub(FrameMap::rax_opr, true, 0);
|
||||
__ unlock_object(rdi, rbx, rax, *stub->entry());
|
||||
__ unlock_object(rdi, rsi, rax, *stub->entry());
|
||||
__ bind(*stub->continuation());
|
||||
}
|
||||
|
||||
if (compilation()->env()->dtrace_method_probes()) {
|
||||
#ifdef _LP64
|
||||
__ mov(rdi, r15_thread);
|
||||
__ mov_metadata(rsi, method()->constant_encoding());
|
||||
#else
|
||||
__ get_thread(rax);
|
||||
__ movptr(Address(rsp, 0), rax);
|
||||
__ mov_metadata(Address(rsp, sizeof(void*)), method()->constant_encoding());
|
||||
#endif
|
||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit)));
|
||||
}
|
||||
|
||||
if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {
|
||||
__ mov(rax, rsi); // Restore the exception
|
||||
__ mov(rax, rbx); // Restore the exception
|
||||
}
|
||||
|
||||
// remove the activation and dispatch to the unwind handler
|
||||
@ -1206,6 +1212,10 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch
|
||||
LIR_Address* addr = src->as_address_ptr();
|
||||
Address from_addr = as_Address(addr);
|
||||
|
||||
if (addr->base()->type() == T_OBJECT) {
|
||||
__ verify_oop(addr->base()->as_pointer_register());
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case T_BOOLEAN: // fall through
|
||||
case T_BYTE: // fall through
|
||||
|
||||
@ -1468,19 +1468,18 @@ void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {
|
||||
addr = new LIR_Address(src.result(), offset, type);
|
||||
}
|
||||
|
||||
if (data != dst) {
|
||||
__ move(data, dst);
|
||||
data = dst;
|
||||
}
|
||||
// Because we want a 2-arg form of xchg and xadd
|
||||
__ move(data, dst);
|
||||
|
||||
if (x->is_add()) {
|
||||
__ xadd(LIR_OprFact::address(addr), data, dst, LIR_OprFact::illegalOpr);
|
||||
__ xadd(LIR_OprFact::address(addr), dst, dst, LIR_OprFact::illegalOpr);
|
||||
} else {
|
||||
if (is_obj) {
|
||||
// Do the pre-write barrier, if any.
|
||||
pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */,
|
||||
true /* do_load */, false /* patch */, NULL);
|
||||
}
|
||||
__ xchg(LIR_OprFact::address(addr), data, dst, LIR_OprFact::illegalOpr);
|
||||
__ xchg(LIR_OprFact::address(addr), dst, dst, LIR_OprFact::illegalOpr);
|
||||
if (is_obj) {
|
||||
// Seems to be a precise address
|
||||
post_barrier(LIR_OprFact::address(addr), data);
|
||||
|
||||
@ -367,7 +367,7 @@ address CppInterpreterGenerator::generate_stack_to_native_abi_converter(BasicTyp
|
||||
return entry;
|
||||
}
|
||||
|
||||
address CppInterpreter::return_entry(TosState state, int length) {
|
||||
address CppInterpreter::return_entry(TosState state, int length, Bytecodes::Code code) {
|
||||
// make it look good in the debugger
|
||||
return CAST_FROM_FN_PTR(address, RecursiveInterpreterActivation);
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ define_pd_global(bool, UseMembar, false);
|
||||
// GC Ergo Flags
|
||||
define_pd_global(uintx, CMSYoungGenPerWorker, 64*M); // default max size of CMS young gen, per GC worker thread
|
||||
|
||||
define_pd_global(uintx, TypeProfileLevel, 11);
|
||||
define_pd_global(uintx, TypeProfileLevel, 111);
|
||||
|
||||
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
|
||||
\
|
||||
|
||||
229
hotspot/src/cpu/x86/vm/interp_masm_x86.cpp
Normal file
229
hotspot/src/cpu/x86/vm/interp_masm_x86.cpp
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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 "interp_masm_x86.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "oops/methodData.hpp"
|
||||
|
||||
#ifndef CC_INTERP
|
||||
void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
|
||||
Label update, next, none;
|
||||
|
||||
verify_oop(obj);
|
||||
|
||||
testptr(obj, obj);
|
||||
jccb(Assembler::notZero, update);
|
||||
orptr(mdo_addr, TypeEntries::null_seen);
|
||||
jmpb(next);
|
||||
|
||||
bind(update);
|
||||
load_klass(obj, obj);
|
||||
|
||||
xorptr(obj, mdo_addr);
|
||||
testptr(obj, TypeEntries::type_klass_mask);
|
||||
jccb(Assembler::zero, next); // klass seen before, nothing to
|
||||
// do. The unknown bit may have been
|
||||
// set already but no need to check.
|
||||
|
||||
testptr(obj, TypeEntries::type_unknown);
|
||||
jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
|
||||
|
||||
cmpptr(mdo_addr, 0);
|
||||
jccb(Assembler::equal, none);
|
||||
cmpptr(mdo_addr, TypeEntries::null_seen);
|
||||
jccb(Assembler::equal, none);
|
||||
// There is a chance that the checks above (re-reading profiling
|
||||
// data from memory) fail if another thread has just set the
|
||||
// profiling to this obj's klass
|
||||
xorptr(obj, mdo_addr);
|
||||
testptr(obj, TypeEntries::type_klass_mask);
|
||||
jccb(Assembler::zero, next);
|
||||
|
||||
// different than before. Cannot keep accurate profile.
|
||||
orptr(mdo_addr, TypeEntries::type_unknown);
|
||||
jmpb(next);
|
||||
|
||||
bind(none);
|
||||
// first time here. Set profile type.
|
||||
movptr(mdo_addr, obj);
|
||||
|
||||
bind(next);
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual) {
|
||||
if (!ProfileInterpreter) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (MethodData::profile_arguments() || MethodData::profile_return()) {
|
||||
Label profile_continue;
|
||||
|
||||
test_method_data_pointer(mdp, profile_continue);
|
||||
|
||||
int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size());
|
||||
|
||||
cmpb(Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start), is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag);
|
||||
jcc(Assembler::notEqual, profile_continue);
|
||||
|
||||
if (MethodData::profile_arguments()) {
|
||||
Label done;
|
||||
int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset());
|
||||
addptr(mdp, off_to_args);
|
||||
|
||||
for (int i = 0; i < TypeProfileArgsLimit; i++) {
|
||||
if (i > 0 || MethodData::profile_return()) {
|
||||
// If return value type is profiled we may have no argument to profile
|
||||
movptr(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
|
||||
subl(tmp, i*TypeStackSlotEntries::per_arg_count());
|
||||
cmpl(tmp, TypeStackSlotEntries::per_arg_count());
|
||||
jcc(Assembler::less, done);
|
||||
}
|
||||
movptr(tmp, Address(callee, Method::const_offset()));
|
||||
load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset()));
|
||||
// stack offset o (zero based) from the start of the argument
|
||||
// list, for n arguments translates into offset n - o - 1 from
|
||||
// the end of the argument list
|
||||
subptr(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args));
|
||||
subl(tmp, 1);
|
||||
Address arg_addr = argument_address(tmp);
|
||||
movptr(tmp, arg_addr);
|
||||
|
||||
Address mdo_arg_addr(mdp, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args);
|
||||
profile_obj_type(tmp, mdo_arg_addr);
|
||||
|
||||
int to_add = in_bytes(TypeStackSlotEntries::per_arg_size());
|
||||
addptr(mdp, to_add);
|
||||
off_to_args += to_add;
|
||||
}
|
||||
|
||||
if (MethodData::profile_return()) {
|
||||
movptr(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
|
||||
subl(tmp, TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count());
|
||||
}
|
||||
|
||||
bind(done);
|
||||
|
||||
if (MethodData::profile_return()) {
|
||||
// We're right after the type profile for the last
|
||||
// argument. tmp is the number of cell left in the
|
||||
// CallTypeData/VirtualCallTypeData to reach its end. Non null
|
||||
// if there's a return to profile.
|
||||
assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type");
|
||||
shll(tmp, exact_log2(DataLayout::cell_size));
|
||||
addptr(mdp, tmp);
|
||||
}
|
||||
movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp);
|
||||
} else {
|
||||
assert(MethodData::profile_return(), "either profile call args or call ret");
|
||||
update_mdp_by_constant(mdp, in_bytes(ReturnTypeEntry::size()));
|
||||
}
|
||||
|
||||
// mdp points right after the end of the
|
||||
// CallTypeData/VirtualCallTypeData, right after the cells for the
|
||||
// return value type if there's one
|
||||
|
||||
bind(profile_continue);
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::profile_return_type(Register mdp, Register ret, Register tmp) {
|
||||
assert_different_registers(mdp, ret, tmp, _bcp_register);
|
||||
if (ProfileInterpreter && MethodData::profile_return()) {
|
||||
Label profile_continue, done;
|
||||
|
||||
test_method_data_pointer(mdp, profile_continue);
|
||||
|
||||
if (MethodData::profile_return_jsr292_only()) {
|
||||
// If we don't profile all invoke bytecodes we must make sure
|
||||
// it's a bytecode we indeed profile. We can't go back to the
|
||||
// begining of the ProfileData we intend to update to check its
|
||||
// type because we're right after it and we don't known its
|
||||
// length
|
||||
Label do_profile;
|
||||
cmpb(Address(_bcp_register, 0), Bytecodes::_invokedynamic);
|
||||
jcc(Assembler::equal, do_profile);
|
||||
cmpb(Address(_bcp_register, 0), Bytecodes::_invokehandle);
|
||||
jcc(Assembler::equal, do_profile);
|
||||
get_method(tmp);
|
||||
cmpb(Address(tmp, Method::intrinsic_id_offset_in_bytes()), vmIntrinsics::_compiledLambdaForm);
|
||||
jcc(Assembler::notEqual, profile_continue);
|
||||
|
||||
bind(do_profile);
|
||||
}
|
||||
|
||||
Address mdo_ret_addr(mdp, -in_bytes(ReturnTypeEntry::size()));
|
||||
mov(tmp, ret);
|
||||
profile_obj_type(tmp, mdo_ret_addr);
|
||||
|
||||
bind(profile_continue);
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::profile_parameters_type(Register mdp, Register tmp1, Register tmp2) {
|
||||
if (ProfileInterpreter && MethodData::profile_parameters()) {
|
||||
Label profile_continue, done;
|
||||
|
||||
test_method_data_pointer(mdp, profile_continue);
|
||||
|
||||
// Load the offset of the area within the MDO used for
|
||||
// parameters. If it's negative we're not profiling any parameters
|
||||
movl(tmp1, Address(mdp, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset())));
|
||||
testl(tmp1, tmp1);
|
||||
jcc(Assembler::negative, profile_continue);
|
||||
|
||||
// Compute a pointer to the area for parameters from the offset
|
||||
// and move the pointer to the slot for the last
|
||||
// parameters. Collect profiling from last parameter down.
|
||||
// mdo start + parameters offset + array length - 1
|
||||
addptr(mdp, tmp1);
|
||||
movptr(tmp1, Address(mdp, in_bytes(ArrayData::array_len_offset())));
|
||||
decrement(tmp1, TypeStackSlotEntries::per_arg_count());
|
||||
|
||||
Label loop;
|
||||
bind(loop);
|
||||
|
||||
int off_base = in_bytes(ParametersTypeData::stack_slot_offset(0));
|
||||
int type_base = in_bytes(ParametersTypeData::type_offset(0));
|
||||
Address::ScaleFactor per_arg_scale = Address::times(DataLayout::cell_size);
|
||||
Address arg_off(mdp, tmp1, per_arg_scale, off_base);
|
||||
Address arg_type(mdp, tmp1, per_arg_scale, type_base);
|
||||
|
||||
// load offset on the stack from the slot for this parameter
|
||||
movptr(tmp2, arg_off);
|
||||
negptr(tmp2);
|
||||
// read the parameter from the local area
|
||||
movptr(tmp2, Address(_locals_register, tmp2, Interpreter::stackElementScale()));
|
||||
|
||||
// profile the parameter
|
||||
profile_obj_type(tmp2, arg_type);
|
||||
|
||||
// go to next parameter
|
||||
decrement(tmp1, TypeStackSlotEntries::per_arg_count());
|
||||
jcc(Assembler::positive, loop);
|
||||
|
||||
bind(profile_continue);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
60
hotspot/src/cpu/x86/vm/interp_masm_x86.hpp
Normal file
60
hotspot/src/cpu/x86/vm/interp_masm_x86.hpp
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPU_X86_VM_INTERP_MASM_X86_HPP
|
||||
#define CPU_X86_VM_INTERP_MASM_X86_HPP
|
||||
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "interpreter/invocationCounter.hpp"
|
||||
#include "runtime/frame.hpp"
|
||||
|
||||
// This file specializes the assember with interpreter-specific macros
|
||||
|
||||
|
||||
class InterpreterMacroAssembler: public MacroAssembler {
|
||||
|
||||
#ifdef TARGET_ARCH_MODEL_x86_32
|
||||
# include "interp_masm_x86_32.hpp"
|
||||
#endif
|
||||
#ifdef TARGET_ARCH_MODEL_x86_64
|
||||
# include "interp_masm_x86_64.hpp"
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
Register _locals_register; // register that contains the pointer to the locals
|
||||
Register _bcp_register; // register that contains the bcp
|
||||
|
||||
public:
|
||||
#ifndef CC_INTERP
|
||||
void profile_obj_type(Register obj, const Address& mdo_addr);
|
||||
void profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual);
|
||||
void profile_return_type(Register mdp, Register ret, Register tmp);
|
||||
void profile_parameters_type(Register mdp, Register tmp1, Register tmp2);
|
||||
#endif /* !CC_INTERP */
|
||||
|
||||
};
|
||||
|
||||
#endif // CPU_X86_VM_INTERP_MASM_X86_HPP
|
||||
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "interp_masm_x86_32.hpp"
|
||||
#include "interp_masm_x86.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "interpreter/interpreterRuntime.hpp"
|
||||
#include "oops/arrayOop.hpp"
|
||||
@ -1046,159 +1046,6 @@ void InterpreterMacroAssembler::profile_not_taken_branch(Register mdp) {
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
|
||||
Label update, next, none;
|
||||
|
||||
verify_oop(obj);
|
||||
|
||||
testptr(obj, obj);
|
||||
jccb(Assembler::notZero, update);
|
||||
orptr(mdo_addr, TypeEntries::null_seen);
|
||||
jmpb(next);
|
||||
|
||||
bind(update);
|
||||
load_klass(obj, obj);
|
||||
|
||||
xorptr(obj, mdo_addr);
|
||||
testptr(obj, TypeEntries::type_klass_mask);
|
||||
jccb(Assembler::zero, next); // klass seen before, nothing to
|
||||
// do. The unknown bit may have been
|
||||
// set already but no need to check.
|
||||
|
||||
testptr(obj, TypeEntries::type_unknown);
|
||||
jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
|
||||
|
||||
cmpptr(mdo_addr, 0);
|
||||
jccb(Assembler::equal, none);
|
||||
cmpptr(mdo_addr, TypeEntries::null_seen);
|
||||
jccb(Assembler::equal, none);
|
||||
// There is a chance that the checks above (re-reading profiling
|
||||
// data from memory) fail if another thread has just set the
|
||||
// profiling to this obj's klass
|
||||
xorptr(obj, mdo_addr);
|
||||
testptr(obj, TypeEntries::type_klass_mask);
|
||||
jccb(Assembler::zero, next);
|
||||
|
||||
// different than before. Cannot keep accurate profile.
|
||||
orptr(mdo_addr, TypeEntries::type_unknown);
|
||||
jmpb(next);
|
||||
|
||||
bind(none);
|
||||
// first time here. Set profile type.
|
||||
movptr(mdo_addr, obj);
|
||||
|
||||
bind(next);
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual) {
|
||||
if (!ProfileInterpreter) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (MethodData::profile_arguments() || MethodData::profile_return()) {
|
||||
Label profile_continue;
|
||||
|
||||
test_method_data_pointer(mdp, profile_continue);
|
||||
|
||||
int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size());
|
||||
|
||||
cmpb(Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start), is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag);
|
||||
jcc(Assembler::notEqual, profile_continue);
|
||||
|
||||
if (MethodData::profile_arguments()) {
|
||||
Label done;
|
||||
int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset());
|
||||
addptr(mdp, off_to_args);
|
||||
|
||||
for (int i = 0; i < TypeProfileArgsLimit; i++) {
|
||||
if (i > 0 || MethodData::profile_return()) {
|
||||
// If return value type is profiled we may have no argument to profile
|
||||
movl(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
|
||||
subl(tmp, i*TypeStackSlotEntries::per_arg_count());
|
||||
cmpl(tmp, TypeStackSlotEntries::per_arg_count());
|
||||
jcc(Assembler::less, done);
|
||||
}
|
||||
movptr(tmp, Address(callee, Method::const_offset()));
|
||||
load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset()));
|
||||
// stack offset o (zero based) from the start of the argument
|
||||
// list, for n arguments translates into offset n - o - 1 from
|
||||
// the end of the argument list
|
||||
subl(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args));
|
||||
subl(tmp, 1);
|
||||
Address arg_addr = argument_address(tmp);
|
||||
movptr(tmp, arg_addr);
|
||||
|
||||
Address mdo_arg_addr(mdp, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args);
|
||||
profile_obj_type(tmp, mdo_arg_addr);
|
||||
|
||||
int to_add = in_bytes(TypeStackSlotEntries::per_arg_size());
|
||||
addptr(mdp, to_add);
|
||||
off_to_args += to_add;
|
||||
}
|
||||
|
||||
if (MethodData::profile_return()) {
|
||||
movl(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
|
||||
subl(tmp, TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count());
|
||||
}
|
||||
|
||||
bind(done);
|
||||
|
||||
if (MethodData::profile_return()) {
|
||||
// We're right after the type profile for the last
|
||||
// argument. tmp is the number of cell left in the
|
||||
// CallTypeData/VirtualCallTypeData to reach its end. Non null
|
||||
// if there's a return to profile.
|
||||
assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type");
|
||||
shll(tmp, exact_log2(DataLayout::cell_size));
|
||||
addptr(mdp, tmp);
|
||||
}
|
||||
movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp);
|
||||
} else {
|
||||
assert(MethodData::profile_return(), "either profile call args or call ret");
|
||||
update_mdp_by_constant(mdp, in_bytes(ReturnTypeEntry::size()));
|
||||
}
|
||||
|
||||
// mdp points right after the end of the
|
||||
// CallTypeData/VirtualCallTypeData, right after the cells for the
|
||||
// return value type if there's one
|
||||
|
||||
bind(profile_continue);
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::profile_return_type(Register mdp, Register ret, Register tmp) {
|
||||
assert_different_registers(mdp, ret, tmp, rsi);
|
||||
if (ProfileInterpreter && MethodData::profile_return()) {
|
||||
Label profile_continue, done;
|
||||
|
||||
test_method_data_pointer(mdp, profile_continue);
|
||||
|
||||
if (MethodData::profile_return_jsr292_only()) {
|
||||
// If we don't profile all invoke bytecodes we must make sure
|
||||
// it's a bytecode we indeed profile. We can't go back to the
|
||||
// begining of the ProfileData we intend to update to check its
|
||||
// type because we're right after it and we don't known its
|
||||
// length
|
||||
Label do_profile;
|
||||
cmpb(Address(rsi, 0), Bytecodes::_invokedynamic);
|
||||
jcc(Assembler::equal, do_profile);
|
||||
cmpb(Address(rsi, 0), Bytecodes::_invokehandle);
|
||||
jcc(Assembler::equal, do_profile);
|
||||
get_method(tmp);
|
||||
cmpb(Address(tmp, Method::intrinsic_id_offset_in_bytes()), vmIntrinsics::_compiledLambdaForm);
|
||||
jcc(Assembler::notEqual, profile_continue);
|
||||
|
||||
bind(do_profile);
|
||||
}
|
||||
|
||||
Address mdo_ret_addr(mdp, -in_bytes(ReturnTypeEntry::size()));
|
||||
mov(tmp, ret);
|
||||
profile_obj_type(tmp, mdo_ret_addr);
|
||||
|
||||
bind(profile_continue);
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::profile_call(Register mdp) {
|
||||
if (ProfileInterpreter) {
|
||||
Label profile_continue;
|
||||
|
||||
@ -22,18 +22,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPU_X86_VM_INTERP_MASM_X86_32_HPP
|
||||
#define CPU_X86_VM_INTERP_MASM_X86_32_HPP
|
||||
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "interpreter/invocationCounter.hpp"
|
||||
#include "runtime/frame.hpp"
|
||||
|
||||
// This file specializes the assember with interpreter-specific macros
|
||||
|
||||
|
||||
class InterpreterMacroAssembler: public MacroAssembler {
|
||||
#ifndef CC_INTERP
|
||||
protected:
|
||||
// Interpreter specific version of call_VM_base
|
||||
@ -59,7 +47,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
#endif /* CC_INTERP */
|
||||
|
||||
public:
|
||||
InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {}
|
||||
InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code), _locals_register(rdi), _bcp_register(rsi) {}
|
||||
|
||||
void load_earlyret_value(TosState state);
|
||||
|
||||
@ -215,9 +203,6 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
|
||||
void profile_taken_branch(Register mdp, Register bumped_count);
|
||||
void profile_not_taken_branch(Register mdp);
|
||||
void profile_obj_type(Register obj, const Address& mdo_addr);
|
||||
void profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual);
|
||||
void profile_return_type(Register mdp, Register ret, Register tmp);
|
||||
void profile_call(Register mdp);
|
||||
void profile_final_call(Register mdp);
|
||||
void profile_virtual_call(Register receiver, Register mdp, Register scratch2,
|
||||
@ -236,7 +221,3 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
// support for jvmti
|
||||
void notify_method_entry();
|
||||
void notify_method_exit(TosState state, NotifyMethodExitMode mode);
|
||||
|
||||
};
|
||||
|
||||
#endif // CPU_X86_VM_INTERP_MASM_X86_32_HPP
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "interp_masm_x86_64.hpp"
|
||||
#include "interp_masm_x86.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "interpreter/interpreterRuntime.hpp"
|
||||
#include "oops/arrayOop.hpp"
|
||||
@ -1067,160 +1067,6 @@ void InterpreterMacroAssembler::profile_not_taken_branch(Register mdp) {
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
|
||||
Label update, next, none;
|
||||
|
||||
verify_oop(obj);
|
||||
|
||||
testptr(obj, obj);
|
||||
jccb(Assembler::notZero, update);
|
||||
orptr(mdo_addr, TypeEntries::null_seen);
|
||||
jmpb(next);
|
||||
|
||||
bind(update);
|
||||
load_klass(obj, obj);
|
||||
|
||||
xorptr(obj, mdo_addr);
|
||||
testptr(obj, TypeEntries::type_klass_mask);
|
||||
jccb(Assembler::zero, next); // klass seen before, nothing to
|
||||
// do. The unknown bit may have been
|
||||
// set already but no need to check.
|
||||
|
||||
testptr(obj, TypeEntries::type_unknown);
|
||||
jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
|
||||
|
||||
// There is a chance that by the time we do these checks (re-reading
|
||||
// profiling data from memory) another thread has set the profling
|
||||
// to this obj's klass and we set the profiling as unknow
|
||||
// erroneously
|
||||
cmpptr(mdo_addr, 0);
|
||||
jccb(Assembler::equal, none);
|
||||
cmpptr(mdo_addr, TypeEntries::null_seen);
|
||||
jccb(Assembler::equal, none);
|
||||
// There is a chance that the checks above (re-reading profiling
|
||||
// data from memory) fail if another thread has just set the
|
||||
// profiling to this obj's klass
|
||||
xorptr(obj, mdo_addr);
|
||||
testptr(obj, TypeEntries::type_klass_mask);
|
||||
jccb(Assembler::zero, next);
|
||||
|
||||
// different than before. Cannot keep accurate profile.
|
||||
orptr(mdo_addr, TypeEntries::type_unknown);
|
||||
jmpb(next);
|
||||
|
||||
bind(none);
|
||||
// first time here. Set profile type.
|
||||
movptr(mdo_addr, obj);
|
||||
|
||||
bind(next);
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual) {
|
||||
if (!ProfileInterpreter) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (MethodData::profile_arguments() || MethodData::profile_return()) {
|
||||
Label profile_continue;
|
||||
|
||||
test_method_data_pointer(mdp, profile_continue);
|
||||
|
||||
int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size());
|
||||
|
||||
cmpb(Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start), is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag);
|
||||
jcc(Assembler::notEqual, profile_continue);
|
||||
|
||||
if (MethodData::profile_arguments()) {
|
||||
Label done;
|
||||
int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset());
|
||||
addptr(mdp, off_to_args);
|
||||
|
||||
for (int i = 0; i < TypeProfileArgsLimit; i++) {
|
||||
if (i > 0 || MethodData::profile_return()) {
|
||||
// If return value type is profiled we may have no argument to profile
|
||||
movq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
|
||||
subl(tmp, i*TypeStackSlotEntries::per_arg_count());
|
||||
cmpl(tmp, TypeStackSlotEntries::per_arg_count());
|
||||
jcc(Assembler::less, done);
|
||||
}
|
||||
movptr(tmp, Address(callee, Method::const_offset()));
|
||||
load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset()));
|
||||
subq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args));
|
||||
subl(tmp, 1);
|
||||
Address arg_addr = argument_address(tmp);
|
||||
movptr(tmp, arg_addr);
|
||||
|
||||
Address mdo_arg_addr(mdp, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args);
|
||||
profile_obj_type(tmp, mdo_arg_addr);
|
||||
|
||||
int to_add = in_bytes(TypeStackSlotEntries::per_arg_size());
|
||||
addptr(mdp, to_add);
|
||||
off_to_args += to_add;
|
||||
}
|
||||
|
||||
if (MethodData::profile_return()) {
|
||||
movq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
|
||||
subl(tmp, TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count());
|
||||
}
|
||||
|
||||
bind(done);
|
||||
|
||||
if (MethodData::profile_return()) {
|
||||
// We're right after the type profile for the last
|
||||
// argument. tmp is the number of cell left in the
|
||||
// CallTypeData/VirtualCallTypeData to reach its end. Non null
|
||||
// if there's a return to profile.
|
||||
assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type");
|
||||
shll(tmp, exact_log2(DataLayout::cell_size));
|
||||
addptr(mdp, tmp);
|
||||
}
|
||||
movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp);
|
||||
} else {
|
||||
assert(MethodData::profile_return(), "either profile call args or call ret");
|
||||
update_mdp_by_constant(mdp, in_bytes(ReturnTypeEntry::size()));
|
||||
}
|
||||
|
||||
// mdp points right after the end of the
|
||||
// CallTypeData/VirtualCallTypeData, right after the cells for the
|
||||
// return value type if there's one
|
||||
|
||||
bind(profile_continue);
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::profile_return_type(Register mdp, Register ret, Register tmp) {
|
||||
assert_different_registers(mdp, ret, tmp, r13);
|
||||
if (ProfileInterpreter && MethodData::profile_return()) {
|
||||
Label profile_continue, done;
|
||||
|
||||
test_method_data_pointer(mdp, profile_continue);
|
||||
|
||||
if (MethodData::profile_return_jsr292_only()) {
|
||||
// If we don't profile all invoke bytecodes we must make sure
|
||||
// it's a bytecode we indeed profile. We can't go back to the
|
||||
// begining of the ProfileData we intend to update to check its
|
||||
// type because we're right after it and we don't known its
|
||||
// length
|
||||
Label do_profile;
|
||||
cmpb(Address(r13, 0), Bytecodes::_invokedynamic);
|
||||
jcc(Assembler::equal, do_profile);
|
||||
cmpb(Address(r13, 0), Bytecodes::_invokehandle);
|
||||
jcc(Assembler::equal, do_profile);
|
||||
get_method(tmp);
|
||||
cmpb(Address(tmp, Method::intrinsic_id_offset_in_bytes()), vmIntrinsics::_compiledLambdaForm);
|
||||
jcc(Assembler::notEqual, profile_continue);
|
||||
|
||||
bind(do_profile);
|
||||
}
|
||||
|
||||
Address mdo_ret_addr(mdp, -in_bytes(ReturnTypeEntry::size()));
|
||||
mov(tmp, ret);
|
||||
profile_obj_type(tmp, mdo_ret_addr);
|
||||
|
||||
bind(profile_continue);
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::profile_call(Register mdp) {
|
||||
if (ProfileInterpreter) {
|
||||
Label profile_continue;
|
||||
|
||||
@ -22,18 +22,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPU_X86_VM_INTERP_MASM_X86_64_HPP
|
||||
#define CPU_X86_VM_INTERP_MASM_X86_64_HPP
|
||||
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "interpreter/invocationCounter.hpp"
|
||||
#include "runtime/frame.hpp"
|
||||
|
||||
// This file specializes the assember with interpreter-specific macros
|
||||
|
||||
|
||||
class InterpreterMacroAssembler: public MacroAssembler {
|
||||
#ifndef CC_INTERP
|
||||
protected:
|
||||
// Interpreter specific version of call_VM_base
|
||||
@ -55,7 +43,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
#endif // CC_INTERP
|
||||
|
||||
public:
|
||||
InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {}
|
||||
InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code), _locals_register(r14), _bcp_register(r13) {}
|
||||
|
||||
void load_earlyret_value(TosState state);
|
||||
|
||||
@ -224,9 +212,6 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
|
||||
void profile_taken_branch(Register mdp, Register bumped_count);
|
||||
void profile_not_taken_branch(Register mdp);
|
||||
void profile_obj_type(Register obj, const Address& mdo_addr);
|
||||
void profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual);
|
||||
void profile_return_type(Register mdp, Register ret, Register tmp);
|
||||
void profile_call(Register mdp);
|
||||
void profile_final_call(Register mdp);
|
||||
void profile_virtual_call(Register receiver, Register mdp,
|
||||
@ -253,6 +238,3 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
// support for jvmti/dtrace
|
||||
void notify_method_entry();
|
||||
void notify_method_exit(TosState state, NotifyMethodExitMode mode);
|
||||
};
|
||||
|
||||
#endif // CPU_X86_VM_INTERP_MASM_X86_64_HPP
|
||||
|
||||
@ -5049,25 +5049,32 @@ void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) {
|
||||
}
|
||||
|
||||
void MacroAssembler::encode_klass_not_null(Register r) {
|
||||
assert(Universe::narrow_klass_base() != NULL, "Base should be initialized");
|
||||
// Use r12 as a scratch register in which to temporarily load the narrow_klass_base.
|
||||
assert(r != r12_heapbase, "Encoding a klass in r12");
|
||||
mov64(r12_heapbase, (int64_t)Universe::narrow_klass_base());
|
||||
subq(r, r12_heapbase);
|
||||
if (Universe::narrow_klass_base() != NULL) {
|
||||
// Use r12 as a scratch register in which to temporarily load the narrow_klass_base.
|
||||
assert(r != r12_heapbase, "Encoding a klass in r12");
|
||||
mov64(r12_heapbase, (int64_t)Universe::narrow_klass_base());
|
||||
subq(r, r12_heapbase);
|
||||
}
|
||||
if (Universe::narrow_klass_shift() != 0) {
|
||||
assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
|
||||
shrq(r, LogKlassAlignmentInBytes);
|
||||
}
|
||||
reinit_heapbase();
|
||||
if (Universe::narrow_klass_base() != NULL) {
|
||||
reinit_heapbase();
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
|
||||
if (dst == src) {
|
||||
encode_klass_not_null(src);
|
||||
} else {
|
||||
mov64(dst, (int64_t)Universe::narrow_klass_base());
|
||||
negq(dst);
|
||||
addq(dst, src);
|
||||
if (Universe::narrow_klass_base() != NULL) {
|
||||
mov64(dst, (int64_t)Universe::narrow_klass_base());
|
||||
negq(dst);
|
||||
addq(dst, src);
|
||||
} else {
|
||||
movptr(dst, src);
|
||||
}
|
||||
if (Universe::narrow_klass_shift() != 0) {
|
||||
assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
|
||||
shrq(dst, LogKlassAlignmentInBytes);
|
||||
@ -5081,15 +5088,19 @@ void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
|
||||
// generate change, then this method needs to be updated.
|
||||
int MacroAssembler::instr_size_for_decode_klass_not_null() {
|
||||
assert (UseCompressedClassPointers, "only for compressed klass ptrs");
|
||||
// mov64 + addq + shlq? + mov64 (for reinit_heapbase()).
|
||||
return (Universe::narrow_klass_shift() == 0 ? 20 : 24);
|
||||
if (Universe::narrow_klass_base() != NULL) {
|
||||
// mov64 + addq + shlq? + mov64 (for reinit_heapbase()).
|
||||
return (Universe::narrow_klass_shift() == 0 ? 20 : 24);
|
||||
} else {
|
||||
// longest load decode klass function, mov64, leaq
|
||||
return 16;
|
||||
}
|
||||
}
|
||||
|
||||
// !!! If the instructions that get generated here change then function
|
||||
// instr_size_for_decode_klass_not_null() needs to get updated.
|
||||
void MacroAssembler::decode_klass_not_null(Register r) {
|
||||
// Note: it will change flags
|
||||
assert(Universe::narrow_klass_base() != NULL, "Base should be initialized");
|
||||
assert (UseCompressedClassPointers, "should only be used for compressed headers");
|
||||
assert(r != r12_heapbase, "Decoding a klass in r12");
|
||||
// Cannot assert, unverified entry point counts instructions (see .ad file)
|
||||
@ -5100,14 +5111,15 @@ void MacroAssembler::decode_klass_not_null(Register r) {
|
||||
shlq(r, LogKlassAlignmentInBytes);
|
||||
}
|
||||
// Use r12 as a scratch register in which to temporarily load the narrow_klass_base.
|
||||
mov64(r12_heapbase, (int64_t)Universe::narrow_klass_base());
|
||||
addq(r, r12_heapbase);
|
||||
reinit_heapbase();
|
||||
if (Universe::narrow_klass_base() != NULL) {
|
||||
mov64(r12_heapbase, (int64_t)Universe::narrow_klass_base());
|
||||
addq(r, r12_heapbase);
|
||||
reinit_heapbase();
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
|
||||
// Note: it will change flags
|
||||
assert(Universe::narrow_klass_base() != NULL, "Base should be initialized");
|
||||
assert (UseCompressedClassPointers, "should only be used for compressed headers");
|
||||
if (dst == src) {
|
||||
decode_klass_not_null(dst);
|
||||
@ -5115,7 +5127,6 @@ void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
|
||||
// Cannot assert, unverified entry point counts instructions (see .ad file)
|
||||
// vtableStubs also counts instructions in pd_code_size_limit.
|
||||
// Also do not verify_oop as this is called by verify_oop.
|
||||
|
||||
mov64(dst, (int64_t)Universe::narrow_klass_base());
|
||||
if (Universe::narrow_klass_shift() != 0) {
|
||||
assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
|
||||
|
||||
@ -26,11 +26,8 @@
|
||||
#include "asm/assembler.hpp"
|
||||
#include "asm/register.hpp"
|
||||
#include "register_x86.hpp"
|
||||
#ifdef TARGET_ARCH_MODEL_x86_32
|
||||
# include "interp_masm_x86_32.hpp"
|
||||
#endif
|
||||
#ifdef TARGET_ARCH_MODEL_x86_64
|
||||
# include "interp_masm_x86_64.hpp"
|
||||
#ifdef TARGET_ARCH_x86
|
||||
# include "interp_masm_x86.hpp"
|
||||
#endif
|
||||
|
||||
REGISTER_DEFINITION(Register, noreg);
|
||||
|
||||
@ -34,9 +34,9 @@
|
||||
// Run with +PrintInterpreter to get the VM to print out the size.
|
||||
// Max size with JVMTI
|
||||
#ifdef AMD64
|
||||
const static int InterpreterCodeSize = 208 * 1024;
|
||||
const static int InterpreterCodeSize = 256 * 1024;
|
||||
#else
|
||||
const static int InterpreterCodeSize = 176 * 1024;
|
||||
const static int InterpreterCodeSize = 224 * 1024;
|
||||
#endif // AMD64
|
||||
|
||||
#endif // CPU_X86_VM_TEMPLATEINTERPRETER_X86_HPP
|
||||
|
||||
@ -150,13 +150,12 @@ address TemplateInterpreterGenerator::generate_continuation_for(TosState state)
|
||||
}
|
||||
|
||||
|
||||
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) {
|
||||
TosState incoming_state = state;
|
||||
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {
|
||||
address entry = __ pc();
|
||||
|
||||
#ifdef COMPILER2
|
||||
// The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases
|
||||
if ((incoming_state == ftos && UseSSE < 1) || (incoming_state == dtos && UseSSE < 2)) {
|
||||
if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) {
|
||||
for (int i = 1; i < 8; i++) {
|
||||
__ ffree(i);
|
||||
}
|
||||
@ -164,7 +163,7 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
||||
__ empty_FPU_stack();
|
||||
}
|
||||
#endif
|
||||
if ((incoming_state == ftos && UseSSE < 1) || (incoming_state == dtos && UseSSE < 2)) {
|
||||
if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) {
|
||||
__ MacroAssembler::verify_FPU(1, "generate_return_entry_for compiled");
|
||||
} else {
|
||||
__ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled");
|
||||
@ -172,12 +171,12 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
||||
|
||||
// In SSE mode, interpreter returns FP results in xmm0 but they need
|
||||
// to end up back on the FPU so it can operate on them.
|
||||
if (incoming_state == ftos && UseSSE >= 1) {
|
||||
if (state == ftos && UseSSE >= 1) {
|
||||
__ subptr(rsp, wordSize);
|
||||
__ movflt(Address(rsp, 0), xmm0);
|
||||
__ fld_s(Address(rsp, 0));
|
||||
__ addptr(rsp, wordSize);
|
||||
} else if (incoming_state == dtos && UseSSE >= 2) {
|
||||
} else if (state == dtos && UseSSE >= 2) {
|
||||
__ subptr(rsp, 2*wordSize);
|
||||
__ movdbl(Address(rsp, 0), xmm0);
|
||||
__ fld_d(Address(rsp, 0));
|
||||
@ -194,32 +193,21 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
||||
__ restore_bcp();
|
||||
__ restore_locals();
|
||||
|
||||
if (incoming_state == atos) {
|
||||
if (state == atos) {
|
||||
Register mdp = rbx;
|
||||
Register tmp = rcx;
|
||||
__ profile_return_type(mdp, rax, tmp);
|
||||
}
|
||||
|
||||
Label L_got_cache, L_giant_index;
|
||||
if (EnableInvokeDynamic) {
|
||||
__ cmpb(Address(rsi, 0), Bytecodes::_invokedynamic);
|
||||
__ jcc(Assembler::equal, L_giant_index);
|
||||
}
|
||||
__ get_cache_and_index_at_bcp(rbx, rcx, 1, sizeof(u2));
|
||||
__ bind(L_got_cache);
|
||||
__ movl(rbx, Address(rbx, rcx,
|
||||
Address::times_ptr, ConstantPoolCache::base_offset() +
|
||||
ConstantPoolCacheEntry::flags_offset()));
|
||||
__ andptr(rbx, 0xFF);
|
||||
__ lea(rsp, Address(rsp, rbx, Interpreter::stackElementScale()));
|
||||
__ dispatch_next(state, step);
|
||||
const Register cache = rbx;
|
||||
const Register index = rcx;
|
||||
__ get_cache_and_index_at_bcp(cache, index, 1, index_size);
|
||||
|
||||
// out of the main line of code...
|
||||
if (EnableInvokeDynamic) {
|
||||
__ bind(L_giant_index);
|
||||
__ get_cache_and_index_at_bcp(rbx, rcx, 1, sizeof(u4));
|
||||
__ jmp(L_got_cache);
|
||||
}
|
||||
const Register flags = cache;
|
||||
__ movl(flags, Address(cache, index, Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
|
||||
__ andl(flags, ConstantPoolCacheEntry::parameter_size_mask);
|
||||
__ lea(rsp, Address(rsp, flags, Interpreter::stackElementScale()));
|
||||
__ dispatch_next(state, step);
|
||||
|
||||
return entry;
|
||||
}
|
||||
@ -1490,6 +1478,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
|
||||
in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()));
|
||||
__ movbool(do_not_unlock_if_synchronized, true);
|
||||
|
||||
__ profile_parameters_type(rax, rcx, rdx);
|
||||
// increment invocation count & check for overflow
|
||||
Label invocation_counter_overflow;
|
||||
Label profile_method;
|
||||
|
||||
@ -166,7 +166,7 @@ address TemplateInterpreterGenerator::generate_continuation_for(TosState state)
|
||||
}
|
||||
|
||||
|
||||
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) {
|
||||
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {
|
||||
address entry = __ pc();
|
||||
|
||||
// Restore stack bottom in case i2c adjusted stack
|
||||
@ -183,27 +183,15 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
||||
__ profile_return_type(mdp, rax, tmp);
|
||||
}
|
||||
|
||||
Label L_got_cache, L_giant_index;
|
||||
if (EnableInvokeDynamic) {
|
||||
__ cmpb(Address(r13, 0), Bytecodes::_invokedynamic);
|
||||
__ jcc(Assembler::equal, L_giant_index);
|
||||
}
|
||||
__ get_cache_and_index_at_bcp(rbx, rcx, 1, sizeof(u2));
|
||||
__ bind(L_got_cache);
|
||||
__ movl(rbx, Address(rbx, rcx,
|
||||
Address::times_ptr,
|
||||
in_bytes(ConstantPoolCache::base_offset()) +
|
||||
3 * wordSize));
|
||||
__ andl(rbx, 0xFF);
|
||||
__ lea(rsp, Address(rsp, rbx, Address::times_8));
|
||||
__ dispatch_next(state, step);
|
||||
const Register cache = rbx;
|
||||
const Register index = rcx;
|
||||
__ get_cache_and_index_at_bcp(cache, index, 1, index_size);
|
||||
|
||||
// out of the main line of code...
|
||||
if (EnableInvokeDynamic) {
|
||||
__ bind(L_giant_index);
|
||||
__ get_cache_and_index_at_bcp(rbx, rcx, 1, sizeof(u4));
|
||||
__ jmp(L_got_cache);
|
||||
}
|
||||
const Register flags = cache;
|
||||
__ movl(flags, Address(cache, index, Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
|
||||
__ andl(flags, ConstantPoolCacheEntry::parameter_size_mask);
|
||||
__ lea(rsp, Address(rsp, flags, Interpreter::stackElementScale()));
|
||||
__ dispatch_next(state, step);
|
||||
|
||||
return entry;
|
||||
}
|
||||
@ -1497,6 +1485,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
|
||||
in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()));
|
||||
__ movbool(do_not_unlock_if_synchronized, true);
|
||||
|
||||
__ profile_parameters_type(rax, rcx, rdx);
|
||||
// increment invocation count & check for overflow
|
||||
Label invocation_counter_overflow;
|
||||
Label profile_method;
|
||||
|
||||
@ -2925,9 +2925,7 @@ void TemplateTable::prepare_invoke(int byte_no,
|
||||
ConstantPoolCacheEntry::verify_tos_state_shift();
|
||||
// load return address
|
||||
{
|
||||
const address table_addr = (is_invokeinterface || is_invokedynamic) ?
|
||||
(address)Interpreter::return_5_addrs_by_index_table() :
|
||||
(address)Interpreter::return_3_addrs_by_index_table();
|
||||
const address table_addr = (address) Interpreter::invoke_return_entry_table_for(code);
|
||||
ExternalAddress table(table_addr);
|
||||
__ movptr(flags, ArrayAddress(table, Address(noreg, flags, Address::times_ptr)));
|
||||
}
|
||||
|
||||
@ -2980,9 +2980,7 @@ void TemplateTable::prepare_invoke(int byte_no,
|
||||
ConstantPoolCacheEntry::verify_tos_state_shift();
|
||||
// load return address
|
||||
{
|
||||
const address table_addr = (is_invokeinterface || is_invokedynamic) ?
|
||||
(address)Interpreter::return_5_addrs_by_index_table() :
|
||||
(address)Interpreter::return_3_addrs_by_index_table();
|
||||
const address table_addr = (address) Interpreter::invoke_return_entry_table_for(code);
|
||||
ExternalAddress table(table_addr);
|
||||
__ lea(rscratch1, table);
|
||||
__ movptr(flags, Address(rscratch1, flags, Address::times_ptr));
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "interp_masm_x86_32.hpp"
|
||||
#include "interp_masm_x86.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/klassVtable.hpp"
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "interp_masm_x86_64.hpp"
|
||||
#include "interp_masm_x86.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/klassVtable.hpp"
|
||||
|
||||
@ -1538,6 +1538,11 @@ const RegMask Matcher::mathExactI_result_proj_mask() {
|
||||
return EAX_REG_mask();
|
||||
}
|
||||
|
||||
const RegMask Matcher::mathExactL_result_proj_mask() {
|
||||
ShouldNotReachHere();
|
||||
return RegMask();
|
||||
}
|
||||
|
||||
const RegMask Matcher::mathExactI_flags_proj_mask() {
|
||||
return INT_FLAGS_mask();
|
||||
}
|
||||
@ -7519,7 +7524,7 @@ instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{
|
||||
//----------Arithmetic Instructions--------------------------------------------
|
||||
//----------Addition Instructions----------------------------------------------
|
||||
|
||||
instruct addExactI_rReg(eAXRegI dst, rRegI src, eFlagsReg cr)
|
||||
instruct addExactI_eReg(eAXRegI dst, rRegI src, eFlagsReg cr)
|
||||
%{
|
||||
match(AddExactI dst src);
|
||||
effect(DEF cr);
|
||||
@ -7531,7 +7536,7 @@ instruct addExactI_rReg(eAXRegI dst, rRegI src, eFlagsReg cr)
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct addExactI_rReg_imm(eAXRegI dst, immI src, eFlagsReg cr)
|
||||
instruct addExactI_eReg_imm(eAXRegI dst, immI src, eFlagsReg cr)
|
||||
%{
|
||||
match(AddExactI dst src);
|
||||
effect(DEF cr);
|
||||
@ -7543,6 +7548,20 @@ instruct addExactI_rReg_imm(eAXRegI dst, immI src, eFlagsReg cr)
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct addExactI_eReg_mem(eAXRegI dst, memory src, eFlagsReg cr)
|
||||
%{
|
||||
match(AddExactI dst (LoadI src));
|
||||
effect(DEF cr);
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "ADD $dst,$src\t# addExact int" %}
|
||||
ins_encode %{
|
||||
__ addl($dst$$Register, $src$$Address);
|
||||
%}
|
||||
ins_pipe( ialu_reg_mem );
|
||||
%}
|
||||
|
||||
|
||||
// Integer Addition Instructions
|
||||
instruct addI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
|
||||
match(Set dst (AddI dst src));
|
||||
@ -7851,6 +7870,44 @@ instruct xchgP( memory mem, pRegP newval) %{
|
||||
%}
|
||||
|
||||
//----------Subtraction Instructions-------------------------------------------
|
||||
|
||||
instruct subExactI_eReg(eAXRegI dst, rRegI src, eFlagsReg cr)
|
||||
%{
|
||||
match(SubExactI dst src);
|
||||
effect(DEF cr);
|
||||
|
||||
format %{ "SUB $dst, $src\t# subExact int" %}
|
||||
ins_encode %{
|
||||
__ subl($dst$$Register, $src$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct subExactI_eReg_imm(eAXRegI dst, immI src, eFlagsReg cr)
|
||||
%{
|
||||
match(SubExactI dst src);
|
||||
effect(DEF cr);
|
||||
|
||||
format %{ "SUB $dst, $src\t# subExact int" %}
|
||||
ins_encode %{
|
||||
__ subl($dst$$Register, $src$$constant);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct subExactI_eReg_mem(eAXRegI dst, memory src, eFlagsReg cr)
|
||||
%{
|
||||
match(SubExactI dst (LoadI src));
|
||||
effect(DEF cr);
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "SUB $dst,$src\t# subExact int" %}
|
||||
ins_encode %{
|
||||
__ subl($dst$$Register, $src$$Address);
|
||||
%}
|
||||
ins_pipe( ialu_reg_mem );
|
||||
%}
|
||||
|
||||
// Integer Subtraction Instructions
|
||||
instruct subI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
|
||||
match(Set dst (SubI dst src));
|
||||
@ -7919,6 +7976,16 @@ instruct negI_eReg(rRegI dst, immI0 zero, eFlagsReg cr) %{
|
||||
ins_pipe( ialu_reg );
|
||||
%}
|
||||
|
||||
instruct negExactI_eReg(eAXRegI dst, eFlagsReg cr) %{
|
||||
match(NegExactI dst);
|
||||
effect(DEF cr);
|
||||
|
||||
format %{ "NEG $dst\t# negExact int"%}
|
||||
ins_encode %{
|
||||
__ negl($dst$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
//----------Multiplication/Division Instructions-------------------------------
|
||||
// Integer Multiplication Instructions
|
||||
@ -8131,6 +8198,46 @@ instruct mulL_eReg_con(eADXRegL dst, immL_127 src, rRegI tmp, eFlagsReg cr) %{
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct mulExactI_eReg(eAXRegI dst, rRegI src, eFlagsReg cr)
|
||||
%{
|
||||
match(MulExactI dst src);
|
||||
effect(DEF cr);
|
||||
|
||||
ins_cost(300);
|
||||
format %{ "IMUL $dst, $src\t# mulExact int" %}
|
||||
ins_encode %{
|
||||
__ imull($dst$$Register, $src$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg_alu0);
|
||||
%}
|
||||
|
||||
instruct mulExactI_eReg_imm(eAXRegI dst, rRegI src, immI imm, eFlagsReg cr)
|
||||
%{
|
||||
match(MulExactI src imm);
|
||||
effect(DEF cr);
|
||||
|
||||
ins_cost(300);
|
||||
format %{ "IMUL $dst, $src, $imm\t# mulExact int" %}
|
||||
ins_encode %{
|
||||
__ imull($dst$$Register, $src$$Register, $imm$$constant);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg_alu0);
|
||||
%}
|
||||
|
||||
instruct mulExactI_eReg_mem(eAXRegI dst, memory src, eFlagsReg cr)
|
||||
%{
|
||||
match(MulExactI dst (LoadI src));
|
||||
effect(DEF cr);
|
||||
|
||||
ins_cost(350);
|
||||
format %{ "IMUL $dst, $src\t# mulExact int" %}
|
||||
ins_encode %{
|
||||
__ imull($dst$$Register, $src$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem_alu0);
|
||||
%}
|
||||
|
||||
|
||||
// Integer DIV with Register
|
||||
instruct divI_eReg(eAXRegI rax, eDXRegI rdx, eCXRegI div, eFlagsReg cr) %{
|
||||
match(Set rax (DivI rax div));
|
||||
|
||||
@ -1653,6 +1653,10 @@ const RegMask Matcher::mathExactI_result_proj_mask() {
|
||||
return INT_RAX_REG_mask();
|
||||
}
|
||||
|
||||
const RegMask Matcher::mathExactL_result_proj_mask() {
|
||||
return LONG_RAX_REG_mask();
|
||||
}
|
||||
|
||||
const RegMask Matcher::mathExactI_flags_proj_mask() {
|
||||
return INT_FLAGS_mask();
|
||||
}
|
||||
@ -6962,6 +6966,58 @@ instruct addExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr)
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct addExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
|
||||
%{
|
||||
match(AddExactI dst (LoadI src));
|
||||
effect(DEF cr);
|
||||
|
||||
ins_cost(125); // XXX
|
||||
format %{ "addl $dst, $src\t# addExact int" %}
|
||||
ins_encode %{
|
||||
__ addl($dst$$Register, $src$$Address);
|
||||
%}
|
||||
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
instruct addExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr)
|
||||
%{
|
||||
match(AddExactL dst src);
|
||||
effect(DEF cr);
|
||||
|
||||
format %{ "addq $dst, $src\t# addExact long" %}
|
||||
ins_encode %{
|
||||
__ addq($dst$$Register, $src$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct addExactL_rReg_imm(rax_RegL dst, immL32 src, rFlagsReg cr)
|
||||
%{
|
||||
match(AddExactL dst src);
|
||||
effect(DEF cr);
|
||||
|
||||
format %{ "addq $dst, $src\t# addExact long" %}
|
||||
ins_encode %{
|
||||
__ addq($dst$$Register, $src$$constant);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct addExactL_rReg_mem(rax_RegL dst, memory src, rFlagsReg cr)
|
||||
%{
|
||||
match(AddExactL dst (LoadL src));
|
||||
effect(DEF cr);
|
||||
|
||||
ins_cost(125); // XXX
|
||||
format %{ "addq $dst, $src\t# addExact long" %}
|
||||
ins_encode %{
|
||||
__ addq($dst$$Register, $src$$Address);
|
||||
%}
|
||||
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
|
||||
%{
|
||||
match(Set dst (AddI dst src));
|
||||
@ -7574,6 +7630,80 @@ instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr)
|
||||
ins_pipe(ialu_mem_imm);
|
||||
%}
|
||||
|
||||
instruct subExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr)
|
||||
%{
|
||||
match(SubExactI dst src);
|
||||
effect(DEF cr);
|
||||
|
||||
format %{ "subl $dst, $src\t# subExact int" %}
|
||||
ins_encode %{
|
||||
__ subl($dst$$Register, $src$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct subExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr)
|
||||
%{
|
||||
match(SubExactI dst src);
|
||||
effect(DEF cr);
|
||||
|
||||
format %{ "subl $dst, $src\t# subExact int" %}
|
||||
ins_encode %{
|
||||
__ subl($dst$$Register, $src$$constant);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct subExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
|
||||
%{
|
||||
match(SubExactI dst (LoadI src));
|
||||
effect(DEF cr);
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "subl $dst, $src\t# subExact int" %}
|
||||
ins_encode %{
|
||||
__ subl($dst$$Register, $src$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
instruct subExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr)
|
||||
%{
|
||||
match(SubExactL dst src);
|
||||
effect(DEF cr);
|
||||
|
||||
format %{ "subq $dst, $src\t# subExact long" %}
|
||||
ins_encode %{
|
||||
__ subq($dst$$Register, $src$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct subExactL_rReg_imm(rax_RegL dst, immL32 src, rFlagsReg cr)
|
||||
%{
|
||||
match(SubExactL dst (LoadL src));
|
||||
effect(DEF cr);
|
||||
|
||||
format %{ "subq $dst, $src\t# subExact long" %}
|
||||
ins_encode %{
|
||||
__ subq($dst$$Register, $src$$constant);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct subExactL_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
|
||||
%{
|
||||
match(SubExactI dst src);
|
||||
effect(DEF cr);
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "subq $dst, $src\t# subExact long" %}
|
||||
ins_encode %{
|
||||
__ subq($dst$$Register, $src$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
|
||||
%{
|
||||
match(Set dst (SubL dst src));
|
||||
@ -7690,6 +7820,30 @@ instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr)
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct negExactI_rReg(rax_RegI dst, rFlagsReg cr)
|
||||
%{
|
||||
match(NegExactI dst);
|
||||
effect(KILL cr);
|
||||
|
||||
format %{ "negl $dst\t# negExact int" %}
|
||||
ins_encode %{
|
||||
__ negl($dst$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct negExactL_rReg(rax_RegL dst, rFlagsReg cr)
|
||||
%{
|
||||
match(NegExactL dst);
|
||||
effect(KILL cr);
|
||||
|
||||
format %{ "negq $dst\t# negExact long" %}
|
||||
ins_encode %{
|
||||
__ negq($dst$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
|
||||
//----------Multiplication/Division Instructions-------------------------------
|
||||
// Integer Multiplication Instructions
|
||||
@ -7807,6 +7961,86 @@ instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
|
||||
ins_pipe(ialu_reg_reg_alu0);
|
||||
%}
|
||||
|
||||
|
||||
instruct mulExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr)
|
||||
%{
|
||||
match(MulExactI dst src);
|
||||
effect(DEF cr);
|
||||
|
||||
ins_cost(300);
|
||||
format %{ "imull $dst, $src\t# mulExact int" %}
|
||||
ins_encode %{
|
||||
__ imull($dst$$Register, $src$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg_alu0);
|
||||
%}
|
||||
|
||||
|
||||
instruct mulExactI_rReg_imm(rax_RegI dst, rRegI src, immI imm, rFlagsReg cr)
|
||||
%{
|
||||
match(MulExactI src imm);
|
||||
effect(DEF cr);
|
||||
|
||||
ins_cost(300);
|
||||
format %{ "imull $dst, $src, $imm\t# mulExact int" %}
|
||||
ins_encode %{
|
||||
__ imull($dst$$Register, $src$$Register, $imm$$constant);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg_alu0);
|
||||
%}
|
||||
|
||||
instruct mulExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
|
||||
%{
|
||||
match(MulExactI dst (LoadI src));
|
||||
effect(DEF cr);
|
||||
|
||||
ins_cost(350);
|
||||
format %{ "imull $dst, $src\t# mulExact int" %}
|
||||
ins_encode %{
|
||||
__ imull($dst$$Register, $src$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem_alu0);
|
||||
%}
|
||||
|
||||
instruct mulExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr)
|
||||
%{
|
||||
match(MulExactL dst src);
|
||||
effect(DEF cr);
|
||||
|
||||
ins_cost(300);
|
||||
format %{ "imulq $dst, $src\t# mulExact long" %}
|
||||
ins_encode %{
|
||||
__ imulq($dst$$Register, $src$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg_alu0);
|
||||
%}
|
||||
|
||||
instruct mulExactL_rReg_imm(rax_RegL dst, rRegL src, immL32 imm, rFlagsReg cr)
|
||||
%{
|
||||
match(MulExactL src imm);
|
||||
effect(DEF cr);
|
||||
|
||||
ins_cost(300);
|
||||
format %{ "imulq $dst, $src, $imm\t# mulExact long" %}
|
||||
ins_encode %{
|
||||
__ imulq($dst$$Register, $src$$Register, $imm$$constant);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg_alu0);
|
||||
%}
|
||||
|
||||
instruct mulExactL_rReg_mem(rax_RegL dst, memory src, rFlagsReg cr)
|
||||
%{
|
||||
match(MulExactL dst (LoadL src));
|
||||
effect(DEF cr);
|
||||
|
||||
ins_cost(350);
|
||||
format %{ "imulq $dst, $src\t# mulExact long" %}
|
||||
ins_encode %{
|
||||
__ imulq($dst$$Register, $src$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem_alu0);
|
||||
%}
|
||||
|
||||
instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
|
||||
rFlagsReg cr)
|
||||
%{
|
||||
|
||||
@ -1006,7 +1006,7 @@ void BytecodeInterpreter::layout_interpreterState(interpreterState istate,
|
||||
istate->set_stack_limit(stack_base - method->max_stack() - 1);
|
||||
}
|
||||
|
||||
address CppInterpreter::return_entry(TosState state, int length) {
|
||||
address CppInterpreter::return_entry(TosState state, int length, Bytecodes::Code code) {
|
||||
ShouldNotCallThis();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -57,6 +57,8 @@ define_pd_global(bool, UseMembar, true);
|
||||
// GC Ergo Flags
|
||||
define_pd_global(uintx, CMSYoungGenPerWorker, 16*M); // default max size of CMS young gen, per GC worker thread
|
||||
|
||||
define_pd_global(uintx, TypeProfileLevel, 0);
|
||||
|
||||
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct)
|
||||
|
||||
#endif // CPU_ZERO_VM_GLOBALS_ZERO_HPP
|
||||
|
||||
@ -945,17 +945,15 @@ extern "C" Thread* get_thread() {
|
||||
// Used by VMSelfDestructTimer and the MemProfiler.
|
||||
double os::elapsedTime() {
|
||||
|
||||
return (double)(os::elapsed_counter()) * 0.000001;
|
||||
return ((double)os::elapsed_counter()) / os::elapsed_frequency();
|
||||
}
|
||||
|
||||
jlong os::elapsed_counter() {
|
||||
timeval time;
|
||||
int status = gettimeofday(&time, NULL);
|
||||
return jlong(time.tv_sec) * 1000 * 1000 + jlong(time.tv_usec) - initial_time_count;
|
||||
return javaTimeNanos() - initial_time_count;
|
||||
}
|
||||
|
||||
jlong os::elapsed_frequency() {
|
||||
return (1000 * 1000);
|
||||
return NANOSECS_PER_SEC; // nanosecond resolution
|
||||
}
|
||||
|
||||
bool os::supports_vtime() { return true; }
|
||||
@ -3582,7 +3580,7 @@ void os::init(void) {
|
||||
Bsd::_main_thread = pthread_self();
|
||||
|
||||
Bsd::clock_init();
|
||||
initial_time_count = os::elapsed_counter();
|
||||
initial_time_count = javaTimeNanos();
|
||||
|
||||
#ifdef __APPLE__
|
||||
// XXXDARWIN
|
||||
@ -4746,6 +4744,10 @@ int os::fork_and_exec(char* cmd) {
|
||||
// as libawt.so, and renamed libawt_xawt.so
|
||||
//
|
||||
bool os::is_headless_jre() {
|
||||
#ifdef __APPLE__
|
||||
// We no longer build headless-only on Mac OS X
|
||||
return false;
|
||||
#else
|
||||
struct stat statbuf;
|
||||
char buf[MAXPATHLEN];
|
||||
char libmawtpath[MAXPATHLEN];
|
||||
@ -4777,6 +4779,7 @@ bool os::is_headless_jre() {
|
||||
if (::stat(libmawtpath, &statbuf) == 0) return false;
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Get the default path to the core file
|
||||
|
||||
@ -1333,17 +1333,15 @@ void os::Linux::capture_initial_stack(size_t max_size) {
|
||||
// Used by VMSelfDestructTimer and the MemProfiler.
|
||||
double os::elapsedTime() {
|
||||
|
||||
return (double)(os::elapsed_counter()) * 0.000001;
|
||||
return ((double)os::elapsed_counter()) / os::elapsed_frequency(); // nanosecond resolution
|
||||
}
|
||||
|
||||
jlong os::elapsed_counter() {
|
||||
timeval time;
|
||||
int status = gettimeofday(&time, NULL);
|
||||
return jlong(time.tv_sec) * 1000 * 1000 + jlong(time.tv_usec) - initial_time_count;
|
||||
return javaTimeNanos() - initial_time_count;
|
||||
}
|
||||
|
||||
jlong os::elapsed_frequency() {
|
||||
return (1000 * 1000);
|
||||
return NANOSECS_PER_SEC; // nanosecond resolution
|
||||
}
|
||||
|
||||
bool os::supports_vtime() { return true; }
|
||||
@ -4750,7 +4748,7 @@ void os::init(void) {
|
||||
Linux::_main_thread = pthread_self();
|
||||
|
||||
Linux::clock_init();
|
||||
initial_time_count = os::elapsed_counter();
|
||||
initial_time_count = javaTimeNanos();
|
||||
|
||||
// pthread_condattr initialization for monotonic clock
|
||||
int status;
|
||||
|
||||
@ -79,6 +79,15 @@
|
||||
# include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
// needed by current_stack_region() workaround for Mavericks
|
||||
#if defined(__APPLE__)
|
||||
# include <errno.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/sysctl.h>
|
||||
# define DEFAULT_MAIN_THREAD_STACK_PAGES 2048
|
||||
# define OS_X_10_9_0_KERNEL_MAJOR_VERSION 13
|
||||
#endif
|
||||
|
||||
#ifdef AMD64
|
||||
#define SPELL_REG_SP "rsp"
|
||||
#define SPELL_REG_FP "rbp"
|
||||
@ -828,6 +837,21 @@ static void current_stack_region(address * bottom, size_t * size) {
|
||||
pthread_t self = pthread_self();
|
||||
void *stacktop = pthread_get_stackaddr_np(self);
|
||||
*size = pthread_get_stacksize_np(self);
|
||||
// workaround for OS X 10.9.0 (Mavericks)
|
||||
// pthread_get_stacksize_np returns 128 pages even though the actual size is 2048 pages
|
||||
if (pthread_main_np() == 1) {
|
||||
if ((*size) < (DEFAULT_MAIN_THREAD_STACK_PAGES * (size_t)getpagesize())) {
|
||||
char kern_osrelease[256];
|
||||
size_t kern_osrelease_size = sizeof(kern_osrelease);
|
||||
int ret = sysctlbyname("kern.osrelease", kern_osrelease, &kern_osrelease_size, NULL, 0);
|
||||
if (ret == 0) {
|
||||
// get the major number, atoi will ignore the minor amd micro portions of the version string
|
||||
if (atoi(kern_osrelease) >= OS_X_10_9_0_KERNEL_MAJOR_VERSION) {
|
||||
*size = (DEFAULT_MAIN_THREAD_STACK_PAGES*getpagesize());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*bottom = (address) stacktop - *size;
|
||||
#elif defined(__OpenBSD__)
|
||||
stack_t ss;
|
||||
|
||||
@ -1193,6 +1193,13 @@ void ArchDesc::buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp) {
|
||||
|| strcmp(idealName,"FastLock") == 0
|
||||
|| strcmp(idealName,"FastUnlock") == 0
|
||||
|| strcmp(idealName,"AddExactI") == 0
|
||||
|| strcmp(idealName,"AddExactL") == 0
|
||||
|| strcmp(idealName,"SubExactI") == 0
|
||||
|| strcmp(idealName,"SubExactL") == 0
|
||||
|| strcmp(idealName,"MulExactI") == 0
|
||||
|| strcmp(idealName,"MulExactL") == 0
|
||||
|| strcmp(idealName,"NegExactI") == 0
|
||||
|| strcmp(idealName,"NegExactL") == 0
|
||||
|| strcmp(idealName,"FlagsProj") == 0
|
||||
|| strcmp(idealName,"Bool") == 0
|
||||
|| strcmp(idealName,"Binary") == 0 ) {
|
||||
|
||||
@ -536,12 +536,6 @@ bool InstructForm::rematerialize(FormDict &globals, RegisterForm *registers ) {
|
||||
if( data_type != Form::none )
|
||||
rematerialize = true;
|
||||
|
||||
// Ugly: until a better fix is implemented, disable rematerialization for
|
||||
// negD nodes because they are proved to be problematic.
|
||||
if (is_ideal_negD()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Constants
|
||||
if( _components.count() == 1 && _components[0]->is(Component::USE_DEF) )
|
||||
rematerialize = true;
|
||||
|
||||
@ -238,7 +238,18 @@ class Compilation: public StackObj {
|
||||
return env()->comp_level() == CompLevel_full_profile &&
|
||||
C1UpdateMethodData && C1ProfileCheckcasts;
|
||||
}
|
||||
|
||||
bool profile_parameters() {
|
||||
return env()->comp_level() == CompLevel_full_profile &&
|
||||
C1UpdateMethodData && MethodData::profile_parameters();
|
||||
}
|
||||
bool profile_arguments() {
|
||||
return env()->comp_level() == CompLevel_full_profile &&
|
||||
C1UpdateMethodData && MethodData::profile_arguments();
|
||||
}
|
||||
bool profile_return() {
|
||||
return env()->comp_level() == CompLevel_full_profile &&
|
||||
C1UpdateMethodData && MethodData::profile_return();
|
||||
}
|
||||
// will compilation make optimistic assumptions that might lead to
|
||||
// deoptimization and that the runtime will account for?
|
||||
bool is_optimistic() const {
|
||||
|
||||
@ -1470,7 +1470,7 @@ void GraphBuilder::method_return(Value x) {
|
||||
set_state(state()->caller_state()->copy_for_parsing());
|
||||
if (x != NULL) {
|
||||
state()->push(x->type(), x);
|
||||
if (profile_calls() && MethodData::profile_return() && x->type()->is_object_kind()) {
|
||||
if (profile_return() && x->type()->is_object_kind()) {
|
||||
ciMethod* caller = state()->scope()->method();
|
||||
ciMethodData* md = caller->method_data_or_null();
|
||||
ciProfileData* data = md->bci_to_data(invoke_bci);
|
||||
@ -1672,15 +1672,23 @@ Dependencies* GraphBuilder::dependency_recorder() const {
|
||||
}
|
||||
|
||||
// How many arguments do we want to profile?
|
||||
Values* GraphBuilder::args_list_for_profiling(int& start, bool may_have_receiver) {
|
||||
Values* GraphBuilder::args_list_for_profiling(ciMethod* target, int& start, bool may_have_receiver) {
|
||||
int n = 0;
|
||||
assert(start == 0, "should be initialized");
|
||||
if (MethodData::profile_arguments()) {
|
||||
bool has_receiver = may_have_receiver && Bytecodes::has_receiver(method()->java_code_at_bci(bci()));
|
||||
start = has_receiver ? 1 : 0;
|
||||
if (profile_arguments()) {
|
||||
ciProfileData* data = method()->method_data()->bci_to_data(bci());
|
||||
if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) {
|
||||
n = data->is_CallTypeData() ? data->as_CallTypeData()->number_of_arguments() : data->as_VirtualCallTypeData()->number_of_arguments();
|
||||
bool has_receiver = may_have_receiver && Bytecodes::has_receiver(method()->java_code_at_bci(bci()));
|
||||
start = has_receiver ? 1 : 0;
|
||||
}
|
||||
}
|
||||
// If we are inlining then we need to collect arguments to profile parameters for the target
|
||||
if (profile_parameters() && target != NULL) {
|
||||
if (target->method_data() != NULL && target->method_data()->parameters_type_data() != NULL) {
|
||||
// The receiver is profiled on method entry so it's included in
|
||||
// the number of parameters but here we're only interested in
|
||||
// actual arguments.
|
||||
n = MAX2(n, target->method_data()->parameters_type_data()->number_of_parameters() - start);
|
||||
}
|
||||
}
|
||||
if (n > 0) {
|
||||
@ -1690,9 +1698,9 @@ Values* GraphBuilder::args_list_for_profiling(int& start, bool may_have_receiver
|
||||
}
|
||||
|
||||
// Collect arguments that we want to profile in a list
|
||||
Values* GraphBuilder::collect_args_for_profiling(Values* args, bool may_have_receiver) {
|
||||
Values* GraphBuilder::collect_args_for_profiling(Values* args, ciMethod* target, bool may_have_receiver) {
|
||||
int start = 0;
|
||||
Values* obj_args = args_list_for_profiling(start, may_have_receiver);
|
||||
Values* obj_args = args_list_for_profiling(target, start, may_have_receiver);
|
||||
if (obj_args == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@ -1865,7 +1873,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
|
||||
// number of implementors for decl_interface is 0 or 1. If
|
||||
// it's 0 then no class implements decl_interface and there's
|
||||
// no point in inlining.
|
||||
if (!holder->is_loaded() || decl_interface->nof_implementors() != 1) {
|
||||
if (!holder->is_loaded() || decl_interface->nof_implementors() != 1 || decl_interface->has_default_methods()) {
|
||||
singleton = NULL;
|
||||
}
|
||||
}
|
||||
@ -2006,7 +2014,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
|
||||
} else if (exact_target != NULL) {
|
||||
target_klass = exact_target->holder();
|
||||
}
|
||||
profile_call(target, recv, target_klass, collect_args_for_profiling(args, false), false);
|
||||
profile_call(target, recv, target_klass, collect_args_for_profiling(args, NULL, false), false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2021,7 +2029,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
|
||||
push(result_type, result);
|
||||
}
|
||||
}
|
||||
if (profile_calls() && MethodData::profile_return() && result_type->is_object_kind()) {
|
||||
if (profile_return() && result_type->is_object_kind()) {
|
||||
profile_return_type(result, target);
|
||||
}
|
||||
}
|
||||
@ -3561,7 +3569,7 @@ bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) {
|
||||
recv = args->at(0);
|
||||
null_check(recv);
|
||||
}
|
||||
profile_call(callee, recv, NULL, collect_args_for_profiling(args, true), true);
|
||||
profile_call(callee, recv, NULL, collect_args_for_profiling(args, callee, true), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3572,7 +3580,7 @@ bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) {
|
||||
Value value = append_split(result);
|
||||
if (result_type != voidType) push(result_type, value);
|
||||
|
||||
if (callee != method() && profile_calls() && MethodData::profile_return() && result_type->is_object_kind()) {
|
||||
if (callee != method() && profile_return() && result_type->is_object_kind()) {
|
||||
profile_return_type(result, callee);
|
||||
}
|
||||
|
||||
@ -3760,6 +3768,7 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecode
|
||||
|
||||
// now perform tests that are based on flag settings
|
||||
if (callee->force_inline()) {
|
||||
if (inline_level() > MaxForceInlineLevel) INLINE_BAILOUT("MaxForceInlineLevel");
|
||||
print_inlining(callee, "force inline by annotation");
|
||||
} else if (callee->should_inline()) {
|
||||
print_inlining(callee, "force inline by CompileOracle");
|
||||
@ -3820,7 +3829,7 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecode
|
||||
|
||||
if (profile_calls()) {
|
||||
int start = 0;
|
||||
Values* obj_args = args_list_for_profiling(start, has_receiver);
|
||||
Values* obj_args = args_list_for_profiling(callee, start, has_receiver);
|
||||
if (obj_args != NULL) {
|
||||
int s = obj_args->size();
|
||||
// if called through method handle invoke, some arguments may have been popped
|
||||
|
||||
@ -386,9 +386,12 @@ class GraphBuilder VALUE_OBJ_CLASS_SPEC {
|
||||
bool profile_calls() { return _compilation->profile_calls(); }
|
||||
bool profile_inlined_calls() { return _compilation->profile_inlined_calls(); }
|
||||
bool profile_checkcasts() { return _compilation->profile_checkcasts(); }
|
||||
bool profile_parameters() { return _compilation->profile_parameters(); }
|
||||
bool profile_arguments() { return _compilation->profile_arguments(); }
|
||||
bool profile_return() { return _compilation->profile_return(); }
|
||||
|
||||
Values* args_list_for_profiling(int& start, bool may_have_receiver);
|
||||
Values* collect_args_for_profiling(Values* args, bool may_have_receiver);
|
||||
Values* args_list_for_profiling(ciMethod* target, int& start, bool may_have_receiver);
|
||||
Values* collect_args_for_profiling(Values* args, ciMethod* target, bool may_have_receiver);
|
||||
|
||||
public:
|
||||
NOT_PRODUCT(void print_stats();)
|
||||
|
||||
@ -183,10 +183,10 @@ char LIR_OprDesc::type_char(BasicType t) {
|
||||
case T_LONG:
|
||||
case T_OBJECT:
|
||||
case T_ADDRESS:
|
||||
case T_METADATA:
|
||||
case T_VOID:
|
||||
return ::type2char(t);
|
||||
|
||||
case T_METADATA:
|
||||
return 'M';
|
||||
case T_ILLEGAL:
|
||||
return '?';
|
||||
|
||||
|
||||
@ -1175,7 +1175,7 @@ void LIRGenerator::do_Return(Return* x) {
|
||||
if (compilation()->env()->dtrace_method_probes()) {
|
||||
BasicTypeList signature;
|
||||
signature.append(LP64_ONLY(T_LONG) NOT_LP64(T_INT)); // thread
|
||||
signature.append(T_OBJECT); // Method*
|
||||
signature.append(T_METADATA); // Method*
|
||||
LIR_OprList* args = new LIR_OprList();
|
||||
args->append(getThreadPointer());
|
||||
LIR_Opr meth = new_register(T_METADATA);
|
||||
@ -1265,6 +1265,7 @@ void LIRGenerator::do_getClass(Intrinsic* x) {
|
||||
|
||||
LIRItem rcvr(x->argument_at(0), this);
|
||||
rcvr.load_item();
|
||||
LIR_Opr temp = new_register(T_METADATA);
|
||||
LIR_Opr result = rlock_result(x);
|
||||
|
||||
// need to perform the null check on the rcvr
|
||||
@ -1272,8 +1273,11 @@ void LIRGenerator::do_getClass(Intrinsic* x) {
|
||||
if (x->needs_null_check()) {
|
||||
info = state_for(x);
|
||||
}
|
||||
__ move(new LIR_Address(rcvr.result(), oopDesc::klass_offset_in_bytes(), T_ADDRESS), result, info);
|
||||
__ move_wide(new LIR_Address(result, in_bytes(Klass::java_mirror_offset()), T_OBJECT), result);
|
||||
|
||||
// FIXME T_ADDRESS should actually be T_METADATA but it can't because the
|
||||
// meaning of these two is mixed up (see JDK-8026837).
|
||||
__ move(new LIR_Address(rcvr.result(), oopDesc::klass_offset_in_bytes(), T_ADDRESS), temp, info);
|
||||
__ move_wide(new LIR_Address(temp, in_bytes(Klass::java_mirror_offset()), T_OBJECT), result);
|
||||
}
|
||||
|
||||
|
||||
@ -2643,6 +2647,39 @@ ciKlass* LIRGenerator::profile_arg_type(ciMethodData* md, int md_base_offset, in
|
||||
return result;
|
||||
}
|
||||
|
||||
// profile parameters on entry to the root of the compilation
|
||||
void LIRGenerator::profile_parameters(Base* x) {
|
||||
if (compilation()->profile_parameters()) {
|
||||
CallingConvention* args = compilation()->frame_map()->incoming_arguments();
|
||||
ciMethodData* md = scope()->method()->method_data_or_null();
|
||||
assert(md != NULL, "Sanity");
|
||||
|
||||
if (md->parameters_type_data() != NULL) {
|
||||
ciParametersTypeData* parameters_type_data = md->parameters_type_data();
|
||||
ciTypeStackSlotEntries* parameters = parameters_type_data->parameters();
|
||||
LIR_Opr mdp = LIR_OprFact::illegalOpr;
|
||||
for (int java_index = 0, i = 0, j = 0; j < parameters_type_data->number_of_parameters(); i++) {
|
||||
LIR_Opr src = args->at(i);
|
||||
assert(!src->is_illegal(), "check");
|
||||
BasicType t = src->type();
|
||||
if (t == T_OBJECT || t == T_ARRAY) {
|
||||
intptr_t profiled_k = parameters->type(j);
|
||||
Local* local = x->state()->local_at(java_index)->as_Local();
|
||||
ciKlass* exact = profile_arg_type(md, md->byte_offset_of_slot(parameters_type_data, ParametersTypeData::type_offset(0)),
|
||||
in_bytes(ParametersTypeData::type_offset(j)) - in_bytes(ParametersTypeData::type_offset(0)),
|
||||
profiled_k, local, mdp, false, local->declared_type()->as_klass());
|
||||
// If the profile is known statically set it once for all and do not emit any code
|
||||
if (exact != NULL) {
|
||||
md->set_parameter_type(j, exact);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
java_index += type2size[t];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LIRGenerator::do_Base(Base* x) {
|
||||
__ std_entry(LIR_OprFact::illegalOpr);
|
||||
// Emit moves from physical registers / stack slots to virtual registers
|
||||
@ -2683,7 +2720,7 @@ void LIRGenerator::do_Base(Base* x) {
|
||||
if (compilation()->env()->dtrace_method_probes()) {
|
||||
BasicTypeList signature;
|
||||
signature.append(LP64_ONLY(T_LONG) NOT_LP64(T_INT)); // thread
|
||||
signature.append(T_OBJECT); // Method*
|
||||
signature.append(T_METADATA); // Method*
|
||||
LIR_OprList* args = new LIR_OprList();
|
||||
args->append(getThreadPointer());
|
||||
LIR_Opr meth = new_register(T_METADATA);
|
||||
@ -2718,6 +2755,7 @@ void LIRGenerator::do_Base(Base* x) {
|
||||
|
||||
// increment invocation counters if needed
|
||||
if (!method()->is_accessor()) { // Accessors do not have MDOs, so no counting.
|
||||
profile_parameters(x);
|
||||
CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL, false);
|
||||
increment_invocation_counter(info);
|
||||
}
|
||||
@ -3077,11 +3115,12 @@ void LIRGenerator::do_Intrinsic(Intrinsic* x) {
|
||||
}
|
||||
|
||||
void LIRGenerator::profile_arguments(ProfileCall* x) {
|
||||
if (MethodData::profile_arguments()) {
|
||||
if (compilation()->profile_arguments()) {
|
||||
int bci = x->bci_of_invoke();
|
||||
ciMethodData* md = x->method()->method_data_or_null();
|
||||
ciProfileData* data = md->bci_to_data(bci);
|
||||
if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) {
|
||||
if ((data->is_CallTypeData() && data->as_CallTypeData()->has_arguments()) ||
|
||||
(data->is_VirtualCallTypeData() && data->as_VirtualCallTypeData()->has_arguments())) {
|
||||
ByteSize extra = data->is_CallTypeData() ? CallTypeData::args_data_offset() : VirtualCallTypeData::args_data_offset();
|
||||
int base_offset = md->byte_offset_of_slot(data, extra);
|
||||
LIR_Opr mdp = LIR_OprFact::illegalOpr;
|
||||
@ -3107,6 +3146,71 @@ void LIRGenerator::profile_arguments(ProfileCall* x) {
|
||||
md->set_argument_type(bci, i, exact);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifdef ASSERT
|
||||
Bytecodes::Code code = x->method()->raw_code_at_bci(x->bci_of_invoke());
|
||||
int n = x->nb_profiled_args();
|
||||
assert(MethodData::profile_parameters() && x->inlined() &&
|
||||
((code == Bytecodes::_invokedynamic && n <= 1) || (code == Bytecodes::_invokehandle && n <= 2)),
|
||||
"only at JSR292 bytecodes");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// profile parameters on entry to an inlined method
|
||||
void LIRGenerator::profile_parameters_at_call(ProfileCall* x) {
|
||||
if (compilation()->profile_parameters() && x->inlined()) {
|
||||
ciMethodData* md = x->callee()->method_data_or_null();
|
||||
if (md != NULL) {
|
||||
ciParametersTypeData* parameters_type_data = md->parameters_type_data();
|
||||
if (parameters_type_data != NULL) {
|
||||
ciTypeStackSlotEntries* parameters = parameters_type_data->parameters();
|
||||
LIR_Opr mdp = LIR_OprFact::illegalOpr;
|
||||
bool has_receiver = !x->callee()->is_static();
|
||||
ciSignature* sig = x->callee()->signature();
|
||||
ciSignatureStream sig_stream(sig, has_receiver ? x->callee()->holder() : NULL);
|
||||
int i = 0; // to iterate on the Instructions
|
||||
Value arg = x->recv();
|
||||
bool not_null = false;
|
||||
int bci = x->bci_of_invoke();
|
||||
Bytecodes::Code bc = x->method()->java_code_at_bci(bci);
|
||||
// The first parameter is the receiver so that's what we start
|
||||
// with if it exists. On exception if method handle call to
|
||||
// virtual method has receiver in the args list
|
||||
if (arg == NULL || !Bytecodes::has_receiver(bc)) {
|
||||
i = 1;
|
||||
arg = x->profiled_arg_at(0);
|
||||
not_null = !x->arg_needs_null_check(0);
|
||||
}
|
||||
int k = 0; // to iterate on the profile data
|
||||
for (;;) {
|
||||
intptr_t profiled_k = parameters->type(k);
|
||||
ciKlass* exact = profile_arg_type(md, md->byte_offset_of_slot(parameters_type_data, ParametersTypeData::type_offset(0)),
|
||||
in_bytes(ParametersTypeData::type_offset(k)) - in_bytes(ParametersTypeData::type_offset(0)),
|
||||
profiled_k, arg, mdp, not_null, sig_stream.next_klass());
|
||||
// If the profile is known statically set it once for all and do not emit any code
|
||||
if (exact != NULL) {
|
||||
md->set_parameter_type(k, exact);
|
||||
}
|
||||
k++;
|
||||
if (k >= parameters_type_data->number_of_parameters()) {
|
||||
#ifdef ASSERT
|
||||
int extra = 0;
|
||||
if (MethodData::profile_arguments() && TypeProfileParmsLimit != -1 &&
|
||||
x->nb_profiled_args() >= TypeProfileParmsLimit &&
|
||||
x->recv() != NULL && Bytecodes::has_receiver(bc)) {
|
||||
extra += 1;
|
||||
}
|
||||
assert(i == x->nb_profiled_args() - extra || (TypeProfileParmsLimit != -1 && TypeProfileArgsLimit > TypeProfileParmsLimit), "unused parameters?");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
arg = x->profiled_arg_at(i);
|
||||
not_null = !x->arg_needs_null_check(i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3122,6 +3226,11 @@ void LIRGenerator::do_ProfileCall(ProfileCall* x) {
|
||||
profile_arguments(x);
|
||||
}
|
||||
|
||||
// profile parameters on inlined method entry including receiver
|
||||
if (x->recv() != NULL || x->nb_profiled_args() > 0) {
|
||||
profile_parameters_at_call(x);
|
||||
}
|
||||
|
||||
if (x->recv() != NULL) {
|
||||
LIRItem value(x->recv(), this);
|
||||
value.load_item();
|
||||
@ -3222,7 +3331,7 @@ void LIRGenerator::do_RuntimeCall(RuntimeCall* x) {
|
||||
BasicTypeList* signature = new BasicTypeList(x->number_of_arguments());
|
||||
|
||||
if (x->pass_thread()) {
|
||||
signature->append(T_ADDRESS);
|
||||
signature->append(LP64_ONLY(T_LONG) NOT_LP64(T_INT)); // thread
|
||||
args->append(getThreadPointer());
|
||||
}
|
||||
|
||||
|
||||
@ -436,6 +436,8 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure {
|
||||
#endif
|
||||
ciKlass* profile_arg_type(ciMethodData* md, int md_first_offset, int md_offset, intptr_t profiled_k, Value arg, LIR_Opr& mdp, bool not_null, ciKlass* signature_k);
|
||||
void profile_arguments(ProfileCall* x);
|
||||
void profile_parameters(Base* x);
|
||||
void profile_parameters_at_call(ProfileCall* x);
|
||||
|
||||
public:
|
||||
Compilation* compilation() const { return _compilation; }
|
||||
|
||||
@ -75,9 +75,9 @@
|
||||
|
||||
// Map BasicType to spill size in 32-bit words, matching VMReg's notion of words
|
||||
#ifdef _LP64
|
||||
static int type2spill_size[T_CONFLICT+1]={ -1, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 0, 1, -1};
|
||||
static int type2spill_size[T_CONFLICT+1]={ -1, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 0, 2, 1, 2, 1, -1};
|
||||
#else
|
||||
static int type2spill_size[T_CONFLICT+1]={ -1, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 0, 1, -1};
|
||||
static int type2spill_size[T_CONFLICT+1]={ -1, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 0, 1, -1, 1, 1, -1};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@ -341,6 +341,8 @@
|
||||
diagnostic(bool, C1PatchInvokeDynamic, true, \
|
||||
"Patch invokedynamic appendix not known at compile time") \
|
||||
\
|
||||
develop(intx, MaxForceInlineLevel, 100, \
|
||||
"maximum number of nested @ForceInline calls that are inlined") \
|
||||
\
|
||||
|
||||
|
||||
|
||||
@ -483,8 +483,7 @@ ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool,
|
||||
{
|
||||
// We have to lock the cpool to keep the oop from being resolved
|
||||
// while we are accessing it.
|
||||
oop cplock = cpool->lock();
|
||||
ObjectLocker ol(cplock, THREAD, cplock != NULL);
|
||||
MonitorLockerEx ml(cpool->lock());
|
||||
constantTag tag = cpool->tag_at(index);
|
||||
if (tag.is_klass()) {
|
||||
// The klass has been inserted into the constant pool
|
||||
|
||||
@ -57,6 +57,7 @@ ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) :
|
||||
_init_state = ik->init_state();
|
||||
_nonstatic_field_size = ik->nonstatic_field_size();
|
||||
_has_nonstatic_fields = ik->has_nonstatic_fields();
|
||||
_has_default_methods = ik->has_default_methods();
|
||||
_nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields:
|
||||
|
||||
_implementor = NULL; // we will fill these lazily
|
||||
|
||||
@ -52,6 +52,7 @@ private:
|
||||
bool _has_finalizer;
|
||||
bool _has_subklass;
|
||||
bool _has_nonstatic_fields;
|
||||
bool _has_default_methods;
|
||||
|
||||
ciFlags _flags;
|
||||
jint _nonstatic_field_size;
|
||||
@ -171,6 +172,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool has_default_methods() {
|
||||
assert(is_loaded(), "must be loaded");
|
||||
return _has_default_methods;
|
||||
}
|
||||
|
||||
ciInstanceKlass* get_canonical_holder(int offset);
|
||||
ciField* get_field_by_offset(int field_offset, bool is_static);
|
||||
ciField* get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static);
|
||||
|
||||
@ -565,6 +565,116 @@ void ciCallProfile::add_receiver(ciKlass* receiver, int receiver_count) {
|
||||
if (_limit < MorphismLimit) _limit++;
|
||||
}
|
||||
|
||||
|
||||
void ciMethod::assert_virtual_call_type_ok(int bci) {
|
||||
assert(java_code_at_bci(bci) == Bytecodes::_invokevirtual ||
|
||||
java_code_at_bci(bci) == Bytecodes::_invokeinterface, err_msg("unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci))));
|
||||
}
|
||||
|
||||
void ciMethod::assert_call_type_ok(int bci) {
|
||||
assert(java_code_at_bci(bci) == Bytecodes::_invokestatic ||
|
||||
java_code_at_bci(bci) == Bytecodes::_invokespecial ||
|
||||
java_code_at_bci(bci) == Bytecodes::_invokedynamic, err_msg("unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether profiling provides a type for the argument i to the
|
||||
* call at bci bci
|
||||
*
|
||||
* @param bci bci of the call
|
||||
* @param i argument number
|
||||
* @return profiled type
|
||||
*
|
||||
* If the profile reports that the argument may be null, return false
|
||||
* at least for now.
|
||||
*/
|
||||
ciKlass* ciMethod::argument_profiled_type(int bci, int i) {
|
||||
if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) {
|
||||
ciProfileData* data = method_data()->bci_to_data(bci);
|
||||
if (data != NULL) {
|
||||
if (data->is_VirtualCallTypeData()) {
|
||||
assert_virtual_call_type_ok(bci);
|
||||
ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData();
|
||||
if (i >= call->number_of_arguments()) {
|
||||
return NULL;
|
||||
}
|
||||
ciKlass* type = call->valid_argument_type(i);
|
||||
if (type != NULL && !call->argument_maybe_null(i)) {
|
||||
return type;
|
||||
}
|
||||
} else if (data->is_CallTypeData()) {
|
||||
assert_call_type_ok(bci);
|
||||
ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData();
|
||||
if (i >= call->number_of_arguments()) {
|
||||
return NULL;
|
||||
}
|
||||
ciKlass* type = call->valid_argument_type(i);
|
||||
if (type != NULL && !call->argument_maybe_null(i)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether profiling provides a type for the return value from
|
||||
* the call at bci bci
|
||||
*
|
||||
* @param bci bci of the call
|
||||
* @return profiled type
|
||||
*
|
||||
* If the profile reports that the argument may be null, return false
|
||||
* at least for now.
|
||||
*/
|
||||
ciKlass* ciMethod::return_profiled_type(int bci) {
|
||||
if (MethodData::profile_return() && method_data() != NULL && method_data()->is_mature()) {
|
||||
ciProfileData* data = method_data()->bci_to_data(bci);
|
||||
if (data != NULL) {
|
||||
if (data->is_VirtualCallTypeData()) {
|
||||
assert_virtual_call_type_ok(bci);
|
||||
ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData();
|
||||
ciKlass* type = call->valid_return_type();
|
||||
if (type != NULL && !call->return_maybe_null()) {
|
||||
return type;
|
||||
}
|
||||
} else if (data->is_CallTypeData()) {
|
||||
assert_call_type_ok(bci);
|
||||
ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData();
|
||||
ciKlass* type = call->valid_return_type();
|
||||
if (type != NULL && !call->return_maybe_null()) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether profiling provides a type for the parameter i
|
||||
*
|
||||
* @param i parameter number
|
||||
* @return profiled type
|
||||
*
|
||||
* If the profile reports that the argument may be null, return false
|
||||
* at least for now.
|
||||
*/
|
||||
ciKlass* ciMethod::parameter_profiled_type(int i) {
|
||||
if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) {
|
||||
ciParametersTypeData* parameters = method_data()->parameters_type_data();
|
||||
if (parameters != NULL && i < parameters->number_of_parameters()) {
|
||||
ciKlass* type = parameters->valid_parameter_type(i);
|
||||
if (type != NULL && !parameters->parameter_maybe_null(i)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// ciMethod::find_monomorphic_target
|
||||
//
|
||||
|
||||
@ -117,6 +117,10 @@ class ciMethod : public ciMetadata {
|
||||
*bcp = code;
|
||||
}
|
||||
|
||||
// Check bytecode and profile data collected are compatible
|
||||
void assert_virtual_call_type_ok(int bci);
|
||||
void assert_call_type_ok(int bci);
|
||||
|
||||
public:
|
||||
// Basic method information.
|
||||
ciFlags flags() const { check_is_loaded(); return _flags; }
|
||||
@ -230,6 +234,11 @@ class ciMethod : public ciMetadata {
|
||||
ciCallProfile call_profile_at_bci(int bci);
|
||||
int interpreter_call_site_count(int bci);
|
||||
|
||||
// Does type profiling provide a useful type at this point?
|
||||
ciKlass* argument_profiled_type(int bci, int i);
|
||||
ciKlass* parameter_profiled_type(int i);
|
||||
ciKlass* return_profiled_type(int bci);
|
||||
|
||||
ciField* get_field_at_bci( int bci, bool &will_link);
|
||||
ciMethod* get_method_at_bci(int bci, bool &will_link, ciSignature* *declared_signature);
|
||||
|
||||
|
||||
@ -53,6 +53,7 @@ ciMethodData::ciMethodData(MethodData* md) : ciMetadata(md) {
|
||||
_hint_di = first_di();
|
||||
// Initialize the escape information (to "don't know.");
|
||||
_eflags = _arg_local = _arg_stack = _arg_returned = 0;
|
||||
_parameters = NULL;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
@ -74,6 +75,7 @@ ciMethodData::ciMethodData() : ciMetadata(NULL) {
|
||||
_hint_di = first_di();
|
||||
// Initialize the escape information (to "don't know.");
|
||||
_eflags = _arg_local = _arg_stack = _arg_returned = 0;
|
||||
_parameters = NULL;
|
||||
}
|
||||
|
||||
void ciMethodData::load_data() {
|
||||
@ -108,6 +110,12 @@ void ciMethodData::load_data() {
|
||||
ci_data = next_data(ci_data);
|
||||
data = mdo->next_data(data);
|
||||
}
|
||||
if (mdo->parameters_type_data() != NULL) {
|
||||
_parameters = data_layout_at(mdo->parameters_type_data_di());
|
||||
ciParametersTypeData* parameters = new ciParametersTypeData(_parameters);
|
||||
parameters->translate_from(mdo->parameters_type_data());
|
||||
}
|
||||
|
||||
// Note: Extra data are all BitData, and do not need translation.
|
||||
_current_mileage = MethodData::mileage_of(mdo->method());
|
||||
_invocation_counter = mdo->invocation_count();
|
||||
@ -182,6 +190,8 @@ ciProfileData* ciMethodData::data_at(int data_index) {
|
||||
return new ciCallTypeData(data_layout);
|
||||
case DataLayout::virtual_call_type_data_tag:
|
||||
return new ciVirtualCallTypeData(data_layout);
|
||||
case DataLayout::parameters_type_data_tag:
|
||||
return new ciParametersTypeData(data_layout);
|
||||
};
|
||||
}
|
||||
|
||||
@ -318,6 +328,14 @@ void ciMethodData::set_argument_type(int bci, int i, ciKlass* k) {
|
||||
}
|
||||
}
|
||||
|
||||
void ciMethodData::set_parameter_type(int i, ciKlass* k) {
|
||||
VM_ENTRY_MARK;
|
||||
MethodData* mdo = get_MethodData();
|
||||
if (mdo != NULL) {
|
||||
mdo->parameters_type_data()->set_type(i, k->get_Klass());
|
||||
}
|
||||
}
|
||||
|
||||
void ciMethodData::set_return_type(int bci, ciKlass* k) {
|
||||
VM_ENTRY_MARK;
|
||||
MethodData* mdo = get_MethodData();
|
||||
@ -605,4 +623,9 @@ void ciVirtualCallTypeData::print_data_on(outputStream* st) const {
|
||||
ret()->print_data_on(st);
|
||||
}
|
||||
}
|
||||
|
||||
void ciParametersTypeData::print_data_on(outputStream* st) const {
|
||||
st->print_cr("Parametertypes");
|
||||
parameters()->print_data_on(st);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -43,6 +43,7 @@ class ciMultiBranchData;
|
||||
class ciArgInfoData;
|
||||
class ciCallTypeData;
|
||||
class ciVirtualCallTypeData;
|
||||
class ciParametersTypeData;
|
||||
|
||||
typedef ProfileData ciProfileData;
|
||||
|
||||
@ -99,6 +100,10 @@ public:
|
||||
return valid_ciklass(type(i));
|
||||
}
|
||||
|
||||
bool maybe_null(int i) const {
|
||||
return was_null_seen(type(i));
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void print_data_on(outputStream* st) const;
|
||||
#endif
|
||||
@ -112,6 +117,10 @@ public:
|
||||
return valid_ciklass(type());
|
||||
}
|
||||
|
||||
bool maybe_null() const {
|
||||
return was_null_seen(type());
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void print_data_on(outputStream* st) const;
|
||||
#endif
|
||||
@ -124,7 +133,7 @@ public:
|
||||
ciTypeStackSlotEntries* args() const { return (ciTypeStackSlotEntries*)CallTypeData::args(); }
|
||||
ciReturnTypeEntry* ret() const { return (ciReturnTypeEntry*)CallTypeData::ret(); }
|
||||
|
||||
void translate_type_data_from(const ProfileData* data) {
|
||||
void translate_from(const ProfileData* data) {
|
||||
if (has_arguments()) {
|
||||
args()->translate_type_data_from(data->as_CallTypeData()->args());
|
||||
}
|
||||
@ -153,6 +162,14 @@ public:
|
||||
return ret()->valid_type();
|
||||
}
|
||||
|
||||
bool argument_maybe_null(int i) const {
|
||||
return args()->maybe_null(i);
|
||||
}
|
||||
|
||||
bool return_maybe_null() const {
|
||||
return ret()->maybe_null();
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void print_data_on(outputStream* st) const;
|
||||
#endif
|
||||
@ -259,6 +276,14 @@ public:
|
||||
return ret()->valid_type();
|
||||
}
|
||||
|
||||
bool argument_maybe_null(int i) const {
|
||||
return args()->maybe_null(i);
|
||||
}
|
||||
|
||||
bool return_maybe_null() const {
|
||||
return ret()->maybe_null();
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void print_data_on(outputStream* st) const;
|
||||
#endif
|
||||
@ -290,6 +315,29 @@ public:
|
||||
ciArgInfoData(DataLayout* layout) : ArgInfoData(layout) {};
|
||||
};
|
||||
|
||||
class ciParametersTypeData : public ParametersTypeData {
|
||||
public:
|
||||
ciParametersTypeData(DataLayout* layout) : ParametersTypeData(layout) {}
|
||||
|
||||
virtual void translate_from(const ProfileData* data) {
|
||||
parameters()->translate_type_data_from(data->as_ParametersTypeData()->parameters());
|
||||
}
|
||||
|
||||
ciTypeStackSlotEntries* parameters() const { return (ciTypeStackSlotEntries*)ParametersTypeData::parameters(); }
|
||||
|
||||
ciKlass* valid_parameter_type(int i) const {
|
||||
return parameters()->valid_type(i);
|
||||
}
|
||||
|
||||
bool parameter_maybe_null(int i) const {
|
||||
return parameters()->maybe_null(i);
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void print_data_on(outputStream* st) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
// ciMethodData
|
||||
//
|
||||
// This class represents a MethodData* in the HotSpot virtual
|
||||
@ -335,6 +383,10 @@ private:
|
||||
// Coherent snapshot of original header.
|
||||
MethodData _orig;
|
||||
|
||||
// Dedicated area dedicated to parameters. Null if no parameter
|
||||
// profiling for this method.
|
||||
DataLayout* _parameters;
|
||||
|
||||
ciMethodData(MethodData* md);
|
||||
ciMethodData();
|
||||
|
||||
@ -403,6 +455,7 @@ public:
|
||||
// If the compiler finds a profiled type that is known statically
|
||||
// for sure, set it in the MethodData
|
||||
void set_argument_type(int bci, int i, ciKlass* k);
|
||||
void set_parameter_type(int i, ciKlass* k);
|
||||
void set_return_type(int bci, ciKlass* k);
|
||||
|
||||
void load_data();
|
||||
@ -467,6 +520,10 @@ public:
|
||||
bool is_arg_returned(int i) const;
|
||||
uint arg_modified(int arg) const;
|
||||
|
||||
ciParametersTypeData* parameters_type_data() const {
|
||||
return _parameters != NULL ? new ciParametersTypeData(_parameters) : NULL;
|
||||
}
|
||||
|
||||
// Code generation helper
|
||||
ByteSize offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data);
|
||||
int byte_offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) { return in_bytes(offset_of_slot(data, slot_offset_in_data)); }
|
||||
|
||||
@ -131,6 +131,17 @@ void ClassLoaderData::classes_do(void f(Klass * const)) {
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderData::loaded_classes_do(KlassClosure* klass_closure) {
|
||||
// Lock to avoid classes being modified/added/removed during iteration
|
||||
MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag);
|
||||
for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
|
||||
// Do not filter ArrayKlass oops here...
|
||||
if (k->oop_is_array() || (k->oop_is_instance() && InstanceKlass::cast(k)->is_loaded())) {
|
||||
klass_closure->do_klass(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderData::classes_do(void f(InstanceKlass*)) {
|
||||
for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
|
||||
if (k->oop_is_instance()) {
|
||||
@ -600,6 +611,12 @@ void ClassLoaderDataGraph::classes_do(void f(Klass* const)) {
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::loaded_classes_do(KlassClosure* klass_closure) {
|
||||
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
|
||||
cld->loaded_classes_do(klass_closure);
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::classes_unloading_do(void f(Klass* const)) {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
|
||||
for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) {
|
||||
|
||||
@ -78,6 +78,7 @@ class ClassLoaderDataGraph : public AllStatic {
|
||||
static void keep_alive_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
|
||||
static void classes_do(KlassClosure* klass_closure);
|
||||
static void classes_do(void f(Klass* const));
|
||||
static void loaded_classes_do(KlassClosure* klass_closure);
|
||||
static void classes_unloading_do(void f(Klass* const));
|
||||
static bool do_unloading(BoolObjectClosure* is_alive);
|
||||
|
||||
@ -186,6 +187,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
||||
bool keep_alive() const { return _keep_alive; }
|
||||
bool is_alive(BoolObjectClosure* is_alive_closure) const;
|
||||
void classes_do(void f(Klass*));
|
||||
void loaded_classes_do(KlassClosure* klass_closure);
|
||||
void classes_do(void f(InstanceKlass*));
|
||||
|
||||
// Deallocate free list during class unloading.
|
||||
|
||||
@ -2360,6 +2360,11 @@ methodHandle SystemDictionary::find_method_handle_invoker(Symbol* name,
|
||||
objArrayHandle appendix_box = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1, CHECK_(empty));
|
||||
assert(appendix_box->obj_at(0) == NULL, "");
|
||||
|
||||
// This should not happen. JDK code should take care of that.
|
||||
if (accessing_klass.is_null() || method_type.is_null()) {
|
||||
THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad invokehandle", empty);
|
||||
}
|
||||
|
||||
// call java.lang.invoke.MethodHandleNatives::linkMethod(... String, MethodType) -> MemberName
|
||||
JavaCallArguments args;
|
||||
args.push_oop(accessing_klass()->java_mirror());
|
||||
@ -2485,6 +2490,9 @@ Handle SystemDictionary::link_method_handle_constant(KlassHandle caller,
|
||||
Handle type;
|
||||
if (signature->utf8_length() > 0 && signature->byte_at(0) == '(') {
|
||||
type = find_method_handle_type(signature, caller, CHECK_(empty));
|
||||
} else if (caller.is_null()) {
|
||||
// This should not happen. JDK code should take care of that.
|
||||
THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad MH constant", empty);
|
||||
} else {
|
||||
ResourceMark rm(THREAD);
|
||||
SignatureStream ss(signature, false);
|
||||
@ -2548,6 +2556,11 @@ methodHandle SystemDictionary::find_dynamic_call_site_invoker(KlassHandle caller
|
||||
Handle method_name = java_lang_String::create_from_symbol(name, CHECK_(empty));
|
||||
Handle method_type = find_method_handle_type(type, caller, CHECK_(empty));
|
||||
|
||||
// This should not happen. JDK code should take care of that.
|
||||
if (caller.is_null() || method_type.is_null()) {
|
||||
THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad invokedynamic", empty);
|
||||
}
|
||||
|
||||
objArrayHandle appendix_box = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1, CHECK_(empty));
|
||||
assert(appendix_box->obj_at(0) == NULL, "");
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user