Merge
This commit is contained in:
commit
0fff7bc455
@ -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
|
||||
|
@ -295,3 +295,4 @@ a13c49c5f2899b702652a460ed7aa73123e671e6 jdk9-b48
|
||||
224f593393e5b01b3c8f1e591b7f4b1790a3737a jdk9-b50
|
||||
2309c02386d1fa4ced5051873ffb9e04874f7a44 jdk9-b51
|
||||
b8538bbb6f224ab1dabba579137099c166ad4724 jdk9-b52
|
||||
aadc16ca5ab7d56f92ef9dbfa443595a939241b4 jdk9-b53
|
||||
|
@ -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
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user