This commit is contained in:
J. Duke 2017-07-05 20:23:19 +02:00
commit 0fff7bc455
429 changed files with 62391 additions and 5461 deletions

View File

@ -295,3 +295,4 @@ d91ed1951b948210590ce1394bea5515357246ba jdk9-b49
d1f37d39ff2421f956a6ddf316cf763807bc3363 jdk9-b50
6207b4b8731ca75c51b031c47daa813ab92ef558 jdk9-b51
1822e59f17121b09e7899cf338cfb6e37fe5fceb jdk9-b52
d6ed47125a76cd1cf8a100568507bfb5e9669d9f jdk9-b53

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -215,7 +215,7 @@ AC_DEFUN([BPERF_SETUP_CCACHE_USAGE],
if test "x$CCACHE" != x; then
if test "x$USE_PRECOMPILED_HEADER" = "x1"; then
HAS_BAD_CCACHE=[`$ECHO $CCACHE_VERSION | \
$GREP -e '^1.*' -e '^2.*' -e '^3\.0.*' -e '^3\.1\.[0123]'`]
$GREP -e '^1.*' -e '^2.*' -e '^3\.0.*' -e '^3\.1\.[0123]$'`]
if test "x$HAS_BAD_CCACHE" != "x"; then
AC_MSG_ERROR([Precompiled headers requires ccache 3.1.4 or later, found $CCACHE_VERSION])
fi

View File

@ -761,9 +761,6 @@ DUMPBIN
RC
MT
LIPO
ac_ct_OBJC
OBJCFLAGS
OBJC
ac_ct_AR
AR
AS
@ -1198,8 +1195,6 @@ CPP
CXXCPP
AS
AR
OBJC
OBJCFLAGS
LIPO
STRIP
NM
@ -2080,8 +2075,6 @@ Some influential environment variables:
CXXCPP C++ preprocessor
AS Override default value for AS
AR Override default value for AR
OBJC Objective C compiler command
OBJCFLAGS Objective C compiler flags
LIPO Override default value for LIPO
STRIP Override default value for STRIP
NM Override default value for NM
@ -2340,44 +2333,6 @@ fi
} # ac_fn_cxx_try_cpp
# ac_fn_objc_try_compile LINENO
# -----------------------------
# Try to compile conftest.$ac_ext, and return whether this succeeded.
ac_fn_objc_try_compile ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
rm -f conftest.$ac_objext
if { { ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_compile") 2>conftest.err
ac_status=$?
if test -s conftest.err; then
grep -v '^ *+' conftest.err >conftest.er1
cat conftest.er1 >&5
mv -f conftest.er1 conftest.err
fi
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } && {
test -z "$ac_objc_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then :
ac_retval=0
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_objc_try_compile
# ac_fn_c_try_link LINENO
# -----------------------
# Try to link conftest.$ac_ext, and return whether this succeeded.
@ -4183,7 +4138,7 @@ pkgadd_help() {
#
# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -4393,7 +4348,7 @@ VS_SDK_PLATFORM_NAME_2013=
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
DATE_WHEN_GENERATED=1424872170
DATE_WHEN_GENERATED=1425490712
###############################################################################
#
@ -13645,6 +13600,12 @@ test -n "$target_alias" &&
VAR_CPU_BITS=32
VAR_CPU_ENDIAN=little
;;
aarch64)
VAR_CPU=aarch64
VAR_CPU_ARCH=aarch64
VAR_CPU_BITS=64
VAR_CPU_ENDIAN=little
;;
powerpc)
VAR_CPU=ppc
VAR_CPU_ARCH=ppc
@ -13778,6 +13739,12 @@ $as_echo "$OPENJDK_BUILD_OS-$OPENJDK_BUILD_CPU" >&6; }
VAR_CPU_BITS=32
VAR_CPU_ENDIAN=little
;;
aarch64)
VAR_CPU=aarch64
VAR_CPU_ARCH=aarch64
VAR_CPU_BITS=64
VAR_CPU_ENDIAN=little
;;
powerpc)
VAR_CPU=ppc
VAR_CPU_ARCH=ppc
@ -14633,6 +14600,9 @@ $as_echo "$with_jvm_variants" >&6; }
if test "x$OPENJDK_TARGET_OS" = xaix ; then
INCLUDE_SA=false
fi
if test "x$OPENJDK_TARGET_CPU" = xaarch64; then
INCLUDE_SA=false
fi
if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
@ -26639,7 +26609,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
# Store the CFLAGS etc passed to the configure script.
ORG_CFLAGS="$CFLAGS"
ORG_CXXFLAGS="$CXXFLAGS"
ORG_OBJCFLAGS="$OBJCFLAGS"
# On Windows, we need to detect the visual studio installation first.
# This will change the PATH, but we need to keep that new PATH even
@ -33527,543 +33496,6 @@ $as_echo "$as_me: Rewriting AR to \"$new_complete\"" >&6;}
if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
ac_ext=m
ac_cpp='$OBJCPP $CPPFLAGS'
ac_compile='$OBJC -c $OBJCFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$OBJC -o conftest$ac_exeext $OBJCFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_objc_compiler_gnu
if test -n "$ac_tool_prefix"; then
for ac_prog in gcc objcc objc cc CC
do
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_OBJC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$OBJC"; then
ac_cv_prog_OBJC="$OBJC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OBJC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
OBJC=$ac_cv_prog_OBJC
if test -n "$OBJC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJC" >&5
$as_echo "$OBJC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$OBJC" && break
done
fi
if test -z "$OBJC"; then
ac_ct_OBJC=$OBJC
for ac_prog in gcc objcc objc cc CC
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_OBJC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_OBJC"; then
ac_cv_prog_ac_ct_OBJC="$ac_ct_OBJC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OBJC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
ac_ct_OBJC=$ac_cv_prog_ac_ct_OBJC
if test -n "$ac_ct_OBJC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJC" >&5
$as_echo "$ac_ct_OBJC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$ac_ct_OBJC" && break
done
if test "x$ac_ct_OBJC" = x; then
OBJC="gcc"
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
OBJC=$ac_ct_OBJC
fi
fi
# Provide some information about the compiler.
$as_echo "$as_me:${as_lineno-$LINENO}: checking for Objective C compiler version" >&5
set X $ac_compile
ac_compiler=$2
for ac_option in --version -v -V -qversion; do
{ { ac_try="$ac_compiler $ac_option >&5"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_compiler $ac_option >&5") 2>conftest.err
ac_status=$?
if test -s conftest.err; then
sed '10a\
... rest of stderr output deleted ...
10q' conftest.err >conftest.er1
cat conftest.er1 >&5
fi
rm -f conftest.er1 conftest.err
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
done
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Objective C compiler" >&5
$as_echo_n "checking whether we are using the GNU Objective C compiler... " >&6; }
if ${ac_cv_objc_compiler_gnu+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
#ifndef __GNUC__
choke me
#endif
;
return 0;
}
_ACEOF
if ac_fn_objc_try_compile "$LINENO"; then :
ac_compiler_gnu=yes
else
ac_compiler_gnu=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_cv_objc_compiler_gnu=$ac_compiler_gnu
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objc_compiler_gnu" >&5
$as_echo "$ac_cv_objc_compiler_gnu" >&6; }
if test $ac_compiler_gnu = yes; then
GOBJC=yes
else
GOBJC=
fi
ac_test_OBJCFLAGS=${OBJCFLAGS+set}
ac_save_OBJCFLAGS=$OBJCFLAGS
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $OBJC accepts -g" >&5
$as_echo_n "checking whether $OBJC accepts -g... " >&6; }
if ${ac_cv_prog_objc_g+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_save_objc_werror_flag=$ac_objc_werror_flag
ac_objc_werror_flag=yes
ac_cv_prog_objc_g=no
OBJCFLAGS="-g"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_objc_try_compile "$LINENO"; then :
ac_cv_prog_objc_g=yes
else
OBJCFLAGS=""
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_objc_try_compile "$LINENO"; then :
else
ac_objc_werror_flag=$ac_save_objc_werror_flag
OBJCFLAGS="-g"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_objc_try_compile "$LINENO"; then :
ac_cv_prog_objc_g=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_objc_werror_flag=$ac_save_objc_werror_flag
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_objc_g" >&5
$as_echo "$ac_cv_prog_objc_g" >&6; }
if test "$ac_test_OBJCFLAGS" = set; then
OBJCFLAGS=$ac_save_OBJCFLAGS
elif test $ac_cv_prog_objc_g = yes; then
if test "$GOBJC" = yes; then
OBJCFLAGS="-g -O2"
else
OBJCFLAGS="-g"
fi
else
if test "$GOBJC" = yes; then
OBJCFLAGS="-O2"
else
OBJCFLAGS=
fi
fi
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
# Only process if variable expands to non-empty
if test "x$OBJC" != x; then
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
# First separate the path from the arguments. This will split at the first
# space.
complete="$OBJC"
path="${complete%% *}"
tmp="$complete EOL"
arguments="${tmp#* }"
# Input might be given as Windows format, start by converting to
# unix format.
new_path=`$CYGPATH -u "$path"`
# Now try to locate executable using which
new_path=`$WHICH "$new_path" 2> /dev/null`
# bat and cmd files are not always considered executable in cygwin causing which
# to not find them
if test "x$new_path" = x \
&& test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \
&& test "x`$LS \"$path\" 2>/dev/null`" != x; then
new_path=`$CYGPATH -u "$path"`
fi
if test "x$new_path" = x; then
# Oops. Which didn't find the executable.
# The splitting of arguments from the executable at a space might have been incorrect,
# since paths with space are more likely in Windows. Give it another try with the whole
# argument.
path="$complete"
arguments="EOL"
new_path=`$CYGPATH -u "$path"`
new_path=`$WHICH "$new_path" 2> /dev/null`
# bat and cmd files are not always considered executable in cygwin causing which
# to not find them
if test "x$new_path" = x \
&& test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \
&& test "x`$LS \"$path\" 2>/dev/null`" != x; then
new_path=`$CYGPATH -u "$path"`
fi
if test "x$new_path" = x; then
# It's still not found. Now this is an unrecoverable error.
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of OBJC, which resolves as \"$complete\", is not found." >&5
$as_echo "$as_me: The path of OBJC, which resolves as \"$complete\", is not found." >&6;}
has_space=`$ECHO "$complete" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: You might be mixing spaces in the path and extra arguments, which is not allowed." >&5
$as_echo "$as_me: You might be mixing spaces in the path and extra arguments, which is not allowed." >&6;}
fi
as_fn_error $? "Cannot locate the the path of OBJC" "$LINENO" 5
fi
fi
# Cygwin tries to hide some aspects of the Windows file system, such that binaries are
# named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
# This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
# Short path failed, file does not exist as specified.
# Try adding .exe or .cmd
if test -f "${new_path}.exe"; then
input_to_shortpath="${new_path}.exe"
elif test -f "${new_path}.cmd"; then
input_to_shortpath="${new_path}.cmd"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of OBJC, which resolves as \"$new_path\", is invalid." >&5
$as_echo "$as_me: The path of OBJC, which resolves as \"$new_path\", is invalid." >&6;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: Neither \"$new_path\" nor \"$new_path.exe/cmd\" can be found" >&5
$as_echo "$as_me: Neither \"$new_path\" nor \"$new_path.exe/cmd\" can be found" >&6;}
as_fn_error $? "Cannot locate the the path of OBJC" "$LINENO" 5
fi
else
input_to_shortpath="$new_path"
fi
# Call helper function which possibly converts this using DOS-style short mode.
# If so, the updated path is stored in $new_path.
new_path="$input_to_shortpath"
input_path="$input_to_shortpath"
# Check if we need to convert this using DOS-style short mode. If the path
# contains just simple characters, use it. Otherwise (spaces, weird characters),
# take no chances and rewrite it.
# Note: m4 eats our [], so we need to use [ and ] instead.
has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
if test "x$has_forbidden_chars" != x; then
# Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
shortmode_path=`$CYGPATH -s -m -a "$input_path"`
path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
# Going to short mode and back again did indeed matter. Since short mode is
# case insensitive, let's make it lowercase to improve readability.
shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
# Now convert it back to Unix-stile (cygpath)
input_path=`$CYGPATH -u "$shortmode_path"`
new_path="$input_path"
fi
fi
test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
if test "x$test_cygdrive_prefix" = x; then
# As a simple fix, exclude /usr/bin since it's not a real path.
if test "x`$ECHO $input_to_shortpath | $GREP ^/usr/bin/`" = x; then
# The path is in a Cygwin special directory (e.g. /home). We need this converted to
# a path prefixed by /cygdrive for fixpath to work.
new_path="$CYGWIN_ROOT_PATH$input_path"
fi
fi
# remove trailing .exe if any
new_path="${new_path/%.exe/}"
elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
# First separate the path from the arguments. This will split at the first
# space.
complete="$OBJC"
path="${complete%% *}"
tmp="$complete EOL"
arguments="${tmp#* }"
# Input might be given as Windows format, start by converting to
# unix format.
new_path="$path"
windows_path="$new_path"
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
unix_path=`$CYGPATH -u "$windows_path"`
new_path="$unix_path"
elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
new_path="$unix_path"
fi
# Now try to locate executable using which
new_path=`$WHICH "$new_path" 2> /dev/null`
if test "x$new_path" = x; then
# Oops. Which didn't find the executable.
# The splitting of arguments from the executable at a space might have been incorrect,
# since paths with space are more likely in Windows. Give it another try with the whole
# argument.
path="$complete"
arguments="EOL"
new_path="$path"
windows_path="$new_path"
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
unix_path=`$CYGPATH -u "$windows_path"`
new_path="$unix_path"
elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
new_path="$unix_path"
fi
new_path=`$WHICH "$new_path" 2> /dev/null`
# bat and cmd files are not always considered executable in MSYS causing which
# to not find them
if test "x$new_path" = x \
&& test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \
&& test "x`$LS \"$path\" 2>/dev/null`" != x; then
new_path="$path"
windows_path="$new_path"
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
unix_path=`$CYGPATH -u "$windows_path"`
new_path="$unix_path"
elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
new_path="$unix_path"
fi
fi
if test "x$new_path" = x; then
# It's still not found. Now this is an unrecoverable error.
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of OBJC, which resolves as \"$complete\", is not found." >&5
$as_echo "$as_me: The path of OBJC, which resolves as \"$complete\", is not found." >&6;}
has_space=`$ECHO "$complete" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: You might be mixing spaces in the path and extra arguments, which is not allowed." >&5
$as_echo "$as_me: You might be mixing spaces in the path and extra arguments, which is not allowed." >&6;}
fi
as_fn_error $? "Cannot locate the the path of OBJC" "$LINENO" 5
fi
fi
# Now new_path has a complete unix path to the binary
if test "x`$ECHO $new_path | $GREP ^/bin/`" != x; then
# Keep paths in /bin as-is, but remove trailing .exe if any
new_path="${new_path/%.exe/}"
# Do not save /bin paths to all_fixpath_prefixes!
else
# Not in mixed or Windows style, start by that.
new_path=`cmd //c echo $new_path`
input_path="$new_path"
# Check if we need to convert this using DOS-style short mode. If the path
# contains just simple characters, use it. Otherwise (spaces, weird characters),
# take no chances and rewrite it.
# Note: m4 eats our [], so we need to use [ and ] instead.
has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
if test "x$has_forbidden_chars" != x; then
# Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
fi
# Output is in $new_path
windows_path="$new_path"
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
unix_path=`$CYGPATH -u "$windows_path"`
new_path="$unix_path"
elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
new_path="$unix_path"
fi
# remove trailing .exe if any
new_path="${new_path/%.exe/}"
# Save the first 10 bytes of this path to the storage, so fixpath can work.
all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
fi
else
# We're on a unix platform. Hooray! :)
# First separate the path from the arguments. This will split at the first
# space.
complete="$OBJC"
path="${complete%% *}"
tmp="$complete EOL"
arguments="${tmp#* }"
# Cannot rely on the command "which" here since it doesn't always work.
is_absolute_path=`$ECHO "$path" | $GREP ^/`
if test -z "$is_absolute_path"; then
# Path to executable is not absolute. Find it.
IFS_save="$IFS"
IFS=:
for p in $PATH; do
if test -f "$p/$path" && test -x "$p/$path"; then
new_path="$p/$path"
break
fi
done
IFS="$IFS_save"
else
# This is an absolute path, we can use it without further modifications.
new_path="$path"
fi
if test "x$new_path" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of OBJC, which resolves as \"$complete\", is not found." >&5
$as_echo "$as_me: The path of OBJC, which resolves as \"$complete\", is not found." >&6;}
has_space=`$ECHO "$complete" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: This might be caused by spaces in the path, which is not allowed." >&5
$as_echo "$as_me: This might be caused by spaces in the path, which is not allowed." >&6;}
fi
as_fn_error $? "Cannot locate the the path of OBJC" "$LINENO" 5
fi
fi
# Now join together the path and the arguments once again
if test "x$arguments" != xEOL; then
new_complete="$new_path ${arguments% *}"
else
new_complete="$new_path"
fi
if test "x$complete" != "x$new_complete"; then
OBJC="$new_complete"
{ $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting OBJC to \"$new_complete\"" >&5
$as_echo "$as_me: Rewriting OBJC to \"$new_complete\"" >&6;}
fi
fi
# Publish this variable in the help.
@ -34536,8 +33968,6 @@ $as_echo "$as_me: Rewriting LIPO to \"$new_complete\"" >&6;}
fi
fi
else
OBJC=
fi
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
@ -39836,7 +39266,6 @@ $as_echo "$as_me: Rewriting OBJDUMP to \"$new_complete\"" >&6;}
# This is necessary since AC_PROG_CC defaults CFLAGS to "-g -O2"
CFLAGS="$ORG_CFLAGS"
CXXFLAGS="$ORG_CXXFLAGS"
OBJCFLAGS="$ORG_OBJCFLAGS"
# Finally do some processing after the detection phase
@ -52090,7 +51519,7 @@ $as_echo "$as_me: WARNING: --with-ccache-dir has no meaning when ccache is not e
if test "x$CCACHE" != x; then
if test "x$USE_PRECOMPILED_HEADER" = "x1"; then
HAS_BAD_CCACHE=`$ECHO $CCACHE_VERSION | \
$GREP -e '^1.*' -e '^2.*' -e '^3\.0.*' -e '^3\.1\.[0123]'`
$GREP -e '^1.*' -e '^2.*' -e '^3\.0.*' -e '^3\.1\.[0123]$'`
if test "x$HAS_BAD_CCACHE" != "x"; then
as_fn_error $? "Precompiled headers requires ccache 3.1.4 or later, found $CCACHE_VERSION" "$LINENO" 5
fi

View File

@ -161,6 +161,9 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JVM_VARIANTS],
if test "x$OPENJDK_TARGET_OS" = xaix ; then
INCLUDE_SA=false
fi
if test "x$OPENJDK_TARGET_CPU" = xaarch64; then
INCLUDE_SA=false
fi
AC_SUBST(INCLUDE_SA)
if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then

View File

@ -48,6 +48,12 @@ AC_DEFUN([PLATFORM_EXTRACT_VARS_FROM_CPU],
VAR_CPU_BITS=32
VAR_CPU_ENDIAN=little
;;
aarch64)
VAR_CPU=aarch64
VAR_CPU_ARCH=aarch64
VAR_CPU_BITS=64
VAR_CPU_ENDIAN=little
;;
powerpc)
VAR_CPU=ppc
VAR_CPU_ARCH=ppc

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -342,9 +342,6 @@ CXXFLAGS_JDKEXE:=@CXXFLAGS_JDKEXE@
CXX:=@FIXPATH@ @CCACHE@ @CXX@
#CXXFLAGS:=@CXXFLAGS@
OBJC:=@CCACHE@ @OBJC@
#OBJCFLAGS:=@OBJCFLAGS@
CPP:=@FIXPATH@ @CPP@
#CPPFLAGS:=@CPPFLAGS@

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -188,7 +188,6 @@ AC_DEFUN_ONCE([TOOLCHAIN_PRE_DETECTION],
# Store the CFLAGS etc passed to the configure script.
ORG_CFLAGS="$CFLAGS"
ORG_CXXFLAGS="$CXXFLAGS"
ORG_OBJCFLAGS="$OBJCFLAGS"
# On Windows, we need to detect the visual studio installation first.
# This will change the PATH, but we need to keep that new PATH even
@ -232,7 +231,6 @@ AC_DEFUN_ONCE([TOOLCHAIN_POST_DETECTION],
# This is necessary since AC_PROG_CC defaults CFLAGS to "-g -O2"
CFLAGS="$ORG_CFLAGS"
CXXFLAGS="$ORG_CXXFLAGS"
OBJCFLAGS="$ORG_OBJCFLAGS"
])
# Check if a compiler is of the toolchain type we expect, and save the version
@ -541,12 +539,8 @@ AC_DEFUN_ONCE([TOOLCHAIN_DETECT_TOOLCHAIN_CORE],
AC_DEFUN_ONCE([TOOLCHAIN_DETECT_TOOLCHAIN_EXTRA],
[
if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
AC_PROG_OBJC
BASIC_FIXUP_EXECUTABLE(OBJC)
BASIC_PATH_PROGS(LIPO, lipo)
BASIC_FIXUP_EXECUTABLE(LIPO)
else
OBJC=
fi
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then

View File

@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -26,7 +26,7 @@
# the root of the build directory.
##########################################################################################
################################################################################
# Check that we are run via the wrapper generated by configure
if [ -z "$SRC_ROOT" ]; then
@ -35,7 +35,7 @@ if [ -z "$SRC_ROOT" ]; then
fi
if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
FULLDUMP_CMD="$OTOOL -v -V -h -X -t -d"
FULLDUMP_CMD="$OTOOL -v -V -h -X -d"
LDD_CMD="$OTOOL -L"
DIS_CMD="$OTOOL -v -t"
STAT_PRINT_SIZE="-f %z"
@ -61,7 +61,7 @@ fi
# Include exception definitions
. "$COMPARE_EXCEPTIONS_INCLUDE"
##########################################################################################
################################################################################
# Compare text files and ignore specific differences:
#
# * Timestamps in Java sources generated by idl2java
@ -134,9 +134,15 @@ diff_text() {
$SED -e '/[<>].*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d')
fi
if test "x$SUFFIX" = "xhtml"; then
TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \
# Some javadoc versions do not put quotes around font size
HTML_FILTER="$SED \
-e 's/<font size=-1>/<font size=\"-1\">/g'"
$CAT $THIS_FILE | eval "$HTML_FILTER" > $THIS_FILE.filtered
$CAT $OTHER_FILE | eval "$HTML_FILTER" > $OTHER_FILE.filtered
TMP=$(LC_ALL=C $DIFF $OTHER_FILE.filtered $THIS_FILE.filtered | \
$GREP '^[<>]' | \
$SED -e '/[<>] <!-- Generated by javadoc .* on .* -->/d' )
$SED -e '/[<>] <!-- Generated by javadoc .* on .* -->/d' \
-e '/[<>] <meta name="date" content=".*">/d' )
fi
if test -n "$TMP"; then
echo Files $OTHER_FILE and $THIS_FILE differ
@ -146,7 +152,7 @@ diff_text() {
return 0
}
##########################################################################################
################################################################################
# Compare directory structure
compare_dirs() {
@ -182,7 +188,7 @@ compare_dirs() {
}
##########################################################################################
################################################################################
# Compare file structure
compare_files() {
@ -218,7 +224,7 @@ compare_files() {
}
##########################################################################################
################################################################################
# Compare permissions
compare_permissions() {
@ -249,7 +255,7 @@ compare_permissions() {
fi
}
##########################################################################################
################################################################################
# Compare file command output
compare_file_types() {
@ -289,7 +295,7 @@ compare_file_types() {
fi
}
##########################################################################################
################################################################################
# Compare the rest of the files
compare_general_files() {
@ -297,12 +303,14 @@ compare_general_files() {
OTHER_DIR=$2
WORK_DIR=$3
GENERAL_FILES=$(cd $THIS_DIR && $FIND . -type f ! -name "*.so" ! -name "*.jar" ! -name "*.zip" \
! -name "*.debuginfo" ! -name "*.dylib" ! -name "jexec" ! -name "*.jimage" \
! -name "ct.sym" ! -name "*.diz" ! -name "*.dll" ! -name "*.cpl" \
! -name "*.pdb" ! -name "*.exp" ! -name "*.ilk" \
GENERAL_FILES=$(cd $THIS_DIR && $FIND . -type f ! -name "*.so" ! -name "*.jar" \
! -name "*.zip" ! -name "*.debuginfo" ! -name "*.dylib" ! -name "jexec" \
! -name "*.jimage" ! -name "ct.sym" ! -name "*.diz" ! -name "*.dll" \
! -name "*.cpl" ! -name "*.pdb" ! -name "*.exp" ! -name "*.ilk" \
! -name "*.lib" ! -name "*.war" ! -name "JavaControlPanel" \
! -name "*.obj" ! -name "*.o" ! -name "JavaControlPanelHelper" ! -name "JavaUpdater" \
! -name "*.obj" ! -name "*.o" ! -name "JavaControlPanelHelper" \
! -name "JavaUpdater" ! -name "JavaWSApplicationStub" \
! -name "jspawnhelper" \
| $GREP -v "./bin/" | $SORT | $FILTER)
echo General files...
@ -357,7 +365,7 @@ compare_general_files() {
}
##########################################################################################
################################################################################
# Compare zip file
compare_zip_file() {
@ -456,8 +464,9 @@ compare_zip_file() {
fi
if [ "$OPENJDK_TARGET_OS" = "solaris" ]; then
DIFFING_FILES=$($GREP -e "differ$" -e "^diff " $CONTENTS_DIFF_FILE \
| $CUT -f 3 -d ' ' | $SED "s|$OTHER_UNZIPDIR/||g")
DIFFING_FILES=$($GREP -e 'differ$' -e '^diff ' $CONTENTS_DIFF_FILE \
| $SED -e 's/^Files //g' -e 's/diff -r //g' | $CUT -f 1 -d ' ' \
| $SED "s|$OTHER_UNZIPDIR/||g")
else
DIFFING_FILES=$($GREP -e "differ$" $CONTENTS_DIFF_FILE \
| $CUT -f 2 -d ' ' | $SED "s|$OTHER_UNZIPDIR/||g")
@ -473,7 +482,7 @@ compare_zip_file() {
if [ -s "$WORK_DIR/$ZIP_FILE.diffs" ]; then
return_value=1
echo " Differing files in $ZIP_FILE"
$CAT $WORK_DIR/$ZIP_FILE.diffs | $GREP differ | cut -f 2 -d ' ' | \
$CAT $WORK_DIR/$ZIP_FILE.diffs | $GREP 'differ$' | cut -f 2 -d ' ' | \
$SED "s|$OTHER_UNZIPDIR| |g" > $WORK_DIR/$ZIP_FILE.difflist
$CAT $WORK_DIR/$ZIP_FILE.difflist
@ -494,7 +503,7 @@ compare_zip_file() {
}
##########################################################################################
################################################################################
# Compare all zip files
compare_all_zip_files() {
@ -522,7 +531,7 @@ compare_all_zip_files() {
return $return_value
}
##########################################################################################
################################################################################
# Compare all jar files
compare_all_jar_files() {
@ -552,7 +561,7 @@ compare_all_jar_files() {
return $return_value
}
##########################################################################################
################################################################################
# Compare binary (executable/library) file
compare_bin_file() {
@ -798,8 +807,12 @@ compare_bin_file() {
# Compare fulldump output
if [ -n "$FULLDUMP_CMD" ] && [ -z "$SKIP_FULLDUMP_DIFF" ]; then
$FULLDUMP_CMD $OTHER_FILE > $WORK_FILE_BASE.fulldump.other 2>&1
$FULLDUMP_CMD $THIS_FILE > $WORK_FILE_BASE.fulldump.this 2>&1
if [ -z "$FULLDUMP_DIFF_FILTER" ]; then
FULLDUMP_DIFF_FILTER="$CAT"
fi
$FULLDUMP_CMD $OTHER_FILE | eval "$FULLDUMP_DIFF_FILTER" > $WORK_FILE_BASE.fulldump.other 2>&1
$FULLDUMP_CMD $THIS_FILE | eval "$FULLDUMP_DIFF_FILTER" > $WORK_FILE_BASE.fulldump.this 2>&1
LC_ALL=C $DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this > $WORK_FILE_BASE.fulldump.diff
if [ -s $WORK_FILE_BASE.fulldump.diff ]; then
@ -895,7 +908,7 @@ compare_bin_file() {
return 0
}
##########################################################################################
################################################################################
# Print binary diff header
print_binary_diff_header() {
@ -908,7 +921,7 @@ print_binary_diff_header() {
echo
}
##########################################################################################
################################################################################
# Compare all libraries
compare_all_libs() {
@ -936,7 +949,7 @@ compare_all_libs() {
return $return_value
}
##########################################################################################
################################################################################
# Compare all executables
compare_all_execs() {
@ -971,7 +984,7 @@ compare_all_execs() {
return $return_value
}
##########################################################################################
################################################################################
# Initiate configuration
COMPARE_ROOT=/tmp/cimages.$USER
@ -982,7 +995,7 @@ if [ "$OPENJDK_TARGET_OS" = "windows" ]; then
fi
fi
THIS="$( cd "$( dirname "$0" )" && pwd )"
THIS="$( cd "$( dirname "$0" )" > /dev/null && pwd )"
echo "$THIS"
THIS_SCRIPT="$0"
@ -1072,8 +1085,8 @@ while [ -n "$1" ]; do
CMP_EXECS=true
;;
-2dirs)
THIS="$(cd "$2" && pwd )"
OTHER="$(cd "$3" && pwd )"
THIS="$(cd "$2" > /dev/null && pwd )"
OTHER="$(cd "$3" > /dev/null && pwd )"
THIS_BASE_DIR="$THIS"
OTHER_BASE_DIR="$OTHER"
SKIP_DEFAULT=true
@ -1114,9 +1127,9 @@ done
if [ "$CMP_2_ZIPS" = "true" ]; then
THIS_DIR="$(dirname $THIS_FILE)"
THIS_DIR="$(cd "$THIS_DIR" && pwd )"
THIS_DIR="$(cd "$THIS_DIR" > /dev/null && pwd )"
OTHER_DIR="$(dirname $OTHER_FILE)"
OTHER_DIR="$(cd "$OTHER_DIR" && pwd )"
OTHER_DIR="$(cd "$OTHER_DIR" > /dev/null && pwd )"
THIS_FILE_NAME="$(basename $THIS_FILE)"
OTHER_FILE_NAME="$(basename $OTHER_FILE)"
echo Comparing $THIS_DIR/$THIS_FILE_NAME and $OTHER_DIR/$OTHER_FILE_NAME
@ -1126,9 +1139,9 @@ fi
if [ "$CMP_2_BINS" = "true" ]; then
THIS_DIR="$(dirname $THIS_FILE)"
THIS_DIR="$(cd "$THIS_DIR" && pwd )"
THIS_DIR="$(cd "$THIS_DIR" > /dev/null && pwd )"
OTHER_DIR="$(dirname $OTHER_FILE)"
OTHER_DIR="$(cd "$OTHER_DIR" && pwd )"
OTHER_DIR="$(cd "$OTHER_DIR" > /dev/null && pwd )"
THIS_FILE_NAME="$(basename $THIS_FILE)"
OTHER_FILE_NAME="$(basename $OTHER_FILE)"
echo Comparing $THIS_DIR/$THIS_FILE_NAME and $OTHER_DIR/$OTHER_FILE_NAME
@ -1161,7 +1174,7 @@ if [ "$SKIP_DEFAULT" != "true" ]; then
echo "$OTHER"
exit 1
fi
OTHER="$( cd "$OTHER" && pwd )"
OTHER="$( cd "$OTHER" > /dev/null && pwd )"
echo "Comparing to:"
echo "$OTHER"
echo
@ -1170,45 +1183,98 @@ if [ "$SKIP_DEFAULT" != "true" ]; then
# Find the common images to compare, prioritizing later build stages
if [ -d "$THIS/install/jdk" ] && [ -d "$OTHER/install/jdk" ]; then
THIS_J2SDK="$THIS/install/jdk"
THIS_J2RE="$THIS/install/jre"
OTHER_J2SDK="$OTHER/install/jdk"
OTHER_J2RE="$OTHER/install/jre"
THIS_JDK="$THIS/install/jdk"
THIS_JRE="$THIS/install/jre"
OTHER_JDK="$OTHER/install/jdk"
OTHER_JRE="$OTHER/install/jre"
echo "Selecting install images for compare"
elif [ -d "$THIS/deploy/jdk" ] && [ -d "$OTHER/deploy/jdk" ]; then
THIS_J2SDK="$THIS/deploy/jdk"
THIS_J2RE="$THIS/deploy/jre"
OTHER_J2SDK="$OTHER/deploy/jdk"
OTHER_J2RE="$OTHER/deploy/jre"
elif [ -d "$THIS/deploy/jdk" -o -d "$THIS/deploy/images/jdk" ] \
&& [ -d "$OTHER/deploy/jdk" -o -d "$OTHER/deploy/images/jdk" ]; then
if [ -d "$THIS/deploy/images/jdk" ]; then
THIS_JDK="$THIS/deploy/images/jdk"
THIS_JRE="$THIS/deploy/images/jre"
else
THIS_JDK="$THIS/deploy/jdk"
THIS_JRE="$THIS/deploy/jre"
fi
if [ -d "$OTHER/deploy/images/jdk" ]; then
OTHER_JDK="$OTHER/deploy/images/jdk"
OTHER_JRE="$OTHER/deploy/images/jre"
else
OTHER_JDK="$OTHER/deploy/jdk"
OTHER_JRE="$OTHER/deploy/jre"
fi
echo "Selecting deploy images for compare"
elif [ -d "$THIS/deploy/images/jdk" ] && [ -d "$OTHER/deploy/jdk" ]; then
THIS_JDK="$THIS/deploy/jdk"
THIS_JRE="$THIS/deploy/jre"
OTHER_JDK="$OTHER/deploy/jdk"
OTHER_JRE="$OTHER/deploy/jre"
echo "Selecting deploy images for compare"
elif [ -d "$THIS/images/jdk" ] && [ -d "$OTHER/images/jdk" ]; then
THIS_J2SDK="$THIS/images/jdk"
THIS_J2RE="$THIS/images/jre"
OTHER_J2SDK="$OTHER/images/jdk"
OTHER_J2RE="$OTHER/images/jre"
THIS_JDK="$THIS/images/jdk"
THIS_JRE="$THIS/images/jre"
OTHER_JDK="$OTHER/images/jdk"
OTHER_JRE="$OTHER/images/jre"
echo "Selecting jdk images for compare"
else
echo "No common images found."
exit 1
fi
if [ -d "$THIS/images/jdk-bundle" ] && [ -d "$OTHER/images/jdk-bundle" ]; then
THIS_J2SDK_BUNDLE="$THIS/images/jdk-bundle"
THIS_J2RE_BUNDLE="$THIS/images/jre-bundle"
OTHER_J2SDK_BUNDLE="$OTHER/images/jdk-bundle"
OTHER_J2RE_BUNDLE="$OTHER/images/jre-bundle"
if [ -d "$THIS/deploy/jdk-bundle" -o -d "$THIS/deploy/images/jdk-bundle" ] \
&& [ -d "$OTHER/deploy/jdk-bundle" -o -d "$OTHER/deploy/images/jdk-bundle" ]; then
if [ -d "$THIS/deploy/images/jdk-bundle" ]; then
THIS_JDK_BUNDLE="$THIS/deploy/images/jdk-bundle"
THIS_JRE_BUNDLE="$THIS/deploy/images/jre-bundle"
else
THIS_JDK_BUNDLE="$THIS/deploy/jdk-bundle"
THIS_JRE_BUNDLE="$THIS/deploy/jre-bundle"
fi
if [ -d "$OTHER/deploy/images/jdk-bundle" ]; then
OTHER_JDK_BUNDLE="$OTHER/deploy/images/jdk-bundle"
OTHER_JRE_BUNDLE="$OTHER/deploy/images/jre-bundle"
else
OTHER_JDK_BUNDLE="$OTHER/deploy/jdk-bundle"
OTHER_JRE_BUNDLE="$OTHER/deploy/jre-bundle"
fi
echo "Also comparing deploy macosx bundles"
elif [ -d "$THIS/images/jdk-bundle" ] && [ -d "$OTHER/images/jdk-bundle" ]; then
THIS_JDK_BUNDLE="$THIS/images/jdk-bundle"
THIS_JRE_BUNDLE="$THIS/images/jre-bundle"
OTHER_JDK_BUNDLE="$OTHER/images/jdk-bundle"
OTHER_JRE_BUNDLE="$OTHER/images/jre-bundle"
echo "Also comparing macosx bundles"
fi
if [ -d "$THIS/deploy" ] && [ -d "$OTHER/deploy" ]; then
THIS_DEPLOY_BUNDLE_DIR="$THIS/deploy/dist/installer/bundles"
OTHER_DEPLOY_BUNDLE_DIR="$OTHER/deploy/bundles"
echo "Also comparing deploy/bundles"
if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
if [ -d "$THIS/deploy/bundles" -o -d "$THIS/deploy/images/bundles" ] \
&& [ -d "$OTHER/deploy/bundles" -o -d "$OTHER/deploy/images/bundles" ]; then
if [ -d "$THIS/deploy/images/bundles" ]; then
THIS_DEPLOY_BUNDLE_DIR="$THIS/deploy/images/bundles"
else
THIS_DEPLOY_BUNDLE_DIR="$THIS/deploy/bundles"
fi
if [ -d "$OTHER/deploy/images/bundles" ]; then
OTHER_DEPLOY_BUNDLE_DIR="$OTHER/deploy/images/bundles"
else
OTHER_DEPLOY_BUNDLE_DIR="$OTHER/deploy/bundles"
fi
echo "Also comparing deploy javadoc bundles"
fi
if [ -d "$THIS/deploy/JavaAppletPlugin.plugin" -o -d "$THIS/deploy/images/JavaAppletPlugin.plugin" ] \
&& [ -d "$OTHER/deploy/JavaAppletPlugin.plugin" -o -d "$OTHER/deploy/images/JavaAppletPlugin.plugin" ]; then
if [ -d "$THIS/deploy/images/bundles" ]; then
THIS_DEPLOY_APPLET_PLUGIN_DIR="$THIS/deploy/images/JavaAppletPlugin.plugin"
else
THIS_DEPLOY_APPLET_PLUGIN_DIR="$THIS/deploy/JavaAppletPlugin.plugin"
fi
if [ -d "$OTHER/deploy/images/bundles" ]; then
OTHER_DEPLOY_APPLET_PLUGIN_DIR="$OTHER/deploy/images/JavaAppletPlugin.plugin"
else
OTHER_DEPLOY_APPLET_PLUGIN_DIR="$OTHER/deploy/JavaAppletPlugin.plugin"
echo "Also comparing JavaAppletPlugin"
fi
fi
echo "Also comparing deploy applet image"
fi
if [ -d "$OTHER/images" ]; then
@ -1240,31 +1306,31 @@ if [ "$SKIP_DEFAULT" != "true" ]; then
fi
fi
##########################################################################################
################################################################################
# Do the work
if [ "$CMP_NAMES" = "true" ]; then
if [ -n "$THIS_J2SDK" ] && [ -n "$OTHER_J2SDK" ]; then
echo -n "J2SDK "
compare_dirs $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk
echo -n "J2RE "
compare_dirs $THIS_J2RE $OTHER_J2RE $COMPARE_ROOT/j2re
if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
echo -n "JDK "
compare_dirs $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
echo -n "JRE "
compare_dirs $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
echo -n "J2SDK "
compare_files $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk
echo -n "J2RE "
compare_files $THIS_J2RE $OTHER_J2RE $COMPARE_ROOT/j2re
echo -n "JDK "
compare_files $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
echo -n "JRE "
compare_files $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
fi
if [ -n "$THIS_J2SDK_BUNDLE" ] && [ -n "$OTHER_J2SDK_BUNDLE" ]; then
echo -n "J2SDK Bundle "
compare_dirs $THIS_J2SDK_BUNDLE $OTHER_J2SDK_BUNDLE $COMPARE_ROOT/jdk-bundle
echo -n "J2RE Bundle "
compare_dirs $THIS_J2RE_BUNDLE $OTHER_J2RE_BUNDLE $COMPARE_ROOT/jre-bundle
if [ -n "$THIS_JDK_BUNDLE" ] && [ -n "$OTHER_JDK_BUNDLE" ]; then
echo -n "JDK Bundle "
compare_dirs $THIS_JDK_BUNDLE $OTHER_JDK_BUNDLE $COMPARE_ROOT/jdk-bundle
echo -n "JRE Bundle "
compare_dirs $THIS_JRE_BUNDLE $OTHER_JRE_BUNDLE $COMPARE_ROOT/jre-bundle
echo -n "J2SDK Bundle "
compare_files $THIS_J2SDK_BUNDLE $OTHER_J2SDK_BUNDLE $COMPARE_ROOT/jdk-bundle
echo -n "J2RE Bundle "
compare_files $THIS_J2RE_BUNDLE $OTHER_J2RE_BUNDLE $COMPARE_ROOT/jre-bundle
echo -n "JDK Bundle "
compare_files $THIS_JDK_BUNDLE $OTHER_JDK_BUNDLE $COMPARE_ROOT/jdk-bundle
echo -n "JRE Bundle "
compare_files $THIS_JRE_BUNDLE $OTHER_JRE_BUNDLE $COMPARE_ROOT/jre-bundle
fi
if [ -n "$THIS_DOCS" ] && [ -n "$OTHER_DOCS" ]; then
echo -n "Docs "
@ -1285,11 +1351,11 @@ if [ "$CMP_NAMES" = "true" ]; then
fi
if [ "$CMP_PERMS" = "true" ]; then
if [ -n "$THIS_J2SDK" ] && [ -n "$OTHER_J2SDK" ]; then
echo -n "J2SDK "
compare_permissions $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk
echo -n "J2RE "
compare_permissions $THIS_J2RE $OTHER_J2RE $COMPARE_ROOT/j2re
if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
echo -n "JDK "
compare_permissions $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
echo -n "JRE "
compare_permissions $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
fi
if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then
compare_permissions $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
@ -1301,17 +1367,17 @@ if [ "$CMP_PERMS" = "true" ]; then
fi
if [ "$CMP_TYPES" = "true" ]; then
if [ -n "$THIS_J2SDK" ] && [ -n "$OTHER_J2SDK" ]; then
echo -n "J2SDK "
compare_file_types $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk
echo -n "J2RE "
compare_file_types $THIS_J2RE $OTHER_J2RE $COMPARE_ROOT/j2re
if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
echo -n "JDK "
compare_file_types $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
echo -n "JRE "
compare_file_types $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
fi
if [ -n "$THIS_J2SDK_BUNDLE" ] && [ -n "$OTHER_J2SDK_BUNDLE" ]; then
echo -n "J2SDK Bundle "
compare_file_types $THIS_J2SDK_BUNDLE $OTHER_J2SDK_BUNDLE $COMPARE_ROOT/jdk-bundle
echo -n "J2RE Bundle "
compare_file_types $THIS_J2RE_BUNDLE $OTHER_J2RE_BUNDLE $COMPARE_ROOT/jre-bundle
if [ -n "$THIS_JDK_BUNDLE" ] && [ -n "$OTHER_JDK_BUNDLE" ]; then
echo -n "JDK Bundle "
compare_file_types $THIS_JDK_BUNDLE $OTHER_JDK_BUNDLE $COMPARE_ROOT/jdk-bundle
echo -n "JRE Bundle "
compare_file_types $THIS_JRE_BUNDLE $OTHER_JRE_BUNDLE $COMPARE_ROOT/jre-bundle
fi
if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then
compare_file_types $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
@ -1323,17 +1389,17 @@ if [ "$CMP_TYPES" = "true" ]; then
fi
if [ "$CMP_GENERAL" = "true" ]; then
if [ -n "$THIS_J2SDK" ] && [ -n "$OTHER_J2SDK" ]; then
echo -n "J2SDK "
compare_general_files $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk
echo -n "J2RE "
compare_general_files $THIS_J2RE $OTHER_J2RE $COMPARE_ROOT/j2re
if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
echo -n "JDK "
compare_general_files $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
echo -n "JRE "
compare_general_files $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
fi
if [ -n "$THIS_J2SDK_BUNDLE" ] && [ -n "$OTHER_J2SDK_BUNDLE" ]; then
echo -n "J2SDK Bundle "
compare_general_files $THIS_J2SDK_BUNDLE $OTHER_J2SDK_BUNDLE $COMPARE_ROOT/jdk-bundle
echo -n "J2RE Bundle "
compare_general_files $THIS_J2RE_BUNDLE $OTHER_J2RE_BUNDLE $COMPARE_ROOT/jre-bundle
if [ -n "$THIS_JDK_BUNDLE" ] && [ -n "$OTHER_JDK_BUNDLE" ]; then
echo -n "JDK Bundle "
compare_general_files $THIS_JDK_BUNDLE $OTHER_JDK_BUNDLE $COMPARE_ROOT/jdk-bundle
echo -n "JRE Bundle "
compare_general_files $THIS_JRE_BUNDLE $OTHER_JRE_BUNDLE $COMPARE_ROOT/jre-bundle
fi
if [ -n "$THIS_DOCS" ] && [ -n "$OTHER_DOCS" ]; then
echo -n "Docs "
@ -1349,8 +1415,8 @@ if [ "$CMP_GENERAL" = "true" ]; then
fi
if [ "$CMP_ZIPS" = "true" ]; then
if [ -n "$THIS_J2SDK" ] && [ -n "$OTHER_J2SDK" ]; then
compare_all_zip_files $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk
if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
compare_all_zip_files $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
fi
if [ -n "$THIS_SEC_BIN" ] && [ -n "$OTHER_SEC_BIN" ]; then
if [ -n "$(echo $THIS_SEC_BIN | $FILTER)" ]; then
@ -1382,8 +1448,8 @@ if [ "$CMP_ZIPS" = "true" ]; then
fi
if [ "$CMP_JARS" = "true" ]; then
if [ -n "$THIS_J2SDK" ] && [ -n "$OTHER_J2SDK" ]; then
compare_all_jar_files $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk
if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
compare_all_jar_files $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
fi
if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then
compare_all_jar_files $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
@ -1394,12 +1460,12 @@ if [ "$CMP_JARS" = "true" ]; then
fi
if [ "$CMP_LIBS" = "true" ]; then
if [ -n "$THIS_J2SDK" ] && [ -n "$OTHER_J2SDK" ]; then
echo -n "J2SDK "
compare_all_libs $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk
if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
echo -n "JDK "
compare_all_libs $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
echo -n "J2RE "
compare_all_libs $THIS_J2RE $OTHER_J2RE $COMPARE_ROOT/j2re
echo -n "JRE "
compare_all_libs $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
fi
fi
if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then
@ -1412,11 +1478,11 @@ if [ "$CMP_LIBS" = "true" ]; then
fi
if [ "$CMP_EXECS" = "true" ]; then
if [ -n "$THIS_J2SDK" ] && [ -n "$OTHER_J2SDK" ]; then
compare_all_execs $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk
if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
compare_all_execs $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
echo -n "J2RE "
compare_all_execs $THIS_J2RE $OTHER_J2RE $COMPARE_ROOT/j2re
echo -n "JRE "
compare_all_execs $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
fi
fi
if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then

View File

@ -59,17 +59,17 @@ ACCEPTED_BIN_DIFF="
./demo/jvmti/mtrace/lib/libmtrace.so
./demo/jvmti/versionCheck/lib/libversionCheck.so
./demo/jvmti/waiters/lib/libwaiters.so
./jre/lib/i386/client/libjvm.so
./jre/lib/i386/libattach.so
./jre/lib/i386/libdt_socket.so
./jre/lib/i386/libhprof.so
./jre/lib/i386/libinstrument.so
./jre/lib/i386/libjava_crw_demo.so
./jre/lib/i386/libjsdt.so
./jre/lib/i386/libmanagement.so
./jre/lib/i386/libnpt.so
./jre/lib/i386/libverify.so
./jre/lib/i386/server/libjvm.so
./lib/i386/client/libjvm.so
./lib/i386/libattach.so
./lib/i386/libdt_socket.so
./lib/i386/libhprof.so
./lib/i386/libinstrument.so
./lib/i386/libjava_crw_demo.so
./lib/i386/libjsdt.so
./lib/i386/libmanagement.so
./lib/i386/libnpt.so
./lib/i386/libverify.so
./lib/i386/server/libjvm.so
./bin/appletviewer
./bin/idlj
./bin/jar
@ -109,16 +109,6 @@ ACCEPTED_BIN_DIFF="
./bin/wsgen
./bin/wsimport
./bin/xjc
./jre/bin/java
./jre/bin/jjs
./jre/bin/keytool
./jre/bin/orbd
./jre/bin/pack200
./jre/bin/policytool
./jre/bin/rmid
./jre/bin/rmiregistry
./jre/bin/servertool
./jre/bin/tnameserv
"
fi
@ -147,19 +137,19 @@ ACCEPTED_BIN_DIFF="
./demo/jvmti/mtrace/lib/libmtrace.so
./demo/jvmti/versionCheck/lib/libversionCheck.so
./demo/jvmti/waiters/lib/libwaiters.so
./jre/lib/amd64/libattach.so
./jre/lib/amd64/libdt_socket.so
./jre/lib/amd64/libhprof.so
./jre/lib/amd64/libinstrument.so
./jre/lib/amd64/libjava_crw_demo.so
./jre/lib/amd64/libjsdt.so
./jre/lib/amd64/libjsig.so
./jre/lib/amd64/libmanagement.so
./jre/lib/amd64/libnpt.so
./jre/lib/amd64/libsaproc.so
./jre/lib/amd64/libverify.so
./jre/lib/amd64/server/libjsig.so
./jre/lib/amd64/server/libjvm.so
./lib/amd64/libattach.so
./lib/amd64/libdt_socket.so
./lib/amd64/libhprof.so
./lib/amd64/libinstrument.so
./lib/amd64/libjava_crw_demo.so
./lib/amd64/libjsdt.so
./lib/amd64/libjsig.so
./lib/amd64/libmanagement.so
./lib/amd64/libnpt.so
./lib/amd64/libsaproc.so
./lib/amd64/libverify.so
./lib/amd64/server/libjsig.so
./lib/amd64/server/libjvm.so
./bin/appletviewer
./bin/idlj
./bin/jar
@ -199,318 +189,12 @@ ACCEPTED_BIN_DIFF="
./bin/wsgen
./bin/wsimport
./bin/xjc
./jre/bin/java
./jre/bin/jjs
./jre/bin/keytool
./jre/bin/orbd
./jre/bin/pack200
./jre/bin/policytool
./jre/bin/rmid
./jre/bin/rmiregistry
./jre/bin/servertool
./jre/bin/tnameserv
"
fi
if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "x86" ]; then
STRIP_BEFORE_COMPARE="
./demo/jni/Poller/lib/libPoller.so
./demo/jvmti/compiledMethodLoad/lib/libcompiledMethodLoad.so
./demo/jvmti/gctest/lib/libgctest.so
./demo/jvmti/heapTracker/lib/libheapTracker.so
./demo/jvmti/heapViewer/lib/libheapViewer.so
./demo/jvmti/hprof/lib/libhprof.so
./demo/jvmti/minst/lib/libminst.so
./demo/jvmti/mtrace/lib/libmtrace.so
./demo/jvmti/versionCheck/lib/libversionCheck.so
./demo/jvmti/waiters/lib/libwaiters.so
./jre/lib/i386/jexec
"
SORT_SYMBOLS="
./jre/lib/i386/client/libjvm.so
./jre/lib/i386/libsaproc.so
./jre/lib/i386/server/libjvm.so
"
SKIP_BIN_DIFF="true"
ACCEPTED_SMALL_SIZE_DIFF="
./demo/jni/Poller/lib/libPoller.so
./demo/jvmti/compiledMethodLoad/lib/libcompiledMethodLoad.so
./demo/jvmti/gctest/lib/libgctest.so
./demo/jvmti/heapTracker/lib/libheapTracker.so
./demo/jvmti/heapViewer/lib/libheapViewer.so
./demo/jvmti/hprof/lib/libhprof.so
./demo/jvmti/minst/lib/libminst.so
./demo/jvmti/mtrace/lib/libmtrace.so
./demo/jvmti/versionCheck/lib/libversionCheck.so
./demo/jvmti/waiters/lib/libwaiters.so
./jre/lib/i386/client/libjvm.so
./jre/lib/i386/jli/libjli.so
./jre/lib/i386/libJdbcOdbc.so
./jre/lib/i386/libattach.so
./jre/lib/i386/libawt.so
./jre/lib/i386/libawt_headless.so
./jre/lib/i386/libawt_xawt.so
./jre/lib/i386/libdcpr.so
./jre/lib/i386/libdt_socket.so
./jre/lib/i386/libfontmanager.so
./jre/lib/i386/libhprof.so
./jre/lib/i386/libinstrument.so
./jre/lib/i386/libj2gss.so
./jre/lib/i386/libj2pcsc.so
./jre/lib/i386/libj2pkcs11.so
./jre/lib/i386/libj2ucrypto.so
./jre/lib/i386/libjaas_unix.so
./jre/lib/i386/libjava.so
./jre/lib/i386/libjava_crw_demo.so
./jre/lib/i386/libjawt.so
./jre/lib/i386/libjdwp.so
./jre/lib/i386/libjfr.so
./jre/lib/i386/libjpeg.so
./jre/lib/i386/libjsdt.so
./jre/lib/i386/libjsound.so
./jre/lib/i386/libkcms.so
./jre/lib/i386/liblcms.so
./jre/lib/i386/libmanagement.so
./jre/lib/i386/libmlib_image.so
./jre/lib/i386/libnet.so
./jre/lib/i386/libnio.so
./jre/lib/i386/libnpt.so
./jre/lib/i386/libsctp.so
./jre/lib/i386/libsplashscreen.so
./jre/lib/i386/libsunec.so
./jre/lib/i386/libsunwjdga.so
./jre/lib/i386/libt2k.so
./jre/lib/i386/libunpack.so
./jre/lib/i386/libverify.so
./jre/lib/i386/libzip.so
./jre/lib/i386/libdeploy.so
./jre/lib/i386/libjavaplugin.so
./jre/lib/i386/libjavaplugin_jni.so
./jre/lib/i386/libjavaplugin_nscp.so
./jre/lib/i386/libjavaplugin_oji.so
./jre/lib/i386/libnpjp2.so
./jre/plugin/i386/ns4/libjavaplugin.so
./jre/plugin/i386/ns7/libjavaplugin_oji.so
./jre/lib/i386/server/libjvm.so
./jre/lib/i386/client/64/libjvm_db.so
./jre/lib/i386/client/64/libjvm_dtrace.so
./jre/lib/i386/client/libjvm_db.so
./jre/lib/i386/client/libjvm_dtrace.so
./jre/lib/i386/server/64/libjvm_db.so
./jre/lib/i386/server/64/libjvm_dtrace.so
./jre/lib/i386/server/libjvm_db.so
./jre/lib/i386/server/libjvm_dtrace.so
./bin/appletviewer
./bin/idlj
./bin/jar
./bin/jarsigner
./bin/java
./bin/javac
./bin/javadoc
./bin/javah
./bin/javap
./bin/jdeps
./bin/javaws
./bin/jcmd
./bin/jconsole
./bin/jdb
./bin/jhat
./bin/jimage
./bin/jinfo
./bin/jjs
./bin/jmap
./bin/jps
./bin/jrunscript
./bin/jsadebugd
./bin/jstack
./bin/jstat
./bin/jstatd
./bin/keytool
./bin/native2ascii
./bin/orbd
./bin/pack200
./bin/policytool
./bin/rmic
./bin/rmid
./bin/rmiregistry
./bin/schemagen
./bin/serialver
./bin/servertool
./bin/tnameserv
./bin/unpack200
./bin/wsgen
./bin/wsimport
./bin/xjc
./jre/bin/java
./jre/bin/java_vm
./jre/bin/javaws
./jre/bin/keytool
./jre/bin/orbd
./jre/bin/pack200
./jre/bin/policytool
./jre/bin/rmid
./jre/bin/rmiregistry
./jre/bin/servertool
./jre/bin/tnameserv
./jre/bin/unpack200
./jre/lib/i386/jexec
"
SKIP_FULLDUMP_DIFF="true"
# Filter random C++ symbol strings.
# Some numbers differ randomly.
# Can't use space in these expressions as the shell will mess with them.
DIS_DIFF_FILTER="$SED -e s/\.[a-zA-Z0-9_\$]\{15,15\}/<SYM>/g -e s/\([0-9a-f][0-9a-f].\)\{2,8\}[0-9a-f][0-9a-f]/<NUMS>/g -e s/\(0x\)[0-9a-f]*\([,(>]\)/\1<HEX>\2/g -e s/\(0x\)[0-9a-f]*$/\1<HEX>/g -e s/\(\#.\)[0-9a-f]*\(.<\)/\1<HEX>\2/g -e s/[\.A-Za-z0-9%]\{16,16\}$/<BIN>/g"
fi
if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "x86_64" ]; then
STRIP_BEFORE_COMPARE="
./demo/jni/Poller/lib/amd64/libPoller.so
./demo/jvmti/compiledMethodLoad/lib/amd64/libcompiledMethodLoad.so
./demo/jvmti/gctest/lib/amd64/libgctest.so
./demo/jvmti/heapTracker/lib/amd64/libheapTracker.so
./demo/jvmti/heapViewer/lib/amd64/libheapViewer.so
./demo/jvmti/hprof/lib/amd64/libhprof.so
./demo/jvmti/minst/lib/amd64/libminst.so
./demo/jvmti/mtrace/lib/amd64/libmtrace.so
./demo/jvmti/versionCheck/lib/amd64/libversionCheck.so
./demo/jvmti/waiters/lib/amd64/libwaiters.so
"
SORT_SYMBOLS="
./jre/lib/amd64/server/libjvm.so
./jre/lib/amd64/libsaproc.so
"
SKIP_BIN_DIFF="true"
ACCEPTED_SMALL_SIZE_DIFF="
./demo/jni/Poller/lib/amd64/libPoller.so
./demo/jvmti/compiledMethodLoad/lib/amd64/libcompiledMethodLoad.so
./demo/jvmti/gctest/lib/amd64/libgctest.so
./demo/jvmti/heapTracker/lib/amd64/libheapTracker.so
./demo/jvmti/heapViewer/lib/amd64/libheapViewer.so
./demo/jvmti/hprof/lib/amd64/libhprof.so
./demo/jvmti/minst/lib/amd64/libminst.so
./demo/jvmti/mtrace/lib/amd64/libmtrace.so
./demo/jvmti/versionCheck/lib/amd64/libversionCheck.so
./demo/jvmti/waiters/lib/amd64/libwaiters.so
./jre/lib/amd64/jli/libjli.so
./jre/lib/amd64/libJdbcOdbc.so
./jre/lib/amd64/libattach.so
./jre/lib/amd64/libawt.so
./jre/lib/amd64/libawt_headless.so
./jre/lib/amd64/libawt_xawt.so
./jre/lib/amd64/libdcpr.so
./jre/lib/amd64/libdt_socket.so
./jre/lib/amd64/libfontmanager.so
./jre/lib/amd64/libhprof.so
./jre/lib/amd64/libinstrument.so
./jre/lib/amd64/libj2gss.so
./jre/lib/amd64/libj2pcsc.so
./jre/lib/amd64/libj2pkcs11.so
./jre/lib/amd64/libj2ucrypto.so
./jre/lib/amd64/libjaas_unix.so
./jre/lib/amd64/libjava.so
./jre/lib/amd64/libjava_crw_demo.so
./jre/lib/amd64/libjawt.so
./jre/lib/amd64/libjdwp.so
./jre/lib/amd64/libjfr.so
./jre/lib/amd64/libjpeg.so
./jre/lib/amd64/libjsdt.so
./jre/lib/amd64/libjsound.so
./jre/lib/amd64/libkcms.so
./jre/lib/amd64/liblcms.so
./jre/lib/amd64/libmanagement.so
./jre/lib/amd64/libmlib_image.so
./jre/lib/amd64/libnet.so
./jre/lib/amd64/libnio.so
./jre/lib/amd64/libnpt.so
./jre/lib/amd64/libsctp.so
./jre/lib/amd64/libsplashscreen.so
./jre/lib/amd64/libsunec.so
./jre/lib/amd64/libsunwjdga.so
./jre/lib/amd64/libt2k.so
./jre/lib/amd64/libunpack.so
./jre/lib/amd64/libverify.so
./jre/lib/amd64/libzip.so
./jre/lib/amd64/server/64/libjvm_db.so
./jre/lib/amd64/server/64/libjvm_dtrace.so
./jre/lib/amd64/server/libjvm.so
./jre/lib/amd64/server/libjvm_db.so
./jre/lib/amd64/server/libjvm_dtrace.so
./bin/amd64/appletviewer
./bin/amd64/idlj
./bin/amd64/jar
./bin/amd64/jarsigner
./bin/amd64/java
./bin/amd64/javac
./bin/amd64/javadoc
./bin/amd64/javah
./bin/amd64/javap
./bin/amd64/jdeps
./bin/amd64/jcmd
./bin/amd64/jconsole
./bin/amd64/jdb
./bin/amd64/jhat
./bin/amd64/jimage
./bin/amd64/jinfo
./bin/amd64/jjs
./bin/amd64/jmap
./bin/amd64/jps
./bin/amd64/jrunscript
./bin/amd64/jsadebugd
./bin/amd64/jstack
./bin/amd64/jstat
./bin/amd64/jstatd
./bin/amd64/keytool
./bin/amd64/native2ascii
./bin/amd64/orbd
./bin/amd64/pack200
./bin/amd64/policytool
./bin/amd64/rmic
./bin/amd64/rmid
./bin/amd64/rmiregistry
./bin/amd64/schemagen
./bin/amd64/serialver
./bin/amd64/servertool
./bin/amd64/tnameserv
./bin/amd64/unpack200
./bin/amd64/wsgen
./bin/amd64/wsimport
./bin/amd64/xjc
./jre/bin/amd64/java
./jre/bin/amd64/keytool
./jre/bin/amd64/orbd
./jre/bin/amd64/pack200
./jre/bin/amd64/policytool
./jre/bin/amd64/rmid
./jre/bin/amd64/rmiregistry
./jre/bin/amd64/servertool
./jre/bin/amd64/tnameserv
./jre/bin/amd64/unpack200
./jre/lib/amd64/jexec
"
SKIP_FULLDUMP_DIFF="true"
# Filter random C++ symbol strings.
# Some numbers differ randomly.
# Can't use space in these expressions as the shell will mess with them.
DIS_DIFF_FILTER="$SED -e s/\.[a-zA-Z0-9_\$]\{15,15\}/<SYM>/g -e s/\([0-9a-f][0-9a-f].\)\{2,8\}[0-9a-f][0-9a-f]/<NUMS>/g -e s/\(0x\)[0-9a-f]*\([,(>]\)/\1<HEX>\2/g -e s/\(0x\)[0-9a-f]*$/\1<HEX>/g -e s/\(\#.\)[0-9a-f]*\(.<\)/\1<HEX>\2/g -e s/[\.A-Za-z0-9%]\{16,16\}$/<BIN>/g"
fi
if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "sparc" ]; then
STRIP_BEFORE_COMPARE="
./demo/jni/Poller/lib/libPoller.so
./demo/jvmti/compiledMethodLoad/lib/libcompiledMethodLoad.so
@ -522,25 +206,11 @@ STRIP_BEFORE_COMPARE="
./demo/jvmti/mtrace/lib/libmtrace.so
./demo/jvmti/versionCheck/lib/libversionCheck.so
./demo/jvmti/waiters/lib/libwaiters.so
./jre/lib/sparc/jexec
"
SORT_SYMBOLS="
./demo/jvmti/waiters/lib/libwaiters.so
./jre/lib/sparc/client/64/libjvm_db.so
./jre/lib/sparc/client/64/libjvm_dtrace.so
./jre/lib/sparc/client/libjsig.so
./jre/lib/sparc/client/libjvm.so
./jre/lib/sparc/client/libjvm_db.so
./jre/lib/sparc/client/libjvm_dtrace.so
./jre/lib/sparc/libjsig.so
./jre/lib/sparc/libsaproc.so
./jre/lib/sparc/server/64/libjvm_db.so
./jre/lib/sparc/server/64/libjvm_dtrace.so
./jre/lib/sparc/server/libjsig.so
./jre/lib/sparc/server/libjvm.so
./jre/lib/sparc/server/libjvm_db.so
./jre/lib/sparc/server/libjvm_dtrace.so
./lib/amd64/server/libjvm.so
./lib/amd64/libsaproc.so
"
SKIP_BIN_DIFF="true"
@ -556,56 +226,51 @@ ACCEPTED_SMALL_SIZE_DIFF="
./demo/jvmti/mtrace/lib/libmtrace.so
./demo/jvmti/versionCheck/lib/libversionCheck.so
./demo/jvmti/waiters/lib/libwaiters.so
./jre/lib/sparc/client/libjvm.so
./jre/lib/sparc/jli/libjli.so
./jre/lib/sparc/libJdbcOdbc.so
./jre/lib/sparc/libattach.so
./jre/lib/sparc/libawt.so
./jre/lib/sparc/libawt_headless.so
./jre/lib/sparc/libawt_xawt.so
./jre/lib/sparc/libdcpr.so
./jre/lib/sparc/libdt_socket.so
./jre/lib/sparc/libfontmanager.so
./jre/lib/sparc/libhprof.so
./jre/lib/sparc/libinstrument.so
./jre/lib/sparc/libj2gss.so
./jre/lib/sparc/libj2pcsc.so
./jre/lib/sparc/libj2pkcs11.so
./jre/lib/sparc/libj2ucrypto.so
./jre/lib/sparc/libjaas_unix.so
./jre/lib/sparc/libjava.so
./jre/lib/sparc/libjava_crw_demo.so
./jre/lib/sparc/libjawt.so
./jre/lib/sparc/libjdwp.so
./jre/lib/sparc/libjfr.so
./jre/lib/sparc/libjpeg.so
./jre/lib/sparc/libjsdt.so
./jre/lib/sparc/libjsound.so
./jre/lib/sparc/libkcms.so
./jre/lib/sparc/liblcms.so
./jre/lib/sparc/libmanagement.so
./jre/lib/sparc/libmlib_image.so
./jre/lib/sparc/libmlib_image_v.so
./jre/lib/sparc/libnet.so
./jre/lib/sparc/libnio.so
./jre/lib/sparc/libnpt.so
./jre/lib/sparc/libsctp.so
./jre/lib/sparc/libsplashscreen.so
./jre/lib/sparc/libsunec.so
./jre/lib/sparc/libsunwjdga.so
./jre/lib/sparc/libt2k.so
./jre/lib/sparc/libunpack.so
./jre/lib/sparc/libverify.so
./jre/lib/sparc/libzip.so
./jre/lib/sparc/libdeploy.so
./jre/lib/sparc/libjavaplugin.so
./jre/lib/sparc/libjavaplugin_jni.so
./jre/lib/sparc/libjavaplugin_nscp.so
./jre/lib/sparc/libjavaplugin_oji.so
./jre/lib/sparc/libnpjp2.so
./jre/plugin/sparc/ns4/libjavaplugin.so
./jre/plugin/sparc/ns7/libjavaplugin_oji.so
./jre/lib/sparc/server/libjvm.so
./lib/amd64/jli/libjli.so
./lib/amd64/jspawnhelper
./lib/amd64/libJdbcOdbc.so
./lib/amd64/libattach.so
./lib/amd64/libawt.so
./lib/amd64/libawt_headless.so
./lib/amd64/libawt_xawt.so
./lib/amd64/libdcpr.so
./lib/amd64/libdt_socket.so
./lib/amd64/libfontmanager.so
./lib/amd64/libhprof.so
./lib/amd64/libinstrument.so
./lib/amd64/libj2gss.so
./lib/amd64/libj2pcsc.so
./lib/amd64/libj2pkcs11.so
./lib/amd64/libj2ucrypto.so
./lib/amd64/libjaas_unix.so
./lib/amd64/libjava.so
./lib/amd64/libjava_crw_demo.so
./lib/amd64/libjawt.so
./lib/amd64/libjdwp.so
./lib/amd64/libjfr.so
./lib/amd64/libjpeg.so
./lib/amd64/libjsdt.so
./lib/amd64/libjsound.so
./lib/amd64/libkcms.so
./lib/amd64/liblcms.so
./lib/amd64/libmanagement.so
./lib/amd64/libmlib_image.so
./lib/amd64/libnet.so
./lib/amd64/libnio.so
./lib/amd64/libnpt.so
./lib/amd64/libsctp.so
./lib/amd64/libsplashscreen.so
./lib/amd64/libsunec.so
./lib/amd64/libsunwjdga.so
./lib/amd64/libt2k.so
./lib/amd64/libunpack.so
./lib/amd64/libverify.so
./lib/amd64/libzip.so
./lib/amd64/server/64/libjvm_db.so
./lib/amd64/server/64/libjvm_dtrace.so
./lib/amd64/server/libjvm.so
./lib/amd64/server/libjvm_db.so
./lib/amd64/server/libjvm_dtrace.so
./bin/appletviewer
./bin/idlj
./bin/jar
@ -616,7 +281,6 @@ ACCEPTED_SMALL_SIZE_DIFF="
./bin/javah
./bin/javap
./bin/jdeps
./bin/javaws
./bin/jcmd
./bin/jconsole
./bin/jdb
@ -647,171 +311,156 @@ ACCEPTED_SMALL_SIZE_DIFF="
./bin/wsgen
./bin/wsimport
./bin/xjc
./jre/bin/java
./jre/bin/java_vm
./jre/bin/javaws
./jre/bin/keytool
./jre/bin/orbd
./jre/bin/pack200
./jre/bin/policytool
./jre/bin/rmid
./jre/bin/rmiregistry
./jre/bin/servertool
./jre/bin/tnameserv
./jre/bin/unpack200
./jre/lib/sparc/jexec
"
# Filter random C++ symbol strings.
# Some numbers differ randomly.
DIS_DIFF_FILTER="$SED -e s/\$[a-zA-Z0-9_\$]\{15,15\}/<SYM>/g -e s/\([0-9a-f][0-9a-f].[0-9a-f][0-9a-f].[0-9a-f][0-9a-f].\)[0-9a-f][0-9a-f]/\1<NUM>/g -e s/\(%g1,.0x\)[0-9a-f]*\(,.%g1\)/\1<HEX>\2/g -e s/\(!.\)[0-9a-f]*\(.<SUNWprivate_1.1+0x\)[0-9a-f]*/\1<NUM>\2<HEX>/g"
# Some xor instructions end up with different args in the lib but not in the object files.
ACCEPTED_DIS_DIFF="
./demo/jvmti/waiters/lib/libwaiters.so
"
SKIP_FULLDUMP_DIFF="true"
# Filter random C++ symbol strings.
# Some numbers differ randomly.
# Can't use space in these expressions as the shell will mess with them.
DIS_DIFF_FILTER="$SED \
-e 's/\.[a-zA-Z0-9_\$]\{15,15\}/<SYM>/g' \
-e 's/\([0-9a-f][0-9a-f].\)\{2,8\}[0-9a-f][0-9a-f]/<NUMS>/g' \
-e 's/\(0x\)[0-9a-f]*\([,(>]\)/\1<HEX>\2/g' \
-e 's/\(0x\)[0-9a-f]*$/\1<HEX>/g' \
-e 's/\(\#.\)[0-9a-f]*\(.<\)/\1<HEX>\2/g' \
-e 's/[\.A-Za-z0-9%]\{16,16\}$/<BIN>/g'"
fi
if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "sparcv9" ]; then
STRIP_BEFORE_COMPARE="
./demo/jni/Poller/lib/sparcv9/libPoller.so
./demo/jvmti/compiledMethodLoad/lib/sparcv9/libcompiledMethodLoad.so
./demo/jvmti/gctest/lib/sparcv9/libgctest.so
./demo/jvmti/heapTracker/lib/sparcv9/libheapTracker.so
./demo/jvmti/heapViewer/lib/sparcv9/libheapViewer.so
./demo/jvmti/hprof/lib/sparcv9/libhprof.so
./demo/jvmti/minst/lib/sparcv9/libminst.so
./demo/jvmti/mtrace/lib/sparcv9/libmtrace.so
./demo/jvmti/versionCheck/lib/sparcv9/libversionCheck.so
./demo/jvmti/waiters/lib/sparcv9/libwaiters.so
./demo/jni/Poller/lib/libPoller.so
./demo/jvmti/compiledMethodLoad/lib/libcompiledMethodLoad.so
./demo/jvmti/gctest/lib/libgctest.so
./demo/jvmti/heapTracker/lib/libheapTracker.so
./demo/jvmti/heapViewer/lib/libheapViewer.so
./demo/jvmti/hprof/lib/libhprof.so
./demo/jvmti/minst/lib/libminst.so
./demo/jvmti/mtrace/lib/libmtrace.so
./demo/jvmti/versionCheck/lib/libversionCheck.so
./demo/jvmti/waiters/lib/libwaiters.so
"
SORT_SYMBOLS="
./demo/jvmti/waiters/lib/sparcv9/libwaiters.so
./jre/lib/sparcv9/libjsig.so
./jre/lib/sparcv9/libsaproc.so
./jre/lib/sparcv9/server/libjvm.so
./jre/lib/sparcv9/server/libjvm_dtrace.so
./demo/jvmti/waiters/lib/libwaiters.so
./lib/sparcv9/libjsig.so
./lib/sparcv9/libsaproc.so
./lib/sparcv9/server/libjvm.so
./lib/sparcv9/server/libjvm_dtrace.so
"
SKIP_BIN_DIFF="true"
ACCEPTED_SMALL_SIZE_DIFF="
./demo/jni/Poller/lib/sparcv9/libPoller.so
./demo/jvmti/compiledMethodLoad/lib/sparcv9/libcompiledMethodLoad.so
./demo/jvmti/gctest/lib/sparcv9/libgctest.so
./demo/jvmti/heapTracker/lib/sparcv9/libheapTracker.so
./demo/jvmti/heapViewer/lib/sparcv9/libheapViewer.so
./demo/jvmti/hprof/lib/sparcv9/libhprof.so
./demo/jvmti/minst/lib/sparcv9/libminst.so
./demo/jvmti/mtrace/lib/sparcv9/libmtrace.so
./demo/jvmti/versionCheck/lib/sparcv9/libversionCheck.so
./demo/jvmti/waiters/lib/sparcv9/libwaiters.so
./jre/lib/sparcv9/client/libjvm.so
./jre/lib/sparcv9/jli/libjli.so
./jre/lib/sparcv9/libJdbcOdbc.so
./jre/lib/sparcv9/libattach.so
./jre/lib/sparcv9/libawt.so
./jre/lib/sparcv9/libawt_headless.so
./jre/lib/sparcv9/libawt_xawt.so
./jre/lib/sparcv9/libdcpr.so
./jre/lib/sparcv9/libdt_socket.so
./jre/lib/sparcv9/libfontmanager.so
./jre/lib/sparcv9/libhprof.so
./jre/lib/sparcv9/libinstrument.so
./jre/lib/sparcv9/libj2gss.so
./jre/lib/sparcv9/libj2pcsc.so
./jre/lib/sparcv9/libj2pkcs11.so
./jre/lib/sparcv9/libj2ucrypto.so
./jre/lib/sparcv9/libjaas_unix.so
./jre/lib/sparcv9/libjava.so
./jre/lib/sparcv9/libjava_crw_demo.so
./jre/lib/sparcv9/libjawt.so
./jre/lib/sparcv9/libjdwp.so
./jre/lib/sparcv9/libjfr.so
./jre/lib/sparcv9/libjpeg.so
./jre/lib/sparcv9/libjsdt.so
./jre/lib/sparcv9/libjsound.so
./jre/lib/sparcv9/libkcms.so
./jre/lib/sparcv9/liblcms.so
./jre/lib/sparcv9/libmanagement.so
./jre/lib/sparcv9/libmlib_image.so
./jre/lib/sparcv9/libmlib_image_v.so
./jre/lib/sparcv9/libnet.so
./jre/lib/sparcv9/libnio.so
./jre/lib/sparcv9/libnpt.so
./jre/lib/sparcv9/libsctp.so
./jre/lib/sparcv9/libsplashscreen.so
./jre/lib/sparcv9/libsunec.so
./jre/lib/sparcv9/libsunwjdga.so
./jre/lib/sparcv9/libt2k.so
./jre/lib/sparcv9/libunpack.so
./jre/lib/sparcv9/libverify.so
./jre/lib/sparcv9/libzip.so
./jre/lib/sparcv9/server/libjvm.so
./bin/sparcv9/appletviewer
./bin/sparcv9/idlj
./bin/sparcv9/jar
./bin/sparcv9/jarsigner
./bin/sparcv9/java
./bin/sparcv9/javac
./bin/sparcv9/javadoc
./bin/sparcv9/javah
./bin/sparcv9/javap
./bin/sparcv9/jdeps
./bin/sparcv9/jcmd
./bin/sparcv9/jconsole
./bin/sparcv9/jdb
./bin/sparcv9/jhat
./bin/sparcv9/jimage
./bin/sparcv9/jinfo
./bin/sparcv9/jjs
./bin/sparcv9/jmap
./bin/sparcv9/jps
./bin/sparcv9/jrunscript
./bin/sparcv9/jsadebugd
./bin/sparcv9/jstack
./bin/sparcv9/jstat
./bin/sparcv9/jstatd
./bin/sparcv9/keytool
./bin/sparcv9/native2ascii
./bin/sparcv9/orbd
./bin/sparcv9/pack200
./bin/sparcv9/policytool
./bin/sparcv9/rmic
./bin/sparcv9/rmid
./bin/sparcv9/rmiregistry
./bin/sparcv9/schemagen
./bin/sparcv9/serialver
./bin/sparcv9/servertool
./bin/sparcv9/tnameserv
./bin/sparcv9/unpack200
./bin/sparcv9/wsgen
./bin/sparcv9/wsimport
./bin/sparcv9/xjc
./jre/bin/sparcv9/java
./jre/bin/sparcv9/keytool
./jre/bin/sparcv9/orbd
./jre/bin/sparcv9/pack200
./jre/bin/sparcv9/policytool
./jre/bin/sparcv9/rmid
./jre/bin/sparcv9/rmiregistry
./jre/bin/sparcv9/servertool
./jre/bin/sparcv9/tnameserv
./jre/bin/sparcv9/unpack200
./demo/jni/Poller/lib/libPoller.so
./demo/jvmti/compiledMethodLoad/lib/libcompiledMethodLoad.so
./demo/jvmti/gctest/lib/libgctest.so
./demo/jvmti/heapTracker/lib/libheapTracker.so
./demo/jvmti/heapViewer/lib/libheapViewer.so
./demo/jvmti/hprof/lib/libhprof.so
./demo/jvmti/minst/lib/libminst.so
./demo/jvmti/mtrace/lib/libmtrace.so
./demo/jvmti/versionCheck/lib/libversionCheck.so
./demo/jvmti/waiters/lib/libwaiters.so
./lib/sparcv9/client/libjvm.so
./lib/sparcv9/jli/libjli.so
./lib/sparcv9/jspawnhelper
./lib/sparcv9/libJdbcOdbc.so
./lib/sparcv9/libattach.so
./lib/sparcv9/libawt.so
./lib/sparcv9/libawt_headless.so
./lib/sparcv9/libawt_xawt.so
./lib/sparcv9/libdcpr.so
./lib/sparcv9/libdt_socket.so
./lib/sparcv9/libfontmanager.so
./lib/sparcv9/libhprof.so
./lib/sparcv9/libinstrument.so
./lib/sparcv9/libj2gss.so
./lib/sparcv9/libj2pcsc.so
./lib/sparcv9/libj2pkcs11.so
./lib/sparcv9/libj2ucrypto.so
./lib/sparcv9/libjaas_unix.so
./lib/sparcv9/libjava.so
./lib/sparcv9/libjava_crw_demo.so
./lib/sparcv9/libjawt.so
./lib/sparcv9/libjdwp.so
./lib/sparcv9/libjfr.so
./lib/sparcv9/libjpeg.so
./lib/sparcv9/libjsdt.so
./lib/sparcv9/libjsound.so
./lib/sparcv9/libkcms.so
./lib/sparcv9/liblcms.so
./lib/sparcv9/libmanagement.so
./lib/sparcv9/libmlib_image.so
./lib/sparcv9/libmlib_image_v.so
./lib/sparcv9/libnet.so
./lib/sparcv9/libnio.so
./lib/sparcv9/libnpt.so
./lib/sparcv9/libsctp.so
./lib/sparcv9/libsplashscreen.so
./lib/sparcv9/libsunec.so
./lib/sparcv9/libsunwjdga.so
./lib/sparcv9/libt2k.so
./lib/sparcv9/libunpack.so
./lib/sparcv9/libverify.so
./lib/sparcv9/libzip.so
./lib/sparcv9/server/libjvm.so
./bin/appletviewer
./bin/idlj
./bin/jar
./bin/jarsigner
./bin/java
./bin/javac
./bin/javadoc
./bin/javah
./bin/javap
./bin/jdeps
./bin/jcmd
./bin/jconsole
./bin/jdb
./bin/jhat
./bin/jimage
./bin/jinfo
./bin/jjs
./bin/jmap
./bin/jps
./bin/jrunscript
./bin/jsadebugd
./bin/jstack
./bin/jstat
./bin/jstatd
./bin/keytool
./bin/native2ascii
./bin/orbd
./bin/pack200
./bin/policytool
./bin/rmic
./bin/rmid
./bin/rmiregistry
./bin/schemagen
./bin/serialver
./bin/servertool
./bin/tnameserv
./bin/unpack200
./bin/wsgen
./bin/wsimport
./bin/xjc
"
# Filter random C++ symbol strings.
# Some numbers differ randomly.
DIS_DIFF_FILTER="$SED -e s/\$[a-zA-Z0-9_\$]\{15,15\}/<SYM>/g -e s/[0-9a-f][0-9a-f].[0-9a-f][0-9a-f].[0-9a-f][0-9a-f].[0-9a-f][0-9a-f]/<NUMS>/g -e s/\(%g1,.0x\)[0-9a-f]*\(,.%g1\)/\1<HEX>\2/g -e s/\(!.\)[0-9a-f]*\(.<SUNWprivate_1.1+0x\)[0-9a-f]*/\1<NUM>\2<HEX>/g"
DIS_DIFF_FILTER="$SED \
-e 's/\$[a-zA-Z0-9_\$]\{15,15\}/<SYM>/g' \
-e 's/[0-9a-f][0-9a-f].[0-9a-f][0-9a-f].[0-9a-f][0-9a-f].[0-9a-f][0-9a-f]/<NUMS>/g' \
-e 's/\(%g1,.0x\)[0-9a-f]*\(,.%g1\)/\1<HEX>\2/g' \
-e 's/\(!.\)[0-9a-f]*\(.<SUNWprivate_1.1+0x\)[0-9a-f]*/\1<NUM>\2<HEX>/g' \
-e 's/\!.[0-9a-f]\{1,4\} <_DYNAMIC+0x[0-9a-f]\{1,4\}>/<DYNAMIC>/g'"
# Some xor instructions end up with different args in the lib but not in the object files.
ACCEPTED_DIS_DIFF="
./demo/jvmti/waiters/lib/sparcv9/libwaiters.so
./demo/jvmti/waiters/lib/libwaiters.so
"
SKIP_FULLDUMP_DIFF="true"
@ -822,7 +471,8 @@ fi
if [ "$OPENJDK_TARGET_OS" = "windows" ]; then
ACCEPTED_JARZIP_CONTENTS="
/bin/w2k_lsa_auth.dll
/modules_libs/java.security.jgss/w2k_lsa_auth.diz
/modules_libs/java.security.jgss/w2k_lsa_auth.dll
"
# Probably should add all libs here
@ -830,10 +480,10 @@ ACCEPTED_SMALL_SIZE_DIFF="
./demo/jvmti/gctest/lib/gctest.dll
./demo/jvmti/heapTracker/lib/heapTracker.dll
./demo/jvmti/minst/lib/minst.dll
./jre/bin/attach.dll
./jre/bin/java_crw_demo.dll
./jre/bin/jsoundds.dll
./jre/bin/server/jvm.dll
./bin/attach.dll
./bin/java_crw_demo.dll
./bin/jsoundds.dll
./bin/server/jvm.dll
./bin/appletviewer.exe
./bin/idlj.exe
./bin/jar.exe
@ -879,32 +529,15 @@ ACCEPTED_SMALL_SIZE_DIFF="
./bin/wsgen.exe
./bin/wsimport.exe
./bin/xjc.exe
./jre/bin/java-rmi.exe
./jre/bin/java.exe
./jre/bin/javaw.exe
./jre/bin/keytool.exe
./jre/bin/kinit.exe
./jre/bin/klist.exe
./jre/bin/ktab.exe
./jre/bin/orbd.exe
./jre/bin/pack200.exe
./jre/bin/policytool.exe
./jre/bin/rmid.exe
./jre/bin/rmiregistry.exe
./jre/bin/servertool.exe
./jre/bin/tnameserv.exe
./jre/bin/unpack200.exe
"
# jabswitch.exe is compiled and linked with incremental turned on in the old
# build. This makes no sense, so it's turned off in the new build.
ACCEPTED_SIZE_DIFF="
./bin/jabswitch.exe
./jre/bin/jabswitch.exe
"
ACCEPTED_DIS_DIFF="
./bin/jabswitch.exe
./jre/bin/jabswitch.exe
"
# On windows, there are unavoidable allignment issues making
@ -913,7 +546,12 @@ ACCEPTED_DIS_DIFF="
# @XXXXX
# * Hexadecimal addresses that are sometimes alligned differently.
# * Dates in version strings XXXX_XX_XX.
DIS_DIFF_FILTER="$SED -e s/[@?][A-Z0-9_]\{1,25\}/<SYM>/g -e s/^.\{2,2\}[0-9A-F]\{16,16\}.\{2,2\}//g -e s/[0-9A-F]\{4,16\}h/<HEXSTR>/g -e s/_[0-9]\{4,4\}_[0-9][0-9]_[0-9][0-9]/<DATE>/g"
DIS_DIFF_FILTER="$SED \
-e 's/^ [0-9A-F]\{16\}: //g' \
-e 's/[@?][A-Za-z0-9_]\{1,25\}/<SYM>/g' \
-e 's/\([\[+]\)[0-9A-F]\{4,16\}h\]/\1<HEXSTR>]/g' \
-e 's/_[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}/_<DATE>/g'"
#DIS_DIFF_FILTER="$CAT"
SKIP_BIN_DIFF="true"
SKIP_FULLDUMP_DIFF="true"
@ -936,6 +574,7 @@ ACCEPTED_BIN_DIFF="
./bin/javadoc
./bin/javah
./bin/javap
./bin/javaws
./bin/jdeps
./bin/jcmd
./bin/jconsole
@ -966,17 +605,6 @@ ACCEPTED_BIN_DIFF="
./bin/wsgen
./bin/wsimport
./bin/xjc
./jre/bin/java
./jre/bin/keytool
./jre/bin/orbd
./jre/bin/pack200
./jre/bin/policytool
./jre/bin/rmid
./jre/bin/rmiregistry
./jre/bin/servertool
./jre/bin/tnameserv
./jre/lib/libsaproc.dylib
./jre/lib/server/libjvm.dylib
./demo/jvmti/compiledMethodLoad/lib/libcompiledMethodLoad.dylib
./demo/jvmti/gctest/lib/libgctest.dylib
./demo/jvmti/heapTracker/lib/libheapTracker.dylib
@ -985,6 +613,11 @@ ACCEPTED_BIN_DIFF="
./demo/jvmti/mtrace/lib/libmtrace.dylib
./demo/jvmti/versionCheck/lib/libversionCheck.dylib
./demo/jvmti/waiters/lib/libwaiters.dylib
./Contents/Home/bin/_javaws
./Contents/Home/bin/idlj
./Contents/Home/bin/servertool
./Contents/Home/lib/shortcuts/JavaWSApplicationStub
./Contents/Home/lib/jli/libjli.dylib
./Contents/Home/lib/libAppleScriptEngine.dylib
./Contents/Home/lib/libattach.dylib
./Contents/Home/lib/libawt_lwawt.dylib
@ -1000,29 +633,15 @@ ACCEPTED_BIN_DIFF="
./Contents/Home/lib/libnpjp2.dylib
./Contents/Home/lib/libosx.dylib
./Contents/Home/lib/libosxapp.dylib
./Contents/Home/lib/libverify.dylib
./Contents/Home/lib/libsaproc.dylib
./Contents/Home/lib/libsplashscreen.dylib
./Contents/Home/lib/libverify.dylib
./Contents/Home/lib/server/libjsig.dylib
./Contents/Home/lib/server/libjvm.dylib
./jre/lib/libAppleScriptEngine.dylib
./jre/lib/libattach.dylib
./jre/lib/libawt_lwawt.dylib
./jre/lib/libdeploy.dylib
./jre/lib/libdt_socket.dylib
./jre/lib/libhprof.dylib
./jre/lib/libinstrument.dylib
./jre/lib/libjava_crw_demo.dylib
./jre/lib/libjdwp.dylib
./jre/lib/libjsdt.dylib
./jre/lib/libjsig.dylib
./jre/lib/libmanagement.dylib
./jre/lib/libosx.dylib
./jre/lib/libosxapp.dylib
./jre/lib/libsaproc.dylib
./jre/lib/libsplashscreen.dylib
./jre/lib/libverify.dylib
./jre/lib/server/libjvm.dylib
./Contents/Home/lib/deploy/JavaControlPanel.prefPane/Contents/MacOS/JavaControlPanel
./Contents/Resources/JavaControlPanelHelper
./Contents/Resources/JavaUpdater.app/Contents/MacOS/JavaUpdater
./lib/shortcuts/JavaWSApplicationStub
./lib/jli/libjli.dylib
./lib/libAppleScriptEngine.dylib
./lib/libattach.dylib
./lib/libawt_lwawt.dylib
@ -1047,12 +666,12 @@ ACCEPTED_BIN_DIFF="
SORT_SYMBOLS="
./Contents/Home/lib/libsaproc.dylib
./jre/lib/libsaproc.dylib
./lib/libsaproc.dylib
"
ACCEPTED_SMALL_SIZE_DIFF="
./bin/javaws
./Contents/Home/bin/_javaws
"
ACCEPTED_SMALL_SIZE_DIFF="$ACCEPTED_BIN_DIFF"
DIS_DIFF_FILTER="$SED \
-e 's/0x[0-9a-f]\{4,16\}/<HEXSTR>/g'"
fi

View File

@ -295,3 +295,4 @@ a13c49c5f2899b702652a460ed7aa73123e671e6 jdk9-b48
224f593393e5b01b3c8f1e591b7f4b1790a3737a jdk9-b50
2309c02386d1fa4ced5051873ffb9e04874f7a44 jdk9-b51
b8538bbb6f224ab1dabba579137099c166ad4724 jdk9-b52
aadc16ca5ab7d56f92ef9dbfa443595a939241b4 jdk9-b53

View File

@ -455,3 +455,4 @@ cc775a4a24c7f5d9e624b4205e9fbd48a17331f6 jdk9-b48
e0947f58c9c1426aa0d98b98ebb78357b27a7b99 jdk9-b50
403b9cbadb04d3d1201823591cf931dc93b38e3a jdk9-b51
9fb7fdc554db5be5c5b10f88f529ec3b870c44e3 jdk9-b52
effd5ef0c3eb4bb85aa975c489d6761dbf13ad6a jdk9-b53

View File

@ -345,7 +345,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo
return (err == PS_OK)? array : 0;
}
#if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9) | defined(ppc64)
#if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9) | defined(ppc64) || defined(aarch64)
JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0
(JNIEnv *env, jobject this_obj, jint lwp_id) {
@ -367,6 +367,9 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo
#ifdef amd64
#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
#endif
#ifdef aarch64
#define NPRGREG 32
#endif
#if defined(sparc) || defined(sparcv9)
#define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG
#endif
@ -466,6 +469,12 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo
regs[REG_INDEX(R_O7)] = gregs.u_regs[14];
#endif /* sparc */
#if defined(aarch64)
#define REG_INDEX(reg) sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_##reg
#endif /* aarch64 */
#ifdef ppc64
#define REG_INDEX(reg) sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_##reg

View File

@ -71,6 +71,9 @@ combination of ptrace and /proc calls.
#if defined(sparc) || defined(sparcv9) || defined(ppc64)
#define user_regs_struct pt_regs
#endif
#if defined(aarch64)
#define user_regs_struct user_pt_regs
#endif
// This C bool type must be int for compatibility with Linux calls and
// it would be a mistake to equivalence it to C++ bool on many platforms

View File

@ -34,6 +34,7 @@ import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.debugger.MachineDescription;
import sun.jvm.hotspot.debugger.MachineDescriptionAMD64;
import sun.jvm.hotspot.debugger.MachineDescriptionPPC64;
import sun.jvm.hotspot.debugger.MachineDescriptionAArch64;
import sun.jvm.hotspot.debugger.MachineDescriptionIA64;
import sun.jvm.hotspot.debugger.MachineDescriptionIntelX86;
import sun.jvm.hotspot.debugger.MachineDescriptionSPARC32Bit;
@ -591,6 +592,8 @@ public class HotSpotAgent {
machDesc = new MachineDescriptionAMD64();
} else if (cpu.equals("ppc64")) {
machDesc = new MachineDescriptionPPC64();
} else if (cpu.equals("aarch64")) {
machDesc = new MachineDescriptionAArch64();
} else if (cpu.equals("sparc")) {
if (LinuxDebuggerLocal.getAddressSize()==8) {
machDesc = new MachineDescriptionSPARC64Bit();

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.debugger;
public class MachineDescriptionAArch64 extends MachineDescriptionTwosComplement implements MachineDescription {
public long getAddressSize() {
return 8;
}
public boolean isLP64() {
return true;
}
public boolean isBigEndian() {
return false;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,6 +24,8 @@
package sun.jvm.hotspot.debugger.amd64;
import java.lang.annotation.Native;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.cdbg.*;
@ -39,6 +41,9 @@ public abstract class AMD64ThreadContext implements ThreadContext {
// subset of the registers' values are guaranteed to be present (and
// must be present for the SA's stack walking to work)
// One instance of the Native annotation is enough to trigger header generation
// for this file.
@Native
public static final int R15 = 0;
public static final int R14 = 1;
public static final int R13 = 2;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,6 +24,8 @@
package sun.jvm.hotspot.debugger.ppc64;
import java.lang.annotation.Native;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.cdbg.*;
@ -38,6 +40,9 @@ public abstract class PPC64ThreadContext implements ThreadContext {
// subset of the registers' values are guaranteed to be present (and
// must be present for the SA's stack walking to work).
// One instance of the Native annotation is enough to trigger header generation
// for this file.
@Native
public static final int R31 = 0;
public static final int R30 = 1;
public static final int R29 = 2;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,6 +24,8 @@
package sun.jvm.hotspot.debugger.sparc;
import java.lang.annotation.Native;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.cdbg.*;
@ -34,6 +36,10 @@ import sun.jvm.hotspot.debugger.cdbg.*;
public abstract class SPARCThreadContext implements ThreadContext {
// Taken from /usr/include/sys/procfs_isa.h
// One instance of the Native annotation is enough to trigger header generation
// for this file.
@Native
public static final int R_G0 = 0;
public static final int R_G1 = 1;
public static final int R_G2 = 2;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,6 +24,8 @@
package sun.jvm.hotspot.debugger.x86;
import java.lang.annotation.Native;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.cdbg.*;
@ -40,6 +42,9 @@ public abstract class X86ThreadContext implements ThreadContext {
// must be present for the SA's stack walking to work): EAX, EBX,
// ECX, EDX, ESI, EDI, EBP, ESP, and EIP.
// One instance of the Native annotation is enough to trigger header generation
// for this file.
@Native
public static final int GS = 0;
public static final int FS = 1;
public static final int ES = 2;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -35,7 +35,8 @@ import sun.jvm.hotspot.utilities.*;
public class GenCollectedHeap extends SharedHeap {
private static CIntegerField nGensField;
private static long gensOffset;
private static AddressField youngGenField;
private static AddressField oldGenField;
private static AddressField genSpecsField;
private static GenerationFactory genFactory;
@ -52,7 +53,8 @@ public class GenCollectedHeap extends SharedHeap {
Type type = db.lookupType("GenCollectedHeap");
nGensField = type.getCIntegerField("_n_gens");
gensOffset = type.getField("_gens").getOffset();
youngGenField = type.getAddressField("_young_gen");
oldGenField = type.getAddressField("_old_gen");
genSpecsField = type.getAddressField("_gen_specs");
genFactory = new GenerationFactory();
@ -68,18 +70,19 @@ public class GenCollectedHeap extends SharedHeap {
public Generation getGen(int i) {
if (Assert.ASSERTS_ENABLED) {
Assert.that((i >= 0) && (i < nGens()), "Index " + i +
" out of range (should be between 0 and " + nGens() + ")");
Assert.that((i == 0) || (i == 1), "Index " + i +
" out of range (should be 0 or 1)");
}
if ((i < 0) || (i >= nGens())) {
switch (i) {
case 0:
return genFactory.newObject(youngGenField.getValue(addr));
case 1:
return genFactory.newObject(oldGenField.getValue(addr));
default:
// no generation for i, and assertions disabled.
return null;
}
Address genAddr = addr.getAddressAt(gensOffset +
(i * VM.getVM().getAddressSize()));
return genFactory.newObject(addr.getAddressAt(gensOffset +
(i * VM.getVM().getAddressSize())));
}
public boolean isIn(Address a) {

View File

@ -61,7 +61,7 @@ public class PlatformInfo {
return "x86";
} else if (cpu.equals("sparc") || cpu.equals("sparcv9")) {
return "sparc";
} else if (cpu.equals("ia64") || cpu.equals("amd64") || cpu.equals("x86_64") || cpu.equals("ppc64")) {
} else if (cpu.equals("ia64") || cpu.equals("amd64") || cpu.equals("x86_64") || cpu.equals("ppc64") || cpu.equals("aarch64")) {
return cpu;
} else {
try {

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
# Copyright 2012, 2013 SAP AG. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
@ -94,7 +94,7 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_FILES)
# are in AGENT_FILES, so use the shell to expand them.
# Be extra carefull to not produce too long command lines in the shell!
$(foreach file,$(AGENT_FILES),$(shell ls -1 $(file) >> $(AGENT_FILES_LIST)))
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES_LIST)
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -h $(GENERATED) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES_LIST)
$(QUIETLY) $(REMOTE) $(COMPILE.RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
@ -105,10 +105,6 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_FILES)
$(QUIETLY) $(CP) -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)/
$(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(SA_CLASSDIR)/ .
$(QUIETLY) $(REMOTE) $(RUN.JAR) uf $@ -C $(AGENT_SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector
$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext
$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.ia64.IA64ThreadContext
$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.sparc.SPARCThreadContext
clean:
rm -rf $(SA_CLASSDIR)

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -120,7 +120,7 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_FILES)
# are in AGENT_FILES, so use the shell to expand them.
# Be extra carefull to not produce too long command lines in the shell!
$(foreach file,$(AGENT_FILES),$(shell ls -1 $(file) >> $(AGENT_FILES_LIST)))
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) $(SA_CLASSPATH_ARG) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES_LIST)
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -h $(GENERATED) $(SA_CLASSPATH_ARG) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES_LIST)
$(QUIETLY) $(REMOTE) $(COMPILE.RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
@ -131,10 +131,6 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_FILES)
$(QUIETLY) $(CP) -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)/
$(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(SA_CLASSDIR)/ .
$(QUIETLY) $(REMOTE) $(RUN.JAR) uf $@ -C $(AGENT_SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector
$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext
$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.sparc.SPARCThreadContext
$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.asm.Disassembler
clean:
rm -rf $(SA_CLASSDIR)

View File

@ -286,7 +286,7 @@ ifneq ($(OSNAME),windows)
# Use uname output for SRCARCH, but deal with platform differences. If ARCH
# is not explicitly listed below, it is treated as x86.
SRCARCH = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 arm ppc ppc64 zero,$(ARCH)))
SRCARCH = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 arm ppc ppc64 aarch64 zero,$(ARCH)))
ARCH/ = x86
ARCH/sparc = sparc
ARCH/sparc64= sparc
@ -296,6 +296,7 @@ ifneq ($(OSNAME),windows)
ARCH/ppc64 = ppc
ARCH/ppc = ppc
ARCH/arm = arm
ARCH/aarch64= aarch64
ARCH/zero = zero
# BUILDARCH is usually the same as SRCARCH, except for sparcv9
@ -326,11 +327,12 @@ ifneq ($(OSNAME),windows)
LIBARCH/sparcv9 = sparcv9
LIBARCH/ia64 = ia64
LIBARCH/ppc64 = ppc64
LIBARCH/aarch64 = aarch64
LIBARCH/ppc = ppc
LIBARCH/arm = arm
LIBARCH/zero = $(ZERO_LIBARCH)
LP64_ARCH = sparcv9 amd64 ia64 ppc64 zero
LP64_ARCH = sparcv9 amd64 ia64 ppc64 aarch64 zero
endif
# Required make macro settings for all platforms

View File

@ -0,0 +1,32 @@
#
# Copyright (c) 2003, 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.
#
#
# The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized
OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT)
# The copied fdlibm routines in sharedRuntimeTrans.o must not be optimized
OPT_CFLAGS/sharedRuntimeTrans.o = $(OPT_CFLAGS/NOOPT)
# Must also specify if CPU is little endian
CFLAGS += -DVM_LITTLE_ENDIAN
CFLAGS += -D_LP64=1

View File

@ -194,6 +194,7 @@ DATA_MODE/sparc = 32
DATA_MODE/sparcv9 = 64
DATA_MODE/amd64 = 64
DATA_MODE/ppc64 = 64
DATA_MODE/aarch64 = 64
DATA_MODE = $(DATA_MODE/$(BUILDARCH))

View File

@ -130,6 +130,15 @@ ifneq (,$(findstring $(ARCH), ppc ppc64))
HS_ARCH = ppc
endif
# AARCH64
ifeq ($(ARCH), aarch64)
ARCH_DATA_MODEL = 64
MAKE_ARGS += LP64=1
PLATFORM = linux-aarch64
VM_PLATFORM = linux_aarch64
HS_ARCH = aarch64
endif
# On 32 bit linux we build server and client, on 64 bit just server.
ifeq ($(JVM_VARIANTS),)
ifeq ($(ARCH_DATA_MODEL), 32)

View File

@ -172,6 +172,7 @@ endif
ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
ARCHFLAG/i486 = -m32 -march=i586
ARCHFLAG/amd64 = -m64 $(STACK_ALIGNMENT_OPT)
ARCHFLAG/aarch64 =
ARCHFLAG/ia64 =
ARCHFLAG/sparc = -m32 -mcpu=v9
ARCHFLAG/sparcv9 = -m64 -mcpu=v9

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -95,7 +95,7 @@ $(GENERATED)/sa-jdi.jar:: $(AGENT_FILES)
# are in AGENT_FILES, so use the shell to expand them.
# Be extra carefull to not produce too long command lines in the shell!
$(foreach file,$(AGENT_FILES),$(shell ls -1 $(file) >> $(AGENT_FILES_LIST)))
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES_LIST)
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -h $(GENERATED) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES_LIST)
$(QUIETLY) $(REMOTE) $(COMPILE.RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
@ -106,11 +106,6 @@ $(GENERATED)/sa-jdi.jar:: $(AGENT_FILES)
$(QUIETLY) $(CP) -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)/
$(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(SA_CLASSDIR)/ .
$(QUIETLY) $(REMOTE) $(RUN.JAR) uf $@ -C $(AGENT_SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector
$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext
$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.sparc.SPARCThreadContext
$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.ppc64.PPC64ThreadContext
$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.asm.Disassembler
clean:
rm -rf $(SA_CLASSDIR)

View File

@ -0,0 +1,15 @@
os_family = linux
arch = aarch64
arch_model = aarch64
os_arch = linux_aarch64
os_arch_model = linux_aarch64
lib_arch = aarch64
compiler = gcc
sysdefs = -DLINUX -D_GNU_SOURCE -DAARCH64

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -86,7 +86,7 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_FILES)
# are in AGENT_FILES, so use the shell to expand them.
# Be extra carefull to not produce too long command lines in the shell!
$(foreach file,$(AGENT_FILES),$(shell ls -1 $(file) >> $(AGENT_FILES_LIST)))
$(QUIETLY) $(COMPILE.JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES_LIST)
$(QUIETLY) $(COMPILE.JAVAC) -h $(GENERATED) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES_LIST)
$(QUIETLY) $(COMPILE.RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
@ -97,8 +97,6 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_FILES)
$(QUIETLY) $(CP) -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)/
$(QUIETLY) $(RUN.JAR) cf $@ -C $(SA_CLASSDIR)/ .
$(QUIETLY) $(RUN.JAR) uf $@ -C $(AGENT_SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector
$(QUIETLY) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.proc.ProcDebuggerLocal
$(QUIETLY) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.asm.Disassembler
clean:
rm -rf $(SA_CLASSDIR)

View File

@ -0,0 +1,81 @@
#
# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
################################################################################
# This file builds the native component of the JTReg tests for Hotspot.
# It also covers the test-image part, where the built files are copied to the
# test image.
################################################################################
default: all
include $(SPEC)
include MakeBase.gmk
include TestFilesCompilation.gmk
################################################################################
# Targets for building the native tests themselves.
################################################################################
# Add more directories here when needed.
BUILD_HOTSPOT_JTREG_NATIVE_SRC := \
$(HOTSPOT_TOPDIR)/test/native_sanity \
#
BUILD_HOTSPOT_JTREG_OUTPUT_DIR := $(BUILD_OUTPUT)/support/test/hotspot/jtreg/native
BUILD_HOTSPOT_JTREG_IMAGE_DIR := $(TEST_IMAGE_DIR)/hotspot/jtreg
$(eval $(call SetupTestFilesCompilation, BUILD_HOTSPOT_JTREG_LIBRARIES, \
TYPE := LIBRARY, \
SOURCE_DIRS := $(BUILD_HOTSPOT_JTREG_NATIVE_SRC), \
OUTPUT_DIR := $(BUILD_HOTSPOT_JTREG_OUTPUT_DIR), \
))
$(eval $(call SetupTestFilesCompilation, BUILD_HOTSPOT_JTREG_EXECUTABLES, \
TYPE := PROGRAM, \
SOURCE_DIRS := $(BUILD_HOTSPOT_JTREG_NATIVE_SRC), \
OUTPUT_DIR := $(BUILD_HOTSPOT_JTREG_OUTPUT_DIR), \
))
build-test-hotspot-jtreg-native: $(BUILD_HOTSPOT_JTREG_LIBRARIES) $(BUILD_HOTSPOT_JTREG_EXECUTABLES)
################################################################################
# Targets for building test-image.
################################################################################
# Copy to hotspot jtreg test image
$(eval $(call SetupCopyFiles,COPY_HOTSPOT_JTREG_NATIVE, \
SRC := $(BUILD_HOTSPOT_JTREG_OUTPUT_DIR), \
DEST := $(TEST_IMAGE_DIR)/hotspot/jtreg/native, \
FILES := $(BUILD_HOTSPOT_JTREG_LIBRARIES) $(BUILD_HOTSPOT_JTREG_EXECUTABLES), \
FLATTEN := true))
test-image-hotspot-jtreg-native: $(COPY_HOTSPOT_JTREG_NATIVE)
all: build-test-hotspot-jtreg-native
test-image: test-image-hotspot-jtreg-native
.PHONY: default all build-test-hotspot-jtreg-native test-image-hotspot-jtreg-native test-image

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -72,7 +72,7 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_FILES)
$(QUIETLY) mkdir -p $(SA_CLASSDIR)
@echo ...Building sa-jdi.jar into $(SA_CLASSDIR)
@echo ...$(COMPILE_JAVAC) -classpath $(SA_CLASSPATH) -d $(SA_CLASSDIR) ....
@$(COMPILE_JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES)
@$(COMPILE_JAVAC) -h $(GENERATED) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES)
$(COMPILE_RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
$(QUIETLY) echo $(SA_BUILD_VERSION_PROP)> $(SA_PROPERTIES)
$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
@ -83,10 +83,6 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_FILES)
$(QUIETLY) $(CP) -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)
$(RUN_JAR) cf $@ -C $(SA_CLASSDIR) .
$(RUN_JAR) uf $@ -C $(AGENT_SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector
$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal
$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext
$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.asm.Disassembler

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include <stdlib.h>
#include "precompiled.hpp"
#include "code/codeBlob.hpp"
#include "asm/macroAssembler.hpp"
// hook routine called during JVM bootstrap to test AArch64 assembler
extern "C" void entry(CodeBuffer*);
void aarch64TestHook()
{
BufferBlob* b = BufferBlob::create("aarch64Test", 500000);
CodeBuffer code(b);
MacroAssembler _masm(&code);
entry(&code);
}

View File

@ -0,0 +1,365 @@
dnl Copyright (c) 2014, Red Hat Inc. All rights reserved.
dnl DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
dnl
dnl This code is free software; you can redistribute it and/or modify it
dnl under the terms of the GNU General Public License version 2 only, as
dnl published by the Free Software Foundation.
dnl
dnl This code is distributed in the hope that it will be useful, but WITHOUT
dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl version 2 for more details (a copy is included in the LICENSE file that
dnl accompanied this code).
dnl
dnl You should have received a copy of the GNU General Public License version
dnl 2 along with this work; if not, write to the Free Software Foundation,
dnl Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
dnl
dnl Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
dnl or visit www.oracle.com if you need additional information or have any
dnl questions.
dnl
dnl
dnl Process this file with m4 aarch64_ad.m4 to generate the arithmetic
dnl and shift patterns patterns used in aarch64.ad.
dnl
// BEGIN This section of the file is automatically generated. Do not edit --------------
define(`BASE_SHIFT_INSN',
`
instruct $2$1_reg_$4_reg(iReg$1NoSp dst,
iReg$1 src1, iReg$1 src2,
immI src3, rFlagsReg cr) %{
match(Set dst ($2$1 src1 ($4$1 src2 src3)));
ins_cost(1.9 * INSN_COST);
format %{ "$3 $dst, $src1, $src2, $5 $src3" %}
ins_encode %{
__ $3(as_Register($dst$$reg),
as_Register($src1$$reg),
as_Register($src2$$reg),
Assembler::$5,
$src3$$constant & 0x3f);
%}
ins_pipe(ialu_reg_reg_shift);
%}')dnl
define(`BASE_INVERTED_INSN',
`
instruct $2$1_reg_not_reg(iReg$1NoSp dst,
iReg$1 src1, iReg$1 src2, imm$1_M1 m1,
rFlagsReg cr) %{
dnl This ifelse is because hotspot reassociates (xor (xor ..)..)
dnl into this canonical form.
ifelse($2,Xor,
match(Set dst (Xor$1 m1 (Xor$1 src2 src1)));,
match(Set dst ($2$1 src1 (Xor$1 src2 m1)));)
ins_cost(INSN_COST);
format %{ "$3 $dst, $src1, $src2" %}
ins_encode %{
__ $3(as_Register($dst$$reg),
as_Register($src1$$reg),
as_Register($src2$$reg),
Assembler::LSL, 0);
%}
ins_pipe(ialu_reg_reg);
%}')dnl
define(`INVERTED_SHIFT_INSN',
`
instruct $2$1_reg_$4_not_reg(iReg$1NoSp dst,
iReg$1 src1, iReg$1 src2,
immI src3, imm$1_M1 src4, rFlagsReg cr) %{
dnl This ifelse is because hotspot reassociates (xor (xor ..)..)
dnl into this canonical form.
ifelse($2,Xor,
match(Set dst ($2$1 src4 (Xor$1($4$1 src2 src3) src1)));,
match(Set dst ($2$1 src1 (Xor$1($4$1 src2 src3) src4)));)
ins_cost(1.9 * INSN_COST);
format %{ "$3 $dst, $src1, $src2, $5 $src3" %}
ins_encode %{
__ $3(as_Register($dst$$reg),
as_Register($src1$$reg),
as_Register($src2$$reg),
Assembler::$5,
$src3$$constant & 0x3f);
%}
ins_pipe(ialu_reg_reg_shift);
%}')dnl
define(`NOT_INSN',
`instruct reg$1_not_reg(iReg$1NoSp dst,
iReg$1 src1, imm$1_M1 m1,
rFlagsReg cr) %{
match(Set dst (Xor$1 src1 m1));
ins_cost(INSN_COST);
format %{ "$2 $dst, $src1, zr" %}
ins_encode %{
__ $2(as_Register($dst$$reg),
as_Register($src1$$reg),
zr,
Assembler::LSL, 0);
%}
ins_pipe(ialu_reg);
%}')dnl
dnl
define(`BOTH_SHIFT_INSNS',
`BASE_SHIFT_INSN(I, $1, ifelse($2,andr,andw,$2w), $3, $4)
BASE_SHIFT_INSN(L, $1, $2, $3, $4)')dnl
dnl
define(`BOTH_INVERTED_INSNS',
`BASE_INVERTED_INSN(I, $1, $2, $3, $4)
BASE_INVERTED_INSN(L, $1, $2, $3, $4)')dnl
dnl
define(`BOTH_INVERTED_SHIFT_INSNS',
`INVERTED_SHIFT_INSN(I, $1, $2w, $3, $4, ~0, int)
INVERTED_SHIFT_INSN(L, $1, $2, $3, $4, ~0l, long)')dnl
dnl
define(`ALL_SHIFT_KINDS',
`BOTH_SHIFT_INSNS($1, $2, URShift, LSR)
BOTH_SHIFT_INSNS($1, $2, RShift, ASR)
BOTH_SHIFT_INSNS($1, $2, LShift, LSL)')dnl
dnl
define(`ALL_INVERTED_SHIFT_KINDS',
`BOTH_INVERTED_SHIFT_INSNS($1, $2, URShift, LSR)
BOTH_INVERTED_SHIFT_INSNS($1, $2, RShift, ASR)
BOTH_INVERTED_SHIFT_INSNS($1, $2, LShift, LSL)')dnl
dnl
NOT_INSN(L, eon)
NOT_INSN(I, eonw)
BOTH_INVERTED_INSNS(And, bic)
BOTH_INVERTED_INSNS(Or, orn)
BOTH_INVERTED_INSNS(Xor, eon)
ALL_INVERTED_SHIFT_KINDS(And, bic)
ALL_INVERTED_SHIFT_KINDS(Xor, eon)
ALL_INVERTED_SHIFT_KINDS(Or, orn)
ALL_SHIFT_KINDS(And, andr)
ALL_SHIFT_KINDS(Xor, eor)
ALL_SHIFT_KINDS(Or, orr)
ALL_SHIFT_KINDS(Add, add)
ALL_SHIFT_KINDS(Sub, sub)
dnl
dnl EXTEND mode, rshift_op, src, lshift_count, rshift_count
define(`EXTEND', `($2$1 (LShift$1 $3 $4) $5)')
define(`BFM_INSN',`
// Shift Left followed by Shift Right.
// This idiom is used by the compiler for the i2b bytecode etc.
instruct $4$1(iReg$1NoSp dst, iReg$1 src, immI lshift_count, immI rshift_count)
%{
match(Set dst EXTEND($1, $3, src, lshift_count, rshift_count));
// Make sure we are not going to exceed what $4 can do.
predicate((unsigned int)n->in(2)->get_int() <= $2
&& (unsigned int)n->in(1)->in(2)->get_int() <= $2);
ins_cost(INSN_COST * 2);
format %{ "$4 $dst, $src, $rshift_count - $lshift_count, #$2 - $lshift_count" %}
ins_encode %{
int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
int s = $2 - lshift;
int r = (rshift - lshift) & $2;
__ $4(as_Register($dst$$reg),
as_Register($src$$reg),
r, s);
%}
ins_pipe(ialu_reg_shift);
%}')
BFM_INSN(L, 63, RShift, sbfm)
BFM_INSN(I, 31, RShift, sbfmw)
BFM_INSN(L, 63, URShift, ubfm)
BFM_INSN(I, 31, URShift, ubfmw)
dnl
// Bitfield extract with shift & mask
define(`BFX_INSN',
`instruct $3$1(iReg$1NoSp dst, iReg$1 src, immI rshift, imm$1_bitmask mask)
%{
match(Set dst (And$1 ($2$1 src rshift) mask));
ins_cost(INSN_COST);
format %{ "$3 $dst, $src, $mask" %}
ins_encode %{
int rshift = $rshift$$constant;
long mask = $mask$$constant;
int width = exact_log2(mask+1);
__ $3(as_Register($dst$$reg),
as_Register($src$$reg), rshift, width);
%}
ins_pipe(ialu_reg_shift);
%}')
BFX_INSN(I,URShift,ubfxw)
BFX_INSN(L,URShift,ubfx)
// We can use ubfx when extending an And with a mask when we know mask
// is positive. We know that because immI_bitmask guarantees it.
instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
%{
match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask)));
ins_cost(INSN_COST * 2);
format %{ "ubfx $dst, $src, $mask" %}
ins_encode %{
int rshift = $rshift$$constant;
long mask = $mask$$constant;
int width = exact_log2(mask+1);
__ ubfx(as_Register($dst$$reg),
as_Register($src$$reg), rshift, width);
%}
ins_pipe(ialu_reg_shift);
%}
// Rotations
define(`EXTRACT_INSN',
`instruct extr$3$1(iReg$1NoSp dst, iReg$1 src1, iReg$1 src2, immI lshift, immI rshift, rFlagsReg cr)
%{
match(Set dst ($3$1 (LShift$1 src1 lshift) (URShift$1 src2 rshift)));
predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & $2));
ins_cost(INSN_COST);
format %{ "extr $dst, $src1, $src2, #$rshift" %}
ins_encode %{
__ $4(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
$rshift$$constant & $2);
%}
ins_pipe(ialu_reg_reg_extr);
%}
')dnl
EXTRACT_INSN(L, 63, Or, extr)
EXTRACT_INSN(I, 31, Or, extrw)
EXTRACT_INSN(L, 63, Add, extr)
EXTRACT_INSN(I, 31, Add, extrw)
define(`ROL_EXPAND', `
// $2 expander
instruct $2$1_rReg(iReg$1NoSp dst, iReg$1 src, iRegI shift, rFlagsReg cr)
%{
effect(DEF dst, USE src, USE shift);
format %{ "$2 $dst, $src, $shift" %}
ins_cost(INSN_COST * 3);
ins_encode %{
__ subw(rscratch1, zr, as_Register($shift$$reg));
__ $3(as_Register($dst$$reg), as_Register($src$$reg),
rscratch1);
%}
ins_pipe(ialu_reg_reg_vshift);
%}')dnl
define(`ROR_EXPAND', `
// $2 expander
instruct $2$1_rReg(iReg$1NoSp dst, iReg$1 src, iRegI shift, rFlagsReg cr)
%{
effect(DEF dst, USE src, USE shift);
format %{ "$2 $dst, $src, $shift" %}
ins_cost(INSN_COST);
ins_encode %{
__ $3(as_Register($dst$$reg), as_Register($src$$reg),
as_Register($shift$$reg));
%}
ins_pipe(ialu_reg_reg_vshift);
%}')dnl
define(ROL_INSN, `
instruct $3$1_rReg_Var_C$2(iRegLNoSp dst, iRegL src, iRegI shift, immI$2 c$2, rFlagsReg cr)
%{
match(Set dst (Or$1 (LShift$1 src shift) (URShift$1 src (SubI c$2 shift))));
expand %{
$3L_rReg(dst, src, shift, cr);
%}
%}')dnl
define(ROR_INSN, `
instruct $3$1_rReg_Var_C$2(iRegLNoSp dst, iRegL src, iRegI shift, immI$2 c$2, rFlagsReg cr)
%{
match(Set dst (Or$1 (URShift$1 src shift) (LShift$1 src (SubI c$2 shift))));
expand %{
$3L_rReg(dst, src, shift, cr);
%}
%}')dnl
ROL_EXPAND(L, rol, rorv)
ROL_EXPAND(I, rol, rorvw)
ROL_INSN(L, _64, rol)
ROL_INSN(L, 0, rol)
ROL_INSN(I, _32, rol)
ROL_INSN(I, 0, rol)
ROR_EXPAND(L, ror, rorv)
ROR_EXPAND(I, ror, rorvw)
ROR_INSN(L, _64, ror)
ROR_INSN(L, 0, ror)
ROR_INSN(I, _32, ror)
ROR_INSN(I, 0, ror)
// Add/subtract (extended)
dnl ADD_SUB_EXTENDED(mode, size, add node, shift node, insn, shift type, wordsize
define(`ADD_SUB_CONV', `
instruct $3Ext$1(iReg$2NoSp dst, iReg$2 src1, iReg$1orL2I src2, rFlagsReg cr)
%{
match(Set dst ($3$2 src1 (ConvI2L src2)));
ins_cost(INSN_COST);
format %{ "$4 $dst, $src1, $5 $src2" %}
ins_encode %{
__ $4(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::$5);
%}
ins_pipe(ialu_reg_reg);
%}')dnl
ADD_SUB_CONV(I,L,Add,add,sxtw);
ADD_SUB_CONV(I,L,Sub,sub,sxtw);
dnl
define(`ADD_SUB_EXTENDED', `
instruct $3Ext$1_$6(iReg$1NoSp dst, iReg$1 src1, iReg$1 src2, immI_`'eval($7-$2) lshift, immI_`'eval($7-$2) rshift, rFlagsReg cr)
%{
match(Set dst ($3$1 src1 EXTEND($1, $4, src2, lshift, rshift)));
ins_cost(INSN_COST);
format %{ "$5 $dst, $src1, $6 $src2" %}
ins_encode %{
__ $5(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::$6);
%}
ins_pipe(ialu_reg_reg);
%}')
ADD_SUB_EXTENDED(I,16,Add,RShift,add,sxth,32)
ADD_SUB_EXTENDED(I,8,Add,RShift,add,sxtb,32)
ADD_SUB_EXTENDED(I,8,Add,URShift,add,uxtb,32)
ADD_SUB_EXTENDED(L,16,Add,RShift,add,sxth,64)
ADD_SUB_EXTENDED(L,32,Add,RShift,add,sxtw,64)
ADD_SUB_EXTENDED(L,8,Add,RShift,add,sxtb,64)
ADD_SUB_EXTENDED(L,8,Add,URShift,add,uxtb,64)
dnl
dnl ADD_SUB_ZERO_EXTEND(mode, size, add node, insn, shift type)
define(`ADD_SUB_ZERO_EXTEND', `
instruct $3Ext$1_$5_and(iReg$1NoSp dst, iReg$1 src1, iReg$1 src2, imm$1_$2 mask, rFlagsReg cr)
%{
match(Set dst ($3$1 src1 (And$1 src2 mask)));
ins_cost(INSN_COST);
format %{ "$4 $dst, $src1, $src2, $5" %}
ins_encode %{
__ $4(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::$5);
%}
ins_pipe(ialu_reg_reg);
%}')
dnl
ADD_SUB_ZERO_EXTEND(I,255,Add,addw,uxtb)
ADD_SUB_ZERO_EXTEND(I,65535,Add,addw,uxth)
ADD_SUB_ZERO_EXTEND(L,255,Add,add,uxtb)
ADD_SUB_ZERO_EXTEND(L,65535,Add,add,uxth)
ADD_SUB_ZERO_EXTEND(L,4294967295,Add,add,uxtw)
dnl
ADD_SUB_ZERO_EXTEND(I,255,Sub,subw,uxtb)
ADD_SUB_ZERO_EXTEND(I,65535,Sub,subw,uxth)
ADD_SUB_ZERO_EXTEND(L,255,Sub,sub,uxtb)
ADD_SUB_ZERO_EXTEND(L,65535,Sub,sub,uxth)
ADD_SUB_ZERO_EXTEND(L,4294967295,Sub,sub,uxtw)
// END This section of the file is automatically generated. Do not edit --------------

View File

@ -0,0 +1,200 @@
/*
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifdef BUILTIN_SIM
#include <stdio.h>
#include <sys/types.h>
#include "asm/macroAssembler.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "../../../../../../simulator/cpustate.hpp"
#include "../../../../../../simulator/simulator.hpp"
/*
* a routine to initialise and enter ARM simulator execution when
* calling into ARM code from x86 code.
*
* we maintain a simulator per-thread and provide it with 8 Mb of
* stack space
*/
#define SIM_STACK_SIZE (1024 * 1024) // in units of u_int64_t
extern "C" u_int64_t get_alt_stack()
{
return AArch64Simulator::altStack();
}
extern "C" void setup_arm_sim(void *sp, u_int64_t calltype)
{
// n.b. this function runs on the simulator stack so as to avoid
// simulator frames appearing in between VM x86 and ARM frames. note
// that arfgument sp points to the old (VM) stack from which the
// call into the sim was made. The stack switch and entry into this
// routine is handled by x86 prolog code planted in the head of the
// ARM code buffer which the sim is about to start executing (see
// aarch64_linkage.S).
//
// The first ARM instruction in the buffer is identified by fnptr
// stored at the top of the old stack. x86 register contents precede
// fnptr. preceding that are the fp and return address of the VM
// caller into ARM code. any extra, non-register arguments passed to
// the linkage routine precede the fp (this is as per any normal x86
// call wirth extra args).
//
// note that the sim creates Java frames on the Java stack just
// above sp (i.e. directly above fnptr). it sets the sim FP register
// to the pushed fp for the caller effectively eliding the register
// data saved by the linkage routine.
//
// x86 register call arguments are loaded from the stack into ARM
// call registers. if extra arguments occur preceding the x86
// caller's fp then they are copied either into extra ARM registers
// (ARM has 8 rather than 6 gp call registers) or up the stack
// beyond the saved x86 registers so that they immediately precede
// the ARM frame where the ARM calling convention expects them to
// be.
//
// n.b. the number of register/stack values passed to the ARM code
// is determined by calltype
//
// +--------+
// | fnptr | <--- argument sp points here
// +--------+ |
// | rax | | return slot if we need to return a value
// +--------+ |
// | rdi | increasing
// +--------+ address
// | rsi | |
// +--------+ V
// | rdx |
// +--------+
// | rcx |
// +--------+
// | r8 |
// +--------+
// | r9 |
// +--------+
// | xmm0 |
// +--------+
// | xmm1 |
// +--------+
// | xmm2 |
// +--------+
// | xmm3 |
// +--------+
// | xmm4 |
// +--------+
// | xmm5 |
// +--------+
// | xmm6 |
// +--------+
// | xmm7 |
// +--------+
// | fp |
// +--------+
// | caller |
// | ret ip |
// +--------+
// | arg0 | <-- any extra call args start here
// +--------+ offset = 18 * wordSize
// | . . . | (i.e. 1 * calladdr + 1 * rax + 6 * gp call regs
// + 8 * fp call regs + 2 * frame words)
//
// we use a unique sim/stack per thread
const int cursor2_offset = 18;
const int fp_offset = 16;
u_int64_t *cursor = (u_int64_t *)sp;
u_int64_t *cursor2 = ((u_int64_t *)sp) + cursor2_offset;
u_int64_t *fp = ((u_int64_t *)sp) + fp_offset;
int gp_arg_count = calltype & 0xf;
int fp_arg_count = (calltype >> 4) & 0xf;
int return_type = (calltype >> 8) & 0x3;
AArch64Simulator *sim = AArch64Simulator::get_current(UseSimulatorCache, DisableBCCheck);
// save previous cpu state in case this is a recursive entry
CPUState saveState = sim->getCPUState();
// set up initial sim pc, sp and fp registers
sim->init(*cursor++, (u_int64_t)sp, (u_int64_t)fp);
u_int64_t *return_slot = cursor++;
// if we need to pass the sim extra args on the stack then bump
// the stack pointer now
u_int64_t *cursor3 = (u_int64_t *)sim->getCPUState().xreg(SP, 1);
if (gp_arg_count > 8) {
cursor3 -= gp_arg_count - 8;
}
if (fp_arg_count > 8) {
cursor3 -= fp_arg_count - 8;
}
sim->getCPUState().xreg(SP, 1) = (u_int64_t)(cursor3++);
for (int i = 0; i < gp_arg_count; i++) {
if (i < 6) {
// copy saved register to sim register
GReg reg = (GReg)i;
sim->getCPUState().xreg(reg, 0) = *cursor++;
} else if (i < 8) {
// copy extra int arg to sim register
GReg reg = (GReg)i;
sim->getCPUState().xreg(reg, 0) = *cursor2++;
} else {
// copy extra fp arg to sim stack
*cursor3++ = *cursor2++;
}
}
for (int i = 0; i < fp_arg_count; i++) {
if (i < 8) {
// copy saved register to sim register
GReg reg = (GReg)i;
sim->getCPUState().xreg(reg, 0) = *cursor++;
} else {
// copy extra arg to sim stack
*cursor3++ = *cursor2++;
}
}
AArch64Simulator::status_t return_status = sim->run();
if (return_status != AArch64Simulator::STATUS_RETURN){
sim->simPrint0();
fatal("invalid status returned from simulator.run()\n");
}
switch (return_type) {
case MacroAssembler::ret_type_void:
default:
break;
case MacroAssembler::ret_type_integral:
// this overwrites the saved r0
*return_slot = sim->getCPUState().xreg(R0, 0);
break;
case MacroAssembler::ret_type_float:
*(float *)return_slot = sim->getCPUState().sreg(V0);
break;
case MacroAssembler::ret_type_double:
*(double *)return_slot = sim->getCPUState().dreg(V0);
break;
}
// restore incoimng cpu state
sim->getCPUState() = saveState;
}
#endif

View File

@ -0,0 +1,167 @@
#
# Copyright (c) 2012, Red Hat. 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.
# Routines used to enable x86 VM C++ code to invoke JIT-compiled ARM code
# -- either Java methods or generated stub -- and to allow JIT-compiled
# ARM code to invoke x86 VM C++ code
#
# the code for aarch64_stub_prolog below can be copied into the start
# of the ARM code buffer and patched with a link to the
# C++ routine which starts execution on the simulator. the ARM
# code can be generated immediately following the copied code.
#ifdef BUILTIN_SIM
.data
.globl setup_arm_sim,
.type setup_arm_sim,@function
.globl get_alt_stack,
.type get_alt_stack,@function
.globl aarch64_stub_prolog
.p2align 4
aarch64_stub_prolog:
// entry point
4: lea 1f(%rip), %r11
mov (%r11), %r10
mov (%r10), %r10
jmp *%r10
.p2align 4
1:
.set entry_offset, . - 1b
.quad aarch64_prolog_ptr
// 64 bit int used to idenitfy called fn arg/return types
.set calltype_offset, . - 1b
.quad 0
// arm JIT code follows the stub
.set arm_code_offset, . - 1b
.size aarch64_stub_prolog, .-aarch64_stub_prolog
aarch64_stub_prolog_end:
.text
aarch64_prolog_ptr:
.quad aarch64_prolog
.globl aarch64_prolog
aarch64_prolog:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
// save all registers used to pass args
sub $8, %rsp
movd %xmm7, (%rsp)
sub $8, %rsp
movd %xmm6, (%rsp)
sub $8, %rsp
movd %xmm5, (%rsp)
sub $8, %rsp
movd %xmm4, (%rsp)
sub $8, %rsp
movd %xmm3, (%rsp)
sub $8, %rsp
movd %xmm2, (%rsp)
sub $8, %rsp
movd %xmm1, (%rsp)
sub $8, %rsp
movd %xmm0, (%rsp)
push %r9
push %r8
push %rcx
push %rdx
push %rsi
push %rdi
// save rax -- this stack slot will be rewritten with a
// return value if needed
push %rax
// temporarily save r11 while we find the other stack
push %r11
// retrieve alt stack
call get_alt_stack@PLT
pop %r11
// push start of arm code
lea (arm_code_offset)(%r11), %rsi
push %rsi
// load call type code in arg reg 1
mov (calltype_offset)(%r11), %rsi
// load current stack pointer in arg reg 0
mov %rsp, %rdi
// switch to alt stack
mov %rax, %rsp
// save previous stack pointer on new stack
push %rdi
// 16-align the new stack pointer
push %rdi
// call sim setup routine
call setup_arm_sim@PLT
// switch back to old stack
pop %rsp
// pop start of arm code
pop %rdi
// pop rax -- either restores old value or installs return value
pop %rax
// pop arg registers
pop %rdi
pop %rsi
pop %rdx
pop %rcx
pop %r8
pop %r9
movd (%rsp), %xmm0
add $8, %rsp
movd (%rsp), %xmm1
add $8, %rsp
movd (%rsp), %xmm2
add $8, %rsp
movd (%rsp), %xmm3
add $8, %rsp
movd (%rsp), %xmm4
add $8, %rsp
movd (%rsp), %xmm5
add $8, %rsp
movd (%rsp), %xmm6
add $8, %rsp
movd (%rsp), %xmm7
add $8, %rsp
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.p2align 4
get_pc:
// get return pc in rdi and then push it back
pop %rdi
push %rdi
ret
.p2align 4
.long
.globl aarch64_stub_prolog_size
.type aarch64_stub_prolog_size,@function
aarch64_stub_prolog_size:
leaq aarch64_stub_prolog_end - aarch64_stub_prolog, %rax
ret
#endif

View File

@ -0,0 +1,98 @@
dnl Copyright (c) 2014, Red Hat Inc. All rights reserved.
dnl DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
dnl
dnl This code is free software; you can redistribute it and/or modify it
dnl under the terms of the GNU General Public License version 2 only, as
dnl published by the Free Software Foundation.
dnl
dnl This code is distributed in the hope that it will be useful, but WITHOUT
dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl version 2 for more details (a copy is included in the LICENSE file that
dnl accompanied this code).
dnl
dnl You should have received a copy of the GNU General Public License version
dnl 2 along with this work; if not, write to the Free Software Foundation,
dnl Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
dnl
dnl Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
dnl or visit www.oracle.com if you need additional information or have any
dnl questions.
dnl
dnl
dnl Process this file with m4 ad_encode.m4 to generate the load/store
dnl patterns used in aarch64.ad.
dnl
define(choose, `loadStore($1, &MacroAssembler::$3, $2, $4,
$5, $6, $7, $8);dnl
%}')dnl
define(access, `
$3Register $1_reg = as_$3Register($$1$$reg);
$4choose(MacroAssembler(&cbuf), $1_reg,$2,$mem->opcode(),
as_Register($mem$$base),$mem$$index,$mem$$scale,$mem$$disp)')dnl
define(load,`
enc_class aarch64_enc_$2($1 dst, memory mem) %{dnl
access(dst,$2,$3)')dnl
load(iRegI,ldrsbw)
load(iRegI,ldrsb)
load(iRegI,ldrb)
load(iRegL,ldrb)
load(iRegI,ldrshw)
load(iRegI,ldrsh)
load(iRegI,ldrh)
load(iRegL,ldrh)
load(iRegI,ldrw)
load(iRegL,ldrw)
load(iRegL,ldrsw)
load(iRegL,ldr)
load(vRegF,ldrs,Float)
load(vRegD,ldrd,Float)
define(STORE,`
enc_class aarch64_enc_$2($1 src, memory mem) %{dnl
access(src,$2,$3,$4)')dnl
define(STORE0,`
enc_class aarch64_enc_$2`'0(memory mem) %{
MacroAssembler _masm(&cbuf);
choose(_masm,zr,$2,$mem->opcode(),
as_$3Register($mem$$base),$mem$$index,$mem$$scale,$mem$$disp)')dnl
STORE(iRegI,strb)
STORE0(iRegI,strb)
STORE(iRegI,strh)
STORE0(iRegI,strh)
STORE(iRegI,strw)
STORE0(iRegI,strw)
STORE(iRegL,str,,
`// we sometimes get asked to store the stack pointer into the
// current thread -- we cannot do that directly on AArch64
if (src_reg == r31_sp) {
MacroAssembler _masm(&cbuf);
assert(as_Register($mem$$base) == rthread, "unexpected store for sp");
__ mov(rscratch2, sp);
src_reg = rscratch2;
}
')
STORE0(iRegL,str)
STORE(vRegF,strs,Float)
STORE(vRegD,strd,Float)
enc_class aarch64_enc_strw_immn(immN src, memory mem) %{
MacroAssembler _masm(&cbuf);
address con = (address)$src$$constant;
// need to do this the hard way until we can manage relocs
// for 32 bit constants
__ movoop(rscratch2, (jobject)con);
if (con) __ encode_heap_oop_not_null(rscratch2);
choose(_masm,rscratch2,strw,$mem->opcode(),
as_Register($mem$$base),$mem$$index,$mem$$scale,$mem$$disp)
enc_class aarch64_enc_strw_immnk(immN src, memory mem) %{
MacroAssembler _masm(&cbuf);
address con = (address)$src$$constant;
// need to do this the hard way until we can manage relocs
// for 32 bit constants
__ movoop(rscratch2, (jobject)con);
__ encode_klass_not_null(rscratch2);
choose(_masm,rscratch2,strw,$mem->opcode(),
as_Register($mem$$base),$mem$$index,$mem$$scale,$mem$$disp)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_ASSEMBLER_AARCH64_INLINE_HPP
#define CPU_AARCH64_VM_ASSEMBLER_AARCH64_INLINE_HPP
#include "asm/assembler.inline.hpp"
#include "asm/codeBuffer.hpp"
#include "code/codeCache.hpp"
#endif // CPU_AARCH64_VM_ASSEMBLER_AARCH64_INLINE_HPP

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/assembler.hpp"
#include "interpreter/bytecodeInterpreter.hpp"
#include "interpreter/bytecodeInterpreter.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "oops/methodData.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/synchronizer.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/debug.hpp"
#include "interp_masm_aarch64.hpp"
#ifdef CC_INTERP
#endif // CC_INTERP (all)

View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_BYTECODEINTERPRETER_AARCH64_HPP
#define CPU_AARCH64_VM_BYTECODEINTERPRETER_AARCH64_HPP
// Platform specific for C++ based Interpreter
private:
interpreterState _self_link; /* Previous interpreter state */ /* sometimes points to self??? */
address _result_handler; /* temp for saving native result handler */
intptr_t* _sender_sp; /* sender's sp before stack (locals) extension */
address _extra_junk1; /* temp to save on recompiles */
address _extra_junk2; /* temp to save on recompiles */
address _extra_junk3; /* temp to save on recompiles */
// address dummy_for_native2; /* a native frame result handler would be here... */
// address dummy_for_native1; /* native result type stored here in a interpreter native frame */
address _extra_junk4; /* temp to save on recompiles */
address _extra_junk5; /* temp to save on recompiles */
address _extra_junk6; /* temp to save on recompiles */
public:
// we have an interpreter frame...
inline intptr_t* sender_sp() {
return _sender_sp;
}
// The interpreter always has the frame anchor fully setup so we don't
// have to do anything going to vm from the interpreter. On return
// we do have to clear the flags in case they we're modified to
// maintain the stack walking invariants.
//
#define SET_LAST_JAVA_FRAME()
#define RESET_LAST_JAVA_FRAME()
/*
* Macros for accessing the stack.
*/
#undef STACK_INT
#undef STACK_FLOAT
#undef STACK_ADDR
#undef STACK_OBJECT
#undef STACK_DOUBLE
#undef STACK_LONG
// JavaStack Implementation
#define GET_STACK_SLOT(offset) (*((intptr_t*) &topOfStack[-(offset)]))
#define STACK_SLOT(offset) ((address) &topOfStack[-(offset)])
#define STACK_ADDR(offset) (*((address *) &topOfStack[-(offset)]))
#define STACK_INT(offset) (*((jint*) &topOfStack[-(offset)]))
#define STACK_FLOAT(offset) (*((jfloat *) &topOfStack[-(offset)]))
#define STACK_OBJECT(offset) (*((oop *) &topOfStack [-(offset)]))
#define STACK_DOUBLE(offset) (((VMJavaVal64*) &topOfStack[-(offset)])->d)
#define STACK_LONG(offset) (((VMJavaVal64 *) &topOfStack[-(offset)])->l)
#define SET_STACK_SLOT(value, offset) (*(intptr_t*)&topOfStack[-(offset)] = *(intptr_t*)(value))
#define SET_STACK_ADDR(value, offset) (*((address *)&topOfStack[-(offset)]) = (value))
#define SET_STACK_INT(value, offset) (*((jint *)&topOfStack[-(offset)]) = (value))
#define SET_STACK_FLOAT(value, offset) (*((jfloat *)&topOfStack[-(offset)]) = (value))
#define SET_STACK_OBJECT(value, offset) (*((oop *)&topOfStack[-(offset)]) = (value))
#define SET_STACK_DOUBLE(value, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->d = (value))
#define SET_STACK_DOUBLE_FROM_ADDR(addr, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->d = \
((VMJavaVal64*)(addr))->d)
#define SET_STACK_LONG(value, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->l = (value))
#define SET_STACK_LONG_FROM_ADDR(addr, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->l = \
((VMJavaVal64*)(addr))->l)
// JavaLocals implementation
#define LOCALS_SLOT(offset) ((intptr_t*)&locals[-(offset)])
#define LOCALS_ADDR(offset) ((address)locals[-(offset)])
#define LOCALS_INT(offset) ((jint)(locals[-(offset)]))
#define LOCALS_FLOAT(offset) (*((jfloat*)&locals[-(offset)]))
#define LOCALS_OBJECT(offset) ((oop)locals[-(offset)])
#define LOCALS_DOUBLE(offset) (((VMJavaVal64*)&locals[-((offset) + 1)])->d)
#define LOCALS_LONG(offset) (((VMJavaVal64*)&locals[-((offset) + 1)])->l)
#define LOCALS_LONG_AT(offset) (((address)&locals[-((offset) + 1)]))
#define LOCALS_DOUBLE_AT(offset) (((address)&locals[-((offset) + 1)]))
#define SET_LOCALS_SLOT(value, offset) (*(intptr_t*)&locals[-(offset)] = *(intptr_t *)(value))
#define SET_LOCALS_ADDR(value, offset) (*((address *)&locals[-(offset)]) = (value))
#define SET_LOCALS_INT(value, offset) (*((jint *)&locals[-(offset)]) = (value))
#define SET_LOCALS_FLOAT(value, offset) (*((jfloat *)&locals[-(offset)]) = (value))
#define SET_LOCALS_OBJECT(value, offset) (*((oop *)&locals[-(offset)]) = (value))
#define SET_LOCALS_DOUBLE(value, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->d = (value))
#define SET_LOCALS_LONG(value, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->l = (value))
#define SET_LOCALS_DOUBLE_FROM_ADDR(addr, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->d = \
((VMJavaVal64*)(addr))->d)
#define SET_LOCALS_LONG_FROM_ADDR(addr, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->l = \
((VMJavaVal64*)(addr))->l)
#endif // CPU_AARCH64_VM_BYTECODEINTERPRETER_AARCH64_HPP

View File

@ -0,0 +1,286 @@
/*
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_BYTECODEINTERPRETER_AARCH64_INLINE_HPP
#define CPU_AARCH64_VM_BYTECODEINTERPRETER_AARCH64_INLINE_HPP
// Inline interpreter functions for IA32
inline jfloat BytecodeInterpreter::VMfloatAdd(jfloat op1, jfloat op2) { return op1 + op2; }
inline jfloat BytecodeInterpreter::VMfloatSub(jfloat op1, jfloat op2) { return op1 - op2; }
inline jfloat BytecodeInterpreter::VMfloatMul(jfloat op1, jfloat op2) { return op1 * op2; }
inline jfloat BytecodeInterpreter::VMfloatDiv(jfloat op1, jfloat op2) { return op1 / op2; }
inline jfloat BytecodeInterpreter::VMfloatRem(jfloat op1, jfloat op2) { return fmod(op1, op2); }
inline jfloat BytecodeInterpreter::VMfloatNeg(jfloat op) { return -op; }
inline int32_t BytecodeInterpreter::VMfloatCompare(jfloat op1, jfloat op2, int32_t direction) {
return ( op1 < op2 ? -1 :
op1 > op2 ? 1 :
op1 == op2 ? 0 :
(direction == -1 || direction == 1) ? direction : 0);
}
inline void BytecodeInterpreter::VMmemCopy64(uint32_t to[2], const uint32_t from[2]) {
// x86 can do unaligned copies but not 64bits at a time
to[0] = from[0]; to[1] = from[1];
}
// The long operations depend on compiler support for "long long" on x86
inline jlong BytecodeInterpreter::VMlongAdd(jlong op1, jlong op2) {
return op1 + op2;
}
inline jlong BytecodeInterpreter::VMlongAnd(jlong op1, jlong op2) {
return op1 & op2;
}
inline jlong BytecodeInterpreter::VMlongDiv(jlong op1, jlong op2) {
// QQQ what about check and throw...
return op1 / op2;
}
inline jlong BytecodeInterpreter::VMlongMul(jlong op1, jlong op2) {
return op1 * op2;
}
inline jlong BytecodeInterpreter::VMlongOr(jlong op1, jlong op2) {
return op1 | op2;
}
inline jlong BytecodeInterpreter::VMlongSub(jlong op1, jlong op2) {
return op1 - op2;
}
inline jlong BytecodeInterpreter::VMlongXor(jlong op1, jlong op2) {
return op1 ^ op2;
}
inline jlong BytecodeInterpreter::VMlongRem(jlong op1, jlong op2) {
return op1 % op2;
}
inline jlong BytecodeInterpreter::VMlongUshr(jlong op1, jint op2) {
// CVM did this 0x3f mask, is the really needed??? QQQ
return ((unsigned long long) op1) >> (op2 & 0x3F);
}
inline jlong BytecodeInterpreter::VMlongShr(jlong op1, jint op2) {
return op1 >> (op2 & 0x3F);
}
inline jlong BytecodeInterpreter::VMlongShl(jlong op1, jint op2) {
return op1 << (op2 & 0x3F);
}
inline jlong BytecodeInterpreter::VMlongNeg(jlong op) {
return -op;
}
inline jlong BytecodeInterpreter::VMlongNot(jlong op) {
return ~op;
}
inline int32_t BytecodeInterpreter::VMlongLtz(jlong op) {
return (op <= 0);
}
inline int32_t BytecodeInterpreter::VMlongGez(jlong op) {
return (op >= 0);
}
inline int32_t BytecodeInterpreter::VMlongEqz(jlong op) {
return (op == 0);
}
inline int32_t BytecodeInterpreter::VMlongEq(jlong op1, jlong op2) {
return (op1 == op2);
}
inline int32_t BytecodeInterpreter::VMlongNe(jlong op1, jlong op2) {
return (op1 != op2);
}
inline int32_t BytecodeInterpreter::VMlongGe(jlong op1, jlong op2) {
return (op1 >= op2);
}
inline int32_t BytecodeInterpreter::VMlongLe(jlong op1, jlong op2) {
return (op1 <= op2);
}
inline int32_t BytecodeInterpreter::VMlongLt(jlong op1, jlong op2) {
return (op1 < op2);
}
inline int32_t BytecodeInterpreter::VMlongGt(jlong op1, jlong op2) {
return (op1 > op2);
}
inline int32_t BytecodeInterpreter::VMlongCompare(jlong op1, jlong op2) {
return (VMlongLt(op1, op2) ? -1 : VMlongGt(op1, op2) ? 1 : 0);
}
// Long conversions
inline jdouble BytecodeInterpreter::VMlong2Double(jlong val) {
return (jdouble) val;
}
inline jfloat BytecodeInterpreter::VMlong2Float(jlong val) {
return (jfloat) val;
}
inline jint BytecodeInterpreter::VMlong2Int(jlong val) {
return (jint) val;
}
// Double Arithmetic
inline jdouble BytecodeInterpreter::VMdoubleAdd(jdouble op1, jdouble op2) {
return op1 + op2;
}
inline jdouble BytecodeInterpreter::VMdoubleDiv(jdouble op1, jdouble op2) {
// Divide by zero... QQQ
return op1 / op2;
}
inline jdouble BytecodeInterpreter::VMdoubleMul(jdouble op1, jdouble op2) {
return op1 * op2;
}
inline jdouble BytecodeInterpreter::VMdoubleNeg(jdouble op) {
return -op;
}
inline jdouble BytecodeInterpreter::VMdoubleRem(jdouble op1, jdouble op2) {
return fmod(op1, op2);
}
inline jdouble BytecodeInterpreter::VMdoubleSub(jdouble op1, jdouble op2) {
return op1 - op2;
}
inline int32_t BytecodeInterpreter::VMdoubleCompare(jdouble op1, jdouble op2, int32_t direction) {
return ( op1 < op2 ? -1 :
op1 > op2 ? 1 :
op1 == op2 ? 0 :
(direction == -1 || direction == 1) ? direction : 0);
}
// Double Conversions
inline jfloat BytecodeInterpreter::VMdouble2Float(jdouble val) {
return (jfloat) val;
}
// Float Conversions
inline jdouble BytecodeInterpreter::VMfloat2Double(jfloat op) {
return (jdouble) op;
}
// Integer Arithmetic
inline jint BytecodeInterpreter::VMintAdd(jint op1, jint op2) {
return op1 + op2;
}
inline jint BytecodeInterpreter::VMintAnd(jint op1, jint op2) {
return op1 & op2;
}
inline jint BytecodeInterpreter::VMintDiv(jint op1, jint op2) {
/* it's possible we could catch this special case implicitly */
if ((juint)op1 == 0x80000000 && op2 == -1) return op1;
else return op1 / op2;
}
inline jint BytecodeInterpreter::VMintMul(jint op1, jint op2) {
return op1 * op2;
}
inline jint BytecodeInterpreter::VMintNeg(jint op) {
return -op;
}
inline jint BytecodeInterpreter::VMintOr(jint op1, jint op2) {
return op1 | op2;
}
inline jint BytecodeInterpreter::VMintRem(jint op1, jint op2) {
/* it's possible we could catch this special case implicitly */
if ((juint)op1 == 0x80000000 && op2 == -1) return 0;
else return op1 % op2;
}
inline jint BytecodeInterpreter::VMintShl(jint op1, jint op2) {
return op1 << op2;
}
inline jint BytecodeInterpreter::VMintShr(jint op1, jint op2) {
return op1 >> (op2 & 0x1f);
}
inline jint BytecodeInterpreter::VMintSub(jint op1, jint op2) {
return op1 - op2;
}
inline jint BytecodeInterpreter::VMintUshr(jint op1, jint op2) {
return ((juint) op1) >> (op2 & 0x1f);
}
inline jint BytecodeInterpreter::VMintXor(jint op1, jint op2) {
return op1 ^ op2;
}
inline jdouble BytecodeInterpreter::VMint2Double(jint val) {
return (jdouble) val;
}
inline jfloat BytecodeInterpreter::VMint2Float(jint val) {
return (jfloat) val;
}
inline jlong BytecodeInterpreter::VMint2Long(jint val) {
return (jlong) val;
}
inline jchar BytecodeInterpreter::VMint2Char(jint val) {
return (jchar) val;
}
inline jshort BytecodeInterpreter::VMint2Short(jint val) {
return (jshort) val;
}
inline jbyte BytecodeInterpreter::VMint2Byte(jint val) {
return (jbyte) val;
}
#endif // CPU_AARCH64_VM_BYTECODEINTERPRETER_AARCH64_INLINE_HPP

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "interpreter/bytecodes.hpp"

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_BYTECODES_AARCH64_HPP
#define CPU_AARCH64_VM_BYTECODES_AARCH64_HPP
// No aarch64 specific bytecodes
#endif // CPU_AARCH64_VM_BYTECODES_AARCH64_HPP

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_BYTES_AARCH64_HPP
#define CPU_AARCH64_VM_BYTES_AARCH64_HPP
#include "memory/allocation.hpp"
class Bytes: AllStatic {
public:
// Returns true if the byte ordering used by Java is different from the native byte ordering
// of the underlying machine. For example, this is true for Intel x86, but false for Solaris
// on Sparc.
static inline bool is_Java_byte_ordering_different(){ return true; }
// Efficient reading and writing of unaligned unsigned data in platform-specific byte ordering
// (no special code is needed since x86 CPUs can access unaligned data)
static inline u2 get_native_u2(address p) { return *(u2*)p; }
static inline u4 get_native_u4(address p) { return *(u4*)p; }
static inline u8 get_native_u8(address p) { return *(u8*)p; }
static inline void put_native_u2(address p, u2 x) { *(u2*)p = x; }
static inline void put_native_u4(address p, u4 x) { *(u4*)p = x; }
static inline void put_native_u8(address p, u8 x) { *(u8*)p = x; }
// Efficient reading and writing of unaligned unsigned data in Java
// byte ordering (i.e. big-endian ordering). Byte-order reversal is
// needed since x86 CPUs use little-endian format.
static inline u2 get_Java_u2(address p) { return swap_u2(get_native_u2(p)); }
static inline u4 get_Java_u4(address p) { return swap_u4(get_native_u4(p)); }
static inline u8 get_Java_u8(address p) { return swap_u8(get_native_u8(p)); }
static inline void put_Java_u2(address p, u2 x) { put_native_u2(p, swap_u2(x)); }
static inline void put_Java_u4(address p, u4 x) { put_native_u4(p, swap_u4(x)); }
static inline void put_Java_u8(address p, u8 x) { put_native_u8(p, swap_u8(x)); }
// Efficient swapping of byte ordering
static inline u2 swap_u2(u2 x); // compiler-dependent implementation
static inline u4 swap_u4(u4 x); // compiler-dependent implementation
static inline u8 swap_u8(u8 x);
};
// The following header contains the implementations of swap_u2, swap_u4, and swap_u8[_base]
#ifdef TARGET_OS_ARCH_linux_aarch64
# include "bytes_linux_aarch64.inline.hpp"
#endif
#endif // CPU_AARCH64_VM_BYTES_AARCH64_HPP

View File

@ -0,0 +1,381 @@
/*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "c1/c1_CodeStubs.hpp"
#include "c1/c1_FrameMap.hpp"
#include "c1/c1_LIRAssembler.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "c1/c1_Runtime1.hpp"
#include "nativeInst_aarch64.hpp"
#include "runtime/sharedRuntime.hpp"
#include "vmreg_aarch64.inline.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
#endif
#define __ ce->masm()->
void CounterOverflowStub::emit_code(LIR_Assembler* ce) {
__ bind(_entry);
ce->store_parameter(_method->as_register(), 1);
ce->store_parameter(_bci, 0);
__ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::counter_overflow_id)));
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
__ b(_continuation);
}
RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index,
bool throw_index_out_of_bounds_exception)
: _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception)
, _index(index)
{
assert(info != NULL, "must have info");
_info = new CodeEmitInfo(info);
}
void RangeCheckStub::emit_code(LIR_Assembler* ce) {
__ bind(_entry);
if (_info->deoptimize_on_exception()) {
address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
__ far_call(RuntimeAddress(a));
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
debug_only(__ should_not_reach_here());
return;
}
if (_index->is_cpu_register()) {
__ mov(rscratch1, _index->as_register());
} else {
__ mov(rscratch1, _index->as_jint());
}
Runtime1::StubID stub_id;
if (_throw_index_out_of_bounds_exception) {
stub_id = Runtime1::throw_index_exception_id;
} else {
stub_id = Runtime1::throw_range_check_failed_id;
}
__ far_call(RuntimeAddress(Runtime1::entry_for(stub_id)), NULL, rscratch2);
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
debug_only(__ should_not_reach_here());
}
PredicateFailedStub::PredicateFailedStub(CodeEmitInfo* info) {
_info = new CodeEmitInfo(info);
}
void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
__ bind(_entry);
address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
__ far_call(RuntimeAddress(a));
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
debug_only(__ should_not_reach_here());
}
void DivByZeroStub::emit_code(LIR_Assembler* ce) {
if (_offset != -1) {
ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
}
__ bind(_entry);
__ far_call(Address(Runtime1::entry_for(Runtime1::throw_div0_exception_id), relocInfo::runtime_call_type));
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
#ifdef ASSERT
__ should_not_reach_here();
#endif
}
// Implementation of NewInstanceStub
NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id) {
_result = result;
_klass = klass;
_klass_reg = klass_reg;
_info = new CodeEmitInfo(info);
assert(stub_id == Runtime1::new_instance_id ||
stub_id == Runtime1::fast_new_instance_id ||
stub_id == Runtime1::fast_new_instance_init_check_id,
"need new_instance id");
_stub_id = stub_id;
}
void NewInstanceStub::emit_code(LIR_Assembler* ce) {
assert(__ rsp_offset() == 0, "frame size should be fixed");
__ bind(_entry);
__ mov(r3, _klass_reg->as_register());
__ far_call(RuntimeAddress(Runtime1::entry_for(_stub_id)));
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
assert(_result->as_register() == r0, "result must in r0,");
__ b(_continuation);
}
// Implementation of NewTypeArrayStub
// Implementation of NewTypeArrayStub
NewTypeArrayStub::NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) {
_klass_reg = klass_reg;
_length = length;
_result = result;
_info = new CodeEmitInfo(info);
}
void NewTypeArrayStub::emit_code(LIR_Assembler* ce) {
assert(__ rsp_offset() == 0, "frame size should be fixed");
__ bind(_entry);
assert(_length->as_register() == r19, "length must in r19,");
assert(_klass_reg->as_register() == r3, "klass_reg must in r3");
__ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::new_type_array_id)));
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
assert(_result->as_register() == r0, "result must in r0");
__ b(_continuation);
}
// Implementation of NewObjectArrayStub
NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) {
_klass_reg = klass_reg;
_result = result;
_length = length;
_info = new CodeEmitInfo(info);
}
void NewObjectArrayStub::emit_code(LIR_Assembler* ce) {
assert(__ rsp_offset() == 0, "frame size should be fixed");
__ bind(_entry);
assert(_length->as_register() == r19, "length must in r19,");
assert(_klass_reg->as_register() == r3, "klass_reg must in r3");
__ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::new_object_array_id)));
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
assert(_result->as_register() == r0, "result must in r0");
__ b(_continuation);
}
// Implementation of MonitorAccessStubs
MonitorEnterStub::MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info)
: MonitorAccessStub(obj_reg, lock_reg)
{
_info = new CodeEmitInfo(info);
}
void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
assert(__ rsp_offset() == 0, "frame size should be fixed");
__ bind(_entry);
ce->store_parameter(_obj_reg->as_register(), 1);
ce->store_parameter(_lock_reg->as_register(), 0);
Runtime1::StubID enter_id;
if (ce->compilation()->has_fpu_code()) {
enter_id = Runtime1::monitorenter_id;
} else {
enter_id = Runtime1::monitorenter_nofpu_id;
}
__ far_call(RuntimeAddress(Runtime1::entry_for(enter_id)));
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
__ b(_continuation);
}
void MonitorExitStub::emit_code(LIR_Assembler* ce) {
__ bind(_entry);
if (_compute_lock) {
// lock_reg was destroyed by fast unlocking attempt => recompute it
ce->monitor_address(_monitor_ix, _lock_reg);
}
ce->store_parameter(_lock_reg->as_register(), 0);
// note: non-blocking leaf routine => no call info needed
Runtime1::StubID exit_id;
if (ce->compilation()->has_fpu_code()) {
exit_id = Runtime1::monitorexit_id;
} else {
exit_id = Runtime1::monitorexit_nofpu_id;
}
__ adr(lr, _continuation);
__ far_jump(RuntimeAddress(Runtime1::entry_for(exit_id)));
}
// Implementation of patching:
// - Copy the code at given offset to an inlined buffer (first the bytes, then the number of bytes)
// - Replace original code with a call to the stub
// At Runtime:
// - call to stub, jump to runtime
// - in runtime: preserve all registers (rspecially objects, i.e., source and destination object)
// - in runtime: after initializing class, restore original code, reexecute instruction
int PatchingStub::_patch_info_offset = -NativeGeneralJump::instruction_size;
void PatchingStub::align_patch_site(MacroAssembler* masm) {
}
void PatchingStub::emit_code(LIR_Assembler* ce) {
assert(false, "AArch64 should not use C1 runtime patching");
}
void DeoptimizeStub::emit_code(LIR_Assembler* ce) {
__ bind(_entry);
__ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::deoptimize_id)));
ce->add_call_info_here(_info);
DEBUG_ONLY(__ should_not_reach_here());
}
void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) {
address a;
if (_info->deoptimize_on_exception()) {
// Deoptimize, do not throw the exception, because it is probably wrong to do it here.
a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
} else {
a = Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id);
}
ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
__ bind(_entry);
__ far_call(RuntimeAddress(a));
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
debug_only(__ should_not_reach_here());
}
void SimpleExceptionStub::emit_code(LIR_Assembler* ce) {
assert(__ rsp_offset() == 0, "frame size should be fixed");
__ bind(_entry);
// pass the object in a scratch register because all other registers
// must be preserved
if (_obj->is_cpu_register()) {
__ mov(rscratch1, _obj->as_register());
}
__ far_call(RuntimeAddress(Runtime1::entry_for(_stub)), NULL, rscratch2);
ce->add_call_info_here(_info);
debug_only(__ should_not_reach_here());
}
void ArrayCopyStub::emit_code(LIR_Assembler* ce) {
//---------------slow case: call to native-----------------
__ bind(_entry);
// Figure out where the args should go
// This should really convert the IntrinsicID to the Method* and signature
// but I don't know how to do that.
//
VMRegPair args[5];
BasicType signature[5] = { T_OBJECT, T_INT, T_OBJECT, T_INT, T_INT};
SharedRuntime::java_calling_convention(signature, args, 5, true);
// push parameters
// (src, src_pos, dest, destPos, length)
Register r[5];
r[0] = src()->as_register();
r[1] = src_pos()->as_register();
r[2] = dst()->as_register();
r[3] = dst_pos()->as_register();
r[4] = length()->as_register();
// next registers will get stored on the stack
for (int i = 0; i < 5 ; i++ ) {
VMReg r_1 = args[i].first();
if (r_1->is_stack()) {
int st_off = r_1->reg2stack() * wordSize;
__ str (r[i], Address(sp, st_off));
} else {
assert(r[i] == args[i].first()->as_Register(), "Wrong register for arg ");
}
}
ce->align_call(lir_static_call);
ce->emit_static_call_stub();
Address resolve(SharedRuntime::get_resolve_static_call_stub(),
relocInfo::static_call_type);
__ trampoline_call(resolve);
ce->add_call_info_here(info());
#ifndef PRODUCT
__ lea(rscratch2, ExternalAddress((address)&Runtime1::_arraycopy_slowcase_cnt));
__ incrementw(Address(rscratch2));
#endif
__ b(_continuation);
}
/////////////////////////////////////////////////////////////////////////////
#if INCLUDE_ALL_GCS
void G1PreBarrierStub::emit_code(LIR_Assembler* ce) {
// At this point we know that marking is in progress.
// If do_load() is true then we have to emit the
// load of the previous value; otherwise it has already
// been loaded into _pre_val.
__ bind(_entry);
assert(pre_val()->is_register(), "Precondition.");
Register pre_val_reg = pre_val()->as_register();
if (do_load()) {
ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false /*wide*/, false /*unaligned*/);
}
__ cbz(pre_val_reg, _continuation);
ce->store_parameter(pre_val()->as_register(), 0);
__ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::g1_pre_barrier_slow_id)));
__ b(_continuation);
}
void G1PostBarrierStub::emit_code(LIR_Assembler* ce) {
__ bind(_entry);
assert(addr()->is_register(), "Precondition.");
assert(new_val()->is_register(), "Precondition.");
Register new_val_reg = new_val()->as_register();
__ cbz(new_val_reg, _continuation);
ce->store_parameter(addr()->as_pointer_register(), 0);
__ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::g1_post_barrier_slow_id)));
__ b(_continuation);
}
#endif // INCLUDE_ALL_GCS
/////////////////////////////////////////////////////////////////////////////
#undef __

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_C1_DEFS_AARCH64_HPP
#define CPU_AARCH64_VM_C1_DEFS_AARCH64_HPP
// native word offsets from memory address (little endian)
enum {
pd_lo_word_offset_in_bytes = 0,
pd_hi_word_offset_in_bytes = BytesPerWord
};
// explicit rounding operations are required to implement the strictFP mode
enum {
pd_strict_fp_requires_explicit_rounding = false
};
// FIXME: There are no callee-saved
// registers
enum {
pd_nof_cpu_regs_frame_map = RegisterImpl::number_of_registers, // number of registers used during code emission
pd_nof_fpu_regs_frame_map = FloatRegisterImpl::number_of_registers, // number of registers used during code emission
pd_nof_caller_save_cpu_regs_frame_map = 19 - 2, // number of registers killed by calls
pd_nof_caller_save_fpu_regs_frame_map = 32, // number of registers killed by calls
pd_first_callee_saved_reg = 19 - 2,
pd_last_callee_saved_reg = 26 - 2,
pd_last_allocatable_cpu_reg = 16,
pd_nof_cpu_regs_reg_alloc
= pd_last_allocatable_cpu_reg + 1, // number of registers that are visible to register allocator
pd_nof_fpu_regs_reg_alloc = 8, // number of registers that are visible to register allocator
pd_nof_cpu_regs_linearscan = 32, // number of registers visible to linear scan
pd_nof_fpu_regs_linearscan = pd_nof_fpu_regs_frame_map, // number of registers visible to linear scan
pd_nof_xmm_regs_linearscan = 0, // like sparc we don't have any of these
pd_first_cpu_reg = 0,
pd_last_cpu_reg = 16,
pd_first_byte_reg = 0,
pd_last_byte_reg = 16,
pd_first_fpu_reg = pd_nof_cpu_regs_frame_map,
pd_last_fpu_reg = pd_first_fpu_reg + 31,
pd_first_callee_saved_fpu_reg = 8 + pd_first_fpu_reg,
pd_last_callee_saved_fpu_reg = 15 + pd_first_fpu_reg,
};
// Encoding of float value in debug info. This is true on x86 where
// floats are extended to doubles when stored in the stack, false for
// AArch64 where floats and doubles are stored in their native form.
enum {
pd_float_saved_as_double = false
};
#endif // CPU_AARCH64_VM_C1_DEFS_AARCH64_HPP

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "c1/c1_FpuStackSim.hpp"
#include "c1/c1_FrameMap.hpp"
#include "utilities/array.hpp"
#include "utilities/ostream.hpp"
//--------------------------------------------------------
// FpuStackSim
//--------------------------------------------------------
// No FPU stack on AARCH64

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_C1_FPUSTACKSIM_HPP
#define CPU_AARCH64_VM_C1_FPUSTACKSIM_HPP
// No FPU stack on AARCH64
class FpuStackSim;
#endif // CPU_AARCH64_VM_C1_FPUSTACKSIM_HPP

View File

@ -0,0 +1,356 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "c1/c1_FrameMap.hpp"
#include "c1/c1_LIR.hpp"
#include "runtime/sharedRuntime.hpp"
#include "vmreg_aarch64.inline.hpp"
LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool) {
LIR_Opr opr = LIR_OprFact::illegalOpr;
VMReg r_1 = reg->first();
VMReg r_2 = reg->second();
if (r_1->is_stack()) {
// Convert stack slot to an SP offset
// The calling convention does not count the SharedRuntime::out_preserve_stack_slots() value
// so we must add it in here.
int st_off = (r_1->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size;
opr = LIR_OprFact::address(new LIR_Address(sp_opr, st_off, type));
} else if (r_1->is_Register()) {
Register reg = r_1->as_Register();
if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) {
Register reg2 = r_2->as_Register();
assert(reg2 == reg, "must be same register");
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);
}
} else if (r_1->is_FloatRegister()) {
assert(type == T_DOUBLE || type == T_FLOAT, "wrong type");
int num = r_1->as_FloatRegister()->encoding();
if (type == T_FLOAT) {
opr = LIR_OprFact::single_fpu(num);
} else {
opr = LIR_OprFact::double_fpu(num);
}
} else {
ShouldNotReachHere();
}
return opr;
}
LIR_Opr FrameMap::r0_opr;
LIR_Opr FrameMap::r1_opr;
LIR_Opr FrameMap::r2_opr;
LIR_Opr FrameMap::r3_opr;
LIR_Opr FrameMap::r4_opr;
LIR_Opr FrameMap::r5_opr;
LIR_Opr FrameMap::r6_opr;
LIR_Opr FrameMap::r7_opr;
LIR_Opr FrameMap::r8_opr;
LIR_Opr FrameMap::r9_opr;
LIR_Opr FrameMap::r10_opr;
LIR_Opr FrameMap::r11_opr;
LIR_Opr FrameMap::r12_opr;
LIR_Opr FrameMap::r13_opr;
LIR_Opr FrameMap::r14_opr;
LIR_Opr FrameMap::r15_opr;
LIR_Opr FrameMap::r16_opr;
LIR_Opr FrameMap::r17_opr;
LIR_Opr FrameMap::r18_opr;
LIR_Opr FrameMap::r19_opr;
LIR_Opr FrameMap::r20_opr;
LIR_Opr FrameMap::r21_opr;
LIR_Opr FrameMap::r22_opr;
LIR_Opr FrameMap::r23_opr;
LIR_Opr FrameMap::r24_opr;
LIR_Opr FrameMap::r25_opr;
LIR_Opr FrameMap::r26_opr;
LIR_Opr FrameMap::r27_opr;
LIR_Opr FrameMap::r28_opr;
LIR_Opr FrameMap::r29_opr;
LIR_Opr FrameMap::r30_opr;
LIR_Opr FrameMap::rfp_opr;
LIR_Opr FrameMap::sp_opr;
LIR_Opr FrameMap::receiver_opr;
LIR_Opr FrameMap::r0_oop_opr;
LIR_Opr FrameMap::r1_oop_opr;
LIR_Opr FrameMap::r2_oop_opr;
LIR_Opr FrameMap::r3_oop_opr;
LIR_Opr FrameMap::r4_oop_opr;
LIR_Opr FrameMap::r5_oop_opr;
LIR_Opr FrameMap::r6_oop_opr;
LIR_Opr FrameMap::r7_oop_opr;
LIR_Opr FrameMap::r8_oop_opr;
LIR_Opr FrameMap::r9_oop_opr;
LIR_Opr FrameMap::r10_oop_opr;
LIR_Opr FrameMap::r11_oop_opr;
LIR_Opr FrameMap::r12_oop_opr;
LIR_Opr FrameMap::r13_oop_opr;
LIR_Opr FrameMap::r14_oop_opr;
LIR_Opr FrameMap::r15_oop_opr;
LIR_Opr FrameMap::r16_oop_opr;
LIR_Opr FrameMap::r17_oop_opr;
LIR_Opr FrameMap::r18_oop_opr;
LIR_Opr FrameMap::r19_oop_opr;
LIR_Opr FrameMap::r20_oop_opr;
LIR_Opr FrameMap::r21_oop_opr;
LIR_Opr FrameMap::r22_oop_opr;
LIR_Opr FrameMap::r23_oop_opr;
LIR_Opr FrameMap::r24_oop_opr;
LIR_Opr FrameMap::r25_oop_opr;
LIR_Opr FrameMap::r26_oop_opr;
LIR_Opr FrameMap::r27_oop_opr;
LIR_Opr FrameMap::r28_oop_opr;
LIR_Opr FrameMap::r29_oop_opr;
LIR_Opr FrameMap::r30_oop_opr;
LIR_Opr FrameMap::rscratch1_opr;
LIR_Opr FrameMap::rscratch2_opr;
LIR_Opr FrameMap::rscratch1_long_opr;
LIR_Opr FrameMap::rscratch2_long_opr;
LIR_Opr FrameMap::r0_metadata_opr;
LIR_Opr FrameMap::r1_metadata_opr;
LIR_Opr FrameMap::r2_metadata_opr;
LIR_Opr FrameMap::r3_metadata_opr;
LIR_Opr FrameMap::r4_metadata_opr;
LIR_Opr FrameMap::r5_metadata_opr;
LIR_Opr FrameMap::long0_opr;
LIR_Opr FrameMap::long1_opr;
LIR_Opr FrameMap::fpu0_float_opr;
LIR_Opr FrameMap::fpu0_double_opr;
LIR_Opr FrameMap::_caller_save_cpu_regs[] = { 0, };
LIR_Opr FrameMap::_caller_save_fpu_regs[] = { 0, };
//--------------------------------------------------------
// FrameMap
//--------------------------------------------------------
void FrameMap::initialize() {
assert(!_init_done, "once");
int i=0;
map_register(i, r0); r0_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r1); r1_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r2); r2_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r3); r3_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r4); r4_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r5); r5_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r6); r6_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r7); r7_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r10); r10_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r11); r11_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r12); r12_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r13); r13_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r14); r14_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r15); r15_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r16); r16_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r17); r17_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r18); r18_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r19); r19_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r20); r20_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r21); r21_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r22); r22_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r23); r23_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r24); r24_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r25); r25_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r26); r26_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r27); r27_opr = LIR_OprFact::single_cpu(i); i++; // rheapbase
map_register(i, r28); r28_opr = LIR_OprFact::single_cpu(i); i++; // rthread
map_register(i, r29); r29_opr = LIR_OprFact::single_cpu(i); i++; // rfp
map_register(i, r30); r30_opr = LIR_OprFact::single_cpu(i); i++; // lr
map_register(i, r31_sp); sp_opr = LIR_OprFact::single_cpu(i); i++; // sp
map_register(i, r8); r8_opr = LIR_OprFact::single_cpu(i); i++; // rscratch1
map_register(i, r9); r9_opr = LIR_OprFact::single_cpu(i); i++; // rscratch2
rscratch1_opr = r8_opr;
rscratch2_opr = r9_opr;
rscratch1_long_opr = LIR_OprFact::double_cpu(r8_opr->cpu_regnr(), r8_opr->cpu_regnr());
rscratch2_long_opr = LIR_OprFact::double_cpu(r9_opr->cpu_regnr(), r9_opr->cpu_regnr());
long0_opr = LIR_OprFact::double_cpu(0, 0);
long1_opr = LIR_OprFact::double_cpu(1, 1);
fpu0_float_opr = LIR_OprFact::single_fpu(0);
fpu0_double_opr = LIR_OprFact::double_fpu(0);
_caller_save_cpu_regs[0] = r0_opr;
_caller_save_cpu_regs[1] = r1_opr;
_caller_save_cpu_regs[2] = r2_opr;
_caller_save_cpu_regs[3] = r3_opr;
_caller_save_cpu_regs[4] = r4_opr;
_caller_save_cpu_regs[5] = r5_opr;
_caller_save_cpu_regs[6] = r6_opr;
_caller_save_cpu_regs[7] = r7_opr;
// rscratch1, rscratch 2 not included
_caller_save_cpu_regs[8] = r10_opr;
_caller_save_cpu_regs[9] = r11_opr;
_caller_save_cpu_regs[10] = r12_opr;
_caller_save_cpu_regs[11] = r13_opr;
_caller_save_cpu_regs[12] = r14_opr;
_caller_save_cpu_regs[13] = r15_opr;
_caller_save_cpu_regs[14] = r16_opr;
_caller_save_cpu_regs[15] = r17_opr;
_caller_save_cpu_regs[16] = r18_opr;
for (int i = 0; i < 8; i++) {
_caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i);
}
_init_done = true;
r0_oop_opr = as_oop_opr(r0);
r1_oop_opr = as_oop_opr(r1);
r2_oop_opr = as_oop_opr(r2);
r3_oop_opr = as_oop_opr(r3);
r4_oop_opr = as_oop_opr(r4);
r5_oop_opr = as_oop_opr(r5);
r6_oop_opr = as_oop_opr(r6);
r7_oop_opr = as_oop_opr(r7);
r8_oop_opr = as_oop_opr(r8);
r9_oop_opr = as_oop_opr(r9);
r10_oop_opr = as_oop_opr(r10);
r11_oop_opr = as_oop_opr(r11);
r12_oop_opr = as_oop_opr(r12);
r13_oop_opr = as_oop_opr(r13);
r14_oop_opr = as_oop_opr(r14);
r15_oop_opr = as_oop_opr(r15);
r16_oop_opr = as_oop_opr(r16);
r17_oop_opr = as_oop_opr(r17);
r18_oop_opr = as_oop_opr(r18);
r19_oop_opr = as_oop_opr(r19);
r20_oop_opr = as_oop_opr(r20);
r21_oop_opr = as_oop_opr(r21);
r22_oop_opr = as_oop_opr(r22);
r23_oop_opr = as_oop_opr(r23);
r24_oop_opr = as_oop_opr(r24);
r25_oop_opr = as_oop_opr(r25);
r26_oop_opr = as_oop_opr(r26);
r27_oop_opr = as_oop_opr(r27);
r28_oop_opr = as_oop_opr(r28);
r29_oop_opr = as_oop_opr(r29);
r30_oop_opr = as_oop_opr(r30);
r0_metadata_opr = as_metadata_opr(r0);
r1_metadata_opr = as_metadata_opr(r1);
r2_metadata_opr = as_metadata_opr(r2);
r3_metadata_opr = as_metadata_opr(r3);
r4_metadata_opr = as_metadata_opr(r4);
r5_metadata_opr = as_metadata_opr(r5);
sp_opr = as_pointer_opr(r31_sp);
rfp_opr = as_pointer_opr(rfp);
VMRegPair regs;
BasicType sig_bt = T_OBJECT;
SharedRuntime::java_calling_convention(&sig_bt, &regs, 1, true);
receiver_opr = as_oop_opr(regs.first()->as_Register());
for (int i = 0; i < nof_caller_save_fpu_regs; i++) {
_caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i);
}
}
Address FrameMap::make_new_address(ByteSize sp_offset) const {
// for rbp, based address use this:
// return Address(rbp, in_bytes(sp_offset) - (framesize() - 2) * 4);
return Address(sp, in_bytes(sp_offset));
}
// ----------------mapping-----------------------
// all mapping is based on rfp addressing, except for simple leaf methods where we access
// the locals sp based (and no frame is built)
// Frame for simple leaf methods (quick entries)
//
// +----------+
// | ret addr | <- TOS
// +----------+
// | args |
// | ...... |
// Frame for standard methods
//
// | .........| <- TOS
// | locals |
// +----------+
// | old fp, | <- RFP
// +----------+
// | ret addr |
// +----------+
// | args |
// | .........|
// For OopMaps, map a local variable or spill index to an VMRegImpl name.
// This is the offset from sp() in the frame of the slot for the index,
// skewed by VMRegImpl::stack0 to indicate a stack location (vs.a register.)
//
// framesize +
// stack0 stack0 0 <- VMReg
// | | <registers> |
// ...........|..............|.............|
// 0 1 2 3 x x 4 5 6 ... | <- local indices
// ^ ^ sp() ( x x indicate link
// | | and return addr)
// arguments non-argument locals
VMReg FrameMap::fpu_regname (int n) {
// Return the OptoReg name for the fpu stack slot "n"
// A spilled fpu stack slot comprises to two single-word OptoReg's.
return as_FloatRegister(n)->as_VMReg();
}
LIR_Opr FrameMap::stack_pointer() {
return FrameMap::sp_opr;
}
// JSR 292
LIR_Opr FrameMap::method_handle_invoke_SP_save_opr() {
// assert(rfp == rbp_mh_SP_save, "must be same register");
return rfp_opr;
}
bool FrameMap::validate_frame() {
return true;
}

View File

@ -0,0 +1,148 @@
/*
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_C1_FRAMEMAP_AARCH64_HPP
#define CPU_AARCH64_VM_C1_FRAMEMAP_AARCH64_HPP
// On AArch64 the frame looks as follows:
//
// +-----------------------------+---------+----------------------------------------+----------------+-----------
// | size_arguments-nof_reg_args | 2 words | size_locals-size_arguments+numreg_args | _size_monitors | spilling .
// +-----------------------------+---------+----------------------------------------+----------------+-----------
public:
static const int pd_c_runtime_reserved_arg_size;
enum {
first_available_sp_in_frame = 0,
frame_pad_in_bytes = 16,
nof_reg_args = 8
};
public:
static LIR_Opr receiver_opr;
static LIR_Opr r0_opr;
static LIR_Opr r1_opr;
static LIR_Opr r2_opr;
static LIR_Opr r3_opr;
static LIR_Opr r4_opr;
static LIR_Opr r5_opr;
static LIR_Opr r6_opr;
static LIR_Opr r7_opr;
static LIR_Opr r8_opr;
static LIR_Opr r9_opr;
static LIR_Opr r10_opr;
static LIR_Opr r11_opr;
static LIR_Opr r12_opr;
static LIR_Opr r13_opr;
static LIR_Opr r14_opr;
static LIR_Opr r15_opr;
static LIR_Opr r16_opr;
static LIR_Opr r17_opr;
static LIR_Opr r18_opr;
static LIR_Opr r19_opr;
static LIR_Opr r20_opr;
static LIR_Opr r21_opr;
static LIR_Opr r22_opr;
static LIR_Opr r23_opr;
static LIR_Opr r24_opr;
static LIR_Opr r25_opr;
static LIR_Opr r26_opr;
static LIR_Opr r27_opr;
static LIR_Opr r28_opr;
static LIR_Opr r29_opr;
static LIR_Opr r30_opr;
static LIR_Opr rfp_opr;
static LIR_Opr sp_opr;
static LIR_Opr r0_oop_opr;
static LIR_Opr r1_oop_opr;
static LIR_Opr r2_oop_opr;
static LIR_Opr r3_oop_opr;
static LIR_Opr r4_oop_opr;
static LIR_Opr r5_oop_opr;
static LIR_Opr r6_oop_opr;
static LIR_Opr r7_oop_opr;
static LIR_Opr r8_oop_opr;
static LIR_Opr r9_oop_opr;
static LIR_Opr r10_oop_opr;
static LIR_Opr r11_oop_opr;
static LIR_Opr r12_oop_opr;
static LIR_Opr r13_oop_opr;
static LIR_Opr r14_oop_opr;
static LIR_Opr r15_oop_opr;
static LIR_Opr r16_oop_opr;
static LIR_Opr r17_oop_opr;
static LIR_Opr r18_oop_opr;
static LIR_Opr r19_oop_opr;
static LIR_Opr r20_oop_opr;
static LIR_Opr r21_oop_opr;
static LIR_Opr r22_oop_opr;
static LIR_Opr r23_oop_opr;
static LIR_Opr r24_oop_opr;
static LIR_Opr r25_oop_opr;
static LIR_Opr r26_oop_opr;
static LIR_Opr r27_oop_opr;
static LIR_Opr r28_oop_opr;
static LIR_Opr r29_oop_opr;
static LIR_Opr r30_oop_opr;
static LIR_Opr rscratch1_opr;
static LIR_Opr rscratch2_opr;
static LIR_Opr rscratch1_long_opr;
static LIR_Opr rscratch2_long_opr;
static LIR_Opr r0_metadata_opr;
static LIR_Opr r1_metadata_opr;
static LIR_Opr r2_metadata_opr;
static LIR_Opr r3_metadata_opr;
static LIR_Opr r4_metadata_opr;
static LIR_Opr r5_metadata_opr;
static LIR_Opr long0_opr;
static LIR_Opr long1_opr;
static LIR_Opr fpu0_float_opr;
static LIR_Opr fpu0_double_opr;
static LIR_Opr as_long_opr(Register r) {
return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r));
}
static LIR_Opr as_pointer_opr(Register r) {
return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r));
}
// VMReg name for spilled physical FPU stack slot n
static VMReg fpu_regname (int n);
static bool is_caller_save_register (LIR_Opr opr) { return true; }
static bool is_caller_save_register (Register r) { return true; }
static int nof_caller_save_cpu_regs() { return pd_nof_caller_save_cpu_regs_frame_map; }
static int last_cpu_reg() { return pd_last_cpu_reg; }
static int last_byte_reg() { return pd_last_byte_reg; }
#endif // CPU_AARCH64_VM_C1_FRAMEMAP_AARCH64_HPP

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_X86_VM_C1_LIRASSEMBLER_X86_HPP
#define CPU_X86_VM_C1_LIRASSEMBLER_X86_HPP
private:
int array_element_size(BasicType type) const;
void arith_fpu_implementation(LIR_Code code, int left_index, int right_index, int dest_index, bool pop_fpu_stack);
// helper functions which checks for overflow and sets bailout if it
// occurs. Always returns a valid embeddable pointer but in the
// bailout case the pointer won't be to unique storage.
address float_constant(float f);
address double_constant(double d);
address int_constant(jlong n);
bool is_literal_address(LIR_Address* addr);
// When we need to use something other than rscratch1 use this
// method.
Address as_Address(LIR_Address* addr, Register tmp);
// Record the type of the receiver in ReceiverTypeData
void type_profile_helper(Register mdo,
ciMethodData *md, ciProfileData *data,
Register recv, Label* update_done);
void add_debug_info_for_branch(address adr, CodeEmitInfo* info);
void casw(Register addr, Register newval, Register cmpval);
void casl(Register addr, Register newval, Register cmpval);
void poll_for_safepoint(relocInfo::relocType rtype, CodeEmitInfo* info = NULL);
static const int max_tableswitches = 20;
struct tableswitch switches[max_tableswitches];
int tableswitch_count;
void init() { tableswitch_count = 0; }
void deoptimize_trap(CodeEmitInfo *info);
public:
void store_parameter(Register r, int offset_from_esp_in_words);
void store_parameter(jint c, int offset_from_esp_in_words);
void store_parameter(jobject c, int offset_from_esp_in_words);
enum { call_stub_size = 12 * NativeInstruction::instruction_size,
exception_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(175),
deopt_handler_size = 7 * NativeInstruction::instruction_size };
#endif // CPU_X86_VM_C1_LIRASSEMBLER_X86_HPP

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 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 "c1/c1_Instruction.hpp"
#include "c1/c1_LinearScan.hpp"
#include "utilities/bitMap.inline.hpp"
void LinearScan::allocate_fpu_stack() {
// No FPU stack on AArch64
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_C1_LINEARSCAN_HPP
#define CPU_AARCH64_VM_C1_LINEARSCAN_HPP
inline bool LinearScan::is_processed_reg_num(int reg_num) {
return reg_num <= FrameMap::last_cpu_reg() || reg_num >= pd_nof_cpu_regs_frame_map;
}
inline int LinearScan::num_physical_regs(BasicType type) {
return 1;
}
inline bool LinearScan::requires_adjacent_regs(BasicType type) {
return false;
}
inline bool LinearScan::is_caller_save(int assigned_reg) {
assert(assigned_reg >= 0 && assigned_reg < nof_regs, "should call this only for registers");
if (assigned_reg < pd_first_callee_saved_reg)
return true;
if (assigned_reg > pd_last_callee_saved_reg && assigned_reg < pd_first_callee_saved_fpu_reg)
return true;
if (assigned_reg > pd_last_callee_saved_fpu_reg && assigned_reg < pd_last_fpu_reg)
return true;
return false;
}
inline void LinearScan::pd_add_temps(LIR_Op* op) {
// FIXME ??
}
// Implementation of LinearScanWalker
inline bool LinearScanWalker::pd_init_regs_for_alloc(Interval* cur) {
if (allocator()->gen()->is_vreg_flag_set(cur->reg_num(), LIRGenerator::callee_saved)) {
assert(cur->type() != T_FLOAT && cur->type() != T_DOUBLE, "cpu regs only");
_first_reg = pd_first_callee_saved_reg;
_last_reg = pd_last_callee_saved_reg;
return true;
} else if (cur->type() == T_INT || cur->type() == T_LONG || cur->type() == T_OBJECT || cur->type() == T_ADDRESS || cur->type() == T_METADATA) {
_first_reg = pd_first_cpu_reg;
_last_reg = pd_last_allocatable_cpu_reg;
return true;
}
return false;
}
#endif // CPU_AARCH64_VM_C1_LINEARSCAN_HPP

View File

@ -0,0 +1,459 @@
/*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "c1/c1_Runtime1.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "interpreter/interpreter.hpp"
#include "oops/arrayOop.hpp"
#include "oops/markOop.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
void C1_MacroAssembler::float_cmp(bool is_float, int unordered_result,
FloatRegister f0, FloatRegister f1,
Register result)
{
Label done;
if (is_float) {
fcmps(f0, f1);
} else {
fcmpd(f0, f1);
}
if (unordered_result < 0) {
// we want -1 for unordered or less than, 0 for equal and 1 for
// greater than.
cset(result, NE); // Not equal or unordered
cneg(result, result, LT); // Less than or unordered
} else {
// we want -1 for less than, 0 for equal and 1 for unordered or
// greater than.
cset(result, NE); // Not equal or unordered
cneg(result, result, LO); // Less than
}
}
int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register scratch, Label& slow_case) {
const int aligned_mask = BytesPerWord -1;
const int hdr_offset = oopDesc::mark_offset_in_bytes();
assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
Label done, fail;
int null_check_offset = -1;
verify_oop(obj);
// save object being locked into the BasicObjectLock
str(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
if (UseBiasedLocking) {
assert(scratch != noreg, "should have scratch register at this point");
null_check_offset = biased_locking_enter(disp_hdr, obj, hdr, scratch, false, done, &slow_case);
} else {
null_check_offset = offset();
}
// Load object header
ldr(hdr, Address(obj, hdr_offset));
// and mark it as unlocked
orr(hdr, hdr, markOopDesc::unlocked_value);
// save unlocked object header into the displaced header location on the stack
str(hdr, Address(disp_hdr, 0));
// test if object header is still the same (i.e. unlocked), and if so, store the
// displaced header address in the object header - if it is not the same, get the
// object header instead
lea(rscratch2, Address(obj, hdr_offset));
cmpxchgptr(hdr, disp_hdr, rscratch2, rscratch1, done, /*fallthough*/NULL);
// if the object header was the same, we're done
// if the object header was not the same, it is now in the hdr register
// => test if it is a stack pointer into the same stack (recursive locking), i.e.:
//
// 1) (hdr & aligned_mask) == 0
// 2) sp <= hdr
// 3) hdr <= sp + page_size
//
// these 3 tests can be done by evaluating the following expression:
//
// (hdr - sp) & (aligned_mask - page_size)
//
// assuming both the stack pointer and page_size have their least
// significant 2 bits cleared and page_size is a power of 2
mov(rscratch1, sp);
sub(hdr, hdr, rscratch1);
ands(hdr, hdr, aligned_mask - os::vm_page_size());
// for recursive locking, the result is zero => save it in the displaced header
// location (NULL in the displaced hdr location indicates recursive locking)
str(hdr, Address(disp_hdr, 0));
// otherwise we don't care about the result and handle locking via runtime call
cbnz(hdr, slow_case);
// done
bind(done);
if (PrintBiasedLockingStatistics) {
lea(rscratch2, ExternalAddress((address)BiasedLocking::fast_path_entry_count_addr()));
addmw(Address(rscratch2, 0), 1, rscratch1);
}
return null_check_offset;
}
void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
const int aligned_mask = BytesPerWord -1;
const int hdr_offset = oopDesc::mark_offset_in_bytes();
assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
Label done;
if (UseBiasedLocking) {
// load object
ldr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
biased_locking_exit(obj, hdr, done);
}
// load displaced header
ldr(hdr, Address(disp_hdr, 0));
// if the loaded hdr is NULL we had recursive locking
// if we had recursive locking, we are done
cbz(hdr, done);
if (!UseBiasedLocking) {
// load object
ldr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
}
verify_oop(obj);
// test if object header is pointing to the displaced header, and if so, restore
// the displaced header in the object - if the object header is not pointing to
// the displaced header, get the object header instead
// if the object header was not pointing to the displaced header,
// we do unlocking via runtime call
if (hdr_offset) {
lea(rscratch1, Address(obj, hdr_offset));
cmpxchgptr(disp_hdr, hdr, rscratch1, rscratch2, done, &slow_case);
} else {
cmpxchgptr(disp_hdr, hdr, obj, rscratch2, done, &slow_case);
}
// done
bind(done);
}
// Defines obj, preserves var_size_in_bytes
void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) {
if (UseTLAB) {
tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
} else {
eden_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
incr_allocated_bytes(noreg, var_size_in_bytes, con_size_in_bytes, t1);
}
}
void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
assert_different_registers(obj, klass, len);
if (UseBiasedLocking && !len->is_valid()) {
assert_different_registers(obj, klass, len, t1, t2);
ldr(t1, Address(klass, Klass::prototype_header_offset()));
} else {
// This assumes that all prototype bits fit in an int32_t
mov(t1, (int32_t)(intptr_t)markOopDesc::prototype());
}
str(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
if (UseCompressedClassPointers) { // Take care not to kill klass
encode_klass_not_null(t1, klass);
strw(t1, Address(obj, oopDesc::klass_offset_in_bytes()));
} else {
str(klass, Address(obj, oopDesc::klass_offset_in_bytes()));
}
if (len->is_valid()) {
strw(len, Address(obj, arrayOopDesc::length_offset_in_bytes()));
} else if (UseCompressedClassPointers) {
store_klass_gap(obj, zr);
}
}
// Zero words; len is in bytes
// Destroys all registers except addr
// len must be a nonzero multiple of wordSize
void C1_MacroAssembler::zero_memory(Register addr, Register len, Register t1) {
assert_different_registers(addr, len, t1, rscratch1, rscratch2);
#ifdef ASSERT
{ Label L;
tst(len, BytesPerWord - 1);
br(Assembler::EQ, L);
stop("len is not a multiple of BytesPerWord");
bind(L);
}
#endif
#ifndef PRODUCT
block_comment("zero memory");
#endif
Label loop;
Label entry;
// Algorithm:
//
// scratch1 = cnt & 7;
// cnt -= scratch1;
// p += scratch1;
// switch (scratch1) {
// do {
// cnt -= 8;
// p[-8] = 0;
// case 7:
// p[-7] = 0;
// case 6:
// p[-6] = 0;
// // ...
// case 1:
// p[-1] = 0;
// case 0:
// p += 8;
// } while (cnt);
// }
const int unroll = 8; // Number of str(zr) instructions we'll unroll
lsr(len, len, LogBytesPerWord);
andr(rscratch1, len, unroll - 1); // tmp1 = cnt % unroll
sub(len, len, rscratch1); // cnt -= unroll
// t1 always points to the end of the region we're about to zero
add(t1, addr, rscratch1, Assembler::LSL, LogBytesPerWord);
adr(rscratch2, entry);
sub(rscratch2, rscratch2, rscratch1, Assembler::LSL, 2);
br(rscratch2);
bind(loop);
sub(len, len, unroll);
for (int i = -unroll; i < 0; i++)
str(zr, Address(t1, i * wordSize));
bind(entry);
add(t1, t1, unroll * wordSize);
cbnz(len, loop);
}
// preserves obj, destroys len_in_bytes
void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1) {
Label done;
assert(obj != len_in_bytes && obj != t1 && t1 != len_in_bytes, "registers must be different");
assert((hdr_size_in_bytes & (BytesPerWord - 1)) == 0, "header size is not a multiple of BytesPerWord");
Register index = len_in_bytes;
// index is positive and ptr sized
subs(index, index, hdr_size_in_bytes);
br(Assembler::EQ, done);
// note: for the remaining code to work, index must be a multiple of BytesPerWord
#ifdef ASSERT
{ Label L;
tst(index, BytesPerWord - 1);
br(Assembler::EQ, L);
stop("index is not a multiple of BytesPerWord");
bind(L);
}
#endif
// Preserve obj
if (hdr_size_in_bytes)
add(obj, obj, hdr_size_in_bytes);
zero_memory(obj, index, t1);
if (hdr_size_in_bytes)
sub(obj, obj, hdr_size_in_bytes);
// done
bind(done);
}
void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) {
assert_different_registers(obj, t1, t2); // XXX really?
assert(header_size >= 0 && object_size >= header_size, "illegal sizes");
try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case);
initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2);
}
void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2) {
assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0,
"con_size_in_bytes is not multiple of alignment");
const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize;
initialize_header(obj, klass, noreg, t1, t2);
// clear rest of allocated space
const Register index = t2;
const int threshold = 16 * BytesPerWord; // approximate break even point for code size (see comments below)
if (var_size_in_bytes != noreg) {
mov(index, var_size_in_bytes);
initialize_body(obj, index, hdr_size_in_bytes, t1);
} else if (con_size_in_bytes <= threshold) {
// use explicit null stores
int i = hdr_size_in_bytes;
if (i < con_size_in_bytes && (con_size_in_bytes % (2 * BytesPerWord))) {
str(zr, Address(obj, i));
i += BytesPerWord;
}
for (; i < con_size_in_bytes; i += 2 * BytesPerWord)
stp(zr, zr, Address(obj, i));
} else if (con_size_in_bytes > hdr_size_in_bytes) {
block_comment("zero memory");
// use loop to null out the fields
int words = (con_size_in_bytes - hdr_size_in_bytes) / BytesPerWord;
mov(index, words / 8);
const int unroll = 8; // Number of str(zr) instructions we'll unroll
int remainder = words % unroll;
lea(rscratch1, Address(obj, hdr_size_in_bytes + remainder * BytesPerWord));
Label entry_point, loop;
b(entry_point);
bind(loop);
sub(index, index, 1);
for (int i = -unroll; i < 0; i++) {
if (-i == remainder)
bind(entry_point);
str(zr, Address(rscratch1, i * wordSize));
}
if (remainder == 0)
bind(entry_point);
add(rscratch1, rscratch1, unroll * wordSize);
cbnz(index, loop);
}
membar(StoreStore);
if (CURRENT_ENV->dtrace_alloc_probes()) {
assert(obj == r0, "must be");
far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
}
verify_oop(obj);
}
void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1, Register t2, int header_size, int f, Register klass, Label& slow_case) {
assert_different_registers(obj, len, t1, t2, klass);
// determine alignment mask
assert(!(BytesPerWord & 1), "must be a multiple of 2 for masking code to work");
// check for negative or excessive length
mov(rscratch1, (int32_t)max_array_allocation_length);
cmp(len, rscratch1);
br(Assembler::HS, slow_case);
const Register arr_size = t2; // okay to be the same
// align object end
mov(arr_size, (int32_t)header_size * BytesPerWord + MinObjAlignmentInBytesMask);
add(arr_size, arr_size, len, ext::uxtw, f);
andr(arr_size, arr_size, ~MinObjAlignmentInBytesMask);
try_allocate(obj, arr_size, 0, t1, t2, slow_case);
initialize_header(obj, klass, len, t1, t2);
// clear rest of allocated space
const Register len_zero = len;
initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero);
membar(StoreStore);
if (CURRENT_ENV->dtrace_alloc_probes()) {
assert(obj == r0, "must be");
far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
}
verify_oop(obj);
}
void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
verify_oop(receiver);
// explicit NULL check not needed since load from [klass_offset] causes a trap
// check against inline cache
assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
cmp_klass(receiver, iCache, rscratch1);
}
void C1_MacroAssembler::build_frame(int framesize, int bang_size_in_bytes) {
// If we have to make this method not-entrant we'll overwrite its
// first instruction with a jump. For this action to be legal we
// must ensure that this first instruction is a B, BL, NOP, BKPT,
// SVC, HVC, or SMC. Make it a NOP.
nop();
assert(bang_size_in_bytes >= framesize, "stack bang size incorrect");
// Make sure there is enough stack space for this method's activation.
// Note that we do this before doing an enter().
generate_stack_overflow_check(bang_size_in_bytes);
MacroAssembler::build_frame(framesize + 2 * wordSize);
if (NotifySimulator) {
notify(Assembler::method_entry);
}
}
void C1_MacroAssembler::remove_frame(int framesize) {
MacroAssembler::remove_frame(framesize + 2 * wordSize);
if (NotifySimulator) {
notify(Assembler::method_reentry);
}
}
void C1_MacroAssembler::verified_entry() {
}
#ifndef PRODUCT
void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
if (!VerifyOops) return;
verify_oop_addr(Address(sp, stack_offset), "oop");
}
void C1_MacroAssembler::verify_not_null_oop(Register r) {
if (!VerifyOops) return;
Label not_null;
cbnz(r, not_null);
stop("non-null oop required");
bind(not_null);
verify_oop(r);
}
void C1_MacroAssembler::invalidate_registers(bool inv_r0, bool inv_r19, bool inv_r2, bool inv_r3, bool inv_r4, bool inv_r5) {
#ifdef ASSERT
static int nn;
if (inv_r0) mov(r0, 0xDEAD);
if (inv_r19) mov(r19, 0xDEAD);
if (inv_r2) mov(r2, nn++);
if (inv_r3) mov(r3, 0xDEAD);
if (inv_r4) mov(r4, 0xDEAD);
if (inv_r5) mov(r5, 0xDEAD);
#endif
}
#endif // ifndef PRODUCT

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_C1_MACROASSEMBLER_AARCH64_HPP
#define CPU_AARCH64_VM_C1_MACROASSEMBLER_AARCH64_HPP
using MacroAssembler::build_frame;
// C1_MacroAssembler contains high-level macros for C1
private:
int _rsp_offset; // track rsp changes
// initialization
void pd_init() { _rsp_offset = 0; }
void zero_memory(Register addr, Register len, Register t1);
public:
void try_allocate(
Register obj, // result: pointer to object after successful allocation
Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
int con_size_in_bytes, // object size in bytes if known at compile time
Register t1, // temp register
Register t2, // temp register
Label& slow_case // continuation point if fast allocation fails
);
void initialize_header(Register obj, Register klass, Register len, Register t1, Register t2);
void initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1);
void float_cmp(bool is_float, int unordered_result,
FloatRegister f0, FloatRegister f1,
Register result);
// locking
// hdr : must be r0, contents destroyed
// obj : must point to the object to lock, contents preserved
// disp_hdr: must point to the displaced header location, contents preserved
// scratch : scratch register, contents destroyed
// returns code offset at which to add null check debug information
int lock_object (Register swap, Register obj, Register disp_hdr, Register scratch, Label& slow_case);
// unlocking
// hdr : contents destroyed
// obj : must point to the object to lock, contents preserved
// disp_hdr: must be r0 & must point to the displaced header location, contents destroyed
void unlock_object(Register swap, Register obj, Register lock, Label& slow_case);
void initialize_object(
Register obj, // result: pointer to object after successful allocation
Register klass, // object klass
Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
int con_size_in_bytes, // object size in bytes if known at compile time
Register t1, // temp register
Register t2 // temp register
);
// allocation of fixed-size objects
// (can also be used to allocate fixed-size arrays, by setting
// hdr_size correctly and storing the array length afterwards)
// obj : will contain pointer to allocated object
// t1, t2 : scratch registers - contents destroyed
// header_size: size of object header in words
// object_size: total size of object in words
// slow_case : exit to slow case implementation if fast allocation fails
void allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case);
enum {
max_array_allocation_length = 0x00FFFFFF
};
// allocation of arrays
// obj : will contain pointer to allocated object
// len : array length in number of elements
// t : scratch register - contents destroyed
// header_size: size of object header in words
// f : element scale factor
// slow_case : exit to slow case implementation if fast allocation fails
void allocate_array(Register obj, Register len, Register t, Register t2, int header_size, int f, Register klass, Label& slow_case);
int rsp_offset() const { return _rsp_offset; }
void set_rsp_offset(int n) { _rsp_offset = n; }
void invalidate_registers(bool inv_r0, bool inv_r19, bool inv_r2, bool inv_r3, bool inv_r4, bool inv_r5) PRODUCT_RETURN;
#endif // CPU_AARCH64_VM_C1_MACROASSEMBLER_AARCH64_HPP

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_C1_GLOBALS_AARCH64_HPP
#define CPU_AARCH64_VM_C1_GLOBALS_AARCH64_HPP
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
// Sets the default values for platform dependent flags used by the client compiler.
// (see c1_globals.hpp)
#ifndef TIERED
define_pd_global(bool, BackgroundCompilation, true );
define_pd_global(bool, UseTLAB, true );
define_pd_global(bool, ResizeTLAB, true );
define_pd_global(bool, InlineIntrinsics, true );
define_pd_global(bool, PreferInterpreterNativeStubs, false);
define_pd_global(bool, ProfileTraps, false);
define_pd_global(bool, UseOnStackReplacement, true );
define_pd_global(bool, TieredCompilation, false);
#ifdef BUILTIN_SIM
// We compile very aggressively with the builtin simulator because
// doing so greatly reduces run times and tests more code.
define_pd_global(intx, CompileThreshold, 150 );
define_pd_global(intx, BackEdgeThreshold, 500);
#else
define_pd_global(intx, CompileThreshold, 1500 );
define_pd_global(intx, BackEdgeThreshold, 100000);
#endif
define_pd_global(intx, OnStackReplacePercentage, 933 );
define_pd_global(intx, FreqInlineSize, 325 );
define_pd_global(intx, NewSizeThreadIncrease, 4*K );
define_pd_global(intx, InitialCodeCacheSize, 160*K);
define_pd_global(intx, ReservedCodeCacheSize, 32*M );
define_pd_global(intx, NonProfiledCodeHeapSize, 13*M );
define_pd_global(intx, ProfiledCodeHeapSize, 14*M );
define_pd_global(intx, NonNMethodCodeHeapSize, 5*M );
define_pd_global(bool, ProfileInterpreter, false);
define_pd_global(intx, CodeCacheExpansionSize, 32*K );
define_pd_global(uintx, CodeCacheMinBlockLength, 1);
define_pd_global(uintx, CodeCacheMinimumUseSpace, 400*K);
define_pd_global(uintx, MetaspaceSize, 12*M );
define_pd_global(bool, NeverActAsServerClassMachine, true );
define_pd_global(uint64_t,MaxRAM, 1ULL*G);
define_pd_global(bool, CICompileOSR, true );
#endif // !TIERED
define_pd_global(bool, UseTypeProfile, false);
define_pd_global(bool, RoundFPResults, true );
define_pd_global(bool, LIRFillDelaySlots, false);
define_pd_global(bool, OptimizeSinglePrecision, true );
define_pd_global(bool, CSEArrayLength, false);
define_pd_global(bool, TwoOperandLIRForm, false );
define_pd_global(intx, SafepointPollOffset, 0 );
#endif // CPU_AARCH64_VM_C1_GLOBALS_AARCH64_HPP

View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_C2_GLOBALS_AARCH64_HPP
#define CPU_AARCH64_VM_C2_GLOBALS_AARCH64_HPP
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
// Sets the default values for platform dependent flags used by the server compiler.
// (see c2_globals.hpp). Alpha-sorted.
define_pd_global(bool, BackgroundCompilation, true);
define_pd_global(bool, UseTLAB, true);
define_pd_global(bool, ResizeTLAB, true);
define_pd_global(bool, CICompileOSR, true);
define_pd_global(bool, InlineIntrinsics, true);
define_pd_global(bool, PreferInterpreterNativeStubs, false);
define_pd_global(bool, ProfileTraps, true);
define_pd_global(bool, UseOnStackReplacement, true);
#ifdef CC_INTERP
define_pd_global(bool, ProfileInterpreter, false);
#else
define_pd_global(bool, ProfileInterpreter, true);
#endif // CC_INTERP
define_pd_global(bool, TieredCompilation, trueInTiered);
define_pd_global(intx, CompileThreshold, 10000);
define_pd_global(intx, BackEdgeThreshold, 100000);
define_pd_global(intx, OnStackReplacePercentage, 140);
define_pd_global(intx, ConditionalMoveLimit, 3);
define_pd_global(intx, FLOATPRESSURE, 64);
define_pd_global(intx, FreqInlineSize, 325);
define_pd_global(intx, MinJumpTableSize, 10);
define_pd_global(intx, INTPRESSURE, 25);
define_pd_global(intx, InteriorEntryAlignment, 16);
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
define_pd_global(intx, LoopUnrollLimit, 60);
// InitialCodeCacheSize derived from specjbb2000 run.
define_pd_global(intx, InitialCodeCacheSize, 2496*K); // Integral multiple of CodeCacheExpansionSize
define_pd_global(intx, CodeCacheExpansionSize, 64*K);
// Ergonomics related flags
define_pd_global(uint64_t,MaxRAM, 128ULL*G);
define_pd_global(intx, RegisterCostAreaRatio, 16000);
// Peephole and CISC spilling both break the graph, and so makes the
// scheduler sick.
define_pd_global(bool, OptoPeephole, true);
define_pd_global(bool, UseCISCSpill, true);
define_pd_global(bool, OptoScheduling, false);
define_pd_global(bool, OptoBundling, false);
define_pd_global(intx, ReservedCodeCacheSize, 48*M);
define_pd_global(intx, NonProfiledCodeHeapSize, 21*M);
define_pd_global(intx, ProfiledCodeHeapSize, 22*M);
define_pd_global(intx, NonNMethodCodeHeapSize, 5*M );
define_pd_global(uintx, CodeCacheMinBlockLength, 4);
define_pd_global(uintx, CodeCacheMinimumUseSpace, 400*K);
// Heap related flags
define_pd_global(uintx,MetaspaceSize, ScaleForWordSize(16*M));
// Ergonomics related flags
define_pd_global(bool, NeverActAsServerClassMachine, false);
define_pd_global(bool, TrapBasedRangeChecks, false); // Not needed.
#endif // CPU_AARCH64_VM_C2_GLOBALS_AARCH64_HPP

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "opto/compile.hpp"
#include "opto/node.hpp"
// processor dependent initialization for i486
void Compile::pd_compiler2_init() {
guarantee(CodeEntryAlignment >= InteriorEntryAlignment, "" );
// QQQ presumably all 64bit cpu's support this. Seems like the ifdef could
// simply be left out.
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_CODEBUFFER_AARCH64_HPP
#define CPU_AARCH64_VM_CODEBUFFER_AARCH64_HPP
private:
void pd_initialize() {}
public:
void flush_bundle(bool start_new_bundle) {}
#endif // CPU_AARCH64_VM_CODEBUFFER_AARCH64_HPP

View File

@ -0,0 +1,152 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "code/compiledIC.hpp"
#include "code/icBuffer.hpp"
#include "code/nmethod.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
// Release the CompiledICHolder* associated with this call site is there is one.
void CompiledIC::cleanup_call_site(virtual_call_Relocation* call_site) {
// This call site might have become stale so inspect it carefully.
NativeCall* call = nativeCall_at(call_site->addr());
if (is_icholder_entry(call->destination())) {
NativeMovConstReg* value = nativeMovConstReg_at(call_site->cached_value());
InlineCacheBuffer::queue_for_release((CompiledICHolder*)value->data());
}
}
bool CompiledIC::is_icholder_call_site(virtual_call_Relocation* call_site) {
// This call site might have become stale so inspect it carefully.
NativeCall* call = nativeCall_at(call_site->addr());
return is_icholder_entry(call->destination());
}
// ----------------------------------------------------------------------------
#define __ _masm.
void CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf) {
// Stub is fixed up when the corresponding call is converted from
// calling compiled code to calling interpreted code.
// mov rmethod, 0
// jmp -4 # to self
address mark = cbuf.insts_mark(); // Get mark within main instrs section.
// Note that the code buffer's insts_mark is always relative to insts.
// That's why we must use the macroassembler to generate a stub.
MacroAssembler _masm(&cbuf);
address base = __ start_a_stub(to_interp_stub_size()*2);
int offset = __ offset();
if (base == NULL) return; // CodeBuffer::expand failed
// static stub relocation stores the instruction address of the call
__ relocate(static_stub_Relocation::spec(mark));
// static stub relocation also tags the Method* in the code-stream.
__ mov_metadata(rmethod, (Metadata*)NULL);
__ movptr(rscratch1, 0);
__ br(rscratch1);
assert((__ offset() - offset) <= (int)to_interp_stub_size(), "stub too big");
__ end_a_stub();
}
#undef __
int CompiledStaticCall::to_interp_stub_size() {
return 7 * NativeInstruction::instruction_size;
}
// Relocation entries for call stub, compiled java to interpreter.
int CompiledStaticCall::reloc_to_interp_stub() {
return 4; // 3 in emit_to_interp_stub + 1 in emit_call
}
void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry) {
address stub = find_stub();
guarantee(stub != NULL, "stub not found");
if (TraceICs) {
ResourceMark rm;
tty->print_cr("CompiledStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
p2i(instruction_address()),
callee->name_and_sig_as_C_string());
}
// Creation also verifies the object.
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
#ifndef PRODUCT
NativeGeneralJump* jump = nativeGeneralJump_at(method_holder->next_instruction_address());
assert(method_holder->data() == 0 || method_holder->data() == (intptr_t)callee(),
"a) MT-unsafe modification of inline cache");
assert(method_holder->data() == 0 || jump->jump_destination() == entry,
"b) MT-unsafe modification of inline cache");
#endif
// Update stub.
method_holder->set_data((intptr_t)callee());
NativeGeneralJump::insert_unconditional(method_holder->next_instruction_address(), entry);
ICache::invalidate_range(stub, to_interp_stub_size());
// Update jump to call.
set_destination_mt_safe(stub);
}
void CompiledStaticCall::set_stub_to_clean(static_stub_Relocation* static_stub) {
assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "mt unsafe call");
// Reset stub.
address stub = static_stub->addr();
assert(stub != NULL, "stub not found");
// Creation also verifies the object.
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
method_holder->set_data(0);
}
//-----------------------------------------------------------------------------
// Non-product mode code
#ifndef PRODUCT
void CompiledStaticCall::verify() {
// Verify call.
NativeCall::verify();
if (os::is_MP()) {
verify_alignment();
}
// Verify stub.
address stub = find_stub();
assert(stub != NULL, "no stub found for static call");
// Creation also verifies the object.
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
// Verify state.
assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted(), "sanity check");
}
#endif // !PRODUCT

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_COPY_AARCH64_HPP
#define CPU_AARCH64_VM_COPY_AARCH64_HPP
// Inline functions for memory copy and fill.
// Contains inline asm implementations
#ifdef TARGET_OS_ARCH_linux_aarch64
# include "copy_linux_aarch64.inline.hpp"
#endif
static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) {
julong* to = (julong*) tohw;
julong v = ((julong) value << 32) | value;
while (count-- > 0) {
*to++ = v;
}
}
static void pd_fill_to_aligned_words(HeapWord* tohw, size_t count, juint value) {
pd_fill_to_words(tohw, count, value);
}
static void pd_fill_to_bytes(void* to, size_t count, jubyte value) {
(void)memset(to, value, count);
}
static void pd_zero_to_words(HeapWord* tohw, size_t count) {
pd_fill_to_words(tohw, count, 0);
}
static void pd_zero_to_bytes(void* to, size_t count) {
(void)memset(to, 0, count);
}
#endif // CPU_AARCH64_VM_COPY_AARCH64_HPP

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_CPPINTERPRETERGENERATOR_AARCH64_HPP
#define CPU_AARCH64_VM_CPPINTERPRETERGENERATOR_AARCH64_HPP
protected:
void generate_more_monitors();
void generate_deopt_handling();
#endif // CPU_AARCH64_VM_CPPINTERPRETERGENERATOR_AARCH64_HPP

View File

@ -0,0 +1,595 @@
/*
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef _CPU_STATE_H
#define _CPU_STATE_H
#include <sys/types.h>
/*
* symbolic names used to identify general registers which also match
* the registers indices in machine code
*
* We have 32 general registers which can be read/written as 32 bit or
* 64 bit sources/sinks and are appropriately referred to as Wn or Xn
* in the assembly code. Some instructions mix these access modes
* (e.g. ADD X0, X1, W2) so the implementation of the instruction
* needs to *know* which type of read or write access is required.
*/
enum GReg {
R0,
R1,
R2,
R3,
R4,
R5,
R6,
R7,
R8,
R9,
R10,
R11,
R12,
R13,
R14,
R15,
R16,
R17,
R18,
R19,
R20,
R21,
R22,
R23,
R24,
R25,
R26,
R27,
R28,
R29,
R30,
R31,
// and now the aliases
RSCRATCH1=R8,
RSCRATCH2=R9,
RMETHOD=R12,
RESP=R20,
RDISPATCH=R21,
RBCP=R22,
RLOCALS=R24,
RMONITORS=R25,
RCPOOL=R26,
RHEAPBASE=R27,
RTHREAD=R28,
FP = R29,
LR = R30,
SP = R31,
ZR = R31
};
/*
* symbolic names used to refer to floating point registers which also
* match the registers indices in machine code
*
* We have 32 FP registers which can be read/written as 8, 16, 32, 64
* and 128 bit sources/sinks and are appropriately referred to as Bn,
* Hn, Sn, Dn and Qn in the assembly code. Some instructions mix these
* access modes (e.g. FCVT S0, D0) so the implementation of the
* instruction needs to *know* which type of read or write access is
* required.
*/
enum VReg {
V0,
V1,
V2,
V3,
V4,
V5,
V6,
V7,
V8,
V9,
V10,
V11,
V12,
V13,
V14,
V15,
V16,
V17,
V18,
V19,
V20,
V21,
V22,
V23,
V24,
V25,
V26,
V27,
V28,
V29,
V30,
V31,
};
/**
* all the different integer bit patterns for the components of a
* general register are overlaid here using a union so as to allow all
* reading and writing of the desired bits.
*
* n.b. the ARM spec says that when you write a 32 bit register you
* are supposed to write the low 32 bits and zero the high 32
* bits. But we don't actually have to care about this because Java
* will only ever consume the 32 bits value as a 64 bit quantity after
* an explicit extend.
*/
union GRegisterValue
{
int8_t s8;
int16_t s16;
int32_t s32;
int64_t s64;
u_int8_t u8;
u_int16_t u16;
u_int32_t u32;
u_int64_t u64;
};
class GRegister
{
public:
GRegisterValue value;
};
/*
* float registers provide for storage of a single, double or quad
* word format float in the same register. single floats are not
* paired within each double register as per 32 bit arm. instead each
* 128 bit register Vn embeds the bits for Sn, and Dn in the lower
* quarter and half, respectively, of the bits for Qn.
*
* The upper bits can also be accessed as single or double floats by
* the float vector operations using indexing e.g. V1.D[1], V1.S[3]
* etc and, for SIMD operations using a horrible index range notation.
*
* The spec also talks about accessing float registers as half words
* and bytes with Hn and Bn providing access to the low 16 and 8 bits
* of Vn but it is not really clear what these bits represent. We can
* probably ignore this for Java anyway. However, we do need to access
* the raw bits at 32 and 64 bit resolution to load to/from integer
* registers.
*/
union FRegisterValue
{
float s;
double d;
long double q;
// eventually we will need to be able to access the data as a vector
// the integral array elements allow us to access the bits in s, d,
// q, vs and vd at an appropriate level of granularity
u_int8_t vb[16];
u_int16_t vh[8];
u_int32_t vw[4];
u_int64_t vx[2];
float vs[4];
double vd[2];
};
class FRegister
{
public:
FRegisterValue value;
};
/*
* CPSR register -- this does not exist as a directly accessible
* register but we need to store the flags so we can implement
* flag-seting and flag testing operations
*
* we can possibly use injected x86 asm to report the outcome of flag
* setting operations. if so we will need to grab the flags
* immediately after the operation in order to ensure we don't lose
* them because of the actions of the simulator. so we still need
* somewhere to store the condition codes.
*/
class CPSRRegister
{
public:
u_int32_t value;
/*
* condition register bit select values
*
* the order of bits here is important because some of
* the flag setting conditional instructions employ a
* bit field to populate the flags when a false condition
* bypasses execution of the operation and we want to
* be able to assign the flags register using the
* supplied value.
*/
enum CPSRIdx {
V_IDX,
C_IDX,
Z_IDX,
N_IDX
};
enum CPSRMask {
V = 1 << V_IDX,
C = 1 << C_IDX,
Z = 1 << Z_IDX,
N = 1 << N_IDX
};
static const int CPSR_ALL_FLAGS = (V | C | Z | N);
};
// auxiliary function to assemble the relevant bits from
// the x86 EFLAGS register into an ARM CPSR value
#define X86_V_IDX 11
#define X86_C_IDX 0
#define X86_Z_IDX 6
#define X86_N_IDX 7
#define X86_V (1 << X86_V_IDX)
#define X86_C (1 << X86_C_IDX)
#define X86_Z (1 << X86_Z_IDX)
#define X86_N (1 << X86_N_IDX)
inline u_int32_t convertX86Flags(u_int32_t x86flags)
{
u_int32_t flags;
// set N flag
flags = ((x86flags & X86_N) >> X86_N_IDX);
// shift then or in Z flag
flags <<= 1;
flags |= ((x86flags & X86_Z) >> X86_Z_IDX);
// shift then or in C flag
flags <<= 1;
flags |= ((x86flags & X86_C) >> X86_C_IDX);
// shift then or in V flag
flags <<= 1;
flags |= ((x86flags & X86_V) >> X86_V_IDX);
return flags;
}
inline u_int32_t convertX86FlagsFP(u_int32_t x86flags)
{
// x86 flags set by fcomi(x,y) are ZF:PF:CF
// (yes, that's PF for parity, WTF?)
// where
// 0) 0:0:0 means x > y
// 1) 0:0:1 means x < y
// 2) 1:0:0 means x = y
// 3) 1:1:1 means x and y are unordered
// note that we don't have to check PF so
// we really have a simple 2-bit case switch
// the corresponding ARM64 flags settings
// in hi->lo bit order are
// 0) --C-
// 1) N---
// 2) -ZC-
// 3) --CV
static u_int32_t armFlags[] = {
0b0010,
0b1000,
0b0110,
0b0011
};
// pick out the ZF and CF bits
u_int32_t zc = ((x86flags & X86_Z) >> X86_Z_IDX);
zc <<= 1;
zc |= ((x86flags & X86_C) >> X86_C_IDX);
return armFlags[zc];
}
/*
* FPSR register -- floating point status register
* this register includes IDC, IXC, UFC, OFC, DZC, IOC and QC bits,
* and the floating point N, Z, C, V bits but the latter are unused in
* aarch64 mode. the sim ignores QC for now.
*
* bit positions are as per the ARMv7 FPSCR register
*
* IDC : 7 ==> Input Denormal (cumulative exception bit)
* IXC : 4 ==> Inexact
* UFC : 3 ==> Underflow
* OFC : 2 ==> Overflow
* DZC : 1 ==> Division by Zero
* IOC : 0 ==> Invalid Operation
*/
class FPSRRegister
{
public:
u_int32_t value;
// indices for bits in the FPSR register value
enum FPSRIdx {
IO_IDX = 0,
DZ_IDX = 1,
OF_IDX = 2,
UF_IDX = 3,
IX_IDX = 4,
ID_IDX = 7
};
// corresponding bits as numeric values
enum FPSRMask {
IO = (1 << IO_IDX),
DZ = (1 << DZ_IDX),
OF = (1 << OF_IDX),
UF = (1 << UF_IDX),
IX = (1 << IX_IDX),
ID = (1 << ID_IDX)
};
static const int FPSR_ALL_FPSRS = (IO | DZ | OF | UF | IX | ID);
};
// debugger support
enum PrintFormat
{
FMT_DECIMAL,
FMT_HEX,
FMT_SINGLE,
FMT_DOUBLE,
FMT_QUAD,
FMT_MULTI
};
/*
* model of the registers and other state associated with the cpu
*/
class CPUState
{
friend class AArch64Simulator;
private:
// this is the PC of the instruction being executed
u_int64_t pc;
// this is the PC of the instruction to be executed next
// it is defaulted to pc + 4 at instruction decode but
// execute may reset it
u_int64_t nextpc;
GRegister gr[33]; // extra register at index 32 is used
// to hold zero value
FRegister fr[32];
CPSRRegister cpsr;
FPSRRegister fpsr;
public:
CPUState() {
gr[20].value.u64 = 0; // establish initial condition for
// checkAssertions()
trace_counter = 0;
}
// General Register access macros
// only xreg or xregs can be used as an lvalue in order to update a
// register. this ensures that the top part of a register is always
// assigned when it is written by the sim.
inline u_int64_t &xreg(GReg reg, int r31_is_sp) {
if (reg == R31 && !r31_is_sp) {
return gr[32].value.u64;
} else {
return gr[reg].value.u64;
}
}
inline int64_t &xregs(GReg reg, int r31_is_sp) {
if (reg == R31 && !r31_is_sp) {
return gr[32].value.s64;
} else {
return gr[reg].value.s64;
}
}
inline u_int32_t wreg(GReg reg, int r31_is_sp) {
if (reg == R31 && !r31_is_sp) {
return gr[32].value.u32;
} else {
return gr[reg].value.u32;
}
}
inline int32_t wregs(GReg reg, int r31_is_sp) {
if (reg == R31 && !r31_is_sp) {
return gr[32].value.s32;
} else {
return gr[reg].value.s32;
}
}
inline u_int32_t hreg(GReg reg, int r31_is_sp) {
if (reg == R31 && !r31_is_sp) {
return gr[32].value.u16;
} else {
return gr[reg].value.u16;
}
}
inline int32_t hregs(GReg reg, int r31_is_sp) {
if (reg == R31 && !r31_is_sp) {
return gr[32].value.s16;
} else {
return gr[reg].value.s16;
}
}
inline u_int32_t breg(GReg reg, int r31_is_sp) {
if (reg == R31 && !r31_is_sp) {
return gr[32].value.u8;
} else {
return gr[reg].value.u8;
}
}
inline int32_t bregs(GReg reg, int r31_is_sp) {
if (reg == R31 && !r31_is_sp) {
return gr[32].value.s8;
} else {
return gr[reg].value.s8;
}
}
// FP Register access macros
// all non-vector accessors return a reference so we can both read
// and assign
inline float &sreg(VReg reg) {
return fr[reg].value.s;
}
inline double &dreg(VReg reg) {
return fr[reg].value.d;
}
inline long double &qreg(VReg reg) {
return fr[reg].value.q;
}
// all vector register accessors return a pointer
inline float *vsreg(VReg reg) {
return &fr[reg].value.vs[0];
}
inline double *vdreg(VReg reg) {
return &fr[reg].value.vd[0];
}
inline u_int8_t *vbreg(VReg reg) {
return &fr[reg].value.vb[0];
}
inline u_int16_t *vhreg(VReg reg) {
return &fr[reg].value.vh[0];
}
inline u_int32_t *vwreg(VReg reg) {
return &fr[reg].value.vw[0];
}
inline u_int64_t *vxreg(VReg reg) {
return &fr[reg].value.vx[0];
}
union GRegisterValue prev_sp, prev_fp;
static const int trace_size = 256;
u_int64_t trace_buffer[trace_size];
int trace_counter;
bool checkAssertions()
{
// Make sure that SP is 16-aligned
// Also make sure that ESP is above SP.
// We don't care about checking ESP if it is null, i.e. it hasn't
// been used yet.
if (gr[31].value.u64 & 0x0f) {
asm volatile("nop");
return false;
}
return true;
}
// pc register accessors
// this instruction can be used to fetch the current PC
u_int64_t getPC();
// instead of setting the current PC directly you can
// first set the next PC (either absolute or PC-relative)
// and later copy the next PC into the current PC
// this supports a default increment by 4 at instruction
// fetch with an optional reset by control instructions
u_int64_t getNextPC();
void setNextPC(u_int64_t next);
void offsetNextPC(int64_t offset);
// install nextpc as current pc
void updatePC();
// this instruction can be used to save the next PC to LR
// just before installing a branch PC
inline void saveLR() { gr[LR].value.u64 = nextpc; }
// cpsr register accessors
u_int32_t getCPSRRegister();
void setCPSRRegister(u_int32_t flags);
// read a specific subset of the flags as a bit pattern
// mask should be composed using elements of enum FlagMask
u_int32_t getCPSRBits(u_int32_t mask);
// assign a specific subset of the flags as a bit pattern
// mask and value should be composed using elements of enum FlagMask
void setCPSRBits(u_int32_t mask, u_int32_t value);
// test the value of a single flag returned as 1 or 0
u_int32_t testCPSR(CPSRRegister::CPSRIdx idx);
// set a single flag
void setCPSR(CPSRRegister::CPSRIdx idx);
// clear a single flag
void clearCPSR(CPSRRegister::CPSRIdx idx);
// utility method to set ARM CSPR flags from an x86 bit mask generated by integer arithmetic
void setCPSRRegisterFromX86(u_int64_t x86Flags);
// utility method to set ARM CSPR flags from an x86 bit mask generated by floating compare
void setCPSRRegisterFromX86FP(u_int64_t x86Flags);
// fpsr register accessors
u_int32_t getFPSRRegister();
void setFPSRRegister(u_int32_t flags);
// read a specific subset of the fprs bits as a bit pattern
// mask should be composed using elements of enum FPSRRegister::FlagMask
u_int32_t getFPSRBits(u_int32_t mask);
// assign a specific subset of the flags as a bit pattern
// mask and value should be composed using elements of enum FPSRRegister::FlagMask
void setFPSRBits(u_int32_t mask, u_int32_t value);
// test the value of a single flag returned as 1 or 0
u_int32_t testFPSR(FPSRRegister::FPSRIdx idx);
// set a single flag
void setFPSR(FPSRRegister::FPSRIdx idx);
// clear a single flag
void clearFPSR(FPSRRegister::FPSRIdx idx);
// debugger support
void printPC(int pending, const char *trailing = "\n");
void printInstr(u_int32_t instr, void (*dasm)(u_int64_t), const char *trailing = "\n");
void printGReg(GReg reg, PrintFormat format = FMT_HEX, const char *trailing = "\n");
void printVReg(VReg reg, PrintFormat format = FMT_HEX, const char *trailing = "\n");
void printCPSR(const char *trailing = "\n");
void printFPSR(const char *trailing = "\n");
void dumpState();
};
#endif // ifndef _CPU_STATE_H

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "code/codeCache.hpp"
#include "code/nmethod.hpp"
#include "runtime/frame.hpp"
#include "runtime/init.hpp"
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
#include "utilities/top.hpp"
void pd_ps(frame f) {}

View File

@ -0,0 +1,412 @@
/*
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef _DECODE_H
#define _DECODE_H
#include <sys/types.h>
#include "cpustate_aarch64.hpp"
// bitfield immediate expansion helper
extern int expandLogicalImmediate(u_int32_t immN, u_int32_t immr,
u_int32_t imms, u_int64_t &bimm);
/*
* codes used in conditional instructions
*
* these are passed to conditional operations to identify which
* condition to test for
*/
enum CondCode {
EQ = 0b0000, // meaning Z == 1
NE = 0b0001, // meaning Z == 0
HS = 0b0010, // meaning C == 1
CS = HS,
LO = 0b0011, // meaning C == 0
CC = LO,
MI = 0b0100, // meaning N == 1
PL = 0b0101, // meaning N == 0
VS = 0b0110, // meaning V == 1
VC = 0b0111, // meaning V == 0
HI = 0b1000, // meaning C == 1 && Z == 0
LS = 0b1001, // meaning !(C == 1 && Z == 0)
GE = 0b1010, // meaning N == V
LT = 0b1011, // meaning N != V
GT = 0b1100, // meaning Z == 0 && N == V
LE = 0b1101, // meaning !(Z == 0 && N == V)
AL = 0b1110, // meaning ANY
NV = 0b1111 // ditto
};
/*
* certain addressing modes for load require pre or post writeback of
* the computed address to a base register
*/
enum WriteBack {
Post = 0,
Pre = 1
};
/*
* certain addressing modes for load require an offset to
* be optionally scaled so the decode needs to pass that
* through to the execute routine
*/
enum Scaling {
Unscaled = 0,
Scaled = 1
};
/*
* when we do have to scale we do so by shifting using
* log(bytes in data element - 1) as the shift count.
* so we don't have to scale offsets when loading
* bytes.
*/
enum ScaleShift {
ScaleShift16 = 1,
ScaleShift32 = 2,
ScaleShift64 = 3,
ScaleShift128 = 4
};
/*
* one of the addressing modes for load requires a 32-bit register
* value to be either zero- or sign-extended for these instructions
* UXTW or SXTW should be passed
*
* arithmetic register data processing operations can optionally
* extend a portion of the second register value for these
* instructions the value supplied must identify the portion of the
* register which is to be zero- or sign-exended
*/
enum Extension {
UXTB = 0,
UXTH = 1,
UXTW = 2,
UXTX = 3,
SXTB = 4,
SXTH = 5,
SXTW = 6,
SXTX = 7
};
/*
* arithmetic and logical register data processing operations
* optionally perform a shift on the second register value
*/
enum Shift {
LSL = 0,
LSR = 1,
ASR = 2,
ROR = 3
};
/*
* bit twiddling helpers for instruction decode
*/
// 32 bit mask with bits [hi,...,lo] set
static inline u_int32_t mask32(int hi = 31, int lo = 0)
{
int nbits = (hi + 1) - lo;
return ((1 << nbits) - 1) << lo;
}
static inline u_int64_t mask64(int hi = 63, int lo = 0)
{
int nbits = (hi + 1) - lo;
return ((1L << nbits) - 1) << lo;
}
// pick bits [hi,...,lo] from val
static inline u_int32_t pick32(u_int32_t val, int hi = 31, int lo = 0)
{
return (val & mask32(hi, lo));
}
// pick bits [hi,...,lo] from val
static inline u_int64_t pick64(u_int64_t val, int hi = 31, int lo = 0)
{
return (val & mask64(hi, lo));
}
// pick bits [hi,...,lo] from val and shift to [(hi-(newlo - lo)),newlo]
static inline u_int32_t pickshift32(u_int32_t val, int hi = 31,
int lo = 0, int newlo = 0)
{
u_int32_t bits = pick32(val, hi, lo);
if (lo < newlo) {
return (bits << (newlo - lo));
} else {
return (bits >> (lo - newlo));
}
}
// mask [hi,lo] and shift down to start at bit 0
static inline u_int32_t pickbits32(u_int32_t val, int hi = 31, int lo = 0)
{
return (pick32(val, hi, lo) >> lo);
}
// mask [hi,lo] and shift down to start at bit 0
static inline u_int64_t pickbits64(u_int64_t val, int hi = 63, int lo = 0)
{
return (pick64(val, hi, lo) >> lo);
}
/*
* decode registers, immediates and constants of various types
*/
static inline GReg greg(u_int32_t val, int lo)
{
return (GReg)pickbits32(val, lo + 4, lo);
}
static inline VReg vreg(u_int32_t val, int lo)
{
return (VReg)pickbits32(val, lo + 4, lo);
}
static inline u_int32_t uimm(u_int32_t val, int hi, int lo)
{
return pickbits32(val, hi, lo);
}
static inline int32_t simm(u_int32_t val, int hi = 31, int lo = 0) {
union {
u_int32_t u;
int32_t n;
};
u = val << (31 - hi);
n = n >> (31 - hi + lo);
return n;
}
static inline int64_t simm(u_int64_t val, int hi = 63, int lo = 0) {
union {
u_int64_t u;
int64_t n;
};
u = val << (63 - hi);
n = n >> (63 - hi + lo);
return n;
}
static inline Shift shift(u_int32_t val, int lo)
{
return (Shift)pickbits32(val, lo+1, lo);
}
static inline Extension extension(u_int32_t val, int lo)
{
return (Extension)pickbits32(val, lo+2, lo);
}
static inline Scaling scaling(u_int32_t val, int lo)
{
return (Scaling)pickbits32(val, lo, lo);
}
static inline WriteBack writeback(u_int32_t val, int lo)
{
return (WriteBack)pickbits32(val, lo, lo);
}
static inline CondCode condcode(u_int32_t val, int lo)
{
return (CondCode)pickbits32(val, lo+3, lo);
}
/*
* operation decode
*/
// bits [28,25] are the primary dispatch vector
static inline u_int32_t dispatchGroup(u_int32_t val)
{
return pickshift32(val, 28, 25, 0);
}
/*
* the 16 possible values for bits [28,25] identified by tags which
* map them to the 5 main instruction groups LDST, DPREG, ADVSIMD,
* BREXSYS and DPIMM.
*
* An extra group PSEUDO is included in one of the unallocated ranges
* for simulator-specific pseudo-instructions.
*/
enum DispatchGroup {
GROUP_PSEUDO_0000,
GROUP_UNALLOC_0001,
GROUP_UNALLOC_0010,
GROUP_UNALLOC_0011,
GROUP_LDST_0100,
GROUP_DPREG_0101,
GROUP_LDST_0110,
GROUP_ADVSIMD_0111,
GROUP_DPIMM_1000,
GROUP_DPIMM_1001,
GROUP_BREXSYS_1010,
GROUP_BREXSYS_1011,
GROUP_LDST_1100,
GROUP_DPREG_1101,
GROUP_LDST_1110,
GROUP_ADVSIMD_1111
};
// bits [31, 29] of a Pseudo are the secondary dispatch vector
static inline u_int32_t dispatchPseudo(u_int32_t val)
{
return pickshift32(val, 31, 29, 0);
}
/*
* the 8 possible values for bits [31,29] in a Pseudo Instruction.
* Bits [28,25] are always 0000.
*/
enum DispatchPseudo {
PSEUDO_UNALLOC_000, // unallocated
PSEUDO_UNALLOC_001, // ditto
PSEUDO_UNALLOC_010, // ditto
PSEUDO_UNALLOC_011, // ditto
PSEUDO_UNALLOC_100, // ditto
PSEUDO_UNALLOC_101, // ditto
PSEUDO_CALLOUT_110, // CALLOUT -- bits [24,0] identify call/ret sig
PSEUDO_HALT_111 // HALT -- bits [24, 0] identify halt code
};
// bits [25, 23] of a DPImm are the secondary dispatch vector
static inline u_int32_t dispatchDPImm(u_int32_t instr)
{
return pickshift32(instr, 25, 23, 0);
}
/*
* the 8 possible values for bits [25,23] in a Data Processing Immediate
* Instruction. Bits [28,25] are always 100_.
*/
enum DispatchDPImm {
DPIMM_PCADR_000, // PC-rel-addressing
DPIMM_PCADR_001, // ditto
DPIMM_ADDSUB_010, // Add/Subtract (immediate)
DPIMM_ADDSUB_011, // ditto
DPIMM_LOG_100, // Logical (immediate)
DPIMM_MOV_101, // Move Wide (immediate)
DPIMM_BITF_110, // Bitfield
DPIMM_EXTR_111 // Extract
};
// bits [29,28:26] of a LS are the secondary dispatch vector
static inline u_int32_t dispatchLS(u_int32_t instr)
{
return (pickshift32(instr, 29, 28, 1) |
pickshift32(instr, 26, 26, 0));
}
/*
* the 8 possible values for bits [29,28:26] in a Load/Store
* Instruction. Bits [28,25] are always _1_0
*/
enum DispatchLS {
LS_EXCL_000, // Load/store exclusive (includes some unallocated)
LS_ADVSIMD_001, // AdvSIMD load/store (various -- includes some unallocated)
LS_LIT_010, // Load register literal (includes some unallocated)
LS_LIT_011, // ditto
LS_PAIR_100, // Load/store register pair (various)
LS_PAIR_101, // ditto
LS_OTHER_110, // other load/store formats
LS_OTHER_111 // ditto
};
// bits [28:24:21] of a DPReg are the secondary dispatch vector
static inline u_int32_t dispatchDPReg(u_int32_t instr)
{
return (pickshift32(instr, 28, 28, 2) |
pickshift32(instr, 24, 24, 1) |
pickshift32(instr, 21, 21, 0));
}
/*
* the 8 possible values for bits [28:24:21] in a Data Processing
* Register Instruction. Bits [28,25] are always _101
*/
enum DispatchDPReg {
DPREG_LOG_000, // Logical (shifted register)
DPREG_LOG_001, // ditto
DPREG_ADDSHF_010, // Add/subtract (shifted register)
DPREG_ADDEXT_011, // Add/subtract (extended register)
DPREG_ADDCOND_100, // Add/subtract (with carry) AND
// Cond compare/select AND
// Data Processing (1/2 source)
DPREG_UNALLOC_101, // Unallocated
DPREG_3SRC_110, // Data Processing (3 source)
DPREG_3SRC_111 // Data Processing (3 source)
};
// bits [31,29] of a BrExSys are the secondary dispatch vector
static inline u_int32_t dispatchBrExSys(u_int32_t instr)
{
return pickbits32(instr, 31, 29);
}
/*
* the 8 possible values for bits [31,29] in a Branch/Exception/System
* Instruction. Bits [28,25] are always 101_
*/
enum DispatchBr {
BR_IMM_000, // Unconditional branch (immediate)
BR_IMMCMP_001, // Compare & branch (immediate) AND
// Test & branch (immediate)
BR_IMMCOND_010, // Conditional branch (immediate) AND Unallocated
BR_UNALLOC_011, // Unallocated
BR_IMM_100, // Unconditional branch (immediate)
BR_IMMCMP_101, // Compare & branch (immediate) AND
// Test & branch (immediate)
BR_REG_110, // Unconditional branch (register) AND System AND
// Excn gen AND Unallocated
BR_UNALLOC_111 // Unallocated
};
/*
* TODO still need to provide secondary decode and dispatch for
* AdvSIMD Insructions with instr[28,25] = 0111 or 1111
*/
#endif // ifndef DECODE_H

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "compiler/disassembler.hpp"
#include "depChecker_aarch64.hpp"
// Nothing to do on aarch64

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_DEPCHECKER_AARCH64_HPP
#define CPU_AARCH64_VM_DEPCHECKER_AARCH64_HPP
// Nothing to do on aarch64
#endif // CPU_AARCH64_VM_DEPCHECKER_AARCH64_HPP

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_DISASSEMBLER_AARCH64_HPP
#define CPU_AARCH64_VM_DISASSEMBLER_AARCH64_HPP
static int pd_instruction_alignment() {
return 1;
}
static const char* pd_cpu_opts() {
return "";
}
#endif // CPU_AARCH64_VM_DISASSEMBLER_AARCH64_HPP

View File

@ -0,0 +1,843 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/resourceArea.hpp"
#include "oops/markOop.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/monitorChunk.hpp"
#include "runtime/os.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
#include "vmreg_aarch64.inline.hpp"
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
#include "runtime/vframeArray.hpp"
#endif
#ifdef ASSERT
void RegisterMap::check_location_valid() {
}
#endif
// Profiling/safepoint support
bool frame::safe_for_sender(JavaThread *thread) {
address sp = (address)_sp;
address fp = (address)_fp;
address unextended_sp = (address)_unextended_sp;
// consider stack guards when trying to determine "safe" stack pointers
static size_t stack_guard_size = os::uses_stack_guard_pages() ? (StackYellowPages + StackRedPages) * os::vm_page_size() : 0;
size_t usable_stack_size = thread->stack_size() - stack_guard_size;
// sp must be within the usable part of the stack (not in guards)
bool sp_safe = (sp < thread->stack_base()) &&
(sp >= thread->stack_base() - usable_stack_size);
if (!sp_safe) {
return false;
}
// unextended sp must be within the stack and above or equal sp
bool unextended_sp_safe = (unextended_sp < thread->stack_base()) &&
(unextended_sp >= sp);
if (!unextended_sp_safe) {
return false;
}
// an fp must be within the stack and above (but not equal) sp
// second evaluation on fp+ is added to handle situation where fp is -1
bool fp_safe = (fp < thread->stack_base() && (fp > sp) && (((fp + (return_addr_offset * sizeof(void*))) < thread->stack_base())));
// We know sp/unextended_sp are safe only fp is questionable here
// If the current frame is known to the code cache then we can attempt to
// to construct the sender and do some validation of it. This goes a long way
// toward eliminating issues when we get in frame construction code
if (_cb != NULL ) {
// First check if frame is complete and tester is reliable
// Unfortunately we can only check frame complete for runtime stubs and nmethod
// other generic buffer blobs are more problematic so we just assume they are
// ok. adapter blobs never have a frame complete and are never ok.
if (!_cb->is_frame_complete_at(_pc)) {
if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) {
return false;
}
}
// Could just be some random pointer within the codeBlob
if (!_cb->code_contains(_pc)) {
return false;
}
// Entry frame checks
if (is_entry_frame()) {
// an entry frame must have a valid fp.
if (!fp_safe) return false;
// Validate the JavaCallWrapper an entry frame must have
address jcw = (address)entry_frame_call_wrapper();
bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > fp);
return jcw_safe;
}
intptr_t* sender_sp = NULL;
intptr_t* sender_unextended_sp = NULL;
address sender_pc = NULL;
intptr_t* saved_fp = NULL;
if (is_interpreted_frame()) {
// fp must be safe
if (!fp_safe) {
return false;
}
sender_pc = (address) this->fp()[return_addr_offset];
// for interpreted frames, the value below is the sender "raw" sp,
// which can be different from the sender unextended sp (the sp seen
// by the sender) because of current frame local variables
sender_sp = (intptr_t*) addr_at(sender_sp_offset);
sender_unextended_sp = (intptr_t*) this->fp()[interpreter_frame_sender_sp_offset];
saved_fp = (intptr_t*) this->fp()[link_offset];
} else {
// must be some sort of compiled/runtime frame
// fp does not have to be safe (although it could be check for c1?)
// check for a valid frame_size, otherwise we are unlikely to get a valid sender_pc
if (_cb->frame_size() <= 0) {
return false;
}
sender_sp = _unextended_sp + _cb->frame_size();
sender_unextended_sp = sender_sp;
sender_pc = (address) *(sender_sp-1);
// Note: frame::sender_sp_offset is only valid for compiled frame
saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset);
}
// If the potential sender is the interpreter then we can do some more checking
if (Interpreter::contains(sender_pc)) {
// fp is always saved in a recognizable place in any code we generate. However
// only if the sender is interpreted/call_stub (c1 too?) are we certain that the saved fp
// is really a frame pointer.
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
if (!saved_fp_safe) {
return false;
}
// construct the potential sender
frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
return sender.is_interpreted_frame_valid(thread);
}
// We must always be able to find a recognizable pc
CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);
if (sender_pc == NULL || sender_blob == NULL) {
return false;
}
// Could be a zombie method
if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
return false;
}
// Could just be some random pointer within the codeBlob
if (!sender_blob->code_contains(sender_pc)) {
return false;
}
// We should never be able to see an adapter if the current frame is something from code cache
if (sender_blob->is_adapter_blob()) {
return false;
}
// Could be the call_stub
if (StubRoutines::returns_to_call_stub(sender_pc)) {
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
if (!saved_fp_safe) {
return false;
}
// construct the potential sender
frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
// Validate the JavaCallWrapper an entry frame must have
address jcw = (address)sender.entry_frame_call_wrapper();
bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp());
return jcw_safe;
}
if (sender_blob->is_nmethod()) {
nmethod* nm = sender_blob->as_nmethod_or_null();
if (nm != NULL) {
if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc)) {
return false;
}
}
}
// If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
// because the return address counts against the callee's frame.
if (sender_blob->frame_size() <= 0) {
assert(!sender_blob->is_nmethod(), "should count return address at least");
return false;
}
// We should never be able to see anything here except an nmethod. If something in the
// code cache (current frame) is called by an entity within the code cache that entity
// should not be anything but the call stub (already covered), the interpreter (already covered)
// or an nmethod.
if (!sender_blob->is_nmethod()) {
return false;
}
// Could put some more validation for the potential non-interpreted sender
// frame we'd create by calling sender if I could think of any. Wait for next crash in forte...
// One idea is seeing if the sender_pc we have is one that we'd expect to call to current cb
// We've validated the potential sender that would be created
return true;
}
// Must be native-compiled frame. Since sender will try and use fp to find
// linkages it must be safe
if (!fp_safe) {
return false;
}
// Will the pc we fetch be non-zero (which we'll find at the oldest frame)
if ( (address) this->fp()[return_addr_offset] == NULL) return false;
// could try and do some more potential verification of native frame if we could think of some...
return true;
}
void frame::patch_pc(Thread* thread, address pc) {
address* pc_addr = &(((address*) sp())[-1]);
if (TracePcPatching) {
tty->print_cr("patch_pc at address " INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "]",
p2i(pc_addr), p2i(*pc_addr), p2i(pc));
}
// Either the return address is the original one or we are going to
// patch in the same address that's already there.
assert(_pc == *pc_addr || pc == *pc_addr, "must be");
*pc_addr = pc;
_cb = CodeCache::find_blob(pc);
address original_pc = nmethod::get_deopt_original_pc(this);
if (original_pc != NULL) {
assert(original_pc == _pc, "expected original PC to be stored before patching");
_deopt_state = is_deoptimized;
// leave _pc as is
} else {
_deopt_state = not_deoptimized;
_pc = pc;
}
}
bool frame::is_interpreted_frame() const {
return Interpreter::contains(pc());
}
int frame::frame_size(RegisterMap* map) const {
frame sender = this->sender(map);
return sender.sp() - sp();
}
intptr_t* frame::entry_frame_argument_at(int offset) const {
// convert offset to index to deal with tsi
int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize);
// Entry frame's arguments are always in relation to unextended_sp()
return &unextended_sp()[index];
}
// sender_sp
#ifdef CC_INTERP
intptr_t* frame::interpreter_frame_sender_sp() const {
assert(is_interpreted_frame(), "interpreted frame expected");
// QQQ why does this specialize method exist if frame::sender_sp() does same thing?
// seems odd and if we always know interpreted vs. non then sender_sp() is really
// doing too much work.
return get_interpreterState()->sender_sp();
}
// monitor elements
BasicObjectLock* frame::interpreter_frame_monitor_begin() const {
return get_interpreterState()->monitor_base();
}
BasicObjectLock* frame::interpreter_frame_monitor_end() const {
return (BasicObjectLock*) get_interpreterState()->stack_base();
}
#else // CC_INTERP
intptr_t* frame::interpreter_frame_sender_sp() const {
assert(is_interpreted_frame(), "interpreted frame expected");
return (intptr_t*) at(interpreter_frame_sender_sp_offset);
}
void frame::set_interpreter_frame_sender_sp(intptr_t* sender_sp) {
assert(is_interpreted_frame(), "interpreted frame expected");
ptr_at_put(interpreter_frame_sender_sp_offset, (intptr_t) sender_sp);
}
// monitor elements
BasicObjectLock* frame::interpreter_frame_monitor_begin() const {
return (BasicObjectLock*) addr_at(interpreter_frame_monitor_block_bottom_offset);
}
BasicObjectLock* frame::interpreter_frame_monitor_end() const {
BasicObjectLock* result = (BasicObjectLock*) *addr_at(interpreter_frame_monitor_block_top_offset);
// make sure the pointer points inside the frame
assert(sp() <= (intptr_t*) result, "monitor end should be above the stack pointer");
assert((intptr_t*) result < fp(), "monitor end should be strictly below the frame pointer");
return result;
}
void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) {
*((BasicObjectLock**)addr_at(interpreter_frame_monitor_block_top_offset)) = value;
}
// Used by template based interpreter deoptimization
void frame::interpreter_frame_set_last_sp(intptr_t* sp) {
*((intptr_t**)addr_at(interpreter_frame_last_sp_offset)) = sp;
}
#endif // CC_INTERP
frame frame::sender_for_entry_frame(RegisterMap* map) const {
assert(map != NULL, "map must be set");
// Java frame called from C; skip all C frames and return top C
// frame of that chunk as the sender
JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor();
assert(!entry_frame_is_first(), "next Java fp must be non zero");
assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
map->clear();
assert(map->include_argument_oops(), "should be set by clear");
if (jfa->last_Java_pc() != NULL ) {
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
return fr;
}
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp());
return fr;
}
//------------------------------------------------------------------------------
// frame::verify_deopt_original_pc
//
// Verifies the calculated original PC of a deoptimization PC for the
// given unextended SP. The unextended SP might also be the saved SP
// for MethodHandle call sites.
#ifdef ASSERT
void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) {
frame fr;
// This is ugly but it's better than to change {get,set}_original_pc
// to take an SP value as argument. And it's only a debugging
// method anyway.
fr._unextended_sp = unextended_sp;
address original_pc = nm->get_original_pc(&fr);
assert(nm->insts_contains(original_pc), "original PC must be in nmethod");
assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be");
}
#endif
//------------------------------------------------------------------------------
// frame::adjust_unextended_sp
void frame::adjust_unextended_sp() {
// If we are returning to a compiled MethodHandle call site, the
// saved_fp will in fact be a saved value of the unextended SP. The
// simplest way to tell whether we are returning to such a call site
// is as follows:
nmethod* sender_nm = (_cb == NULL) ? NULL : _cb->as_nmethod_or_null();
if (sender_nm != NULL) {
// If the sender PC is a deoptimization point, get the original
// PC. For MethodHandle call site the unextended_sp is stored in
// saved_fp.
if (sender_nm->is_deopt_mh_entry(_pc)) {
DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, _fp));
_unextended_sp = _fp;
}
else if (sender_nm->is_deopt_entry(_pc)) {
DEBUG_ONLY(verify_deopt_original_pc(sender_nm, _unextended_sp));
}
else if (sender_nm->is_method_handle_return(_pc)) {
_unextended_sp = _fp;
}
}
}
//------------------------------------------------------------------------------
// frame::update_map_with_saved_link
void frame::update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr) {
// The interpreter and compiler(s) always save fp in a known
// location on entry. We must record where that location is
// so that if fp was live on callout from c2 we can find
// the saved copy no matter what it called.
// Since the interpreter always saves fp if we record where it is then
// we don't have to always save fp on entry and exit to c2 compiled
// code, on entry will be enough.
map->set_location(rfp->as_VMReg(), (address) link_addr);
// this is weird "H" ought to be at a higher address however the
// oopMaps seems to have the "H" regs at the same address and the
// vanilla register.
// XXXX make this go away
if (true) {
map->set_location(rfp->as_VMReg()->next(), (address) link_addr);
}
}
//------------------------------------------------------------------------------
// frame::sender_for_interpreter_frame
frame frame::sender_for_interpreter_frame(RegisterMap* map) const {
// SP is the raw SP from the sender after adapter or interpreter
// extension.
intptr_t* sender_sp = this->sender_sp();
// This is the sp before any possible extension (adapter/locals).
intptr_t* unextended_sp = interpreter_frame_sender_sp();
#ifdef COMPILER2
if (map->update_map()) {
update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset));
}
#endif // COMPILER2
return frame(sender_sp, unextended_sp, link(), sender_pc());
}
//------------------------------------------------------------------------------
// frame::sender_for_compiled_frame
frame frame::sender_for_compiled_frame(RegisterMap* map) const {
// we cannot rely upon the last fp having been saved to the thread
// in C2 code but it will have been pushed onto the stack. so we
// have to find it relative to the unextended sp
assert(_cb->frame_size() >= 0, "must have non-zero frame size");
intptr_t* l_sender_sp = unextended_sp() + _cb->frame_size();
intptr_t* unextended_sp = l_sender_sp;
// the return_address is always the word on the stack
address sender_pc = (address) *(l_sender_sp-1);
intptr_t** saved_fp_addr = (intptr_t**) (l_sender_sp - frame::sender_sp_offset);
// assert (sender_sp() == l_sender_sp, "should be");
// assert (*saved_fp_addr == link(), "should be");
if (map->update_map()) {
// Tell GC to use argument oopmaps for some runtime stubs that need it.
// For C1, the runtime stub might not have oop maps, so set this flag
// outside of update_register_map.
map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread()));
if (_cb->oop_maps() != NULL) {
OopMapSet::update_register_map(this, map);
}
// Since the prolog does the save and restore of FP there is no
// oopmap for it so we must fill in its location as if there was
// an oopmap entry since if our caller was compiled code there
// could be live jvm state in it.
update_map_with_saved_link(map, saved_fp_addr);
}
return frame(l_sender_sp, unextended_sp, *saved_fp_addr, sender_pc);
}
//------------------------------------------------------------------------------
// frame::sender
frame frame::sender(RegisterMap* map) const {
// Default is we done have to follow them. The sender_for_xxx will
// update it accordingly
map->set_include_argument_oops(false);
if (is_entry_frame())
return sender_for_entry_frame(map);
if (is_interpreted_frame())
return sender_for_interpreter_frame(map);
assert(_cb == CodeCache::find_blob(pc()),"Must be the same");
// This test looks odd: why is it not is_compiled_frame() ? That's
// because stubs also have OOP maps.
if (_cb != NULL) {
return sender_for_compiled_frame(map);
}
// Must be native-compiled frame, i.e. the marshaling code for native
// methods that exists in the core system.
return frame(sender_sp(), link(), sender_pc());
}
bool frame::interpreter_frame_equals_unpacked_fp(intptr_t* fp) {
assert(is_interpreted_frame(), "must be interpreter frame");
Method* method = interpreter_frame_method();
// When unpacking an optimized frame the frame pointer is
// adjusted with:
int diff = (method->max_locals() - method->size_of_parameters()) *
Interpreter::stackElementWords;
return _fp == (fp - diff);
}
bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
// QQQ
#ifdef CC_INTERP
#else
assert(is_interpreted_frame(), "Not an interpreted frame");
// These are reasonable sanity checks
if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) {
return false;
}
if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) {
return false;
}
if (fp() + interpreter_frame_initial_sp_offset < sp()) {
return false;
}
// These are hacks to keep us out of trouble.
// The problem with these is that they mask other problems
if (fp() <= sp()) { // this attempts to deal with unsigned comparison above
return false;
}
// do some validation of frame elements
// first the method
Method* m = *interpreter_frame_method_addr();
// validate the method we'd find in this potential sender
if (!m->is_valid_method()) return false;
// stack frames shouldn't be much larger than max_stack elements
// this test requires the use of unextended_sp which is the sp as seen by
// the current frame, and not sp which is the "raw" pc which could point
// further because of local variables of the callee method inserted after
// method arguments
if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
return false;
}
// validate bci/bcx
address bcp = interpreter_frame_bcp();
if (m->validate_bci_from_bcp(bcp) < 0) {
return false;
}
// validate constantPoolCache*
ConstantPoolCache* cp = *interpreter_frame_cache_addr();
if (cp == NULL || !cp->is_metaspace_object()) return false;
// validate locals
address locals = (address) *interpreter_frame_locals_addr();
if (locals > thread->stack_base() || locals < (address) fp()) return false;
// We'd have to be pretty unlucky to be mislead at this point
#endif // CC_INTERP
return true;
}
BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) {
#ifdef CC_INTERP
// Needed for JVMTI. The result should always be in the
// interpreterState object
interpreterState istate = get_interpreterState();
#endif // CC_INTERP
assert(is_interpreted_frame(), "interpreted frame expected");
Method* method = interpreter_frame_method();
BasicType type = method->result_type();
intptr_t* tos_addr;
if (method->is_native()) {
// TODO : ensure AARCH64 does the same as Intel here i.e. push v0 then r0
// Prior to calling into the runtime to report the method_exit the possible
// return value is pushed to the native stack. If the result is a jfloat/jdouble
// then ST0 is saved before EAX/EDX. See the note in generate_native_result
tos_addr = (intptr_t*)sp();
if (type == T_FLOAT || type == T_DOUBLE) {
// This is times two because we do a push(ltos) after pushing XMM0
// and that takes two interpreter stack slots.
tos_addr += 2 * Interpreter::stackElementWords;
}
} else {
tos_addr = (intptr_t*)interpreter_frame_tos_address();
}
switch (type) {
case T_OBJECT :
case T_ARRAY : {
oop obj;
if (method->is_native()) {
#ifdef CC_INTERP
obj = istate->_oop_temp;
#else
obj = cast_to_oop(at(interpreter_frame_oop_temp_offset));
#endif // CC_INTERP
} else {
oop* obj_p = (oop*)tos_addr;
obj = (obj_p == NULL) ? (oop)NULL : *obj_p;
}
assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");
*oop_result = obj;
break;
}
case T_BOOLEAN : value_result->z = *(jboolean*)tos_addr; break;
case T_BYTE : value_result->b = *(jbyte*)tos_addr; break;
case T_CHAR : value_result->c = *(jchar*)tos_addr; break;
case T_SHORT : value_result->s = *(jshort*)tos_addr; break;
case T_INT : value_result->i = *(jint*)tos_addr; break;
case T_LONG : value_result->j = *(jlong*)tos_addr; break;
case T_FLOAT : {
value_result->f = *(jfloat*)tos_addr;
break;
}
case T_DOUBLE : value_result->d = *(jdouble*)tos_addr; break;
case T_VOID : /* Nothing to do */ break;
default : ShouldNotReachHere();
}
return type;
}
intptr_t* frame::interpreter_frame_tos_at(jint offset) const {
int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize);
return &interpreter_frame_tos_address()[index];
}
#ifndef PRODUCT
#define DESCRIBE_FP_OFFSET(name) \
values.describe(frame_no, fp() + frame::name##_offset, #name)
void frame::describe_pd(FrameValues& values, int frame_no) {
if (is_interpreted_frame()) {
DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp);
DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
DESCRIBE_FP_OFFSET(interpreter_frame_method);
DESCRIBE_FP_OFFSET(interpreter_frame_mdp);
DESCRIBE_FP_OFFSET(interpreter_frame_cache);
DESCRIBE_FP_OFFSET(interpreter_frame_locals);
DESCRIBE_FP_OFFSET(interpreter_frame_bcp);
DESCRIBE_FP_OFFSET(interpreter_frame_initial_sp);
}
}
#endif
intptr_t *frame::initial_deoptimization_info() {
// Not used on aarch64, but we must return something.
return NULL;
}
intptr_t* frame::real_fp() const {
if (_cb != NULL) {
// use the frame size if valid
int size = _cb->frame_size();
if (size > 0) {
return unextended_sp() + size;
}
}
// else rely on fp()
assert(! is_compiled_frame(), "unknown compiled frame size");
return fp();
}
#undef DESCRIBE_FP_OFFSET
#define DESCRIBE_FP_OFFSET(name) \
{ \
unsigned long *p = (unsigned long *)fp; \
printf("0x%016lx 0x%016lx %s\n", (unsigned long)(p + frame::name##_offset), \
p[frame::name##_offset], #name); \
}
static __thread unsigned long nextfp;
static __thread unsigned long nextpc;
static __thread unsigned long nextsp;
static __thread RegisterMap *reg_map;
static void printbc(Method *m, intptr_t bcx) {
const char *name;
char buf[16];
if (m->validate_bci_from_bcp((address)bcx) < 0
|| !m->contains((address)bcx)) {
name = "???";
snprintf(buf, sizeof buf, "(bad)");
} else {
int bci = m->bci_from((address)bcx);
snprintf(buf, sizeof buf, "%d", bci);
name = Bytecodes::name(m->code_at(bci));
}
ResourceMark rm;
printf("%s : %s ==> %s\n", m->name_and_sig_as_C_string(), buf, name);
}
void internal_pf(unsigned long sp, unsigned long fp, unsigned long pc, unsigned long bcx) {
if (! fp)
return;
DESCRIBE_FP_OFFSET(return_addr);
DESCRIBE_FP_OFFSET(link);
DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp);
DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
DESCRIBE_FP_OFFSET(interpreter_frame_method);
DESCRIBE_FP_OFFSET(interpreter_frame_mdp);
DESCRIBE_FP_OFFSET(interpreter_frame_cache);
DESCRIBE_FP_OFFSET(interpreter_frame_locals);
DESCRIBE_FP_OFFSET(interpreter_frame_bcp);
DESCRIBE_FP_OFFSET(interpreter_frame_initial_sp);
unsigned long *p = (unsigned long *)fp;
// We want to see all frames, native and Java. For compiled and
// interpreted frames we have special information that allows us to
// unwind them; for everything else we assume that the native frame
// pointer chain is intact.
frame this_frame((intptr_t*)sp, (intptr_t*)fp, (address)pc);
if (this_frame.is_compiled_frame() ||
this_frame.is_interpreted_frame()) {
frame sender = this_frame.sender(reg_map);
nextfp = (unsigned long)sender.fp();
nextpc = (unsigned long)sender.pc();
nextsp = (unsigned long)sender.unextended_sp();
} else {
nextfp = p[frame::link_offset];
nextpc = p[frame::return_addr_offset];
nextsp = (unsigned long)&p[frame::sender_sp_offset];
}
if (bcx == -1ul)
bcx = p[frame::interpreter_frame_bcp_offset];
if (Interpreter::contains((address)pc)) {
Method* m = (Method*)p[frame::interpreter_frame_method_offset];
if(m && m->is_method()) {
printbc(m, bcx);
} else
printf("not a Method\n");
} else {
CodeBlob *cb = CodeCache::find_blob((address)pc);
if (cb != NULL) {
if (cb->is_nmethod()) {
ResourceMark rm;
nmethod* nm = (nmethod*)cb;
printf("nmethod %s\n", nm->method()->name_and_sig_as_C_string());
} else if (cb->name()) {
printf("CodeBlob %s\n", cb->name());
}
}
}
}
extern "C" void npf() {
CodeBlob *cb = CodeCache::find_blob((address)nextpc);
// C2 does not always chain the frame pointers when it can, instead
// preferring to use fixed offsets from SP, so a simple leave() does
// not work. Instead, it adds the frame size to SP then pops FP and
// LR. We have to do the same thing to get a good call chain.
if (cb && cb->frame_size())
nextfp = nextsp + wordSize * (cb->frame_size() - 2);
internal_pf (nextsp, nextfp, nextpc, -1);
}
extern "C" void pf(unsigned long sp, unsigned long fp, unsigned long pc,
unsigned long bcx, unsigned long thread) {
RegisterMap map((JavaThread*)thread, false);
if (!reg_map) {
reg_map = (RegisterMap*)os::malloc(sizeof map, mtNone);
}
memcpy(reg_map, &map, sizeof map);
{
CodeBlob *cb = CodeCache::find_blob((address)pc);
if (cb && cb->frame_size())
fp = sp + wordSize * (cb->frame_size() - 2);
}
internal_pf(sp, fp, pc, bcx);
}
// support for printing out where we are in a Java method
// needs to be passed current fp and bcp register values
// prints method name, bc index and bytecode name
extern "C" void pm(unsigned long fp, unsigned long bcx) {
DESCRIBE_FP_OFFSET(interpreter_frame_method);
unsigned long *p = (unsigned long *)fp;
Method* m = (Method*)p[frame::interpreter_frame_method_offset];
printbc(m, bcx);
}
#ifndef PRODUCT
// This is a generic constructor which is only used by pns() in debug.cpp.
frame::frame(void* sp, void* fp, void* pc) {
init((intptr_t*)sp, (intptr_t*)fp, (address)pc);
}
#endif

View File

@ -0,0 +1,216 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_FRAME_AARCH64_HPP
#define CPU_AARCH64_VM_FRAME_AARCH64_HPP
#include "runtime/synchronizer.hpp"
#include "utilities/top.hpp"
// A frame represents a physical stack frame (an activation). Frames can be
// C or Java frames, and the Java frames can be interpreted or compiled.
// In contrast, vframes represent source-level activations, so that one physical frame
// can correspond to multiple source level frames because of inlining.
// A frame is comprised of {pc, fp, sp}
// ------------------------------ Asm interpreter ----------------------------------------
// Layout of asm interpreter frame:
// [expression stack ] * <- sp
// [monitors[0] ] \
// ... | monitor block size = k
// [monitors[k-1] ] /
// [frame initial esp ] ( == &monitors[0], initially here) initial_sp_offset
// [byte code index/pointr] = bcx() bcx_offset
// [pointer to locals ] = locals() locals_offset
// [constant pool cache ] = cache() cache_offset
// [methodData ] = mdp() mdx_offset
// [methodOop ] = method() method_offset
// [last esp ] = last_sp() last_sp_offset
// [old stack pointer ] (sender_sp) sender_sp_offset
// [old frame pointer ] <- fp = link()
// [return pc ]
// [last sp ]
// [oop temp ] (only for native calls)
// [locals and parameters ]
// <- sender sp
// ------------------------------ Asm interpreter ----------------------------------------
// ------------------------------ C++ interpreter ----------------------------------------
//
// Layout of C++ interpreter frame: (While executing in BytecodeInterpreter::run)
//
// <- SP (current esp/rsp)
// [local variables ] BytecodeInterpreter::run local variables
// ... BytecodeInterpreter::run local variables
// [local variables ] BytecodeInterpreter::run local variables
// [old frame pointer ] fp [ BytecodeInterpreter::run's ebp/rbp ]
// [return pc ] (return to frame manager)
// [interpreter_state* ] (arg to BytecodeInterpreter::run) --------------
// [expression stack ] <- last_Java_sp |
// [... ] * <- interpreter_state.stack |
// [expression stack ] * <- interpreter_state.stack_base |
// [monitors ] \ |
// ... | monitor block size |
// [monitors ] / <- interpreter_state.monitor_base |
// [struct interpretState ] <-----------------------------------------|
// [return pc ] (return to callee of frame manager [1]
// [locals and parameters ]
// <- sender sp
// [1] When the c++ interpreter calls a new method it returns to the frame
// manager which allocates a new frame on the stack. In that case there
// is no real callee of this newly allocated frame. The frame manager is
// aware of the additional frame(s) and will pop them as nested calls
// complete. Howevers tTo make it look good in the debugger the frame
// manager actually installs a dummy pc pointing to RecursiveInterpreterActivation
// with a fake interpreter_state* parameter to make it easy to debug
// nested calls.
// Note that contrary to the layout for the assembly interpreter the
// expression stack allocated for the C++ interpreter is full sized.
// However this is not as bad as it seems as the interpreter frame_manager
// will truncate the unused space on succesive method calls.
//
// ------------------------------ C++ interpreter ----------------------------------------
public:
enum {
pc_return_offset = 0,
// All frames
link_offset = 0,
return_addr_offset = 1,
sender_sp_offset = 2,
#ifndef CC_INTERP
// Interpreter frames
interpreter_frame_oop_temp_offset = 3, // for native calls only
interpreter_frame_sender_sp_offset = -1,
// outgoing sp before a call to an invoked method
interpreter_frame_last_sp_offset = interpreter_frame_sender_sp_offset - 1,
interpreter_frame_method_offset = interpreter_frame_last_sp_offset - 1,
interpreter_frame_mdp_offset = interpreter_frame_method_offset - 1,
interpreter_frame_cache_offset = interpreter_frame_mdp_offset - 1,
interpreter_frame_locals_offset = interpreter_frame_cache_offset - 1,
interpreter_frame_bcp_offset = interpreter_frame_locals_offset - 1,
interpreter_frame_initial_sp_offset = interpreter_frame_bcp_offset - 1,
interpreter_frame_monitor_block_top_offset = interpreter_frame_initial_sp_offset,
interpreter_frame_monitor_block_bottom_offset = interpreter_frame_initial_sp_offset,
#endif // CC_INTERP
// Entry frames
// n.b. these values are determined by the layout defined in
// stubGenerator for the Java call stub
entry_frame_after_call_words = 27,
entry_frame_call_wrapper_offset = -8,
// we don't need a save area
arg_reg_save_area_bytes = 0,
// TODO - check that this is still correct
// Native frames
native_frame_initial_param_offset = 2
};
intptr_t ptr_at(int offset) const {
return *ptr_at_addr(offset);
}
void ptr_at_put(int offset, intptr_t value) {
*ptr_at_addr(offset) = value;
}
private:
// an additional field beyond _sp and _pc:
intptr_t* _fp; // frame pointer
// The interpreter and adapters will extend the frame of the caller.
// Since oopMaps are based on the sp of the caller before extension
// we need to know that value. However in order to compute the address
// of the return address we need the real "raw" sp. Since sparc already
// uses sp() to mean "raw" sp and unextended_sp() to mean the caller's
// original sp we use that convention.
intptr_t* _unextended_sp;
void adjust_unextended_sp();
intptr_t* ptr_at_addr(int offset) const {
return (intptr_t*) addr_at(offset);
}
#ifdef ASSERT
// Used in frame::sender_for_{interpreter,compiled}_frame
static void verify_deopt_original_pc( nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return = false);
static void verify_deopt_mh_original_pc(nmethod* nm, intptr_t* unextended_sp) {
verify_deopt_original_pc(nm, unextended_sp, true);
}
#endif
public:
// Constructors
frame(intptr_t* sp, intptr_t* fp, address pc);
frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc);
frame(intptr_t* sp, intptr_t* fp);
void init(intptr_t* sp, intptr_t* fp, address pc);
// accessors for the instance variables
// Note: not necessarily the real 'frame pointer' (see real_fp)
intptr_t* fp() const { return _fp; }
inline address* sender_pc_addr() const;
// return address of param, zero origin index.
inline address* native_param_addr(int idx) const;
// expression stack tos if we are nested in a java call
intptr_t* interpreter_frame_last_sp() const;
// helper to update a map with callee-saved RBP
static void update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr);
#ifndef CC_INTERP
// deoptimization support
void interpreter_frame_set_last_sp(intptr_t* sp);
#endif // CC_INTERP
#ifdef CC_INTERP
inline interpreterState get_interpreterState() const;
#endif // CC_INTERP
#endif // CPU_AARCH64_VM_FRAME_AARCH64_HPP

View File

@ -0,0 +1,348 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_FRAME_AARCH64_INLINE_HPP
#define CPU_AARCH64_VM_FRAME_AARCH64_INLINE_HPP
#include "code/codeCache.hpp"
#include "code/vmreg.inline.hpp"
// Inline functions for AArch64 frames:
// Constructors:
inline frame::frame() {
_pc = NULL;
_sp = NULL;
_unextended_sp = NULL;
_fp = NULL;
_cb = NULL;
_deopt_state = unknown;
}
static int spin;
inline void frame::init(intptr_t* sp, intptr_t* fp, address pc) {
intptr_t a = intptr_t(sp);
intptr_t b = intptr_t(fp);
#ifndef PRODUCT
if (fp)
if (sp > fp || (fp - sp > 0x100000))
for(;;)
asm("nop");
#endif
_sp = sp;
_unextended_sp = sp;
_fp = fp;
_pc = pc;
assert(pc != NULL, "no pc?");
_cb = CodeCache::find_blob(pc);
adjust_unextended_sp();
address original_pc = nmethod::get_deopt_original_pc(this);
if (original_pc != NULL) {
_pc = original_pc;
_deopt_state = is_deoptimized;
} else {
_deopt_state = not_deoptimized;
}
}
inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) {
init(sp, fp, pc);
}
inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) {
intptr_t a = intptr_t(sp);
intptr_t b = intptr_t(fp);
#ifndef PRODUCT
if (fp)
if (sp > fp || (fp - sp > 0x100000))
for(;;)
asm("nop");
#endif
_sp = sp;
_unextended_sp = unextended_sp;
_fp = fp;
_pc = pc;
assert(pc != NULL, "no pc?");
_cb = CodeCache::find_blob(pc);
adjust_unextended_sp();
address original_pc = nmethod::get_deopt_original_pc(this);
if (original_pc != NULL) {
_pc = original_pc;
assert(((nmethod*)_cb)->insts_contains(_pc), "original PC must be in nmethod");
_deopt_state = is_deoptimized;
} else {
_deopt_state = not_deoptimized;
}
}
inline frame::frame(intptr_t* sp, intptr_t* fp) {
intptr_t a = intptr_t(sp);
intptr_t b = intptr_t(fp);
#ifndef PRODUCT
if (fp)
if (sp > fp || (fp - sp > 0x100000))
for(;;)
asm("nop");
#endif
_sp = sp;
_unextended_sp = sp;
_fp = fp;
_pc = (address)(sp[-1]);
// Here's a sticky one. This constructor can be called via AsyncGetCallTrace
// when last_Java_sp is non-null but the pc fetched is junk. If we are truly
// unlucky the junk value could be to a zombied method and we'll die on the
// find_blob call. This is also why we can have no asserts on the validity
// of the pc we find here. AsyncGetCallTrace -> pd_get_top_frame_for_signal_handler
// -> pd_last_frame should use a specialized version of pd_last_frame which could
// call a specilaized frame constructor instead of this one.
// Then we could use the assert below. However this assert is of somewhat dubious
// value.
// assert(_pc != NULL, "no pc?");
_cb = CodeCache::find_blob(_pc);
adjust_unextended_sp();
address original_pc = nmethod::get_deopt_original_pc(this);
if (original_pc != NULL) {
_pc = original_pc;
_deopt_state = is_deoptimized;
} else {
_deopt_state = not_deoptimized;
}
}
// Accessors
inline bool frame::equal(frame other) const {
bool ret = sp() == other.sp()
&& unextended_sp() == other.unextended_sp()
&& fp() == other.fp()
&& pc() == other.pc();
assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
return ret;
}
// Return unique id for this frame. The id must have a value where we can distinguish
// identity and younger/older relationship. NULL represents an invalid (incomparable)
// frame.
inline intptr_t* frame::id(void) const { return unextended_sp(); }
// Relationals on frames based
// Return true if the frame is younger (more recent activation) than the frame represented by id
inline bool frame::is_younger(intptr_t* id) const { assert(this->id() != NULL && id != NULL, "NULL frame id");
return this->id() < id ; }
// Return true if the frame is older (less recent activation) than the frame represented by id
inline bool frame::is_older(intptr_t* id) const { assert(this->id() != NULL && id != NULL, "NULL frame id");
return this->id() > id ; }
inline intptr_t* frame::link() const { return (intptr_t*) *(intptr_t **)addr_at(link_offset); }
inline void frame::set_link(intptr_t* addr) { *(intptr_t **)addr_at(link_offset) = addr; }
inline intptr_t* frame::unextended_sp() const { return _unextended_sp; }
// Return address:
inline address* frame::sender_pc_addr() const { return (address*) addr_at( return_addr_offset); }
inline address frame::sender_pc() const { return *sender_pc_addr(); }
// return address of param, zero origin index.
inline address* frame::native_param_addr(int idx) const { return (address*) addr_at( native_frame_initial_param_offset+idx); }
#ifdef CC_INTERP
inline interpreterState frame::get_interpreterState() const {
return ((interpreterState)addr_at( -((int)sizeof(BytecodeInterpreter))/wordSize ));
}
inline intptr_t* frame::sender_sp() const {
// Hmm this seems awfully expensive QQQ, is this really called with interpreted frames?
if (is_interpreted_frame()) {
assert(false, "should never happen");
return get_interpreterState()->sender_sp();
} else {
return addr_at(sender_sp_offset);
}
}
inline intptr_t** frame::interpreter_frame_locals_addr() const {
assert(is_interpreted_frame(), "must be interpreted");
return &(get_interpreterState()->_locals);
}
inline intptr_t* frame::interpreter_frame_bcx_addr() const {
assert(is_interpreted_frame(), "must be interpreted");
return (intptr_t*) &(get_interpreterState()->_bcp);
}
// Constant pool cache
inline constantPoolCacheOop* frame::interpreter_frame_cache_addr() const {
assert(is_interpreted_frame(), "must be interpreted");
return &(get_interpreterState()->_constants);
}
// Method
inline methodOop* frame::interpreter_frame_method_addr() const {
assert(is_interpreted_frame(), "must be interpreted");
return &(get_interpreterState()->_method);
}
inline intptr_t* frame::interpreter_frame_mdx_addr() const {
assert(is_interpreted_frame(), "must be interpreted");
return (intptr_t*) &(get_interpreterState()->_mdx);
}
// top of expression stack
inline intptr_t* frame::interpreter_frame_tos_address() const {
assert(is_interpreted_frame(), "wrong frame type");
return get_interpreterState()->_stack + 1;
}
#else /* asm interpreter */
inline intptr_t* frame::sender_sp() const { return addr_at( sender_sp_offset); }
inline intptr_t** frame::interpreter_frame_locals_addr() const {
return (intptr_t**)addr_at(interpreter_frame_locals_offset);
}
inline intptr_t* frame::interpreter_frame_last_sp() const {
return *(intptr_t**)addr_at(interpreter_frame_last_sp_offset);
}
inline intptr_t* frame::interpreter_frame_bcp_addr() const {
return (intptr_t*)addr_at(interpreter_frame_bcp_offset);
}
inline intptr_t* frame::interpreter_frame_mdp_addr() const {
return (intptr_t*)addr_at(interpreter_frame_mdp_offset);
}
// Constant pool cache
inline ConstantPoolCache** frame::interpreter_frame_cache_addr() const {
return (ConstantPoolCache**)addr_at(interpreter_frame_cache_offset);
}
// Method
inline Method** frame::interpreter_frame_method_addr() const {
return (Method**)addr_at(interpreter_frame_method_offset);
}
// top of expression stack
inline intptr_t* frame::interpreter_frame_tos_address() const {
intptr_t* last_sp = interpreter_frame_last_sp();
if (last_sp == NULL) {
return sp();
} else {
// sp() may have been extended or shrunk by an adapter. At least
// check that we don't fall behind the legal region.
// For top deoptimized frame last_sp == interpreter_frame_monitor_end.
assert(last_sp <= (intptr_t*) interpreter_frame_monitor_end(), "bad tos");
return last_sp;
}
}
inline oop* frame::interpreter_frame_temp_oop_addr() const {
return (oop *)(fp() + interpreter_frame_oop_temp_offset);
}
#endif /* CC_INTERP */
inline int frame::pd_oop_map_offset_adjustment() const {
return 0;
}
inline int frame::interpreter_frame_monitor_size() {
return BasicObjectLock::size();
}
// expression stack
// (the max_stack arguments are used by the GC; see class FrameClosure)
inline intptr_t* frame::interpreter_frame_expression_stack() const {
intptr_t* monitor_end = (intptr_t*) interpreter_frame_monitor_end();
return monitor_end-1;
}
inline jint frame::interpreter_frame_expression_stack_direction() { return -1; }
// Entry frames
inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const {
return (JavaCallWrapper**)addr_at(entry_frame_call_wrapper_offset);
}
// Compiled frames
inline int frame::local_offset_for_compiler(int local_index, int nof_args, int max_nof_locals, int max_nof_monitors) {
return (nof_args - local_index + (local_index < nof_args ? 1: -1));
}
inline int frame::monitor_offset_for_compiler(int local_index, int nof_args, int max_nof_locals, int max_nof_monitors) {
return local_offset_for_compiler(local_index, nof_args, max_nof_locals, max_nof_monitors);
}
inline int frame::min_local_offset_for_compiler(int nof_args, int max_nof_locals, int max_nof_monitors) {
return (nof_args - (max_nof_locals + max_nof_monitors*2) - 1);
}
inline bool frame::volatile_across_calls(Register reg) {
return true;
}
inline oop frame::saved_oop_result(RegisterMap* map) const {
oop* result_adr = (oop *)map->location(r0->as_VMReg());
guarantee(result_adr != NULL, "bad register save location");
return (*result_adr);
}
inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) {
oop* result_adr = (oop *)map->location(r0->as_VMReg());
guarantee(result_adr != NULL, "bad register save location");
*result_adr = obj;
}
#endif // CPU_AARCH64_VM_FRAME_AARCH64_INLINE_HPP

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_GLOBALDEFINITIONS_AARCH64_HPP
#define CPU_AARCH64_VM_GLOBALDEFINITIONS_AARCH64_HPP
const int StackAlignmentInBytes = 16;
// Indicates whether the C calling conventions require that
// 32-bit integer argument values are properly extended to 64 bits.
// If set, SharedRuntime::c_calling_convention() must adapt
// signatures accordingly.
const bool CCallingConventionRequiresIntsAsLongs = true;
#define SUPPORTS_NATIVE_CX8
// The maximum B/BL offset range on AArch64 is 128MB.
#undef CODE_CACHE_DEFAULT_LIMIT
#define CODE_CACHE_DEFAULT_LIMIT (128*M)
// According to the ARMv8 ARM, "Concurrent modification and execution
// of instructions can lead to the resulting instruction performing
// any behavior that can be achieved by executing any sequence of
// instructions that can be executed from the same Exception level,
// except where the instruction before modification and the
// instruction after modification is a B, BL, NOP, BKPT, SVC, HVC, or
// SMC instruction."
//
// This makes the games we play when patching difficult, so when we
// come across an access that needs patching we deoptimize. There are
// ways we can avoid this, but these would slow down C1-compiled code
// in the defauilt case. We could revisit this decision if we get any
// evidence that it's worth doing.
#define DEOPTIMIZE_WHEN_PATCHING
#endif // CPU_AARCH64_VM_GLOBALDEFINITIONS_AARCH64_HPP

View File

@ -0,0 +1,129 @@
/*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_GLOBALS_AARCH64_HPP
#define CPU_AARCH64_VM_GLOBALS_AARCH64_HPP
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
// Sets the default values for platform dependent flags used by the runtime system.
// (see globals.hpp)
define_pd_global(bool, ConvertSleepToYield, true);
define_pd_global(bool, ShareVtableStubs, true);
define_pd_global(bool, CountInterpCalls, true);
define_pd_global(bool, NeedsDeoptSuspend, false); // only register window machines need this
define_pd_global(bool, ImplicitNullChecks, true); // Generate code for implicit null checks
define_pd_global(bool, TrapBasedNullChecks, false);
define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast
// See 4827828 for this change. There is no globals_core_i486.hpp. I can't
// assign a different value for C2 without touching a number of files. Use
// #ifdef to minimize the change as it's late in Mantis. -- FIXME.
// c1 doesn't have this problem because the fix to 4858033 assures us
// the the vep is aligned at CodeEntryAlignment whereas c2 only aligns
// the uep and the vep doesn't get real alignment but just slops on by
// only assured that the entry instruction meets the 5 byte size requirement.
#ifdef COMPILER2
define_pd_global(intx, CodeEntryAlignment, 64);
#else
define_pd_global(intx, CodeEntryAlignment, 16);
#endif // COMPILER2
define_pd_global(intx, OptoLoopAlignment, 16);
define_pd_global(intx, InlineFrequencyCount, 100);
define_pd_global(intx, StackYellowPages, 2);
define_pd_global(intx, StackRedPages, 1);
define_pd_global(intx, StackShadowPages, 4 DEBUG_ONLY(+5));
define_pd_global(intx, PreInflateSpin, 10);
define_pd_global(bool, RewriteBytecodes, true);
define_pd_global(bool, RewriteFrequentPairs, false);
define_pd_global(bool, UseMembar, true);
// 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, 111);
// avoid biased locking while we are bootstrapping the aarch64 build
define_pd_global(bool, UseBiasedLocking, false);
#if defined(COMPILER1) || defined(COMPILER2)
define_pd_global(intx, InlineSmallCode, 1000);
#endif
#ifdef BUILTIN_SIM
#define UseBuiltinSim true
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
\
product(bool, NotifySimulator, UseBuiltinSim, \
"tell the AArch64 sim where we are in method code") \
\
product(bool, UseSimulatorCache, false, \
"tell sim to cache memory updates until exclusive op occurs") \
\
product(bool, DisableBCCheck, true, \
"tell sim not to invoke bccheck callback") \
\
product(bool, NearCpool, true, \
"constant pool is close to instructions") \
\
notproduct(bool, UseAcqRelForVolatileFields, false, \
"Use acquire and release insns for volatile fields") \
\
product(bool, UseCRC32, false, \
"Use CRC32 instructions for CRC32 computation") \
// Don't attempt to use Neon on builtin sim until builtin sim supports it
#define UseCRC32 false
#else
#define UseBuiltinSim false
#define NotifySimulator false
#define UseSimulatorCache false
#define DisableBCCheck true
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
\
product(bool, NearCpool, true, \
"constant pool is close to instructions") \
\
notproduct(bool, UseAcqRelForVolatileFields, false, \
"Use acquire and release insns for volatile fields") \
product(bool, UseNeon, false, \
"Use Neon for CRC32 computation") \
product(bool, UseCRC32, false, \
"Use CRC32 instructions for CRC32 computation") \
product(bool, TraceTraps, false, "Trace all traps the signal handler")
#endif
#endif // CPU_AARCH64_VM_GLOBALS_AARCH64_HPP

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "code/icBuffer.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "interpreter/bytecodes.hpp"
#include "memory/resourceArea.hpp"
#include "nativeInst_aarch64.hpp"
#include "oops/oop.inline.hpp"
int InlineCacheBuffer::ic_stub_code_size() {
return (MacroAssembler::far_branches() ? 6 : 4) * NativeInstruction::instruction_size;
}
#define __ masm->
void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin, void* cached_value, address entry_point) {
ResourceMark rm;
CodeBuffer code(code_begin, ic_stub_code_size());
MacroAssembler* masm = new MacroAssembler(&code);
// note: even though the code contains an embedded value, we do not need reloc info
// because
// (1) the value is old (i.e., doesn't matter for scavenges)
// (2) these ICStubs are removed *before* a GC happens, so the roots disappear
// assert(cached_value == NULL || cached_oop->is_perm(), "must be perm oop");
address start = __ pc();
Label l;
__ ldr(rscratch2, l);
__ far_jump(ExternalAddress(entry_point));
__ align(wordSize);
__ bind(l);
__ emit_int64((int64_t)cached_value);
// Only need to invalidate the 1st two instructions - not the whole ic stub
ICache::invalidate_range(code_begin, InlineCacheBuffer::ic_stub_code_size());
assert(__ pc() - start == ic_stub_code_size(), "must be");
}
address InlineCacheBuffer::ic_buffer_entry_point(address code_begin) {
NativeMovConstReg* move = nativeMovConstReg_at(code_begin); // creation also verifies the object
NativeJump* jump = nativeJump_at(code_begin + 4);
return jump->jump_destination();
}
void* InlineCacheBuffer::ic_buffer_cached_value(address code_begin) {
// The word containing the cached value is at the end of this IC buffer
uintptr_t *p = (uintptr_t *)(code_begin + ic_stub_code_size() - wordSize);
void* o = (void*)*p;
return o;
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "runtime/icache.hpp"
extern void aarch64TestHook();
void ICacheStubGenerator::generate_icache_flush(
ICache::flush_icache_stub_t* flush_icache_stub) {
// Give anyone who calls this a surprise
*flush_icache_stub = (ICache::flush_icache_stub_t)NULL;
}
void ICache::initialize() {
aarch64TestHook();
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_ICACHE_AARCH64_HPP
#define CPU_AARCH64_VM_ICACHE_AARCH64_HPP
// Interface for updating the instruction cache. Whenever the VM
// modifies code, part of the processor instruction cache potentially
// has to be flushed.
class ICache : public AbstractICache {
public:
static void initialize();
static void invalidate_word(address addr) {
__clear_cache((char *)addr, (char *)(addr + 3));
}
static void invalidate_range(address start, int nbytes) {
__clear_cache((char *)start, (char *)(start + nbytes));
}
};
#endif // CPU_AARCH64_VM_ICACHE_AARCH64_HPP

View File

@ -0,0 +1,315 @@
/*
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include <stdlib.h>
#include "decode_aarch64.hpp"
#include "immediate_aarch64.hpp"
// there are at most 2^13 possible logical immediate encodings
// however, some combinations of immr and imms are invalid
static const unsigned LI_TABLE_SIZE = (1 << 13);
static int li_table_entry_count;
// for forward lookup we just use a direct array lookup
// and assume that the cient has supplied a valid encoding
// table[encoding] = immediate
static u_int64_t LITable[LI_TABLE_SIZE];
// for reverse lookup we need a sparse map so we store a table of
// immediate and encoding pairs sorted by immediate value
struct li_pair {
u_int64_t immediate;
u_int32_t encoding;
};
static struct li_pair InverseLITable[LI_TABLE_SIZE];
// comparator to sort entries in the inverse table
int compare_immediate_pair(const void *i1, const void *i2)
{
struct li_pair *li1 = (struct li_pair *)i1;
struct li_pair *li2 = (struct li_pair *)i2;
if (li1->immediate < li2->immediate) {
return -1;
}
if (li1->immediate > li2->immediate) {
return 1;
}
return 0;
}
// helper functions used by expandLogicalImmediate
// for i = 1, ... N result<i-1> = 1 other bits are zero
static inline u_int64_t ones(int N)
{
return (N == 64 ? (u_int64_t)-1UL : ((1UL << N) - 1));
}
// result<0> to val<N>
static inline u_int64_t pickbit(u_int64_t val, int N)
{
return pickbits64(val, N, N);
}
// SPEC bits(M*N) Replicate(bits(M) x, integer N);
// this is just an educated guess
u_int64_t replicate(u_int64_t bits, int nbits, int count)
{
u_int64_t result = 0;
// nbits may be 64 in which case we want mask to be -1
u_int64_t mask = ones(nbits);
for (int i = 0; i < count ; i++) {
result <<= nbits;
result |= (bits & mask);
}
return result;
}
// this function writes the supplied bimm reference and returns a
// boolean to indicate success (1) or fail (0) because an illegal
// encoding must be treated as an UNALLOC instruction
// construct a 32 bit immediate value for a logical immediate operation
int expandLogicalImmediate(u_int32_t immN, u_int32_t immr,
u_int32_t imms, u_int64_t &bimm)
{
int len; // ought to be <= 6
u_int32_t levels; // 6 bits
u_int32_t tmask_and; // 6 bits
u_int32_t wmask_and; // 6 bits
u_int32_t tmask_or; // 6 bits
u_int32_t wmask_or; // 6 bits
u_int64_t imm64; // 64 bits
u_int64_t tmask, wmask; // 64 bits
u_int32_t S, R, diff; // 6 bits?
if (immN == 1) {
len = 6; // looks like 7 given the spec above but this cannot be!
} else {
len = 0;
u_int32_t val = (~imms & 0x3f);
for (int i = 5; i > 0; i--) {
if (val & (1 << i)) {
len = i;
break;
}
}
if (len < 1) {
return 0;
}
// for valid inputs leading 1s in immr must be less than leading
// zeros in imms
int len2 = 0; // ought to be < len
u_int32_t val2 = (~immr & 0x3f);
for (int i = 5; i > 0; i--) {
if (!(val2 & (1 << i))) {
len2 = i;
break;
}
}
if (len2 >= len) {
return 0;
}
}
levels = (1 << len) - 1;
if ((imms & levels) == levels) {
return 0;
}
S = imms & levels;
R = immr & levels;
// 6 bit arithmetic!
diff = S - R;
tmask_and = (diff | ~levels) & 0x3f;
tmask_or = (diff & levels) & 0x3f;
tmask = 0xffffffffffffffffULL;
for (int i = 0; i < 6; i++) {
int nbits = 1 << i;
u_int64_t and_bit = pickbit(tmask_and, i);
u_int64_t or_bit = pickbit(tmask_or, i);
u_int64_t and_bits_sub = replicate(and_bit, 1, nbits);
u_int64_t or_bits_sub = replicate(or_bit, 1, nbits);
u_int64_t and_bits_top = (and_bits_sub << nbits) | ones(nbits);
u_int64_t or_bits_top = (0 << nbits) | or_bits_sub;
tmask = ((tmask
& (replicate(and_bits_top, 2 * nbits, 32 / nbits)))
| replicate(or_bits_top, 2 * nbits, 32 / nbits));
}
wmask_and = (immr | ~levels) & 0x3f;
wmask_or = (immr & levels) & 0x3f;
wmask = 0;
for (int i = 0; i < 6; i++) {
int nbits = 1 << i;
u_int64_t and_bit = pickbit(wmask_and, i);
u_int64_t or_bit = pickbit(wmask_or, i);
u_int64_t and_bits_sub = replicate(and_bit, 1, nbits);
u_int64_t or_bits_sub = replicate(or_bit, 1, nbits);
u_int64_t and_bits_top = (ones(nbits) << nbits) | and_bits_sub;
u_int64_t or_bits_top = (or_bits_sub << nbits) | 0;
wmask = ((wmask
& (replicate(and_bits_top, 2 * nbits, 32 / nbits)))
| replicate(or_bits_top, 2 * nbits, 32 / nbits));
}
if (diff & (1U << 6)) {
imm64 = tmask & wmask;
} else {
imm64 = tmask | wmask;
}
bimm = imm64;
return 1;
}
// constructor to initialise the lookup tables
static void initLITables() __attribute__ ((constructor));
static void initLITables()
{
li_table_entry_count = 0;
for (unsigned index = 0; index < LI_TABLE_SIZE; index++) {
u_int32_t N = uimm(index, 12, 12);
u_int32_t immr = uimm(index, 11, 6);
u_int32_t imms = uimm(index, 5, 0);
if (expandLogicalImmediate(N, immr, imms, LITable[index])) {
InverseLITable[li_table_entry_count].immediate = LITable[index];
InverseLITable[li_table_entry_count].encoding = index;
li_table_entry_count++;
}
}
// now sort the inverse table
qsort(InverseLITable, li_table_entry_count,
sizeof(InverseLITable[0]), compare_immediate_pair);
}
// public APIs provided for logical immediate lookup and reverse lookup
u_int64_t logical_immediate_for_encoding(u_int32_t encoding)
{
return LITable[encoding];
}
u_int32_t encoding_for_logical_immediate(u_int64_t immediate)
{
struct li_pair pair;
struct li_pair *result;
pair.immediate = immediate;
result = (struct li_pair *)
bsearch(&pair, InverseLITable, li_table_entry_count,
sizeof(InverseLITable[0]), compare_immediate_pair);
if (result) {
return result->encoding;
}
return 0xffffffff;
}
// floating point immediates are encoded in 8 bits
// fpimm[7] = sign bit
// fpimm[6:4] = signed exponent
// fpimm[3:0] = fraction (assuming leading 1)
// i.e. F = s * 1.f * 2^(e - b)
u_int64_t fp_immediate_for_encoding(u_int32_t imm8, int is_dp)
{
union {
float fpval;
double dpval;
u_int64_t val;
};
u_int32_t s, e, f;
s = (imm8 >> 7 ) & 0x1;
e = (imm8 >> 4) & 0x7;
f = imm8 & 0xf;
// the fp value is s * n/16 * 2r where n is 16+e
fpval = (16.0 + f) / 16.0;
// n.b. exponent is signed
if (e < 4) {
int epos = e;
for (int i = 0; i <= epos; i++) {
fpval *= 2.0;
}
} else {
int eneg = 7 - e;
for (int i = 0; i < eneg; i++) {
fpval /= 2.0;
}
}
if (s) {
fpval = -fpval;
}
if (is_dp) {
dpval = (double)fpval;
}
return val;
}
u_int32_t encoding_for_fp_immediate(float immediate)
{
// given a float which is of the form
//
// s * n/16 * 2r
//
// where n is 16+f and imm1:s, imm4:f, simm3:r
// return the imm8 result [s:r:f]
//
union {
float fpval;
u_int32_t val;
};
fpval = immediate;
u_int32_t s, r, f, res;
// sign bit is 31
s = (val >> 31) & 0x1;
// exponent is bits 30-23 but we only want the bottom 3 bits
// strictly we ought to check that the bits bits 30-25 are
// either all 1s or all 0s
r = (val >> 23) & 0x7;
// fraction is bits 22-0
f = (val >> 19) & 0xf;
res = (s << 7) | (r << 4) | f;
return res;
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef _IMMEDIATE_H
#define _IMMEDIATE_H
#include <sys/types.h>
/*
* functions to map backwards and forwards between logical or floating
* point immediates and their corresponding encodings. the mapping
* from encoding to immediate is required by the simulator. the reverse
* mapping is required by the OpenJDK assembler.
*
* a logical immediate value supplied to or returned from a map lookup
* is always 64 bits. this is sufficient for looking up 32 bit
* immediates or their encodings since a 32 bit immediate has the same
* encoding as the 64 bit immediate produced by concatenating the
* immediate with itself.
*
* a logical immediate encoding is 13 bits N:immr:imms (3 fields of
* widths 1:6:6 -- see the arm spec). they appear as bits [22:10] of a
* logical immediate instruction. encodings are supplied and returned
* as 32 bit values. if a given 13 bit immediate has no corresponding
* encoding then a map lookup will return 0xffffffff.
*/
u_int64_t logical_immediate_for_encoding(u_int32_t encoding);
u_int32_t encoding_for_logical_immediate(u_int64_t immediate);
u_int64_t fp_immediate_for_encoding(u_int32_t imm8, int is_dp);
u_int32_t encoding_for_fp_immediate(float immediate);
#endif // _IMMEDIATE_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,292 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_INTERP_MASM_AARCH64_64_HPP
#define CPU_AARCH64_VM_INTERP_MASM_AARCH64_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:
protected:
// Interpreter specific version of call_VM_base
virtual void call_VM_leaf_base(address entry_point,
int number_of_arguments);
virtual void call_VM_base(Register oop_result,
Register java_thread,
Register last_java_sp,
address entry_point,
int number_of_arguments,
bool check_exceptions);
virtual void check_and_handle_popframe(Register java_thread);
virtual void check_and_handle_earlyret(Register java_thread);
// base routine for all dispatches
void dispatch_base(TosState state, address* table, bool verifyoop = true);
#endif // CC_INTERP
public:
InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {}
void load_earlyret_value(TosState state);
#ifdef CC_INTERP
void save_bcp() { /* not needed in c++ interpreter and harmless */ }
void restore_bcp() { /* not needed in c++ interpreter and harmless */ }
// Helpers for runtime call arguments/results
void get_method(Register reg);
#else
// Interpreter-specific registers
void save_bcp() {
str(rbcp, Address(rfp, frame::interpreter_frame_bcp_offset * wordSize));
}
void restore_bcp() {
ldr(rbcp, Address(rfp, frame::interpreter_frame_bcp_offset * wordSize));
}
void restore_locals() {
ldr(rlocals, Address(rfp, frame::interpreter_frame_locals_offset * wordSize));
}
void restore_constant_pool_cache() {
ldr(rcpool, Address(rfp, frame::interpreter_frame_cache_offset * wordSize));
}
void get_dispatch();
// Helpers for runtime call arguments/results
// Helpers for runtime call arguments/results
void get_method(Register reg) {
ldr(reg, Address(rfp, frame::interpreter_frame_method_offset * wordSize));
}
void get_const(Register reg) {
get_method(reg);
ldr(reg, Address(reg, in_bytes(Method::const_offset())));
}
void get_constant_pool(Register reg) {
get_const(reg);
ldr(reg, Address(reg, in_bytes(ConstMethod::constants_offset())));
}
void get_constant_pool_cache(Register reg) {
get_constant_pool(reg);
ldr(reg, Address(reg, ConstantPool::cache_offset_in_bytes()));
}
void get_cpool_and_tags(Register cpool, Register tags) {
get_constant_pool(cpool);
ldr(tags, Address(cpool, ConstantPool::tags_offset_in_bytes()));
}
void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset);
void get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2));
void get_method_counters(Register method, Register mcs, Label& skip);
// load cpool->resolved_references(index);
void load_resolved_reference_at_index(Register result, Register index);
void pop_ptr(Register r = r0);
void pop_i(Register r = r0);
void pop_l(Register r = r0);
void pop_f(FloatRegister r = v0);
void pop_d(FloatRegister r = v0);
void push_ptr(Register r = r0);
void push_i(Register r = r0);
void push_l(Register r = r0);
void push_f(FloatRegister r = v0);
void push_d(FloatRegister r = v0);
void pop(Register r ) { ((MacroAssembler*)this)->pop(r); }
void push(Register r ) { ((MacroAssembler*)this)->push(r); }
void pop(TosState state); // transition vtos -> state
void push(TosState state); // transition state -> vtos
void pop(RegSet regs, Register stack) { ((MacroAssembler*)this)->pop(regs, stack); }
void push(RegSet regs, Register stack) { ((MacroAssembler*)this)->push(regs, stack); }
void empty_expression_stack() {
ldr(esp, Address(rfp, frame::interpreter_frame_monitor_block_top_offset * wordSize));
// NULL last_sp until next java call
str(zr, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
}
// Helpers for swap and dup
void load_ptr(int n, Register val);
void store_ptr(int n, Register val);
// Generate a subtype check: branch to ok_is_subtype if sub_klass is
// a subtype of super_klass.
void gen_subtype_check( Register sub_klass, Label &ok_is_subtype );
// Dispatching
void dispatch_prolog(TosState state, int step = 0);
void dispatch_epilog(TosState state, int step = 0);
// dispatch via rscratch1
void dispatch_only(TosState state);
// dispatch normal table via rscratch1 (assume rscratch1 is loaded already)
void dispatch_only_normal(TosState state);
void dispatch_only_noverify(TosState state);
// load rscratch1 from [rbcp + step] and dispatch via rscratch1
void dispatch_next(TosState state, int step = 0);
// load rscratch1 from [esi] and dispatch via rscratch1 and table
void dispatch_via (TosState state, address* table);
// jump to an invoked target
void prepare_to_jump_from_interpreted();
void jump_from_interpreted(Register method, Register temp);
// Returning from interpreted functions
//
// Removes the current activation (incl. unlocking of monitors)
// and sets up the return address. This code is also used for
// exception unwindwing. In that case, we do not want to throw
// IllegalMonitorStateExceptions, since that might get us into an
// infinite rethrow exception loop.
// Additionally this code is used for popFrame and earlyReturn.
// In popFrame case we want to skip throwing an exception,
// installing an exception, and notifying jvmdi.
// In earlyReturn case we only want to skip throwing an exception
// and installing an exception.
void remove_activation(TosState state,
bool throw_monitor_exception = true,
bool install_monitor_exception = true,
bool notify_jvmdi = true);
#endif // CC_INTERP
// FIXME: Give us a valid frame at a null check.
virtual void null_check(Register reg, int offset = -1) {
// #ifdef ASSERT
// save_bcp();
// set_last_Java_frame(esp, rfp, (address) pc());
// #endif
MacroAssembler::null_check(reg, offset);
// #ifdef ASSERT
// reset_last_Java_frame(true, false);
// #endif
}
// Object locking
void lock_object (Register lock_reg);
void unlock_object(Register lock_reg);
#ifndef CC_INTERP
// Interpreter profiling operations
void set_method_data_pointer_for_bcp();
void test_method_data_pointer(Register mdp, Label& zero_continue);
void verify_method_data_pointer();
void set_mdp_data_at(Register mdp_in, int constant, Register value);
void increment_mdp_data_at(Address data, bool decrement = false);
void increment_mdp_data_at(Register mdp_in, int constant,
bool decrement = false);
void increment_mdp_data_at(Register mdp_in, Register reg, int constant,
bool decrement = false);
void increment_mask_and_jump(Address counter_addr,
int increment, Address mask,
Register scratch, Register scratch2,
bool preloaded, Condition cond,
Label* where);
void set_mdp_flag_at(Register mdp_in, int flag_constant);
void test_mdp_data_at(Register mdp_in, int offset, Register value,
Register test_value_out,
Label& not_equal_continue);
void record_klass_in_profile(Register receiver, Register mdp,
Register reg2, bool is_virtual_call);
void record_klass_in_profile_helper(Register receiver, Register mdp,
Register reg2, int start_row,
Label& done, bool is_virtual_call);
void update_mdp_by_offset(Register mdp_in, int offset_of_offset);
void update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp);
void update_mdp_by_constant(Register mdp_in, int constant);
void update_mdp_for_ret(Register return_bci);
void profile_taken_branch(Register mdp, Register bumped_count);
void profile_not_taken_branch(Register mdp);
void profile_call(Register mdp);
void profile_final_call(Register mdp);
void profile_virtual_call(Register receiver, Register mdp,
Register scratch2,
bool receiver_can_be_null = false);
void profile_ret(Register return_bci, Register mdp);
void profile_null_seen(Register mdp);
void profile_typecheck(Register mdp, Register klass, Register scratch);
void profile_typecheck_failed(Register mdp);
void profile_switch_default(Register mdp);
void profile_switch_case(Register index_in_scratch, Register mdp,
Register scratch2);
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);
// Debugging
// only if +VerifyOops && state == atos
void verify_oop(Register reg, TosState state = atos);
// only if +VerifyFPU && (state == ftos || state == dtos)
void verify_FPU(int stack_depth, TosState state = ftos);
#endif // !CC_INTERP
typedef enum { NotifyJVMTI, SkipNotifyJVMTI } NotifyMethodExitMode;
// support for jvmti/dtrace
void notify_method_entry();
void notify_method_exit(TosState state, NotifyMethodExitMode mode);
virtual void _call_Unimplemented(address call_site) {
save_bcp();
set_last_Java_frame(esp, rfp, (address) pc(), rscratch1);
MacroAssembler::_call_Unimplemented(call_site);
}
};
#endif // CPU_AARCH64_VM_INTERP_MASM_AARCH64_64_HPP

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_INTERPRETERGENERATOR_AARCH64_HPP
#define CPU_AARCH64_VM_INTERPRETERGENERATOR_AARCH64_HPP
// Generation of Interpreter
//
friend class AbstractInterpreterGenerator;
protected:
void bang_stack_shadow_pages(bool native_call);
private:
address generate_normal_entry(bool synchronized);
address generate_native_entry(bool synchronized);
address generate_abstract_entry(void);
address generate_math_entry(AbstractInterpreter::MethodKind kind);
address generate_jump_to_normal_entry(void);
address generate_accessor_entry(void) { return generate_jump_to_normal_entry(); }
address generate_empty_entry(void) { return generate_jump_to_normal_entry(); }
void generate_transcendental_entry(AbstractInterpreter::MethodKind kind, int fpargs);
address generate_Reference_get_entry();
address generate_CRC32_update_entry();
address generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind);
void lock_method(void);
void generate_stack_overflow_check(void);
void generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue);
void generate_counter_overflow(Label* do_continue);
#endif // CPU_AARCH64_VM_INTERPRETERGENERATOR_AARCH64_HPP

View File

@ -0,0 +1,428 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/universe.inline.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/icache.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/signature.hpp"
#define __ _masm->
// Implementation of SignatureHandlerGenerator
Register InterpreterRuntime::SignatureHandlerGenerator::from() { return rlocals; }
Register InterpreterRuntime::SignatureHandlerGenerator::to() { return sp; }
Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }
void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
switch (_num_int_args) {
case 0:
__ ldr(c_rarg1, src);
_num_int_args++;
break;
case 1:
__ ldr(c_rarg2, src);
_num_int_args++;
break;
case 2:
__ ldr(c_rarg3, src);
_num_int_args++;
break;
case 3:
__ ldr(c_rarg4, src);
_num_int_args++;
break;
case 4:
__ ldr(c_rarg5, src);
_num_int_args++;
break;
case 5:
__ ldr(c_rarg6, src);
_num_int_args++;
break;
case 6:
__ ldr(c_rarg7, src);
_num_int_args++;
break;
default:
__ ldr(r0, src);
__ str(r0, Address(to(), _stack_offset));
_stack_offset += wordSize;
_num_int_args++;
break;
}
}
void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
switch (_num_int_args) {
case 0:
__ ldr(c_rarg1, src);
_num_int_args++;
break;
case 1:
__ ldr(c_rarg2, src);
_num_int_args++;
break;
case 2:
__ ldr(c_rarg3, src);
_num_int_args++;
break;
case 3:
__ ldr(c_rarg4, src);
_num_int_args++;
break;
case 4:
__ ldr(c_rarg5, src);
_num_int_args++;
break;
case 5:
__ ldr(c_rarg6, src);
_num_int_args++;
break;
case 6:
__ ldr(c_rarg7, src);
_num_int_args++;
break;
default:
__ ldr(r0, src);
__ str(r0, Address(to(), _stack_offset));
_stack_offset += wordSize;
_num_int_args++;
break;
}
}
void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
if (_num_fp_args < Argument::n_float_register_parameters_c) {
__ ldrs(as_FloatRegister(_num_fp_args++), src);
} else {
__ ldrh(r0, src);
__ strh(r0, Address(to(), _stack_offset));
_stack_offset += wordSize;
_num_fp_args++;
}
}
void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
if (_num_fp_args < Argument::n_float_register_parameters_c) {
__ ldrd(as_FloatRegister(_num_fp_args++), src);
} else {
__ ldr(r0, src);
__ str(r0, Address(to(), _stack_offset));
_stack_offset += wordSize;
_num_fp_args++;
}
}
void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
switch (_num_int_args) {
case 0:
assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
__ add(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset()));
_num_int_args++;
break;
case 1:
{
__ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
__ mov(c_rarg2, 0);
__ ldr(temp(), r0);
Label L;
__ cbz(temp(), L);
__ mov(c_rarg2, r0);
__ bind(L);
_num_int_args++;
break;
}
case 2:
{
__ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
__ mov(c_rarg3, 0);
__ ldr(temp(), r0);
Label L;
__ cbz(temp(), L);
__ mov(c_rarg3, r0);
__ bind(L);
_num_int_args++;
break;
}
case 3:
{
__ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
__ mov(c_rarg4, 0);
__ ldr(temp(), r0);
Label L;
__ cbz(temp(), L);
__ mov(c_rarg4, r0);
__ bind(L);
_num_int_args++;
break;
}
case 4:
{
__ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
__ mov(c_rarg5, 0);
__ ldr(temp(), r0);
Label L;
__ cbz(temp(), L);
__ mov(c_rarg5, r0);
__ bind(L);
_num_int_args++;
break;
}
case 5:
{
__ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
__ mov(c_rarg6, 0);
__ ldr(temp(), r0);
Label L;
__ cbz(temp(), L);
__ mov(c_rarg6, r0);
__ bind(L);
_num_int_args++;
break;
}
case 6:
{
__ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
__ mov(c_rarg7, 0);
__ ldr(temp(), r0);
Label L;
__ cbz(temp(), L);
__ mov(c_rarg7, r0);
__ bind(L);
_num_int_args++;
break;
}
default:
{
__ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
__ ldr(temp(), r0);
Label L;
__ cbnz(temp(), L);
__ mov(r0, zr);
__ bind(L);
__ str(r0, Address(to(), _stack_offset));
_stack_offset += wordSize;
_num_int_args++;
break;
}
}
}
void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
// generate code to handle arguments
iterate(fingerprint);
// set the call format
// n.b. allow extra 1 for the JNI_Env in c_rarg0
unsigned int call_format = ((_num_int_args + 1) << 6) | (_num_fp_args << 2);
switch (method()->result_type()) {
case T_VOID:
call_format |= MacroAssembler::ret_type_void;
break;
case T_FLOAT:
call_format |= MacroAssembler::ret_type_float;
break;
case T_DOUBLE:
call_format |= MacroAssembler::ret_type_double;
break;
default:
call_format |= MacroAssembler::ret_type_integral;
break;
}
// // store the call format in the method
// __ movw(r0, call_format);
// __ str(r0, Address(rmethod, Method::call_format_offset()));
// return result handler
__ lea(r0, ExternalAddress(Interpreter::result_handler(method()->result_type())));
__ ret(lr);
__ flush();
}
// Implementation of SignatureHandlerLibrary
void SignatureHandlerLibrary::pd_set_handler(address handler) {}
class SlowSignatureHandler
: public NativeSignatureIterator {
private:
address _from;
intptr_t* _to;
intptr_t* _int_args;
intptr_t* _fp_args;
intptr_t* _fp_identifiers;
unsigned int _num_int_args;
unsigned int _num_fp_args;
virtual void pass_int()
{
jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
_from -= Interpreter::stackElementSize;
if (_num_int_args < Argument::n_int_register_parameters_c-1) {
*_int_args++ = from_obj;
_num_int_args++;
} else {
*_to++ = from_obj;
_num_int_args++;
}
}
virtual void pass_long()
{
intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
_from -= 2*Interpreter::stackElementSize;
if (_num_int_args < Argument::n_int_register_parameters_c-1) {
*_int_args++ = from_obj;
_num_int_args++;
} else {
*_to++ = from_obj;
_num_int_args++;
}
}
virtual void pass_object()
{
intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
_from -= Interpreter::stackElementSize;
if (_num_int_args < Argument::n_int_register_parameters_c-1) {
*_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr;
_num_int_args++;
} else {
*_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
_num_int_args++;
}
}
virtual void pass_float()
{
jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0));
_from -= Interpreter::stackElementSize;
if (_num_fp_args < Argument::n_float_register_parameters_c) {
*_fp_args++ = from_obj;
_num_fp_args++;
} else {
*_to++ = from_obj;
_num_int_args++;
}
}
virtual void pass_double()
{
intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
_from -= 2*Interpreter::stackElementSize;
if (_num_fp_args < Argument::n_float_register_parameters_c) {
*_fp_args++ = from_obj;
*_fp_identifiers |= (1 << _num_fp_args); // mark as double
_num_fp_args++;
} else {
*_to++ = from_obj;
_num_int_args++;
}
}
public:
SlowSignatureHandler(methodHandle method, address from, intptr_t* to)
: NativeSignatureIterator(method)
{
_from = from;
_to = to;
_int_args = to - (method->is_static() ? 16 : 17);
_fp_args = to - 8;
_fp_identifiers = to - 9;
*(int*) _fp_identifiers = 0;
_num_int_args = (method->is_static() ? 1 : 0);
_num_fp_args = 0;
}
// n.b. allow extra 1 for the JNI_Env in c_rarg0
unsigned int get_call_format()
{
unsigned int call_format = ((_num_int_args + 1) << 6) | (_num_fp_args << 2);
switch (method()->result_type()) {
case T_VOID:
call_format |= MacroAssembler::ret_type_void;
break;
case T_FLOAT:
call_format |= MacroAssembler::ret_type_float;
break;
case T_DOUBLE:
call_format |= MacroAssembler::ret_type_double;
break;
default:
call_format |= MacroAssembler::ret_type_integral;
break;
}
return call_format;
}
};
IRT_ENTRY(address,
InterpreterRuntime::slow_signature_handler(JavaThread* thread,
Method* method,
intptr_t* from,
intptr_t* to))
methodHandle m(thread, (Method*)method);
assert(m->is_native(), "sanity check");
// handle arguments
SlowSignatureHandler ssh(m, (address)from, to);
ssh.iterate(UCONST64(-1));
// // set the call format
// method->set_call_format(ssh.get_call_format());
// return result handler
return Interpreter::result_handler(m->result_type());
IRT_END

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_INTERPRETERRT_AARCH64_HPP
#define CPU_AARCH64_VM_INTERPRETERRT_AARCH64_HPP
#include "asm/macroAssembler.hpp"
#include "memory/allocation.hpp"
// native method calls
class SignatureHandlerGenerator: public NativeSignatureIterator {
private:
MacroAssembler* _masm;
unsigned int _call_format;
unsigned int _num_fp_args;
unsigned int _num_int_args;
int _stack_offset;
void pass_int();
void pass_long();
void pass_float();
void pass_double();
void pass_object();
public:
// Creation
SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
_masm = new MacroAssembler(buffer);
_num_int_args = (method->is_static() ? 1 : 0);
_num_fp_args = 0;
_stack_offset = 0;
}
// Code generation
void generate(uint64_t fingerprint);
// Code generation support
static Register from();
static Register to();
static Register temp();
};
#endif // CPU_AARCH64_VM_INTERPRETERRT_AARCH64_HPP

View File

@ -0,0 +1,289 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "interpreter/bytecodeHistogram.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterGenerator.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "interpreter/interp_masm.hpp"
#include "interpreter/templateTable.hpp"
#include "oops/arrayOop.hpp"
#include "oops/methodData.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/arguments.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/synchronizer.hpp"
#include "runtime/timer.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/debug.hpp"
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
#endif
#define __ _masm->
address AbstractInterpreterGenerator::generate_slow_signature_handler() {
address entry = __ pc();
__ andr(esp, esp, -16);
__ mov(c_rarg3, esp);
// rmethod
// rlocals
// c_rarg3: first stack arg - wordSize
// adjust sp
__ sub(sp, c_rarg3, 18 * wordSize);
__ str(lr, Address(__ pre(sp, -2 * wordSize)));
__ call_VM(noreg,
CAST_FROM_FN_PTR(address,
InterpreterRuntime::slow_signature_handler),
rmethod, rlocals, c_rarg3);
// r0: result handler
// Stack layout:
// rsp: return address <- sp
// 1 garbage
// 8 integer args (if static first is unused)
// 1 float/double identifiers
// 8 double args
// stack args <- esp
// garbage
// expression stack bottom
// bcp (NULL)
// ...
// Restore LR
__ ldr(lr, Address(__ post(sp, 2 * wordSize)));
// Do FP first so we can use c_rarg3 as temp
__ ldrw(c_rarg3, Address(sp, 9 * wordSize)); // float/double identifiers
for (int i = 0; i < Argument::n_float_register_parameters_c; i++) {
const FloatRegister r = as_FloatRegister(i);
Label d, done;
__ tbnz(c_rarg3, i, d);
__ ldrs(r, Address(sp, (10 + i) * wordSize));
__ b(done);
__ bind(d);
__ ldrd(r, Address(sp, (10 + i) * wordSize));
__ bind(done);
}
// c_rarg0 contains the result from the call of
// InterpreterRuntime::slow_signature_handler so we don't touch it
// here. It will be loaded with the JNIEnv* later.
__ ldr(c_rarg1, Address(sp, 1 * wordSize));
for (int i = c_rarg2->encoding(); i <= c_rarg7->encoding(); i += 2) {
Register rm = as_Register(i), rn = as_Register(i+1);
__ ldp(rm, rn, Address(sp, i * wordSize));
}
__ add(sp, sp, 18 * wordSize);
__ ret(lr);
return entry;
}
//
// Various method entries
//
address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
// rmethod: Method*
// r13: sender sp
// esp: args
if (!InlineIntrinsics) return NULL; // Generate a vanilla entry
// These don't need a safepoint check because they aren't virtually
// callable. We won't enter these intrinsics from compiled code.
// If in the future we added an intrinsic which was virtually callable
// we'd have to worry about how to safepoint so that this code is used.
// mathematical functions inlined by compiler
// (interpreter must provide identical implementation
// in order to avoid monotonicity bugs when switching
// from interpreter to compiler in the middle of some
// computation)
//
// stack:
// [ arg ] <-- esp
// [ arg ]
// retaddr in lr
address entry_point = NULL;
Register continuation = lr;
switch (kind) {
case Interpreter::java_lang_math_abs:
entry_point = __ pc();
__ ldrd(v0, Address(esp));
__ fabsd(v0, v0);
__ mov(sp, r13); // Restore caller's SP
break;
case Interpreter::java_lang_math_sqrt:
entry_point = __ pc();
__ ldrd(v0, Address(esp));
__ fsqrtd(v0, v0);
__ mov(sp, r13);
break;
case Interpreter::java_lang_math_sin :
case Interpreter::java_lang_math_cos :
case Interpreter::java_lang_math_tan :
case Interpreter::java_lang_math_log :
case Interpreter::java_lang_math_log10 :
case Interpreter::java_lang_math_exp :
entry_point = __ pc();
__ ldrd(v0, Address(esp));
__ mov(sp, r13);
__ mov(r19, lr);
continuation = r19; // The first callee-saved register
generate_transcendental_entry(kind, 1);
break;
case Interpreter::java_lang_math_pow :
entry_point = __ pc();
__ mov(r19, lr);
continuation = r19;
__ ldrd(v0, Address(esp, 2 * Interpreter::stackElementSize));
__ ldrd(v1, Address(esp));
__ mov(sp, r13);
generate_transcendental_entry(kind, 2);
break;
default:
;
}
if (entry_point) {
__ br(continuation);
}
return entry_point;
}
// double trigonometrics and transcendentals
// static jdouble dsin(jdouble x);
// static jdouble dcos(jdouble x);
// static jdouble dtan(jdouble x);
// static jdouble dlog(jdouble x);
// static jdouble dlog10(jdouble x);
// static jdouble dexp(jdouble x);
// static jdouble dpow(jdouble x, jdouble y);
void InterpreterGenerator::generate_transcendental_entry(AbstractInterpreter::MethodKind kind, int fpargs) {
address fn;
switch (kind) {
case Interpreter::java_lang_math_sin :
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);
break;
case Interpreter::java_lang_math_cos :
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);
break;
case Interpreter::java_lang_math_tan :
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);
break;
case Interpreter::java_lang_math_log :
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog);
break;
case Interpreter::java_lang_math_log10 :
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10);
break;
case Interpreter::java_lang_math_exp :
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dexp);
break;
case Interpreter::java_lang_math_pow :
fpargs = 2;
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dpow);
break;
default:
ShouldNotReachHere();
}
const int gpargs = 0, rtype = 3;
__ mov(rscratch1, fn);
__ blrt(rscratch1, gpargs, fpargs, rtype);
}
// Jump into normal path for accessor and empty entry to jump to normal entry
// The "fast" optimization don't update compilation count therefore can disable inlining
// for these functions that should be inlined.
address InterpreterGenerator::generate_jump_to_normal_entry(void) {
address entry_point = __ pc();
assert(Interpreter::entry_for_kind(Interpreter::zerolocals) != NULL, "should already be generated");
__ b(Interpreter::entry_for_kind(Interpreter::zerolocals));
return entry_point;
}
// Abstract method entry
// Attempt to execute abstract method. Throw exception
address InterpreterGenerator::generate_abstract_entry(void) {
// rmethod: Method*
// r13: sender SP
address entry_point = __ pc();
// abstract method entry
// pop return address, reset last_sp to NULL
__ empty_expression_stack();
__ restore_bcp(); // bcp must be correct for exception handler (was destroyed)
__ restore_locals(); // make sure locals pointer is correct as well (was destroyed)
// throw exception
__ call_VM(noreg, CAST_FROM_FN_PTR(address,
InterpreterRuntime::throw_AbstractMethodError));
// the call_VM checks for exception, so we should never return here.
__ should_not_reach_here();
return entry_point;
}
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
// the days we had adapter frames. When we deoptimize a situation where a
// compiled caller calls a compiled caller will have registers it expects
// to survive the call to the callee. If we deoptimize the callee the only
// way we can restore these registers is to have the oldest interpreter
// frame that we create restore these values. That is what this routine
// will accomplish.
// At the moment we have modified c2 to not have any callee save registers
// so this problem does not exist and this routine is just a place holder.
assert(f->is_interpreted_frame(), "must be interpreted");
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_INTERPRETER_AARCH64_HPP
#define CPU_AARCH64_VM_INTERPRETER_AARCH64_HPP
public:
// Offset from rsp (which points to the last stack element)
static int expr_offset_in_bytes(int i) { return stackElementSize * i; }
// Stack index relative to tos (which points at value)
static int expr_index_at(int i) { return stackElementWords * i; }
// Already negated by c++ interpreter
static int local_index_at(int i) {
assert(i <= 0, "local direction already negated");
return stackElementWords * i;
}
#endif // CPU_AARCH64_VM_INTERPRETER_AARCH64_HPP

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_JAVAFRAMEANCHOR_AARCH64_HPP
#define CPU_AARCH64_VM_JAVAFRAMEANCHOR_AARCH64_HPP
private:
// FP value associated with _last_Java_sp:
intptr_t* volatile _last_Java_fp; // pointer is volatile not what it points to
public:
// Each arch must define reset, save, restore
// These are used by objects that only care about:
// 1 - initializing a new state (thread creation, javaCalls)
// 2 - saving a current state (javaCalls)
// 3 - restoring an old state (javaCalls)
void clear(void) {
// clearing _last_Java_sp must be first
_last_Java_sp = NULL;
OrderAccess::release();
_last_Java_fp = NULL;
_last_Java_pc = NULL;
}
void copy(JavaFrameAnchor* src) {
// In order to make sure the transition state is valid for "this"
// We must clear _last_Java_sp before copying the rest of the new data
//
// Hack Alert: Temporary bugfix for 4717480/4721647
// To act like previous version (pd_cache_state) don't NULL _last_Java_sp
// unless the value is changing
//
if (_last_Java_sp != src->_last_Java_sp) {
_last_Java_sp = NULL;
OrderAccess::release();
}
_last_Java_fp = src->_last_Java_fp;
_last_Java_pc = src->_last_Java_pc;
// Must be last so profiler will always see valid frame if has_last_frame() is true
_last_Java_sp = src->_last_Java_sp;
}
// Always walkable
bool walkable(void) { return true; }
// Never any thing to do since we are always walkable and can find address of return addresses
void make_walkable(JavaThread* thread) { }
intptr_t* last_Java_sp(void) const { return _last_Java_sp; }
address last_Java_pc(void) { return _last_Java_pc; }
private:
static ByteSize last_Java_fp_offset() { return byte_offset_of(JavaFrameAnchor, _last_Java_fp); }
public:
void set_last_Java_sp(intptr_t* sp) { _last_Java_sp = sp; OrderAccess::release(); }
intptr_t* last_Java_fp(void) { return _last_Java_fp; }
// Assert (last_Java_sp == NULL || fp == NULL)
void set_last_Java_fp(intptr_t* fp) { OrderAccess::release(); _last_Java_fp = fp; }
#endif // CPU_AARCH64_VM_JAVAFRAMEANCHOR_AARCH64_HPP

View File

@ -0,0 +1,174 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "memory/resourceArea.hpp"
#include "prims/jniFastGetField.hpp"
#include "prims/jvm_misc.hpp"
#include "runtime/safepoint.hpp"
#define __ masm->
#define BUFFER_SIZE 30*wordSize
// Instead of issuing a LoadLoad barrier we create an address
// dependency between loads; this might be more efficient.
// Common register usage:
// r0/v0: result
// c_rarg0: jni env
// c_rarg1: obj
// c_rarg2: jfield id
static const Register robj = r3;
static const Register rcounter = r4;
static const Register roffset = r5;
static const Register rcounter_addr = r6;
static const Register result = r7;
address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
const char *name;
switch (type) {
case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
case T_BYTE: name = "jni_fast_GetByteField"; break;
case T_CHAR: name = "jni_fast_GetCharField"; break;
case T_SHORT: name = "jni_fast_GetShortField"; break;
case T_INT: name = "jni_fast_GetIntField"; break;
case T_LONG: name = "jni_fast_GetLongField"; break;
case T_FLOAT: name = "jni_fast_GetFloatField"; break;
case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;
default: ShouldNotReachHere();
}
ResourceMark rm;
BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
CodeBuffer cbuf(blob);
MacroAssembler* masm = new MacroAssembler(&cbuf);
address fast_entry = __ pc();
Label slow;
unsigned long offset;
__ adrp(rcounter_addr,
SafepointSynchronize::safepoint_counter_addr(), offset);
Address safepoint_counter_addr(rcounter_addr, offset);
__ ldrw(rcounter, safepoint_counter_addr);
__ andw(rscratch1, rcounter, 1);
__ cbnzw(rscratch1, slow);
__ eor(robj, c_rarg1, rcounter);
__ eor(robj, robj, rcounter); // obj, since
// robj ^ rcounter ^ rcounter == robj
// robj is address dependent on rcounter.
__ ldr(robj, Address(robj, 0)); // *obj
__ lsr(roffset, c_rarg2, 2); // offset
assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
speculative_load_pclist[count] = __ pc(); // Used by the segfault handler
switch (type) {
case T_BOOLEAN: __ ldrb (result, Address(robj, roffset)); break;
case T_BYTE: __ ldrsb (result, Address(robj, roffset)); break;
case T_CHAR: __ ldrh (result, Address(robj, roffset)); break;
case T_SHORT: __ ldrsh (result, Address(robj, roffset)); break;
case T_FLOAT: __ ldrw (result, Address(robj, roffset)); break;
case T_INT: __ ldrsw (result, Address(robj, roffset)); break;
case T_DOUBLE:
case T_LONG: __ ldr (result, Address(robj, roffset)); break;
default: ShouldNotReachHere();
}
// counter_addr is address dependent on result.
__ eor(rcounter_addr, rcounter_addr, result);
__ eor(rcounter_addr, rcounter_addr, result);
__ ldrw(rscratch1, safepoint_counter_addr);
__ cmpw(rcounter, rscratch1);
__ br (Assembler::NE, slow);
switch (type) {
case T_FLOAT: __ fmovs(v0, result); break;
case T_DOUBLE: __ fmovd(v0, result); break;
default: __ mov(r0, result); break;
}
__ ret(lr);
slowcase_entry_pclist[count++] = __ pc();
__ bind(slow);
address slow_case_addr;
switch (type) {
case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break;
case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break;
case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break;
case T_INT: slow_case_addr = jni_GetIntField_addr(); break;
case T_LONG: slow_case_addr = jni_GetLongField_addr(); break;
case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break;
case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;
default: ShouldNotReachHere();
}
{
__ enter();
__ lea(rscratch1, ExternalAddress(slow_case_addr));
__ blr(rscratch1);
__ maybe_isb();
__ leave();
__ ret(lr);
}
__ flush ();
return fast_entry;
}
address JNI_FastGetField::generate_fast_get_boolean_field() {
return generate_fast_get_int_field0(T_BOOLEAN);
}
address JNI_FastGetField::generate_fast_get_byte_field() {
return generate_fast_get_int_field0(T_BYTE);
}
address JNI_FastGetField::generate_fast_get_char_field() {
return generate_fast_get_int_field0(T_CHAR);
}
address JNI_FastGetField::generate_fast_get_short_field() {
return generate_fast_get_int_field0(T_SHORT);
}
address JNI_FastGetField::generate_fast_get_int_field() {
return generate_fast_get_int_field0(T_INT);
}
address JNI_FastGetField::generate_fast_get_long_field() {
return generate_fast_get_int_field0(T_LONG);
}
address JNI_FastGetField::generate_fast_get_float_field() {
return generate_fast_get_int_field0(T_FLOAT);
}
address JNI_FastGetField::generate_fast_get_double_field() {
return generate_fast_get_int_field0(T_DOUBLE);
}

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_VM_JNITYPES_AARCH64_HPP
#define CPU_AARCH64_VM_JNITYPES_AARCH64_HPP
#include "memory/allocation.hpp"
#include "oops/oop.hpp"
#include "prims/jni.h"
// This file holds platform-dependent routines used to write primitive jni
// types to the array of arguments passed into JavaCalls::call
class JNITypes : AllStatic {
// These functions write a java primitive type (in native format)
// to a java stack slot array to be passed as an argument to JavaCalls:calls.
// I.e., they are functionally 'push' operations if they have a 'pos'
// formal parameter. Note that jlong's and jdouble's are written
// _in reverse_ of the order in which they appear in the interpreter
// stack. This is because call stubs (see stubGenerator_sparc.cpp)
// reverse the argument list constructed by JavaCallArguments (see
// javaCalls.hpp).
public:
// Ints are stored in native format in one JavaCallArgument slot at *to.
static inline void put_int(jint from, intptr_t *to) { *(jint *)(to + 0 ) = from; }
static inline void put_int(jint from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = from; }
static inline void put_int(jint *from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = *from; }
// Longs are stored in native format in one JavaCallArgument slot at
// *(to+1).
static inline void put_long(jlong from, intptr_t *to) {
*(jlong*) (to + 1) = from;
}
static inline void put_long(jlong from, intptr_t *to, int& pos) {
*(jlong*) (to + 1 + pos) = from;
pos += 2;
}
static inline void put_long(jlong *from, intptr_t *to, int& pos) {
*(jlong*) (to + 1 + pos) = *from;
pos += 2;
}
// Oops are stored in native format in one JavaCallArgument slot at *to.
static inline void put_obj(oop from, intptr_t *to) { *(oop *)(to + 0 ) = from; }
static inline void put_obj(oop from, intptr_t *to, int& pos) { *(oop *)(to + pos++) = from; }
static inline void put_obj(oop *from, intptr_t *to, int& pos) { *(oop *)(to + pos++) = *from; }
// Floats are stored in native format in one JavaCallArgument slot at *to.
static inline void put_float(jfloat from, intptr_t *to) { *(jfloat *)(to + 0 ) = from; }
static inline void put_float(jfloat from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = from; }
static inline void put_float(jfloat *from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = *from; }
#undef _JNI_SLOT_OFFSET
#define _JNI_SLOT_OFFSET 1
// Doubles are stored in native word format in one JavaCallArgument
// slot at *(to+1).
static inline void put_double(jdouble from, intptr_t *to) {
*(jdouble*) (to + 1) = from;
}
static inline void put_double(jdouble from, intptr_t *to, int& pos) {
*(jdouble*) (to + 1 + pos) = from;
pos += 2;
}
static inline void put_double(jdouble *from, intptr_t *to, int& pos) {
*(jdouble*) (to + 1 + pos) = *from;
pos += 2;
}
// The get_xxx routines, on the other hand, actually _do_ fetch
// java primitive types from the interpreter stack.
// No need to worry about alignment on Intel.
static inline jint get_int (intptr_t *from) { return *(jint *) from; }
static inline jlong get_long (intptr_t *from) { return *(jlong *) (from + _JNI_SLOT_OFFSET); }
static inline oop get_obj (intptr_t *from) { return *(oop *) from; }
static inline jfloat get_float (intptr_t *from) { return *(jfloat *) from; }
static inline jdouble get_double(intptr_t *from) { return *(jdouble *)(from + _JNI_SLOT_OFFSET); }
#undef _JNI_SLOT_OFFSET
};
#endif // CPU_AARCH64_VM_JNITYPES_AARCH64_HPP

View File

@ -0,0 +1,60 @@
/*
* 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
#if defined(SOLARIS) || defined(LINUX) || defined(_ALLBSD_SOURCE)
// Note: please do not change these without also changing jni_md.h in the JDK
// repository
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif
#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
#define JNIEXPORT __attribute__((visibility("default")))
#define JNIIMPORT __attribute__((visibility("default")))
#else
#define JNIEXPORT
#define JNIIMPORT
#endif
#define JNICALL
typedef int jint;
typedef long jlong;
#else
#define JNIEXPORT __declspec(dllexport)
#define JNIIMPORT __declspec(dllimport)
#define JNICALL __stdcall
typedef int jint;
typedef __int64 jlong;
#endif
typedef signed char jbyte;
#endif /* !_JAVASOFT_JNI_MD_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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