Merge
This commit is contained in:
commit
095a2e5b05
@ -295,3 +295,4 @@ d91ed1951b948210590ce1394bea5515357246ba jdk9-b49
|
||||
d1f37d39ff2421f956a6ddf316cf763807bc3363 jdk9-b50
|
||||
6207b4b8731ca75c51b031c47daa813ab92ef558 jdk9-b51
|
||||
1822e59f17121b09e7899cf338cfb6e37fe5fceb jdk9-b52
|
||||
d6ed47125a76cd1cf8a100568507bfb5e9669d9f jdk9-b53
|
||||
|
1684
common/autoconf/build-aux/autoconf-config.sub
Normal file
1684
common/autoconf/build-aux/autoconf-config.sub
Normal file
File diff suppressed because it is too large
Load Diff
1694
common/autoconf/build-aux/config.sub
vendored
1694
common/autoconf/build-aux/config.sub
vendored
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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@
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -455,3 +455,4 @@ cc775a4a24c7f5d9e624b4205e9fbd48a17331f6 jdk9-b48
|
||||
e0947f58c9c1426aa0d98b98ebb78357b27a7b99 jdk9-b50
|
||||
403b9cbadb04d3d1201823591cf931dc93b38e3a jdk9-b51
|
||||
9fb7fdc554db5be5c5b10f88f529ec3b870c44e3 jdk9-b52
|
||||
effd5ef0c3eb4bb85aa975c489d6761dbf13ad6a jdk9-b53
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
32
hotspot/make/linux/makefiles/aarch64.make
Normal file
32
hotspot/make/linux/makefiles/aarch64.make
Normal 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
|
@ -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))
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
15
hotspot/make/linux/platform_aarch64
Normal file
15
hotspot/make/linux/platform_aarch64
Normal 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
|
@ -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)
|
||||
|
81
hotspot/make/test/JtregNative.gmk
Normal file
81
hotspot/make/test/JtregNative.gmk
Normal 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
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
12194
hotspot/src/cpu/aarch64/vm/aarch64.ad
Normal file
12194
hotspot/src/cpu/aarch64/vm/aarch64.ad
Normal file
File diff suppressed because it is too large
Load Diff
41
hotspot/src/cpu/aarch64/vm/aarch64Test.cpp
Normal file
41
hotspot/src/cpu/aarch64/vm/aarch64Test.cpp
Normal 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);
|
||||
}
|
365
hotspot/src/cpu/aarch64/vm/aarch64_ad.m4
Normal file
365
hotspot/src/cpu/aarch64/vm/aarch64_ad.m4
Normal 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 --------------
|
200
hotspot/src/cpu/aarch64/vm/aarch64_call.cpp
Normal file
200
hotspot/src/cpu/aarch64/vm/aarch64_call.cpp
Normal 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
|
167
hotspot/src/cpu/aarch64/vm/aarch64_linkage.S
Normal file
167
hotspot/src/cpu/aarch64/vm/aarch64_linkage.S
Normal 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
|
98
hotspot/src/cpu/aarch64/vm/ad_encode.m4
Normal file
98
hotspot/src/cpu/aarch64/vm/ad_encode.m4
Normal 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)
|
||||
|
1526
hotspot/src/cpu/aarch64/vm/assembler_aarch64.cpp
Normal file
1526
hotspot/src/cpu/aarch64/vm/assembler_aarch64.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2340
hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp
Normal file
2340
hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp
Normal file
File diff suppressed because it is too large
Load Diff
33
hotspot/src/cpu/aarch64/vm/assembler_aarch64.inline.hpp
Normal file
33
hotspot/src/cpu/aarch64/vm/assembler_aarch64.inline.hpp
Normal 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
|
48
hotspot/src/cpu/aarch64/vm/bytecodeInterpreter_aarch64.cpp
Normal file
48
hotspot/src/cpu/aarch64/vm/bytecodeInterpreter_aarch64.cpp
Normal 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)
|
116
hotspot/src/cpu/aarch64/vm/bytecodeInterpreter_aarch64.hpp
Normal file
116
hotspot/src/cpu/aarch64/vm/bytecodeInterpreter_aarch64.hpp
Normal 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
|
@ -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
|
29
hotspot/src/cpu/aarch64/vm/bytecodes_aarch64.cpp
Normal file
29
hotspot/src/cpu/aarch64/vm/bytecodes_aarch64.cpp
Normal 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"
|
||||
|
||||
|
31
hotspot/src/cpu/aarch64/vm/bytecodes_aarch64.hpp
Normal file
31
hotspot/src/cpu/aarch64/vm/bytecodes_aarch64.hpp
Normal 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
|
75
hotspot/src/cpu/aarch64/vm/bytes_aarch64.hpp
Normal file
75
hotspot/src/cpu/aarch64/vm/bytes_aarch64.hpp
Normal 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
|
381
hotspot/src/cpu/aarch64/vm/c1_CodeStubs_aarch64.cpp
Normal file
381
hotspot/src/cpu/aarch64/vm/c1_CodeStubs_aarch64.cpp
Normal 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 __
|
81
hotspot/src/cpu/aarch64/vm/c1_Defs_aarch64.hpp
Normal file
81
hotspot/src/cpu/aarch64/vm/c1_Defs_aarch64.hpp
Normal 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
|
36
hotspot/src/cpu/aarch64/vm/c1_FpuStackSim_aarch64.cpp
Normal file
36
hotspot/src/cpu/aarch64/vm/c1_FpuStackSim_aarch64.cpp
Normal 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
|
32
hotspot/src/cpu/aarch64/vm/c1_FpuStackSim_aarch64.hpp
Normal file
32
hotspot/src/cpu/aarch64/vm/c1_FpuStackSim_aarch64.hpp
Normal 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
|
356
hotspot/src/cpu/aarch64/vm/c1_FrameMap_aarch64.cpp
Normal file
356
hotspot/src/cpu/aarch64/vm/c1_FrameMap_aarch64.cpp
Normal 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, ®s, 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;
|
||||
}
|
148
hotspot/src/cpu/aarch64/vm/c1_FrameMap_aarch64.hpp
Normal file
148
hotspot/src/cpu/aarch64/vm/c1_FrameMap_aarch64.hpp
Normal 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
|
||||
|
3180
hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp
Normal file
3180
hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp
Normal file
File diff suppressed because it is too large
Load Diff
78
hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.hpp
Normal file
78
hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.hpp
Normal 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
|
1392
hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp
Normal file
1392
hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp
Normal file
File diff suppressed because it is too large
Load Diff
32
hotspot/src/cpu/aarch64/vm/c1_LinearScan_aarch64.cpp
Normal file
32
hotspot/src/cpu/aarch64/vm/c1_LinearScan_aarch64.cpp
Normal 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
|
||||
}
|
76
hotspot/src/cpu/aarch64/vm/c1_LinearScan_aarch64.hpp
Normal file
76
hotspot/src/cpu/aarch64/vm/c1_LinearScan_aarch64.hpp
Normal 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
|
459
hotspot/src/cpu/aarch64/vm/c1_MacroAssembler_aarch64.cpp
Normal file
459
hotspot/src/cpu/aarch64/vm/c1_MacroAssembler_aarch64.cpp
Normal 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
|
108
hotspot/src/cpu/aarch64/vm/c1_MacroAssembler_aarch64.hpp
Normal file
108
hotspot/src/cpu/aarch64/vm/c1_MacroAssembler_aarch64.hpp
Normal 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
|
1322
hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp
Normal file
1322
hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp
Normal file
File diff suppressed because it is too large
Load Diff
81
hotspot/src/cpu/aarch64/vm/c1_globals_aarch64.hpp
Normal file
81
hotspot/src/cpu/aarch64/vm/c1_globals_aarch64.hpp
Normal 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
|
91
hotspot/src/cpu/aarch64/vm/c2_globals_aarch64.hpp
Normal file
91
hotspot/src/cpu/aarch64/vm/c2_globals_aarch64.hpp
Normal 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
|
36
hotspot/src/cpu/aarch64/vm/c2_init_aarch64.cpp
Normal file
36
hotspot/src/cpu/aarch64/vm/c2_init_aarch64.cpp
Normal 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.
|
||||
}
|
35
hotspot/src/cpu/aarch64/vm/codeBuffer_aarch64.hpp
Normal file
35
hotspot/src/cpu/aarch64/vm/codeBuffer_aarch64.hpp
Normal 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
|
152
hotspot/src/cpu/aarch64/vm/compiledIC_aarch64.cpp
Normal file
152
hotspot/src/cpu/aarch64/vm/compiledIC_aarch64.cpp
Normal 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
|
61
hotspot/src/cpu/aarch64/vm/copy_aarch64.hpp
Normal file
61
hotspot/src/cpu/aarch64/vm/copy_aarch64.hpp
Normal 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
|
@ -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
|
595
hotspot/src/cpu/aarch64/vm/cpustate_aarch64.hpp
Normal file
595
hotspot/src/cpu/aarch64/vm/cpustate_aarch64.hpp
Normal 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
|
35
hotspot/src/cpu/aarch64/vm/debug_aarch64.cpp
Normal file
35
hotspot/src/cpu/aarch64/vm/debug_aarch64.cpp
Normal 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) {}
|
412
hotspot/src/cpu/aarch64/vm/decode_aarch64.hpp
Normal file
412
hotspot/src/cpu/aarch64/vm/decode_aarch64.hpp
Normal 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
|
30
hotspot/src/cpu/aarch64/vm/depChecker_aarch64.cpp
Normal file
30
hotspot/src/cpu/aarch64/vm/depChecker_aarch64.cpp
Normal 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
|
31
hotspot/src/cpu/aarch64/vm/depChecker_aarch64.hpp
Normal file
31
hotspot/src/cpu/aarch64/vm/depChecker_aarch64.hpp
Normal 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
|
37
hotspot/src/cpu/aarch64/vm/disassembler_aarch64.hpp
Normal file
37
hotspot/src/cpu/aarch64/vm/disassembler_aarch64.hpp
Normal 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
|
843
hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp
Normal file
843
hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp
Normal 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
|
216
hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp
Normal file
216
hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp
Normal 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
|
348
hotspot/src/cpu/aarch64/vm/frame_aarch64.inline.hpp
Normal file
348
hotspot/src/cpu/aarch64/vm/frame_aarch64.inline.hpp
Normal 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
|
58
hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp
Normal file
58
hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp
Normal 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
|
129
hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp
Normal file
129
hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp
Normal 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
|
76
hotspot/src/cpu/aarch64/vm/icBuffer_aarch64.cpp
Normal file
76
hotspot/src/cpu/aarch64/vm/icBuffer_aarch64.cpp
Normal 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;
|
||||
}
|
40
hotspot/src/cpu/aarch64/vm/icache_aarch64.cpp
Normal file
40
hotspot/src/cpu/aarch64/vm/icache_aarch64.cpp
Normal 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();
|
||||
}
|
44
hotspot/src/cpu/aarch64/vm/icache_aarch64.hpp
Normal file
44
hotspot/src/cpu/aarch64/vm/icache_aarch64.hpp
Normal 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
|
315
hotspot/src/cpu/aarch64/vm/immediate_aarch64.cpp
Normal file
315
hotspot/src/cpu/aarch64/vm/immediate_aarch64.cpp
Normal 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;
|
||||
}
|
||||
|
54
hotspot/src/cpu/aarch64/vm/immediate_aarch64.hpp
Normal file
54
hotspot/src/cpu/aarch64/vm/immediate_aarch64.hpp
Normal 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
|
1684
hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp
Normal file
1684
hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp
Normal file
File diff suppressed because it is too large
Load Diff
292
hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.hpp
Normal file
292
hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.hpp
Normal 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
|
57
hotspot/src/cpu/aarch64/vm/interpreterGenerator_aarch64.hpp
Normal file
57
hotspot/src/cpu/aarch64/vm/interpreterGenerator_aarch64.hpp
Normal 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
|
428
hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp
Normal file
428
hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp
Normal 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
|
66
hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.hpp
Normal file
66
hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.hpp
Normal 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
|
289
hotspot/src/cpu/aarch64/vm/interpreter_aarch64.cpp
Normal file
289
hotspot/src/cpu/aarch64/vm/interpreter_aarch64.cpp
Normal 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");
|
||||
}
|
43
hotspot/src/cpu/aarch64/vm/interpreter_aarch64.hpp
Normal file
43
hotspot/src/cpu/aarch64/vm/interpreter_aarch64.hpp
Normal 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
|
88
hotspot/src/cpu/aarch64/vm/javaFrameAnchor_aarch64.hpp
Normal file
88
hotspot/src/cpu/aarch64/vm/javaFrameAnchor_aarch64.hpp
Normal 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
|
174
hotspot/src/cpu/aarch64/vm/jniFastGetField_aarch64.cpp
Normal file
174
hotspot/src/cpu/aarch64/vm/jniFastGetField_aarch64.cpp
Normal 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);
|
||||
}
|
||||
|
107
hotspot/src/cpu/aarch64/vm/jniTypes_aarch64.hpp
Normal file
107
hotspot/src/cpu/aarch64/vm/jniTypes_aarch64.hpp
Normal 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
|
60
hotspot/src/cpu/aarch64/vm/jni_aarch64.h
Normal file
60
hotspot/src/cpu/aarch64/vm/jni_aarch64.h
Normal 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_ */
|
4138
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
Normal file
4138
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1162
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
Normal file
1162
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
Normal file
File diff suppressed because it is too large
Load Diff
35
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.inline.hpp
Normal file
35
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.inline.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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_MACROASSEMBLER_AARCH64_INLINE_HPP
|
||||
#define CPU_AARCH64_VM_MACROASSEMBLER_AARCH64_INLINE_HPP
|
||||
|
||||
#include "asm/assembler.hpp"
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
#endif // ndef PRODUCT
|
||||
|
||||
#endif // CPU_AARCH64_VM_MACROASSEMBLER_AARCH64_INLINE_HPP
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user