This commit is contained in:
Lana Steuck 2012-11-30 17:09:05 -08:00
commit 76863b84de
1061 changed files with 55269 additions and 5249 deletions

View File

@ -185,3 +185,5 @@ ffe6bce5a521be40146af2ac03c509b7bac30595 jdk8-b56
cdaa6122185f9bf512dcd6600f56bfccc4824e8c jdk8-b61
8d9d430b4244b95f5cf1ebe719f834a1ac5d6cd5 jdk8-b62
21ee1dd7b809639284900a128b9b656a592ebc7a jdk8-b63
70fa4b11f26522e69b51fd652215f60ce350bac3 jdk8-b64
a2cf4d4a484378caea2e827ed604b2bbae58bdba jdk8-b65

View File

@ -185,3 +185,5 @@ e07f499b9dccb529ecf74172cf6ac11a195ec57a jdk8-b60
20ff117b509075c3aec4ee3a57990ecd5db5df9c jdk8-b61
8a3fe0ae06a8cc21347da5a18384b0aa6c2349f5 jdk8-b62
3229597524cab4239325bc3602df6c486397a511 jdk8-b63
1c8370a55b305d35353346202bde042ba9e8a9fd jdk8-b64
b772de306dc24c17f7bd1398531ddeb58723b804 jdk8-b65

View File

@ -345,7 +345,13 @@ AC_ARG_WITH(conf-name, [AS_HELP_STRING([--with-conf-name],
[ CONF_NAME=${with_conf_name} ])
# Test from where we are running configure, in or outside of src root.
if test "x$CURDIR" = "x$SRC_ROOT" || test "x$CURDIR" = "x$SRC_ROOT/common" || test "x$CURDIR" = "x$SRC_ROOT/common/autoconf" || test "x$CURDIR" = "x$SRC_ROOT/common/makefiles" ; then
# To enable comparison of directories, CURDIR needs to be symlink free
# just like SRC_ROOT already is
NOSYM_CURDIR="$CURDIR"
BASIC_REMOVE_SYMBOLIC_LINKS(NOSYM_CURDIR)
if test "x$NOSYM_CURDIR" = "x$SRC_ROOT" || test "x$NOSYM_CURDIR" = "x$SRC_ROOT/common" \
|| test "x$NOSYM_CURDIR" = "x$SRC_ROOT/common/autoconf" \
|| test "x$NOSYM_CURDIR" = "x$SRC_ROOT/common/makefiles" ; then
# We are running configure from the src root.
# Create a default ./build/target-variant-debuglevel output root.
if test "x${CONF_NAME}" = x; then

View File

@ -204,7 +204,7 @@ AC_DEFUN_ONCE([BPERF_SETUP_PRECOMPILED_HEADERS],
#
AC_ARG_ENABLE([precompiled-headers], [AS_HELP_STRING([--disable-precompiled-headers],
[disable using precompiled headers when compiling C++ @<:@enabled@:>@])],
[ENABLE_PRECOMPH=${enable_precompiled-headers}], [ENABLE_PRECOMPH=yes])
[ENABLE_PRECOMPH=${enable_precompiled_headers}], [ENABLE_PRECOMPH=yes])
USE_PRECOMPILED_HEADER=1
if test "x$ENABLE_PRECOMPH" = xno; then
@ -214,17 +214,16 @@ fi
if test "x$ENABLE_PRECOMPH" = xyes; then
# Check that the compiler actually supports precomp headers.
if test "x$GCC" = xyes; then
AC_MSG_CHECKING([that precompiled headers work])
AC_MSG_CHECKING([that precompiled headers work])
echo "int alfa();" > conftest.h
$CXX -x c++-header conftest.h -o conftest.hpp.gch
$CXX -x c++-header conftest.h -o conftest.hpp.gch 2>&AS_MESSAGE_LOG_FD >&AS_MESSAGE_LOG_FD
if test ! -f conftest.hpp.gch; then
echo Precompiled header is not working!
USE_PRECOMPILED_HEADER=0
AC_MSG_RESULT([no])
else
AC_MSG_RESULT([yes])
fi
rm -f conftest.h
rm -f conftest.h conftest.hpp.gch
fi
fi

View File

@ -730,6 +730,8 @@ AR_OUT_OPTION
LD_OUT_OPTION
EXE_OUT_OPTION
CC_OUT_OPTION
BUILD_HOTSPOT
HOTSPOT_DIST
BUILD_OUTPUT
OVERRIDE_SRC_ROOT
ADD_SRC_ROOT
@ -975,6 +977,7 @@ with_override_jaxp
with_override_jaxws
with_override_hotspot
with_override_jdk
with_import_hotspot
with_msvcr_dll
with_extra_cflags
with_extra_cxxflags
@ -990,7 +993,7 @@ with_alsa
with_alsa_include
with_alsa_lib
with_zlib
enable_static_link_stdc__
with_stdc__lib
with_num_cores
with_memory_size
with_sjavac_server_java
@ -1657,9 +1660,6 @@ Optional Features:
--disable-macosx-runtime-support
disable the use of MacOSX Java runtime support
framework [enabled]
--disable-static-link-stdc++
disable static linking of the C++ runtime on Linux
[enabled]
--enable-sjavac use sjavac to do fast incremental compiles
[disabled]
--disable-precompiled-headers
@ -1719,6 +1719,9 @@ Optional Packages:
--with-override-jaxws use this jaxws dir for the build
--with-override-hotspot use this hotspot dir for the build
--with-override-jdk use this jdk dir for the build
--with-import-hotspot import hotspot binaries from this jdk image or
hotspot build dist dir instead of building from
source
--with-msvcr-dll copy this msvcr100.dll into the built JDK (Windows
only) [probed]
--with-extra-cflags extra flags to be used when compiling jdk c-files
@ -1738,6 +1741,10 @@ Optional Packages:
--with-alsa-lib specify directory for the alsa library
--with-zlib use zlib from build system or OpenJDK source
(system, bundled) [bundled]
--with-stdc++lib=<static>,<dynamic>,<default>
force linking of the C++ runtime on Linux to either
static or dynamic, default is static with dynamic as
fallback
--with-num-cores number of cores in the build system, e.g.
--with-num-cores=8 [probed]
--with-memory-size memory (in MB) available in the build system, e.g.
@ -3665,7 +3672,7 @@ fi
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
DATE_WHEN_GENERATED=1351854415
DATE_WHEN_GENERATED=1354106772
###############################################################################
#
@ -7575,7 +7582,56 @@ fi
# Test from where we are running configure, in or outside of src root.
if test "x$CURDIR" = "x$SRC_ROOT" || test "x$CURDIR" = "x$SRC_ROOT/common" || test "x$CURDIR" = "x$SRC_ROOT/common/autoconf" || test "x$CURDIR" = "x$SRC_ROOT/common/makefiles" ; then
# To enable comparison of directories, CURDIR needs to be symlink free
# just like SRC_ROOT already is
NOSYM_CURDIR="$CURDIR"
if test "x$OPENJDK_BUILD_OS" != xwindows; then
# Follow a chain of symbolic links. Use readlink
# where it exists, else fall back to horribly
# complicated shell code.
if test "x$READLINK_TESTED" != yes; then
# On MacOSX there is a readlink tool with a different
# purpose than the GNU readlink tool. Check the found readlink.
ISGNU=`$READLINK --help 2>&1 | $GREP GNU`
if test "x$ISGNU" = x; then
# A readlink that we do not know how to use.
# Are there other non-GNU readlinks out there?
READLINK_TESTED=yes
READLINK=
fi
fi
if test "x$READLINK" != x; then
NOSYM_CURDIR=`$READLINK -f $NOSYM_CURDIR`
else
STARTDIR=$PWD
COUNTER=0
sym_link_dir=`$DIRNAME $NOSYM_CURDIR`
sym_link_file=`$BASENAME $NOSYM_CURDIR`
while test $COUNTER -lt 20; do
ISLINK=`$LS -l $sym_link_dir/$sym_link_file | $GREP '\->' | $SED -e 's/.*-> \(.*\)/\1/'`
if test "x$ISLINK" == x; then
# This is not a symbolic link! We are done!
break
fi
# The link might be relative! We have to use cd to travel safely.
cd $sym_link_dir
# ... and we must get the to the absolute path, not one using symbolic links.
cd `pwd -P`
cd `$DIRNAME $ISLINK`
sym_link_dir=`$THEPWDCMD`
sym_link_file=`$BASENAME $ISLINK`
let COUNTER=COUNTER+1
done
cd $STARTDIR
NOSYM_CURDIR=$sym_link_dir/$sym_link_file
fi
fi
if test "x$NOSYM_CURDIR" = "x$SRC_ROOT" || test "x$NOSYM_CURDIR" = "x$SRC_ROOT/common" \
|| test "x$NOSYM_CURDIR" = "x$SRC_ROOT/common/autoconf" \
|| test "x$NOSYM_CURDIR" = "x$SRC_ROOT/common/makefiles" ; then
# We are running configure from the src root.
# Create a default ./build/target-variant-debuglevel output root.
if test "x${CONF_NAME}" = x; then
@ -15582,6 +15638,31 @@ fi
BUILD_OUTPUT="$OUTPUT_ROOT"
HOTSPOT_DIST="$OUTPUT_ROOT/hotspot/dist"
BUILD_HOTSPOT=true
# Check whether --with-import-hotspot was given.
if test "${with_import_hotspot+set}" = set; then :
withval=$with_import_hotspot;
fi
if test "x$with_import_hotspot" != x; then
CURDIR="$PWD"
cd "$with_import_hotspot"
HOTSPOT_DIST="`pwd`"
cd "$CURDIR"
if ! (test -d $HOTSPOT_DIST/lib && test -d $HOTSPOT_DIST/jre/lib); then
as_fn_error $? "You have to import hotspot from a full jdk image or hotspot build dist dir!" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if hotspot should be imported" >&5
$as_echo_n "checking if hotspot should be imported... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes from $HOTSPOT_DIST" >&5
$as_echo "yes from $HOTSPOT_DIST" >&6; }
BUILD_HOTSPOT=false
fi
JDK_OUTPUTDIR="$OUTPUT_ROOT/jdk"
@ -25583,6 +25664,8 @@ esac
fi
fi
# Only call fixup if objcopy was found.
if test -n "$OBJCOPY"; then
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
@ -25838,6 +25921,7 @@ $as_echo "$as_me: This might be caused by spaces in the path, which is not allow
$as_echo "$as_me: Rewriting OBJCOPY to \"$new_complete\"" >&6;}
fi
fi
fi
if test -n "$ac_tool_prefix"; then
@ -27498,10 +27582,19 @@ else
fi
fi
LDFLAGS_JDKLIB="${LDFLAGS_JDK} $SHARED_LIBRARY_FLAGS \
-L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/server \
-L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/client \
-L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}"
# On some platforms (mac) the linker warns about non existing -L dirs.
# Add server first if available. Linking aginst client does not always produce the same results.
# Only add client dir if client is being built. Default to server for other variants.
if test "x$JVM_VARIANT_SERVER" = xtrue; then
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/server"
elif test "x$JVM_VARIANT_CLIENT" = xtrue; then
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/client"
else
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/server"
fi
LDFLAGS_JDKLIB_SUFFIX="-ljava -ljvm"
if test "x$COMPILER_NAME" = xossc; then
LDFLAGS_JDKLIB_SUFFIX="$LDFLAGS_JDKLIB_SUFFIX -lc"
@ -30159,12 +30252,17 @@ LIBS="$save_LIBS"
# statically link libstdc++ before C++ ABI is stablized on Linux unless
# dynamic build is configured on command line.
#
# Check whether --enable-static-link-stdc++ was given.
if test "${enable_static_link_stdc__+set}" = set; then :
enableval=$enable_static_link_stdc__;
else
enable_static_link_stdc__=yes
# Check whether --with-stdc++lib was given.
if test "${with_stdc__lib+set}" = set; then :
withval=$with_stdc__lib;
if test "x$with_stdc__lib" != xdynamic && test "x$with_stdc__lib" != xstatic \
&& test "x$with_stdc__lib" != xdefault; then
as_fn_error $? "Bad parameter value --with-stdc++lib=$with_stdc__lib!" "$LINENO" 5
fi
else
with_stdc__lib=default
fi
@ -30252,36 +30350,34 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_static_libstdcxx" >&5
$as_echo "$has_static_libstdcxx" >&6; }
if test "x$has_static_libcxx" = xno && test "x$has_dynamic_libcxx" = xno; then
as_fn_error $? "I cannot link to stdc++! Neither dynamically nor statically." "$LINENO" 5
if test "x$has_static_libstdcxx" = xno && test "x$has_dynamic_libstdcxx" = xno; then
as_fn_error $? "Cannot link to stdc++, neither dynamically nor statically!" "$LINENO" 5
fi
if test "x$enable_static_link_stdc__" = xyes && test "x$has_static_libstdcxx" = xno; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Static linking of libstdc++ was not possible reverting to dynamic linking." >&5
$as_echo "$as_me: Static linking of libstdc++ was not possible reverting to dynamic linking." >&6;}
enable_static_link_stdc__=no
if test "x$with_stdc__lib" = xstatic && test "x$has_static_libstdcxx" = xno; then
as_fn_error $? "Static linking of libstdc++ was not possible!" "$LINENO" 5
fi
if test "x$enable_static_link_stdc__" = xno && test "x$has_dynamic_libstdcxx" = xno; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Dynamic linking of libstdc++ was not possible reverting to static linking." >&5
$as_echo "$as_me: Dynamic linking of libstdc++ was not possible reverting to static linking." >&6;}
enable_static_link_stdc__=yes
if test "x$with_stdc__lib" = xdynamic && test "x$has_dynamic_libstdcxx" = xno; then
as_fn_error $? "Dynamic linking of libstdc++ was not possible!" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libstdc++" >&5
$as_echo_n "checking how to link with libstdc++... " >&6; }
if test "x$enable_static_link_stdc__" = xyes; then
LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
LDCXX="$CC"
STATIC_CXX_SETTING="STATIC_CXX=true"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
$as_echo "static" >&6; }
else
# If dynamic was requested, it's available since it would fail above otherwise.
# If dynamic wasn't requested, go with static unless it isn't available.
if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno; then
LIBCXX="$LIBCXX -lstdc++"
LDCXX="$CXX"
STATIC_CXX_SETTING="STATIC_CXX=false"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: dynamic" >&5
$as_echo "dynamic" >&6; }
else
LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
LDCXX="$CC"
STATIC_CXX_SETTING="STATIC_CXX=true"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
$as_echo "static" >&6; }
fi
fi
@ -30733,7 +30829,7 @@ fi
#
# Check whether --enable-precompiled-headers was given.
if test "${enable_precompiled_headers+set}" = set; then :
enableval=$enable_precompiled_headers; ENABLE_PRECOMPH=${enable_precompiled-headers}
enableval=$enable_precompiled_headers; ENABLE_PRECOMPH=${enable_precompiled_headers}
else
ENABLE_PRECOMPH=yes
fi
@ -30750,9 +30846,8 @@ if test "x$ENABLE_PRECOMPH" = xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that precompiled headers work" >&5
$as_echo_n "checking that precompiled headers work... " >&6; }
echo "int alfa();" > conftest.h
$CXX -x c++-header conftest.h -o conftest.hpp.gch
$CXX -x c++-header conftest.h -o conftest.hpp.gch 2>&5 >&5
if test ! -f conftest.hpp.gch; then
echo Precompiled header is not working!
USE_PRECOMPILED_HEADER=0
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
@ -30760,7 +30855,7 @@ $as_echo "no" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
fi
rm -f conftest.h
rm -f conftest.h conftest.hpp.gch
fi
fi

View File

@ -95,6 +95,8 @@ EXTRA_CFLAGS=@LEGACY_EXTRA_CFLAGS@
EXTRA_CXXFLAGS=@LEGACY_EXTRA_CXXFLAGS@
EXTRA_LDFLAGS=@LEGACY_EXTRA_LDFLAGS@
USE_PRECOMPILED_HEADER=@USE_PRECOMPILED_HEADER@
# Sneak this in via the spec.gmk file, since we don't want to mess around too much with the Hotspot make files.
# This is needed to get the LOG setting to work properly.
include $(SRC_ROOT)/common/makefiles/MakeBase.gmk

View File

@ -601,11 +601,16 @@ AC_DEFUN_ONCE([LIB_SETUP_STATIC_LINK_LIBSTDCPP],
# statically link libstdc++ before C++ ABI is stablized on Linux unless
# dynamic build is configured on command line.
#
AC_ARG_ENABLE([static-link-stdc++], [AS_HELP_STRING([--disable-static-link-stdc++],
[disable static linking of the C++ runtime on Linux @<:@enabled@:>@])],,
[
enable_static_link_stdc__=yes
])
AC_ARG_WITH([stdc++lib], [AS_HELP_STRING([--with-stdc++lib=<static>,<dynamic>,<default>],
[force linking of the C++ runtime on Linux to either static or dynamic, default is static with dynamic as fallback])],
[
if test "x$with_stdc__lib" != xdynamic && test "x$with_stdc__lib" != xstatic \
&& test "x$with_stdc__lib" != xdefault; then
AC_MSG_ERROR([Bad parameter value --with-stdc++lib=$with_stdc__lib!])
fi
],
[with_stdc__lib=default]
)
if test "x$OPENJDK_TARGET_OS" = xlinux; then
# Test if -lstdc++ works.
@ -636,31 +641,31 @@ if test "x$OPENJDK_TARGET_OS" = xlinux; then
AC_LANG_POP(C++)
AC_MSG_RESULT([$has_static_libstdcxx])
if test "x$has_static_libcxx" = xno && test "x$has_dynamic_libcxx" = xno; then
AC_MSG_ERROR([I cannot link to stdc++! Neither dynamically nor statically.])
if test "x$has_static_libstdcxx" = xno && test "x$has_dynamic_libstdcxx" = xno; then
AC_MSG_ERROR([Cannot link to stdc++, neither dynamically nor statically!])
fi
if test "x$enable_static_link_stdc__" = xyes && test "x$has_static_libstdcxx" = xno; then
AC_MSG_NOTICE([Static linking of libstdc++ was not possible reverting to dynamic linking.])
enable_static_link_stdc__=no
if test "x$with_stdc__lib" = xstatic && test "x$has_static_libstdcxx" = xno; then
AC_MSG_ERROR([Static linking of libstdc++ was not possible!])
fi
if test "x$enable_static_link_stdc__" = xno && test "x$has_dynamic_libstdcxx" = xno; then
AC_MSG_NOTICE([Dynamic linking of libstdc++ was not possible reverting to static linking.])
enable_static_link_stdc__=yes
if test "x$with_stdc__lib" = xdynamic && test "x$has_dynamic_libstdcxx" = xno; then
AC_MSG_ERROR([Dynamic linking of libstdc++ was not possible!])
fi
AC_MSG_CHECKING([how to link with libstdc++])
if test "x$enable_static_link_stdc__" = xyes; then
LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
LDCXX="$CC"
STATIC_CXX_SETTING="STATIC_CXX=true"
AC_MSG_RESULT([static])
else
# If dynamic was requested, it's available since it would fail above otherwise.
# If dynamic wasn't requested, go with static unless it isn't available.
if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno; then
LIBCXX="$LIBCXX -lstdc++"
LDCXX="$CXX"
STATIC_CXX_SETTING="STATIC_CXX=false"
AC_MSG_RESULT([dynamic])
else
LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
LDCXX="$CC"
STATIC_CXX_SETTING="STATIC_CXX=true"
AC_MSG_RESULT([static])
fi
fi
AC_SUBST(STATIC_CXX_SETTING)

View File

@ -253,5 +253,24 @@ AC_DEFUN_ONCE([SRCDIRS_SETUP_OUTPUT_DIRS],
BUILD_OUTPUT="$OUTPUT_ROOT"
AC_SUBST(BUILD_OUTPUT)
HOTSPOT_DIST="$OUTPUT_ROOT/hotspot/dist"
BUILD_HOTSPOT=true
AC_SUBST(HOTSPOT_DIST)
AC_SUBST(BUILD_HOTSPOT)
AC_ARG_WITH(import-hotspot, [AS_HELP_STRING([--with-import-hotspot],
[import hotspot binaries from this jdk image or hotspot build dist dir instead of building from source])])
if test "x$with_import_hotspot" != x; then
CURDIR="$PWD"
cd "$with_import_hotspot"
HOTSPOT_DIST="`pwd`"
cd "$CURDIR"
if ! (test -d $HOTSPOT_DIST/lib && test -d $HOTSPOT_DIST/jre/lib); then
AC_MSG_ERROR([You have to import hotspot from a full jdk image or hotspot build dist dir!])
fi
AC_MSG_CHECKING([if hotspot should be imported])
AC_MSG_RESULT([yes from $HOTSPOT_DIST])
BUILD_HOTSPOT=false
fi
JDK_OUTPUTDIR="$OUTPUT_ROOT/jdk"
])

View File

@ -224,7 +224,9 @@ LANGTOOLS_DIST=$(LANGTOOLS_OUTPUTDIR)/dist
CORBA_DIST=$(CORBA_OUTPUTDIR)/dist
JAXP_DIST=$(JAXP_OUTPUTDIR)/dist
JAXWS_DIST=$(JAXWS_OUTPUTDIR)/dist
HOTSPOT_DIST=$(HOTSPOT_OUTPUTDIR)/dist
HOTSPOT_DIST=@HOTSPOT_DIST@
BUILD_HOTSPOT=@BUILD_HOTSPOT@
# The boot jdk to use
BOOT_JDK:=@BOOT_JDK@
@ -244,12 +246,6 @@ ENABLE_SJAVAC:=@ENABLE_SJAVAC@
# Store sjavac server synchronization files here, and
# the sjavac server log files.
SJAVAC_SERVER_DIR:=@SJAVAC_SERVER_DIR@
# We can block the Javac server to never use more cores than this.
# This is not for performance reasons, but for memory usage, since each
# core requires its own JavaCompiler. We might have 64 cores and 4GB
# of memory, 64 JavaCompilers will currently not fit in a 3GB heap.
# Since there is no sharing of data between the JavaCompilers.
SJAVAC_SERVER_CORES:=@SJAVAC_SERVER_CORES@
# The OpenJDK makefiles should be changed to using the standard
# configure output ..._CFLAGS and ..._LIBS. In the meantime we
@ -494,7 +490,14 @@ FIXPATH:=@FIXPATH@
# Where the build output is stored for your convenience.
BUILD_LOG:=@BUILD_LOG@
BUILD_LOG_PREVIOUS:=@BUILD_LOG_PREVIOUS@
BUILD_LOG_WRAPPER:=@BUILD_LOG_WRAPPER@
# Disable the build log wrapper on sjavac+winapi until
# we have solved how to prevent the log wrapper to wait
# for the background sjavac server process.
ifeq (@ENABLE_SJAVAC@X@OPENJDK_BUILD_OS_API@,yesXwinapi)
BUILD_LOG_WRAPPER:=
else
BUILD_LOG_WRAPPER:=@BUILD_LOG_WRAPPER@
endif
# Build setup
ENABLE_JFR=@ENABLE_JFR@

View File

@ -437,7 +437,10 @@ fi
# full debug symbols are enabled.
if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; then
AC_CHECK_TOOLS(OBJCOPY, [gobjcopy objcopy])
BASIC_FIXUP_EXECUTABLE(OBJCOPY)
# Only call fixup if objcopy was found.
if test -n "$OBJCOPY"; then
BASIC_FIXUP_EXECUTABLE(OBJCOPY)
fi
fi
AC_CHECK_TOOLS(OBJDUMP, [gobjdump objdump])
@ -935,10 +938,19 @@ else
fi
fi
LDFLAGS_JDKLIB="${LDFLAGS_JDK} $SHARED_LIBRARY_FLAGS \
-L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/server \
-L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/client \
-L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}"
# On some platforms (mac) the linker warns about non existing -L dirs.
# Add server first if available. Linking aginst client does not always produce the same results.
# Only add client dir if client is being built. Default to server for other variants.
if test "x$JVM_VARIANT_SERVER" = xtrue; then
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/server"
elif test "x$JVM_VARIANT_CLIENT" = xtrue; then
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/client"
else
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/server"
fi
LDFLAGS_JDKLIB_SUFFIX="-ljava -ljvm"
if test "x$COMPILER_NAME" = xossc; then
LDFLAGS_JDKLIB_SUFFIX="$LDFLAGS_JDKLIB_SUFFIX -lc"

View File

@ -283,13 +283,14 @@ compare_general_files() {
! -name "*.debuginfo" ! -name "*.dylib" ! -name "jexec" \
! -name "ct.sym" ! -name "*.diz" ! -name "*.dll" \
! -name "*.pdb" ! -name "*.exp" ! -name "*.ilk" \
! -name "*.lib" ! -name "*.war" \
! -name "*.lib" ! -name "*.war" ! -name "JavaControlPanel" \
| $GREP -v "./bin/" | $SORT | $FILTER)
echo General files...
for f in $GENERAL_FILES
do
if [ -e $OTHER_DIR/$f ]; then
SUFFIX="${f##*.}"
if [ "$(basename $f)" = "release" ]; then
# Ignore differences in change numbers in release file.
OTHER_FILE=$WORK_DIR/$f.other
@ -298,6 +299,22 @@ compare_general_files() {
$MKDIR -p $(dirname $THIS_FILE)
$CAT $OTHER_DIR/$f | $SED 's/\:[0-9a-f]\{12,12\}/:CHANGE/g' > $OTHER_FILE
$CAT $THIS_DIR/$f | $SED 's/\:[0-9a-f]\{12,12\}/:CHANGE/g' > $THIS_FILE
elif [ "x$SUFFIX" = "xhtml" ]; then
# Ignore time stamps in docs files
OTHER_FILE=$WORK_DIR/$f.other
THIS_FILE=$WORK_DIR/$f.this
$MKDIR -p $(dirname $OTHER_FILE)
$MKDIR -p $(dirname $THIS_FILE)
$CAT $OTHER_DIR/$f | $SED -e 's/\(-- Generated by javadoc \).*\( --\)/\1(removed)\2/' \
-e 's/\(<meta name="date" content="\).*\(">\)/\1(removed)\2/' \
-e 's/\(Monday\|Tuesday\|Wednesday\|Thursday\|Friday\|Saturday\|Sunday\), [A-Z][a-z]* [0-9][0-9]*, [12][0-9]* [0-9][0-9:]* \(AM\|PM\) [A-Z][A-Z]*/(removed)/' \
-e 's/^\( from \).*\(\.idl\)$/\1(removed)\2/' \
> $OTHER_FILE
$CAT $THIS_DIR/$f | $SED -e 's/\(-- Generated by javadoc \).*\( --\)/\1(removed)\2/' \
-e 's/\(<meta name="date" content="\).*\(">\)/\1(removed)\2/' \
-e 's/\(Monday\|Tuesday\|Wednesday\|Thursday\|Friday\|Saturday\|Sunday\), [A-Z][a-z]* [0-9][0-9]*, [12][0-9]* [0-9][0-9:]* \(AM\|PM\) [A-Z][A-Z]*/(removed)/' \
-e 's/^\( from \).*\(\.idl\)$/\1(removed)\2/' \
> $THIS_FILE
else
OTHER_FILE=$OTHER_DIR/$f
THIS_FILE=$THIS_DIR/$f
@ -611,10 +628,19 @@ compare_bin_file() {
DIFF_SIZE_NUM=$($EXPR $THIS_SIZE - $OTHER_SIZE)
DIFF_SIZE_REL=$($EXPR $THIS_SIZE \* 100 / $OTHER_SIZE)
SIZE_MSG=$($PRINTF "%3d%% %4d" $DIFF_SIZE_REL $DIFF_SIZE_NUM)
if [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] && [ "$DIFF_SIZE_REL" -gt 98 ] && [ "$DIFF_SIZE_REL" -lt 102 ]; then
if [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] && [ "$DIFF_SIZE_REL" -gt 98 ] \
&& [ "$DIFF_SIZE_REL" -lt 102 ]; then
SIZE_MSG="($SIZE_MSG)"
DIFF_SIZE=
elif [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] && [ "$DIFF_SIZE_NUM" = 512 ]; then
elif [ "$OPENJDK_TARGET_OS" = "windows" ] \
&& [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] \
&& [ "$DIFF_SIZE_NUM" = 512 ]; then
# On windows, size of binaries increase in 512 increments.
SIZE_MSG="($SIZE_MSG)"
DIFF_SIZE=
elif [ "$OPENJDK_TARGET_OS" = "windows" ] \
&& [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] \
&& [ "$DIFF_SIZE_NUM" = -512 ]; then
# On windows, size of binaries increase in 512 increments.
SIZE_MSG="($SIZE_MSG)"
DIFF_SIZE=
@ -840,7 +866,7 @@ compare_all_libs() {
OTHER_DIR=$2
WORK_DIR=$3
LIBS=$(cd $THIS_DIR && $FIND . -type f \( -name 'lib*.so' -o -name '*.dylib' -o -name '*.dll' \) | $SORT | $FILTER)
LIBS=$(cd $THIS_DIR && $FIND . -type f \( -name 'lib*.so' -o -name '*.dylib' -o -name '*.dll' -o -name 'JavaControlPanel' \) | $SORT | $FILTER)
if [ -n "$LIBS" ]; then
echo Libraries...
@ -1102,6 +1128,22 @@ if [ -z "$THIS_J2SDK_BUNDLE" ] && [ -n "$OTHER_J2SDK_BUNDLE" ]; then
echo "Skipping bundle compare!"
fi
if [ -d "$THIS/docs" ]; then
THIS_DOCS="$THIS/docs"
fi
if [ -d "$OTHER/docs" ]; then
OTHER_DOCS="$OTHER/docs"
fi
if [ -z "$THIS_DOCS" ]; then
echo "WARNING! Docs haven't been built and won't be compared."
fi
if [ -z "$OTHER_DOCS" ]; then
echo "WARNING! Other build doesn't contain docs, skipping doc compare."
fi
##########################################################################################
# Do the work
@ -1139,6 +1181,12 @@ if [ "$CMP_NAMES" = "true" ]; then
echo -n "J2RE Bundle "
compare_files $THIS_J2RE_BUNDLE $OTHER_J2RE_BUNDLE $COMPARE_ROOT/j2re-bundle
fi
if [ -n "$THIS_DOCS" ] && [ -n "$OTHER_DOCS" ]; then
echo -n "Docs "
compare_dirs $THIS_DOCS $OTHER_DOCS $COMPARE_ROOT/docs
echo -n "Docs "
compare_files $THIS_DOCS $OTHER_DOCS $COMPARE_ROOT/docs
fi
fi
if [ "$CMP_PERMS" = "true" ]; then
@ -1202,6 +1250,10 @@ if [ "$CMP_GENERAL" = "true" ]; then
echo -n "J2RE Bundle "
compare_general_files $THIS_J2RE_BUNDLE $OTHER_J2RE_BUNDLE $COMPARE_ROOT/j2re-bundle
fi
if [ -n "$THIS_DOCS" ] && [ -n "$OTHER_DOCS" ]; then
echo -n "Docs "
compare_general_files $THIS_DOCS $OTHER_DOCS $COMPARE_ROOT/docs
fi
fi
if [ "$CMP_ZIPS" = "true" ]; then
@ -1218,7 +1270,12 @@ 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 [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
echo -n "J2RE "
compare_all_libs $THIS_J2RE $OTHER_J2RE $COMPARE_ROOT/j2re
fi
fi
if [ -n "$THIS_J2SDK_OVERLAY" ] && [ -n "$OTHER_J2SDK_OVERLAY" ]; then
echo -n "Bundle "

View File

@ -291,6 +291,14 @@ ACCEPTED_SMALL_SIZE_DIFF="
./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/extcheck
./bin/idlj
@ -348,7 +356,9 @@ ACCEPTED_SMALL_SIZE_DIFF="
SKIP_FULLDUMP_DIFF="true"
# Filter random C++ symbol strings.
DIS_DIFF_FILTER="$SED -e s/\.[a-zA-Z0-9_\$]\{15,15\}/<SYM>/g"
# 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
@ -426,6 +436,9 @@ ACCEPTED_SMALL_SIZE_DIFF="
./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/extcheck
./bin/amd64/idlj
@ -480,7 +493,9 @@ ACCEPTED_SMALL_SIZE_DIFF="
SKIP_FULLDUMP_DIFF="true"
# Filter random C++ symbol strings.
DIS_DIFF_FILTER="$SED -e s/\.[a-zA-Z0-9_\$]\{15,15\}/<SYM>/g"
# 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
@ -881,6 +896,7 @@ ACCEPTED_JARZIP_CONTENTS="
KNOWN_BIN_DIFF="
./jre/lib/libJObjC.dylib
./lib/libJObjC.dylib
"
ACCEPTED_BIN_DIFF="
@ -932,26 +948,34 @@ ACCEPTED_BIN_DIFF="
./jre/bin/tnameserv
./jre/lib/libsaproc.dylib
./jre/lib/server/libjvm.dylib
./lib/libsaproc.dylib
./lib/server/libjvm.dylib
./lib/deploy/JavaControlPanel.prefPane/Contents/MacOS/JavaControlPanel
"
KNOWN_SIZE_DIFF="
./jre/lib/libJObjC.dylib
./lib/libJObjC.dylib
"
SORT_SYMBOLS="
./jre/lib/libJObjC.dylib
./lib/libJObjC.dylib
"
KNOWN_SYM_DIFF="
./jre/lib/libJObjC.dylib
./lib/libJObjC.dylib
"
KNOWN_ELF_DIFF="
./jre/lib/libJObjC.dylib
./lib/libJObjC.dylib
"
KNOWN_DIS_DIFF="
./jre/lib/libJObjC.dylib
./lib/libJObjC.dylib
"
fi

View File

@ -111,7 +111,7 @@ define SetupArchive
ifeq ($$(word 20,$$($1_GREP_INCLUDE_PATTERNS)),)
$1_GREP_INCLUDES:=| $(GREP) $$(patsubst %,$(SPACE)-e$(SPACE)$(DQUOTE)%$(DQUOTE),$$($1_GREP_INCLUDE_PATTERNS))
else
$$(shell $(RM) $$($1_BIN)/_the.$$($1_JARNAME)_include)
$$(shell $(MKDIR) -p $$($1_BIN) && $(RM) $$($1_BIN)/_the.$$($1_JARNAME)_include)
$$(eval $$(call ListPathsSafelyNow,$1_GREP_INCLUDE_PATTERNS,\n, \
>> $$($1_BIN)/_the.$$($1_JARNAME)_include))
$1_GREP_INCLUDES:=| $(GREP) -f $$($1_BIN)/_the.$$($1_JARNAME)_include
@ -124,7 +124,7 @@ define SetupArchive
ifeq ($$(word 20,$$($1_GREP_EXCLUDE_PATTERNS)),)
$1_GREP_EXCLUDES:=| $(GREP) -v $$(patsubst %,$(SPACE)-e$(SPACE)$(DQUOTE)%$(DQUOTE),$$($1_GREP_EXCLUDE_PATTERNS))
else
$$(shell $(RM) $$($1_BIN)/_the.$$($1_JARNAME)_exclude)
$$(shell $(MKDIR) -p $$($1_BIN) && $(RM) $$($1_BIN)/_the.$$($1_JARNAME)_exclude)
$$(eval $$(call ListPathsSafelyNow,$1_GREP_EXCLUDE_PATTERNS,\n, \
>> $$($1_BIN)/_the.$$($1_JARNAME)_exclude))
$1_GREP_EXCLUDES:=| $(GREP) -v -f $$($1_BIN)/_the.$$($1_JARNAME)_exclude
@ -170,9 +170,10 @@ define SetupArchive
# tells us what to remove from the jar-file.
$1_CAPTURE_DELETES=$$(foreach src,$$($1_SRCS),($(FIND) $$(src) -name _the.package.deleted -newer $$@ -exec $(SED) 's|$$(src)||g' \{\} >> $$($1_DELETES_FILE) \;) $$(NEWLINE))
# The update contents macro updates the jar file with the previously capture contents.
# xargs is used to trim the whitespace from the contents file, to see if it is empty.
$1_UPDATE_CONTENTS=$$(foreach src,$$($1_SRCS),\
(cd $$(src) && \
if [ -s _the.$$($1_JARNAME)_contents ]; then \
if [ -n "`$(CAT) _the.$$($1_JARNAME)_contents | $(XARGS)`" ]; then \
$(ECHO) " updating" `$(WC) -l _the.$$($1_JARNAME)_contents | $(AWK) '{ print $$$$1 }'` files && \
$(JAR) $$($1_JAR_UPDATE_OPTIONS) $$@ @_the.$$($1_JARNAME)_contents; \
fi) $$(NEWLINE))

View File

@ -94,11 +94,13 @@ jaxws-only: start-make
@($(CD) $(JAXWS_TOPDIR)/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f BuildJaxws.gmk)
@$(call TargetExit)
ifeq ($(BUILD_HOTSPOT),true)
hotspot: hotspot-only
hotspot-only: start-make
@$(call TargetEnter)
@($(CD) $(SRC_ROOT)/common/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f HotspotWrapper.gmk)
@$(call TargetExit)
endif
jdk: langtools hotspot corba jaxp jaxws jdk-only
jdk-only: start-make
@ -163,7 +165,7 @@ $(OUTPUT_ROOT)/source_tips: FRC
# Remove everything, except the output from configure.
clean: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-images clean-overlay-images clean-bootcycle-build
clean: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-images clean-overlay-images clean-bootcycle-build clean-docs
@($(CD) $(OUTPUT_ROOT) && $(RM) -r tmp source_tips build.log* build-trace*.log*)
@$(ECHO) Cleaned all build artifacts.
@ -199,6 +201,9 @@ clean-overlay-images:
$(call CleanComponent,overlay-images)
clean-bootcycle-build:
$(call CleanComponent,bootcycle-build)
clean-docs:
$(call CleanComponent,docs)
$(call CleanComponent,docstemp)
.PHONY: langtools corba jaxp jaxws hotspot jdk images overlay-images install
.PHONY: langtools-only corba-only jaxp-only jaxws-only hotspot-only jdk-only images-only overlay-images-only install-only

View File

@ -142,7 +142,7 @@ endef
define TargetExit
$(call RecordEndTime,$(patsubst %-only,%,$@))
$(BUILD_LOG_WRAPPER) $(PRINTF) "## Finished $(patsubst %-only,%,$@) (build time %s)\n\n" \
"`$(CAT) $(BUILDTIMESDIR)/build_time_diff_$(patsubst %-only,%,$@) | $(CUT) -f 1 -d " "`"
"`$(CAT) $(BUILDTIMESDIR)/build_time_diff_$(patsubst %-only,%,$@) | $(CUT) -f 1 -d ' '`"
$(call CheckIfMakeAtEnd)
endef
@ -157,7 +157,7 @@ endef
# Hook to be called as the very last thing for targets that are "top level" targets
define AtMakeEnd
$(if $(SJAVAC_SERVER_DIR),@$(RM) -rf $(SJAVAC_SERVER_DIR)/*.port)
[ -f $(SJAVAC_SERVER_DIR)/server.port ] && echo Stopping sjavac server && $(TOUCH) $(SJAVAC_SERVER_DIR)/server.port.stop; true
$(call StopGlobalTimer)
$(call ReportBuildTimes)
@$(PRINTF) "Finished building $(PRODUCT_NAME) for target '$(call GetRealTarget)'\n"
@ -174,8 +174,8 @@ endef
define ParseLogLevel
ifeq ($$(origin VERBOSE),undefined)
# Setup logging according to LOG (but only if VERBOSE is not given)
# If the "nofile" argument is given, act on it and strip it away
# If the "nofile" argument is given, act on it and strip it away
ifneq ($$(findstring nofile,$$(LOG)),)
# Reset the build log wrapper, regardless of other values
override BUILD_LOG_WRAPPER=

View File

@ -50,17 +50,12 @@ BUILD_NUMBER=$(JDK_BUILD_NUMBER)
BOOT_JAVA_CMD=$(JAVA)
# Langtools
JAVAC_JAR = $(LANGTOOLS_DIST)/bootstrap/lib/javac.jar
JAVADOC_JAR = $(LANGTOOLS_DIST)/bootstrap/lib/javadoc.jar
DOCLETS_JAR = $(LANGTOOLS_DIST)/bootstrap/lib/doclets.jar
JAVADOC_CMD = $(BOOT_JAVA_CMD) \
-Xmx1024m \
-Djava.awt.headless=true \
"-Xbootclasspath/p:$(JAVADOC_JAR)$(CLASSPATH_SEPARATOR)$(JAVAC_JAR)$(CLASSPATH_SEPARATOR)$(DOCLETS_JAR)" \
-jar $(JAVADOC_JAR)
JAVADOC_CMD = javadoc
"-Xbootclasspath/p:$(JAVADOC_JAR)" \
-jar $(JAVADOC_JAR) -bootclasspath $(JDK_OUTPUTDIR)/classes
# Copyright year for beginning of Java and some of the apis
# (Needed when creating the javadocs)
@ -113,7 +108,8 @@ DOCSDIR_URL = {@docroot}/$(GET2DOCSDIR)
# Url to copyright html file
COPYRIGHT_URL-7 = $(DOCSDIR_URL)/legal/cpyr.html
COPYRIGHT_URL-8 = $(DOCSDIR_URL)/legal/cpyr.html
# This isn't added in old build yet.
#COPYRIGHT_URL-8 = $(DOCSDIR_URL)/legal/cpyr.html
COPYRIGHT_URL = $(COPYRIGHT_URL-$(JDK_MINOR_VERSION))
# Url to bug filing site
@ -125,7 +121,8 @@ BUG_SUBMIT_LINE = <a href="$(BUG_SUBMIT_URL)">Submit a bug or feature</a>
# Url to devdocs page
# Was: http://java.sun.com/javase/6/webnotes/devdocs-vs-specs.html
DEV_DOCS_URL-7 = http://download.oracle.com/javase/7/docs/index.html
DEV_DOCS_URL-8 = http://download.oracle.com/javase/7/docs/index.html
# This isn't added in old build yet.
#DEV_DOCS_URL-8 = http://download.oracle.com/javase/7/docs/index.html
DEV_DOCS_URL = $(DEV_DOCS_URL-$(JDK_MINOR_VERSION))
DOCS_BASE_URL = http://download.oracle.com/javase/7/docs
@ -142,9 +139,10 @@ $(FULL_COMPANY_NAME) in the US and other countries.
# Otherwise, you get "No packages or classes specified." due
# to $(CLASSPATH_SEPARATOR) being interpreted as an end of
# command (newline or shell ; character)
ALL_SOURCE_DIRS = $(JDK_IMPSRC) \
ALL_SOURCE_DIRS = $(JDK_SHARE_CLASSES) \
$(JDK_IMPSRC) \
$(JDK_GENSRC) \
$(JDK_SHARE_CLASSES) \
$(JDK_OUTPUTDIR)/gendocsrc_rmic \
$(JDK_TOPDIR)/src/solaris/classes \
$(JDK_TOPDIR)/src/windows/classes \
$(JDK_SHARE_SRC)/doc/stub
@ -440,7 +438,7 @@ docletapidocs: $(DOCLETAPI_INDEX_FILE)
$(DOCLETAPI_INDEX_FILE): GET2DOCSDIR=$(DOCLETAPI2COREAPI)/..
# Run javadoc if the index file is out of date or missing
$(DOCLETAPI_INDEX_FILE): $(DOCLETAPI_OPTIONS_FILE) $(DOCLETAPI_PACKAGES_FILE)
$(DOCLETAPI_INDEX_FILE): $(DOCLETAPI_OPTIONS_FILE) $(DOCLETAPI_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(DOCLETAPI_OPTIONS_FILE),$(DOCLETAPI_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@ -481,7 +479,7 @@ TAGLETAPI_BOTTOM := $(call CommonTrademarkBottom,$(TAGLETAPI_FIRST_COPYRIGHT_Y
TAGLETAPI_TEMPDIR = $(DOCSTMPDIR)/taglets_temp
# The index.html, options, and packages files
TAGLETAPI_INDEX_FILE = $(TAGLETAPI_DOCDIR)/com/sun/tools/doclets/Taglet.html
TAGLETAPI_INDEX_FILE = $(TAGLETAPI_DOCDIR)/index.html
TAGLETAPI_OPTIONS_FILE = $(DOCSTMPDIR)/tagletapi.options
TAGLETAPI_PACKAGES_FILE = $(DOCSTMPDIR)/tagletapi.packages
@ -491,7 +489,7 @@ tagletapidocs: $(TAGLETAPI_INDEX_FILE)
$(TAGLETAPI_INDEX_FILE): GET2DOCSDIR=$(TAGLETAPI2COREAPI)/..
# Run javadoc if the index file is out of date or missing
$(TAGLETAPI_INDEX_FILE): $(TAGLETAPI_OPTIONS_FILE) $(TAGLETAPI_PACKAGES_FILE)
$(TAGLETAPI_INDEX_FILE): $(TAGLETAPI_OPTIONS_FILE) $(TAGLETAPI_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(RM) -r $(TAGLETAPI_TEMPDIR)
$(MKDIR) -p $(TAGLETAPI_TEMPDIR)
@ -517,9 +515,7 @@ $(TAGLETAPI_OPTIONS_FILE):
# Create a file with the package names in it
$(TAGLETAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(TAGLETAPI_PKGS))
$(prep-target)
$(call PackageFilter,$(TAGLETAPI_PKGS))
$(GREP) "$(TAGLETAPI_FILE)" $@ > $@.tmp
$(MV) $@.tmp $@
@($(ECHO) "$(JDK_IMPSRC)/$(TAGLETAPI_FILE)" ) > $@
#############################################################
#
@ -549,7 +545,7 @@ domapidocs: $(DOMAPI_INDEX_FILE)
$(DOMAPI_INDEX_FILE): GET2DOCSDIR=$(DOMAPI2COREAPI)/..
# Run javadoc if the index file is out of date or missing
$(DOMAPI_INDEX_FILE): $(DOMAPI_OPTIONS_FILE) $(DOMAPI_PACKAGES_FILE)
$(DOMAPI_INDEX_FILE): $(DOMAPI_OPTIONS_FILE) $(DOMAPI_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(DOMAPI_OPTIONS_FILE),$(DOMAPI_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@ -611,7 +607,7 @@ jdidocs: $(JDI_INDEX_FILE)
$(JDI_INDEX_FILE): GET2DOCSDIR=$(JDI2COREAPI)/..
# Run javadoc if the index file is out of date or missing
$(JDI_INDEX_FILE): $(JDI_OPTIONS_FILE) $(JDI_PACKAGES_FILE)
$(JDI_INDEX_FILE): $(JDI_OPTIONS_FILE) $(JDI_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(JDI_OPTIONS_FILE),$(JDI_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@ -698,7 +694,7 @@ jaasdocs: $(JAAS_INDEX_FILE)
$(JAAS_INDEX_FILE): GET2DOCSDIR=$(JAAS2COREAPI)/..
# Run javadoc if the index file is out of date or missing
$(JAAS_INDEX_FILE): $(JAAS_OPTIONS_FILE) $(JAAS_PACKAGES_FILE)
$(JAAS_INDEX_FILE): $(JAAS_OPTIONS_FILE) $(JAAS_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(JAAS_OPTIONS_FILE),$(JAAS_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@ -750,7 +746,7 @@ jgssdocs: $(JGSS_INDEX_FILE)
$(JGSS_INDEX_FILE): GET2DOCSDIR=$(JGSS2COREAPI)/..
# Run javadoc if the index file is out of date or missing
$(JGSS_INDEX_FILE): $(JGSS_OPTIONS_FILE) $(JGSS_PACKAGES_FILE)
$(JGSS_INDEX_FILE): $(JGSS_OPTIONS_FILE) $(JGSS_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(JGSS_OPTIONS_FILE),$(JGSS_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@ -802,7 +798,7 @@ smartcardiodocs: $(SMARTCARDIO_INDEX_FILE)
$(SMARTCARDIO_INDEX_FILE): GET2DOCSDIR=$(SMARTCARDIO2COREAPI)/..
# Run javadoc if the index file is out of date or missing
$(SMARTCARDIO_INDEX_FILE): $(SMARTCARDIO_OPTIONS_FILE) $(SMARTCARDIO_PACKAGES_FILE)
$(SMARTCARDIO_INDEX_FILE): $(SMARTCARDIO_OPTIONS_FILE) $(SMARTCARDIO_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(SMARTCARDIO_OPTIONS_FILE),$(SMARTCARDIO_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@ -852,7 +848,7 @@ httpserverdocs: $(HTTPSERVER_INDEX_HTML)
$(HTTPSERVER_INDEX_HTML): GET2DOCSDIR=$(HTTPSERVER2COREAPI)/..
# Run javadoc if the index file is out of date or missing
$(HTTPSERVER_INDEX_HTML): $(HTTPSERVER_OPTIONS_FILE) $(HTTPSERVER_PACKAGES_FILE)
$(HTTPSERVER_INDEX_HTML): $(HTTPSERVER_OPTIONS_FILE) $(HTTPSERVER_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(HTTPSERVER_OPTIONS_FILE),$(HTTPSERVER_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@ -887,7 +883,7 @@ ALL_OTHER_TARGETS += mgmtdocs
MGMT_DOCDIR := $(JRE_API_DOCSDIR)/management/extension
MGMT2COREAPI := ../../$(JDKJRE2COREAPI)
JVM_MIB_NAME := JVM-MANAGEMENT-MIB.mib
JVM_MIB_SRC := $(CLOSED_SRC)/share/classes/sun/management/snmp/$(JVM_MIB_NAME)
JVM_MIB_SRC := $(JDK_TOPDIR)/src/closed/share/classes/sun/management/snmp/$(JVM_MIB_NAME)
MGMT_DOCTITLE := Monitoring and Management Interface for the Java$(TRADEMARK) Platform
MGMT_WINDOWTITLE := Monitoring and Management Interface for the Java Platform
MGMT_HEADER := <strong>Monitoring and Management Interface for the Java Platform</strong>
@ -906,7 +902,7 @@ mgmtdocs: $(MGMT_INDEX_FILE)
$(MGMT_INDEX_FILE): GET2DOCSDIR=$(MGMT2COREAPI)/..
# Run javadoc if the index file is out of date or missing
$(MGMT_INDEX_FILE): $(MGMT_OPTIONS_FILE) $(MGMT_PACKAGES_FILE)
$(MGMT_INDEX_FILE): $(MGMT_OPTIONS_FILE) $(MGMT_PACKAGES_FILE) coredocs
$(prep-javadoc)
@if [ -f $(JVM_MIB_SRC) ] ; then \
$(ECHO) "$(CP) $(JVM_MIB_SRC) $(@D)/.."; \
@ -963,7 +959,7 @@ attachdocs: $(ATTACH_INDEX_HTML)
$(ATTACH_INDEX_HTML): GET2DOCSDIR=$(ATTACH2COREAPI)/..
# Run javadoc if the index file is out of date or missing
$(ATTACH_INDEX_HTML): $(ATTACH_OPTIONS_FILE) $(ATTACH_PACKAGES_FILE)
$(ATTACH_INDEX_HTML): $(ATTACH_OPTIONS_FILE) $(ATTACH_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(ATTACH_OPTIONS_FILE),$(ATTACH_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@ -1013,7 +1009,7 @@ jconsoledocs: $(JCONSOLE_INDEX_HTML)
$(JCONSOLE_INDEX_HTML): GET2DOCSDIR=$(JCONSOLE2COREAPI)/..
# Run javadoc if the index file is out of date or missing
$(JCONSOLE_INDEX_HTML): $(JCONSOLE_OPTIONS_FILE) $(JCONSOLE_PACKAGES_FILE)
$(JCONSOLE_INDEX_HTML): $(JCONSOLE_OPTIONS_FILE) $(JCONSOLE_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(JCONSOLE_OPTIONS_FILE),$(JCONSOLE_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@ -1065,7 +1061,7 @@ treeapidocs: $(TREEAPI_INDEX_HTML)
$(TREEAPI_INDEX_HTML): GET2DOCSDIR=$(TREEAPI2COREAPI)/..
# Run javadoc if the index file is out of date or missing
$(TREEAPI_INDEX_HTML): $(TREEAPI_OPTIONS_FILE) $(TREEAPI_PACKAGES_FILE)
$(TREEAPI_INDEX_HTML): $(TREEAPI_OPTIONS_FILE) $(TREEAPI_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(TREEAPI_OPTIONS_FILE),$(TREEAPI_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@ -1116,7 +1112,7 @@ sctpdocs: $(SCTPAPI_INDEX_HTML)
$(SCTPAPI_INDEX_HTML): GET2DOCSDIR=$(SCTPAPI2COREAPI)/..
# Run javadoc if the index file is out of date or missing
$(SCTPAPI_INDEX_HTML): $(SCTPAPI_OPTIONS_FILE) $(SCTPAPI_PACKAGES_FILE)
$(SCTPAPI_INDEX_HTML): $(SCTPAPI_OPTIONS_FILE) $(SCTPAPI_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(SCTPAPI_OPTIONS_FILE),$(SCTPAPI_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \

View File

@ -185,3 +185,5 @@ d54dc53e223ed9ce7d5f4d2cd02ad9d5def3c2db jdk8-b59
0e08ba7648fb3faa0986cb217887d7c4990977f3 jdk8-b61
08afb9c6f44f11c3595b01fd0985db64b29834dd jdk8-b62
6ccbf67b68bfed1ab9c44ab8748a5bdc7df33506 jdk8-b63
54d599a5b4aad83c235d590652fc81f41c2824fb jdk8-b64
5132f7900a8f0c30c3ca7f7a32f9433f4fee7745 jdk8-b65

View File

@ -291,3 +291,7 @@ dccd40de8db1fa96f186e6179907818d75320440 jdk8-b62
dc16fe422c535ecd4e9f80fb814a1bb9704da6f5 hs25-b07
acabb5c282f59be7e3238920b2ea06b684ab68f7 jdk8-b63
8cb93eadfb6dcab88d91b8e2cd3e0e07d0ac4048 hs25-b08
5920f72e799c8133d1066c4a62fa1fafcb729966 jdk8-b64
b4ee7b773144a88af8b6b92e4384dea82cb948d8 hs25-b09
0f7290a03b24bd562583fa325d3566c21c51fb94 jdk8-b65
cfc5309f03b7bd6c1567618b63cf1fc74c0f2a8f hs25-b10

View File

@ -0,0 +1,41 @@
<html>
<head>
<title>
C2 Replay
</title>
</head>
<body>
<h1>C2 compiler replay</h1>
<p>
The C2 compiler replay is a function to repeat the compiling process from a crashed java process in compiled method<br>
This function only exists in debug version of VM
</p>
<h2>Usage</h2>
<pre>
First, use SA to attach to the core file, if suceeded, do
clhsdb>dumpreplaydata <address> | -a | <thread_id> [> replay.txt]
create file replay.txt, address is address of Method, or nmethod(CodeBlob)
clhsdb>buildreplayjars [all | boot | app]
create files:
all:
app.jar, boot.jar
boot:
boot.jar
app:
app.jar
exit SA now.
Second, use the obtained replay text file, replay.txt and jar files, app.jar and boot.jar, using debug version of java
java -Xbootclasspath/p:boot.jar -cp app.jar -XX:ReplayDataFile=<datafile> -XX:+ReplayCompiles ....
This will replay the compiling process.
With ReplayCompiles, the replay will recompile all the methods in app.jar, and in boot.jar to emulate the process in java app.
notes:
1) Most time, we don't need the boot.jar which is the classes loaded from JDK. It will be only modified when an agent(JVMDI) is running and modifies the classes.
2) If encounter error as "<flag>" not found, that means the SA is using a VMStructs which is different from the one with corefile. In this case, SA has a utility tool vmstructsdump which is located at agent/src/os/<os>/proc/<os_platform>
Use this tool to dump VM type library:
vmstructsdump libjvm.so > <type_name>.db
set env SA_TYPEDB=<type_name>.db (refer different shell for set envs)

View File

@ -37,12 +37,19 @@ Each CLHSDB command can have zero or more arguments and optionally end with outp
Available commands:
assert true | false <font color="red">turn on/off asserts in SA code</font>
attach pid | exec core <font color="red">attach SA to a process or core</font>
buildreplayjars [all | boot | app] <font color="red">build jars for replay, boot.jar for bootclasses, app.jar for application classes</font>
class name <font color="red">find a Java class from debuggee and print oop</font>
classes <font color="red">print all loaded Java classes with Klass*</font>
detach <font color="red">detach SA from current target</font>
dis address [ length ] <font color="red">disassemble (sparc/x86) specified number of instructions from given address</font>
dissemble address <font color="red">disassemble nmethod</font>
dumpcfg -a | id <font color="red">Dump the PhaseCFG for every compiler thread that has one live</font>
dumpclass { address | name } [ directory ] <font color="red">dump .class file for given Klass* or class name</font>
dumpcodecache <font color="red">dump codecache contents</font>
dumpheap [ file ] <font color="red">dump heap in hprof binary format</font>
dumpideal -a | id <font color="red">dump ideal graph like debug flag -XX:+PrintIdeal</font>
dumpilt -a | id <font color="red">dump inline tree for C2 compilation</font>
dumpreplaydata <address> | -a | <thread_id> [>replay.txt] <font color="red">dump replay data into a file</font>
echo [ true | false ] <font color="red">turn on/off command echo mode</font>
examine [ address/count ] | [ address,address] <font color="red">show contents of memory from given address</font>
field [ type [ name fieldtype isStatic offset address ] ] <font color="red">print info about a field of HotSpot type</font>
@ -51,29 +58,35 @@ Available commands:
help [ command ] <font color="red">print help message for all commands or just given command</font>
history <font color="red">show command history. usual !command-number syntax works.</font>
inspect expression <font color="red">inspect a given oop</font>
intConstant [ name [ value ] ] <font color="red">print out hotspot integer constant(s)</font>
jdis address <font color="red">show bytecode disassembly of a given Method*</font>
jhisto <font color="red">show Java heap histogram</font>
jseval script <font color="red">evaluate a given string as JavaScript code</font>
jsload file <font color="red">load and evaluate a JavaScript file</font>
jstack [-v] <font color="red">show Java stack trace of all Java threads. -v is verbose mode</font>
livenmethods <font color="red">show all live nmethods</font>
longConstant [ name [ value ] ] <font color="red">print out hotspot long constant(s)s</font>
mem address [ length ] <font color="red">show contents of memory -- also shows closest ELF/COFF symbol if found</font>
pmap <font color="red">show Solaris pmap-like output</font>
print expression <font color="red">print given Klass*, Method* or arbitrary address</font>
printas type expression <font color="red">print given address as given HotSpot type. eg. print JavaThread &lt;address&gt;</font>
printmdo -a | expression <font color="red">print method data oop</font>
printstatics [ type ] <font color="red">print static fields of given HotSpot type (or all types if none specified)</font>
pstack [-v] <font color="red">show mixed mode stack trace for all Java, non-Java threads. -v is verbose mode</font>
quit <font color="red">quit CLHSDB tool</font>
reattach <font color="red">detach and re-attach SA to current target</font>
revptrs <font color="red">find liveness of oops</font>
scanoops start end [ type ] <font color="red">scan a Oop from given start to end address</font>
search [ heap | codecache | threads ] value <font color="red">search a value in heap or codecache or threads</font>
source filename <font color="red">load and execute CLHSDB commands from given file</font>
symbol name <font color="red">show address of a given ELF/COFF symbol</font>
sysprops <font color="red">show all Java System properties</font>
thread id <font color="red">show thread of id</font>
threads <font color="red">show all Java threads</font>
tokenize ...
type [ type [ name super isOop isInteger isUnsigned size ] ] <font color="red">show info. on HotSpot type</font>
universe <font color="red">print gc universe</font>
vmstructsdump <font color="red">dump hotspot type library in text</font>
verbose true | false <font color="red">turn on/off verbose mode</font>
versioncheck [ true | false ] <font color="red">turn on/off debuggee VM version check</font>
whatis address <font color="red">print info about any arbitrary address</font>
@ -114,5 +127,11 @@ hsdb&gt; jsload test.js
</code>
</pre>
<h3>C2 Compilation Replay</h3>
<p>
When a java process crashes in compiled method, usually a core file is saved.
The C2 replay function can reproduce the compiling process in the core.
<a href="c2replay.html">c2replay.html</a>
</body>
</html>

View File

@ -220,6 +220,12 @@ These scripts are used to run SA remotely.
</tr>
</table>
<h3>C2 Compilation Replay</h3>
<p>
When a java process crashes in compiled method, usually a core file is saved.
The C2 replay function can reproduce the compiling process in the core.
<a href="c2replay.html">c2replay.html</a>
<h3>Debugging transported core dumps</h3>
<p>
When a core dump is moved from the machine where it was produced to a

View File

@ -58,10 +58,8 @@ sun.jvm.hotspot.debugger.cdbg.basic \
sun.jvm.hotspot.debugger.cdbg.basic.amd64 \
sun.jvm.hotspot.debugger.cdbg.basic.x86 \
sun.jvm.hotspot.debugger.dummy \
sun.jvm.hotspot.debugger.ia64 \
sun.jvm.hotspot.debugger.linux \
sun.jvm.hotspot.debugger.linux.amd64 \
sun.jvm.hotspot.debugger.linux.ia64 \
sun.jvm.hotspot.debugger.linux.x86 \
sun.jvm.hotspot.debugger.posix \
sun.jvm.hotspot.debugger.posix.elf \
@ -77,7 +75,6 @@ sun.jvm.hotspot.debugger.sparc \
sun.jvm.hotspot.debugger.win32.coff \
sun.jvm.hotspot.debugger.windbg \
sun.jvm.hotspot.debugger.windbg.amd64 \
sun.jvm.hotspot.debugger.windbg.ia64 \
sun.jvm.hotspot.debugger.windbg.x86 \
sun.jvm.hotspot.debugger.x86 \
sun.jvm.hotspot.gc_implementation \
@ -97,10 +94,8 @@ sun.jvm.hotspot.runtime.amd64 \
sun.jvm.hotspot.runtime.bsd \
sun.jvm.hotspot.runtime.bsd_amd64 \
sun.jvm.hotspot.runtime.bsd_x86 \
sun.jvm.hotspot.runtime.ia64 \
sun.jvm.hotspot.runtime.linux \
sun.jvm.hotspot.runtime.linux_amd64 \
sun.jvm.hotspot.runtime.linux_ia64 \
sun.jvm.hotspot.runtime.linux_sparc \
sun.jvm.hotspot.runtime.linux_x86 \
sun.jvm.hotspot.runtime.posix \
@ -109,7 +104,6 @@ sun.jvm.hotspot.runtime.solaris_sparc \
sun.jvm.hotspot.runtime.solaris_x86 \
sun.jvm.hotspot.runtime.sparc \
sun.jvm.hotspot.runtime.win32_amd64 \
sun.jvm.hotspot.runtime.win32_ia64 \
sun.jvm.hotspot.runtime.win32_x86 \
sun.jvm.hotspot.runtime.x86 \
sun.jvm.hotspot.tools \
@ -152,7 +146,6 @@ sun/jvm/hotspot/debugger/cdbg/basic/*.java \
sun/jvm/hotspot/debugger/cdbg/basic/amd64/*.java \
sun/jvm/hotspot/debugger/cdbg/basic/x86/*.java \
sun/jvm/hotspot/debugger/dummy/*.java \
sun/jvm/hotspot/debugger/ia64/*.java \
sun/jvm/hotspot/debugger/linux/*.java \
sun/jvm/hotspot/debugger/linux/x86/*.java \
sun/jvm/hotspot/debugger/posix/*.java \
@ -168,7 +161,6 @@ sun/jvm/hotspot/debugger/remote/x86/*.java \
sun/jvm/hotspot/debugger/sparc/*.java \
sun/jvm/hotspot/debugger/win32/coff/*.java \
sun/jvm/hotspot/debugger/windbg/*.java \
sun/jvm/hotspot/debugger/windbg/ia64/*.java \
sun/jvm/hotspot/debugger/windbg/x86/*.java \
sun/jvm/hotspot/debugger/x86/*.java \
sun/jvm/hotspot/gc_implementation/g1/*.java \
@ -186,10 +178,8 @@ sun/jvm/hotspot/runtime/amd64/*.java \
sun/jvm/hotspot/runtime/bsd/*.java \
sun/jvm/hotspot/runtime/bsd_amd64/*.java \
sun/jvm/hotspot/runtime/bsd_x86/*.java \
sun/jvm/hotspot/runtime/ia64/*.java \
sun/jvm/hotspot/runtime/linux/*.java \
sun/jvm/hotspot/runtime/linux_amd64/*.java \
sun/jvm/hotspot/runtime/linux_ia64/*.java \
sun/jvm/hotspot/runtime/linux_sparc/*.java \
sun/jvm/hotspot/runtime/linux_x86/*.java \
sun/jvm/hotspot/runtime/posix/*.java \
@ -198,7 +188,6 @@ sun/jvm/hotspot/runtime/solaris_sparc/*.java \
sun/jvm/hotspot/runtime/solaris_x86/*.java \
sun/jvm/hotspot/runtime/sparc/*.java \
sun/jvm/hotspot/runtime/win32_amd64/*.java \
sun/jvm/hotspot/runtime/win32_ia64/*.java \
sun/jvm/hotspot/runtime/win32_x86/*.java \
sun/jvm/hotspot/runtime/x86/*.java \
sun/jvm/hotspot/tools/*.java \
@ -258,6 +247,7 @@ SA_BUILD_VERSION_PROP = "sun.jvm.hotspot.runtime.VM.saBuildVersion=$(SA_BUILD_VE
SA_PROPERTIES = $(OUTPUT_DIR)/sa.properties
JAVAC = $(JDK_HOME)/bin/javac
JAVA = $(JDK_HOME)/bin/java
JAVADOC = $(JDK_HOME)/bin/javadoc
RMIC = $(JDK_HOME)/bin/rmic
@ -298,7 +288,7 @@ filelist: $(ALLFILES)
.PHONY: natives
natives:
cd ../src/os/`java -classpath $(OUTPUT_DIR) sun.jvm.hotspot.utilities.PlatformInfo`; $(MAKE) all
cd ../src/os/`$(JAVA) -classpath $(OUTPUT_DIR) sun.jvm.hotspot.utilities.PlatformInfo`; $(MAKE) all
.PHONY: sa-jdi.jar
sa-jdi.jar:
@ -323,5 +313,5 @@ sa.jar:
clean::
rm -rf filelist
cd ../src/os/`java -classpath $(OUTPUT_DIR) sun.jvm.hotspot.utilities.PlatformInfo`; $(MAKE) clean
cd ../src/os/`$(JAVA) -classpath $(OUTPUT_DIR) sun.jvm.hotspot.utilities.PlatformInfo`; $(MAKE) clean
rm -rf $(BUILD_DIR)/*

View File

@ -33,6 +33,7 @@ import sun.jvm.hotspot.types.Type;
import sun.jvm.hotspot.types.Field;
import sun.jvm.hotspot.HotSpotTypeDataBase;
import sun.jvm.hotspot.types.basic.BasicType;
import sun.jvm.hotspot.types.basic.BasicTypeDataBase;
import sun.jvm.hotspot.types.CIntegerType;
import sun.jvm.hotspot.code.*;
import sun.jvm.hotspot.compiler.*;
@ -448,6 +449,112 @@ public class CommandProcessor {
}
}
},
new Command("dumpreplaydata", "dumpreplaydata { <address > | -a | <thread_id> }", false) {
// This is used to dump replay data from ciInstanceKlass, ciMethodData etc
// default file name is replay.txt, also if java crashes in compiler
// thread, this file will be dumped in error processing.
public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
return;
}
String name = t.nextToken();
Address a = null;
try {
a = VM.getVM().getDebugger().parseAddress(name);
} catch (NumberFormatException e) { }
if (a != null) {
// only nmethod, Method, MethodData and InstanceKlass needed to
// dump replay data
CodeBlob cb = VM.getVM().getCodeCache().findBlob(a);
if (cb != null && (cb instanceof NMethod)) {
((NMethod)cb).dumpReplayData(out);
return;
}
// assume it is Metadata
Metadata meta = Metadata.instantiateWrapperFor(a);
if (meta != null) {
meta.dumpReplayData(out);
} else {
usage();
return;
}
}
// Not an address
boolean all = name.equals("-a");
Threads threads = VM.getVM().getThreads();
for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
thread.printThreadIDOn(new PrintStream(bos));
if (all || bos.toString().equals(name)) {
if (thread instanceof CompilerThread) {
CompilerThread ct = (CompilerThread)thread;
ciEnv env = ct.env();
if (env != null) {
env.dumpReplayData(out);
}
}
}
}
}
},
new Command("buildreplayjars", "buildreplayjars [ all | app | boot ] | [ prefix ]", false) {
// This is used to dump jar files of all the classes
// loaded in the core. Everything on the bootclasspath
// will go in boot.jar and everything else will go in
// app.jar. Then the classes can be loaded by the replay
// jvm using -Xbootclasspath/p:boot.jar -cp app.jar. boot.jar usually
// not needed, unless changed by jvmti.
public void doit(Tokens t) {
int tcount = t.countTokens();
if (tcount > 2) {
usage();
return;
}
try {
String prefix = "";
String option = "all"; // default
switch(tcount) {
case 0:
break;
case 1:
option = t.nextToken();
if (!option.equalsIgnoreCase("all") && !option.equalsIgnoreCase("app") &&
!option.equalsIgnoreCase("root")) {
prefix = option;
option = "all";
}
break;
case 2:
option = t.nextToken();
prefix = t.nextToken();
break;
default:
usage();
return;
}
if (!option.equalsIgnoreCase("all") && !option.equalsIgnoreCase("app") &&
!option.equalsIgnoreCase("boot")) {
usage();
return;
}
ClassDump cd = new ClassDump();
if (option.equalsIgnoreCase("all") || option.equalsIgnoreCase("boot")) {
cd.setClassFilter(new BootFilter());
cd.setJarOutput(prefix + "boot.jar");
cd.run();
}
if (option.equalsIgnoreCase("all") || option.equalsIgnoreCase("app")) {
cd.setClassFilter(new NonBootFilter());
cd.setJarOutput(prefix + "app.jar");
cd.run();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
},
new Command("findpc", "findpc address", false) {
public void doit(Tokens t) {
if (t.countTokens() != 1) {

View File

@ -16,9 +16,9 @@
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
* 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.
*
*/
@ -50,4 +50,8 @@ public class ciBaseObject extends VMObject {
public ciBaseObject(Address addr) {
super(addr);
}
public void dumpReplayData(PrintStream out) {
out.println("# Unknown ci type " + getAddress().getAddressAt(0));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2012, 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
@ -16,9 +16,9 @@
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
* 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.
*
*/
@ -60,4 +60,8 @@ public class ciConstant extends VMObject {
public ciConstant(Address addr) {
super(addr);
}
public void dumpReplayData(PrintStream out) {
// Nothing to be done
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2012, 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
@ -16,9 +16,9 @@
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
* 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.
*
*/
@ -74,4 +74,29 @@ public class ciEnv extends VMObject {
public CompileTask task() {
return new CompileTask(taskField.getValue(this.getAddress()));
}
public void dumpReplayData(PrintStream out) {
out.println("JvmtiExport can_access_local_variables " +
(JvmtiExport.canAccessLocalVariables() ? '1' : '0'));
out.println("JvmtiExport can_hotswap_or_post_breakpoint " +
(JvmtiExport.canHotswapOrPostBreakpoint() ? '1' : '0'));
out.println("JvmtiExport can_post_on_exceptions " +
(JvmtiExport.canPostOnExceptions() ? '1' : '0'));
GrowableArray<ciMetadata> objects = factory().objects();
out.println("# " + objects.length() + " ciObject found");
for (int i = 0; i < objects.length(); i++) {
ciMetadata o = objects.at(i);
out.println("# ciMetadata" + i + " @ " + o);
o.dumpReplayData(out);
}
CompileTask task = task();
Method method = task.method();
int entryBci = task.osrBci();
Klass holder = method.getMethodHolder();
out.println("compile " + holder.getName().asString() + " " +
OopUtilities.escapeString(method.getName().asString()) + " " +
method.getSignature().asString() + " " +
entryBci);
}
}

View File

@ -16,9 +16,9 @@
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
* 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.
*
*/
@ -80,4 +80,84 @@ public class ciInstanceKlass extends ciKlass {
public boolean isInitialized() {
return initState() == CLASS_STATE_FULLY_INITIALIZED;
}
public void dumpReplayData(PrintStream out) {
InstanceKlass ik = (InstanceKlass)getMetadata();
ConstantPool cp = ik.getConstants();
// Try to record related loaded classes
Klass sub = ik.getSubklassKlass();
while (sub != null) {
if (sub instanceof InstanceKlass) {
out.println("instanceKlass " + sub.getName().asString());
}
sub = sub.getNextSiblingKlass();
}
final int length = (int) cp.getLength();
out.print("ciInstanceKlass " + name() + " " + (isLinked() ? 1 : 0) + " " + (isInitialized() ? 1 : 0) + " " + length);
for (int index = 1; index < length; index++) {
out.print(" " + cp.getTags().at(index));
}
out.println();
if (isInitialized()) {
Field[] staticFields = ik.getStaticFields();
for (int i = 0; i < staticFields.length; i++) {
Field f = staticFields[i];
Oop mirror = ik.getJavaMirror();
if (f.isFinal() && !f.hasInitialValue()) {
out.print("staticfield " + name() + " " +
OopUtilities.escapeString(f.getID().getName()) + " " +
f.getFieldType().getSignature().asString() + " ");
if (f instanceof ByteField) {
ByteField bf = (ByteField)f;
out.println(bf.getValue(mirror));
} else if (f instanceof BooleanField) {
BooleanField bf = (BooleanField)f;
out.println(bf.getValue(mirror) ? 1 : 0);
} else if (f instanceof ShortField) {
ShortField bf = (ShortField)f;
out.println(bf.getValue(mirror));
} else if (f instanceof CharField) {
CharField bf = (CharField)f;
out.println(bf.getValue(mirror) & 0xffff);
} else if (f instanceof IntField) {
IntField bf = (IntField)f;
out.println(bf.getValue(mirror));
} else if (f instanceof LongField) {
LongField bf = (LongField)f;
out.println(bf.getValue(mirror));
} else if (f instanceof FloatField) {
FloatField bf = (FloatField)f;
out.println(Float.floatToRawIntBits(bf.getValue(mirror)));
} else if (f instanceof DoubleField) {
DoubleField bf = (DoubleField)f;
out.println(Double.doubleToRawLongBits(bf.getValue(mirror)));
} else if (f instanceof OopField) {
OopField bf = (OopField)f;
Oop value = bf.getValue(mirror);
if (value == null) {
out.println("null");
} else if (value.isInstance()) {
Instance inst = (Instance)value;
if (inst.isA(SystemDictionary.getStringKlass())) {
out.println("\"" + OopUtilities.stringOopToEscapedString(inst) + "\"");
} else {
out.println(inst.getKlass().getName().asString());
}
} else if (value.isObjArray()) {
ObjArray oa = (ObjArray)value;
Klass ek = (ObjArrayKlass)oa.getKlass();
out.println(oa.getLength() + " " + ek.getName().asString());
} else if (value.isTypeArray()) {
TypeArray ta = (TypeArray)value;
out.println(ta.getLength());
} else {
out.println(value);
}
}
}
}
}
}
}

View File

@ -16,9 +16,9 @@
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
* 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.
*
*/
@ -88,4 +88,19 @@ public class ciMethod extends ciMetadata {
st.printf(" %s::%s", method.getMethodHolder().getName().asString().replace('/', '.'),
method.getName().asString());
}
public void dumpReplayData(PrintStream out) {
Method method = (Method)getMetadata();
NMethod nm = method.getNativeMethod();
Klass holder = method.getMethodHolder();
out.println("ciMethod " +
holder.getName().asString() + " " +
OopUtilities.escapeString(method.getName().asString()) + " " +
method.getSignature().asString() + " " +
method.getInvocationCounter() + " " +
method.getBackedgeCounter() + " " +
interpreterInvocationCount() + " " +
interpreterThrowoutCount() + " " +
instructionsSize());
}
}

View File

@ -16,9 +16,9 @@
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
* 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.
*
*/
@ -174,4 +174,52 @@ public class ciMethodData extends ciMetadata {
}
}
public void dumpReplayData(PrintStream out) {
MethodData mdo = (MethodData)getMetadata();
Method method = mdo.getMethod();
Klass holder = method.getMethodHolder();
out.print("ciMethodData " +
holder.getName().asString() + " " +
OopUtilities.escapeString(method.getName().asString()) + " " +
method.getSignature().asString() + " " +
state() + " " + currentMileage());
byte[] orig = orig();
out.print(" orig " + orig.length);
for (int i = 0; i < orig.length; i++) {
out.print(" " + (orig[i] & 0xff));
}
long[] data = data();
out.print(" data " + data.length);
for (int i = 0; i < data.length; i++) {
out.print(" 0x" + Long.toHexString(data[i]));
}
int count = 0;
for (int round = 0; round < 2; round++) {
if (round == 1) out.print(" oops " + count);
ProfileData pdata = firstData();
for ( ; isValid(pdata); pdata = nextData(pdata)) {
if (pdata instanceof ciReceiverTypeData) {
ciReceiverTypeData vdata = (ciReceiverTypeData)pdata;
for (int i = 0; i < vdata.rowLimit(); i++) {
ciKlass k = vdata.receiverAt(i);
if (k != null) {
if (round == 0) count++;
else out.print(" " + ((vdata.dp() + vdata.cellOffset(vdata.receiverCellIndex(i))) / MethodData.cellSize) + " " + k.name());
}
}
} else if (pdata instanceof ciVirtualCallData) {
ciVirtualCallData vdata = (ciVirtualCallData)pdata;
for (int i = 0; i < vdata.rowLimit(); i++) {
ciKlass k = vdata.receiverAt(i);
if (k != null) {
if (round == 0) count++;
else out.print(" " + ((vdata.dp() + vdata.cellOffset(vdata.receiverCellIndex(i))) / MethodData.cellSize + " " + k.name()));
}
}
}
}
}
out.println();
}
}

View File

@ -498,6 +498,42 @@ public class NMethod extends CodeBlob {
method.getSignature().asString();
}
public void dumpReplayData(PrintStream out) {
HashMap h = new HashMap();
for (int i = 1; i < getMetadataLength(); i++) {
Metadata meta = Metadata.instantiateWrapperFor(getMetadataAt(i));
System.err.println(meta);
if (h.get(meta) != null) continue;
h.put(meta, meta);
if (meta instanceof InstanceKlass) {
((InstanceKlass)meta).dumpReplayData(out);
} else if (meta instanceof Method) {
((Method)meta).dumpReplayData(out);
MethodData mdo = ((Method)meta).getMethodData();
if (mdo != null) {
mdo.dumpReplayData(out);
}
}
}
Method method = getMethod();
if (h.get(method) == null) {
method.dumpReplayData(out);
MethodData mdo = method.getMethodData();
if (mdo != null) {
mdo.dumpReplayData(out);
}
}
if (h.get(method.getMethodHolder()) == null) {
((InstanceKlass)method.getMethodHolder()).dumpReplayData(out);
}
Klass holder = method.getMethodHolder();
out.println("compile " + holder.getName().asString() + " " +
OopUtilities.escapeString(method.getName().asString()) + " " +
method.getSignature().asString() + " " +
getEntryBCI());
}
//--------------------------------------------------------------------------------
// Internals only below this point
//

View File

@ -56,7 +56,7 @@ public class CompileTask extends VMObject {
}
public Method method() {
Address oh = methodField.getValue(getAddress()).getAddressAt(0);
Address oh = methodField.getValue(getAddress());
return (Method)Metadata.instantiateWrapperFor(oh);
}

View File

@ -121,7 +121,7 @@ public class ConstantPool extends Metadata implements ClassConstants {
Address addr = cache.getValue(getAddress());
return (ConstantPoolCache) VMObjectFactory.newObject(ConstantPoolCache.class, addr);
}
public Klass getPoolHolder() { return (Klass) poolHolder.getValue(this); }
public InstanceKlass getPoolHolder() { return (InstanceKlass)poolHolder.getValue(this); }
public int getLength() { return (int)length.getValue(getAddress()); }
public Oop getResolvedReferences() {
Address handle = resolvedReferences.getValue(getAddress());

View File

@ -86,7 +86,7 @@ public class ConstantPoolCache extends Metadata {
public void printValueOn(PrintStream tty) {
tty.print("ConstantPoolCache for " + getConstants().getPoolHolder().getName().asString());
tty.print("ConstantPoolCache for " + getConstants().getPoolHolder().getName().asString() + " address = " + getAddress() + " offset = " + baseOffset);
}
public int getLength() {

View File

@ -110,6 +110,8 @@ public class Field {
public Symbol getSignature() { return signature; }
public Symbol getGenericSignature() { return genericSignature; }
public boolean hasInitialValue() { return holder.getFieldInitialValueIndex(fieldIndex) != 0; }
//
// Following acccessors are for named, non-VM fields only
//

View File

@ -278,7 +278,7 @@ public class InstanceKlass extends Klass {
}
public short getFieldGenericSignatureIndex(int index) {
int len = getFields().length();
// int len = getFields().length();
int allFieldsCount = getAllFieldsCount();
int generic_signature_slot = allFieldsCount * FIELD_SLOTS;
for (int i = 0; i < allFieldsCount; i++) {
@ -325,7 +325,7 @@ public class InstanceKlass extends Klass {
public KlassArray getTransitiveInterfaces() { return new KlassArray(transitiveInterfaces.getValue(getAddress())); }
public int getJavaFieldsCount() { return (int) javaFieldsCount.getValue(this); }
public int getAllFieldsCount() {
int len = getFields().length();
int len = getFields().length();
int allFieldsCount = 0;
for (; allFieldsCount*FIELD_SLOTS < len; allFieldsCount++) {
short flags = getFieldAccessFlags(allFieldsCount);
@ -581,6 +581,19 @@ public class InstanceKlass extends Klass {
}
}
public Field[] getStaticFields() {
U2Array fields = getFields();
int length = getJavaFieldsCount();
ArrayList result = new ArrayList();
for (int index = 0; index < length; index++) {
Field f = newField(index);
if (f.isStatic()) {
result.add(f);
}
}
return (Field[])result.toArray(new Field[result.size()]);
}
public void iterateNonStaticFields(OopVisitor visitor, Oop obj) {
if (getSuper() != null) {
((InstanceKlass) getSuper()).iterateNonStaticFields(visitor, obj);
@ -979,4 +992,84 @@ public class InstanceKlass extends Klass {
}
return -1;
}
public void dumpReplayData(PrintStream out) {
ConstantPool cp = getConstants();
// Try to record related loaded classes
Klass sub = getSubklassKlass();
while (sub != null) {
if (sub instanceof InstanceKlass) {
out.println("instanceKlass " + sub.getName().asString());
}
sub = sub.getNextSiblingKlass();
}
final int length = (int) cp.getLength();
out.print("ciInstanceKlass " + getName().asString() + " " + (isLinked() ? 1 : 0) + " " + (isInitialized() ? 1 : 0) + " " + length);
for (int index = 1; index < length; index++) {
out.print(" " + cp.getTags().at(index));
}
out.println();
if (isInitialized()) {
Field[] staticFields = getStaticFields();
for (int i = 0; i < staticFields.length; i++) {
Field f = staticFields[i];
Oop mirror = getJavaMirror();
if (f.isFinal() && !f.hasInitialValue()) {
out.print("staticfield " + getName().asString() + " " +
OopUtilities.escapeString(f.getID().getName()) + " " +
f.getFieldType().getSignature().asString() + " ");
if (f instanceof ByteField) {
ByteField bf = (ByteField)f;
out.println(bf.getValue(mirror));
} else if (f instanceof BooleanField) {
BooleanField bf = (BooleanField)f;
out.println(bf.getValue(mirror) ? 1 : 0);
} else if (f instanceof ShortField) {
ShortField bf = (ShortField)f;
out.println(bf.getValue(mirror));
} else if (f instanceof CharField) {
CharField bf = (CharField)f;
out.println(bf.getValue(mirror) & 0xffff);
} else if (f instanceof IntField) {
IntField bf = (IntField)f;
out.println(bf.getValue(mirror));
} else if (f instanceof LongField) {
LongField bf = (LongField)f;
out.println(bf.getValue(mirror));
} else if (f instanceof FloatField) {
FloatField bf = (FloatField)f;
out.println(Float.floatToRawIntBits(bf.getValue(mirror)));
} else if (f instanceof DoubleField) {
DoubleField bf = (DoubleField)f;
out.println(Double.doubleToRawLongBits(bf.getValue(mirror)));
} else if (f instanceof OopField) {
OopField bf = (OopField)f;
Oop value = bf.getValue(mirror);
if (value == null) {
out.println("null");
} else if (value.isInstance()) {
Instance inst = (Instance)value;
if (inst.isA(SystemDictionary.getStringKlass())) {
out.println("\"" + OopUtilities.stringOopToEscapedString(inst) + "\"");
} else {
out.println(inst.getKlass().getName().asString());
}
} else if (value.isObjArray()) {
ObjArray oa = (ObjArray)value;
Klass ek = (ObjArrayKlass)oa.getKlass();
out.println(oa.getLength() + " " + ek.getName().asString());
} else if (value.isTypeArray()) {
TypeArray ta = (TypeArray)value;
out.println(ta.getLength());
} else {
out.println(value);
}
}
}
}
}
}
}

View File

@ -79,4 +79,7 @@ abstract public class Metadata extends VMObject {
}
abstract public void printValueOn(PrintStream tty);
public void dumpReplayData(PrintStream out) {
out.println("# Unknown Metadata");
}
}

View File

@ -177,7 +177,7 @@ public class Method extends Metadata {
bci. It is required that there is currently a bytecode at this
bci. */
public int getOrigBytecodeAt(int bci) {
BreakpointInfo bp = ((InstanceKlass) getMethodHolder()).getBreakpoints();
BreakpointInfo bp = getMethodHolder().getBreakpoints();
for (; bp != null; bp = bp.getNext()) {
if (bp.match(this, bci)) {
return bp.getOrigBytecode();
@ -238,7 +238,7 @@ public class Method extends Metadata {
}
// Method holder (the Klass holding this method)
public Klass getMethodHolder() { return getConstants().getPoolHolder(); }
public InstanceKlass getMethodHolder() { return getConstants().getPoolHolder(); }
// Access flags
public boolean isPublic() { return getAccessFlagsObj().isPublic(); }
@ -358,6 +358,25 @@ public class Method extends Metadata {
buf.append(")");
return buf.toString().replace('/', '.');
}
public void dumpReplayData(PrintStream out) {
NMethod nm = getNativeMethod();
int code_size = 0;
if (nm != null) {
code_size = (int)nm.codeEnd().minus(nm.getVerifiedEntryPoint());
}
Klass holder = getMethodHolder();
out.println("ciMethod " +
holder.getName().asString() + " " +
OopUtilities.escapeString(getName().asString()) + " " +
getSignature().asString() + " " +
getInvocationCounter() + " " +
getBackedgeCounter() + " " +
interpreterInvocationCount() + " " +
interpreterThrowoutCount() + " " +
code_size);
}
public int interpreterThrowoutCount() {
return (int) interpreterThrowoutCountField.getValue(this);
}

View File

@ -332,4 +332,59 @@ public class MethodData extends Metadata {
public int currentMileage() {
return 20000;
}
public void dumpReplayData(PrintStream out) {
Method method = getMethod();
Klass holder = method.getMethodHolder();
out.print("ciMethodData " +
holder.getName().asString() + " " +
OopUtilities.escapeString(method.getName().asString()) + " " +
method.getSignature().asString() + " " +
"2" + " " +
currentMileage());
byte[] orig = orig();
out.print(" orig " + orig.length);
for (int i = 0; i < orig.length; i++) {
out.print(" " + (orig[i] & 0xff));
}
long[] data = data();
out.print(" data " + data.length);
for (int i = 0; i < data.length; i++) {
out.print(" 0x" + Long.toHexString(data[i]));
}
int count = 0;
for (int round = 0; round < 2; round++) {
if (round == 1) out.print(" oops " + count);
ProfileData pdata = firstData();
for ( ; isValid(pdata); pdata = nextData(pdata)) {
if (pdata instanceof ReceiverTypeData) {
ReceiverTypeData vdata = (ReceiverTypeData)pdata;
for (int i = 0; i < vdata.rowLimit(); i++) {
Klass k = vdata.receiver(i);
if (k != null) {
if (round == 0) count++;
else out.print(" " +
(dpToDi(vdata.dp() +
vdata.cellOffset(vdata.receiverCellIndex(i))) / cellSize) + " " +
k.getName().asString());
}
}
} else if (pdata instanceof VirtualCallData) {
VirtualCallData vdata = (VirtualCallData)pdata;
for (int i = 0; i < vdata.rowLimit(); i++) {
Klass k = vdata.receiver(i);
if (k != null) {
if (round == 0) count++;
else out.print(" " +
(dpToDi(vdata.dp() +
vdata.cellOffset(vdata.receiverCellIndex(i))) / cellSize) + " " +
k.getName().asString());
}
}
}
}
}
out.println();
}
}

View File

@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2012
HS_MAJOR_VER=25
HS_MINOR_VER=0
HS_BUILD_NUMBER=08
HS_BUILD_NUMBER=10
JDK_MAJOR_VER=1
JDK_MINOR_VER=8

View File

@ -170,68 +170,70 @@ ifeq ($(JDK6_OR_EARLIER),0)
# overridden in some situations, e.g., a BUILD_FLAVOR != product
# build.
ifeq ($(BUILD_FLAVOR), product)
FULL_DEBUG_SYMBOLS ?= 1
ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
else
# debug variants always get Full Debug Symbols (if available)
ENABLE_FULL_DEBUG_SYMBOLS = 1
endif
_JUNK_ := $(shell \
echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
# since objcopy is optional, we set ZIP_DEBUGINFO_FILES later
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
# Default OBJCOPY comes from GNU Binutils on Linux:
DEF_OBJCOPY=/usr/bin/objcopy
ifdef CROSS_COMPILE_ARCH
# don't try to generate .debuginfo files when cross compiling
_JUNK_ := $(shell \
echo >&2 "INFO: cross compiling for ARCH $(CROSS_COMPILE_ARCH)," \
"skipping .debuginfo generation.")
OBJCOPY=
# Due to the multiple sub-make processes that occur this logic gets
# executed multiple times. We reduce the noise by at least checking that
# BUILD_FLAVOR has been set.
ifneq ($(BUILD_FLAVOR),)
ifeq ($(BUILD_FLAVOR), product)
FULL_DEBUG_SYMBOLS ?= 1
ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
else
# debug variants always get Full Debug Symbols (if available)
ENABLE_FULL_DEBUG_SYMBOLS = 1
endif
_JUNK_ := $(shell \
echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
# since objcopy is optional, we set ZIP_DEBUGINFO_FILES later
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
# Default OBJCOPY comes from GNU Binutils on Linux
ifeq ($(CROSS_COMPILE_ARCH),)
DEF_OBJCOPY=/usr/bin/objcopy
else
# Assume objcopy is part of the cross-compilation toolset
ifneq ($(ALT_COMPILER_PATH),)
DEF_OBJCOPY=$(ALT_COMPILER_PATH)/objcopy
endif
endif
OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY))
ifneq ($(ALT_OBJCOPY),)
_JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)")
OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
endif
endif
else
OBJCOPY=
endif
ifeq ($(OBJCOPY),)
_JUNK_ := $(shell \
echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.")
ENABLE_FULL_DEBUG_SYMBOLS=0
_JUNK_ := $(shell \
echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
else
_JUNK_ := $(shell \
echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.")
ifeq ($(OBJCOPY),)
_JUNK_ := $(shell \
echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files. You may need to set ALT_OBJCOPY.")
ENABLE_FULL_DEBUG_SYMBOLS=0
_JUNK_ := $(shell \
echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
else
_JUNK_ := $(shell \
echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.")
# Library stripping policies for .debuginfo configs:
# all_strip - strips everything from the library
# min_strip - strips most stuff from the library; leaves minimum symbols
# no_strip - does not strip the library at all
#
# Oracle security policy requires "all_strip". A waiver was granted on
# 2011.09.01 that permits using "min_strip" in the Java JDK and Java JRE.
#
# Currently, STRIP_POLICY is only used when Full Debug Symbols is enabled.
#
STRIP_POLICY ?= min_strip
# Library stripping policies for .debuginfo configs:
# all_strip - strips everything from the library
# min_strip - strips most stuff from the library; leaves minimum symbols
# no_strip - does not strip the library at all
#
# Oracle security policy requires "all_strip". A waiver was granted on
# 2011.09.01 that permits using "min_strip" in the Java JDK and Java JRE.
#
# Currently, STRIP_POLICY is only used when Full Debug Symbols is enabled.
#
STRIP_POLICY ?= min_strip
_JUNK_ := $(shell \
echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)")
_JUNK_ := $(shell \
echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)")
ZIP_DEBUGINFO_FILES ?= 1
ZIP_DEBUGINFO_FILES ?= 1
_JUNK_ := $(shell \
echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)")
endif
endif
_JUNK_ := $(shell \
echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)")
endif
endif # ENABLE_FULL_DEBUG_SYMBOLS=1
endif # BUILD_FLAVOR
endif # JDK_6_OR_EARLIER
JDK_INCLUDE_SUBDIR=linux

View File

@ -336,24 +336,23 @@ $(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE) $(LD_SCRIPT)
fi \
fi \
}
ifeq ($(CROSS_COMPILE_ARCH),)
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DEBUGINFO)
$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DEBUGINFO) $@
ifeq ($(STRIP_POLICY),all_strip)
ifeq ($(STRIP_POLICY),all_strip)
$(QUIETLY) $(STRIP) $@
else
ifeq ($(STRIP_POLICY),min_strip)
else
ifeq ($(STRIP_POLICY),min_strip)
$(QUIETLY) $(STRIP) -g $@
# implied else here is no stripping at all
endif
# implied else here is no stripping at all
endif
endif
$(QUIETLY) [ -f $(LIBJVM_G_DEBUGINFO) ] || ln -s $(LIBJVM_DEBUGINFO) $(LIBJVM_G_DEBUGINFO)
ifeq ($(ZIP_DEBUGINFO_FILES),1)
ifeq ($(ZIP_DEBUGINFO_FILES),1)
$(ZIPEXE) -q -y $(LIBJVM_DIZ) $(LIBJVM_DEBUGINFO) $(LIBJVM_G_DEBUGINFO)
$(RM) $(LIBJVM_DEBUGINFO) $(LIBJVM_G_DEBUGINFO)
[ -f $(LIBJVM_G_DIZ) ] || { ln -s $(LIBJVM_DIZ) $(LIBJVM_G_DIZ); }
endif
endif
endif

View File

@ -109,60 +109,63 @@ ifeq ($(JDK6_OR_EARLIER),0)
# overridden in some situations, e.g., a BUILD_FLAVOR != product
# build.
ifeq ($(BUILD_FLAVOR), product)
FULL_DEBUG_SYMBOLS ?= 1
ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
else
# debug variants always get Full Debug Symbols (if available)
ENABLE_FULL_DEBUG_SYMBOLS = 1
endif
_JUNK_ := $(shell \
echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
# since objcopy is optional, we set ZIP_DEBUGINFO_FILES later
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
# Default OBJCOPY comes from the SUNWbinutils package:
DEF_OBJCOPY=/usr/sfw/bin/gobjcopy
OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY))
ifneq ($(ALT_OBJCOPY),)
_JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)")
OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
# Due to the multiple sub-make processes that occur this logic gets
# executed multiple times. We reduce the noise by at least checking that
# BUILD_FLAVOR has been set.
ifneq ($(BUILD_FLAVOR),)
ifeq ($(BUILD_FLAVOR), product)
FULL_DEBUG_SYMBOLS ?= 1
ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
else
# debug variants always get Full Debug Symbols (if available)
ENABLE_FULL_DEBUG_SYMBOLS = 1
endif
else
OBJCOPY=
endif
ifeq ($(OBJCOPY),)
_JUNK_ := $(shell \
echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.")
ENABLE_FULL_DEBUG_SYMBOLS=0
_JUNK_ := $(shell \
echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
else
_JUNK_ := $(shell \
echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.")
# since objcopy is optional, we set ZIP_DEBUGINFO_FILES later
# Library stripping policies for .debuginfo configs:
# all_strip - strips everything from the library
# min_strip - strips most stuff from the library; leaves minimum symbols
# no_strip - does not strip the library at all
#
# Oracle security policy requires "all_strip". A waiver was granted on
# 2011.09.01 that permits using "min_strip" in the Java JDK and Java JRE.
#
# Currently, STRIP_POLICY is only used when Full Debug Symbols is enabled.
#
STRIP_POLICY ?= min_strip
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
# Default OBJCOPY comes from the SUNWbinutils package:
DEF_OBJCOPY=/usr/sfw/bin/gobjcopy
OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY))
ifneq ($(ALT_OBJCOPY),)
_JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)")
OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
endif
_JUNK_ := $(shell \
echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)")
ifeq ($(OBJCOPY),)
_JUNK_ := $(shell \
echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.")
ENABLE_FULL_DEBUG_SYMBOLS=0
_JUNK_ := $(shell \
echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
else
_JUNK_ := $(shell \
echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.")
ZIP_DEBUGINFO_FILES ?= 1
# Library stripping policies for .debuginfo configs:
# all_strip - strips everything from the library
# min_strip - strips most stuff from the library; leaves minimum symbols
# no_strip - does not strip the library at all
#
# Oracle security policy requires "all_strip". A waiver was granted on
# 2011.09.01 that permits using "min_strip" in the Java JDK and Java JRE.
#
# Currently, STRIP_POLICY is only used when Full Debug Symbols is enabled.
#
STRIP_POLICY ?= min_strip
_JUNK_ := $(shell \
echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)")
endif
endif
_JUNK_ := $(shell \
echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)")
ZIP_DEBUGINFO_FILES ?= 1
_JUNK_ := $(shell \
echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)")
endif
endif # ENABLE_FULL_DEBUG_SYMBOLS=1
endif # BUILD_FLAVOR
endif # JDK_6_OR_EARLIER
JDK_INCLUDE_SUBDIR=solaris

View File

@ -131,23 +131,29 @@ endif
# overridden in some situations, e.g., a BUILD_FLAVOR != product
# build.
ifeq ($(BUILD_FLAVOR), product)
FULL_DEBUG_SYMBOLS ?= 1
ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
else
# debug variants always get Full Debug Symbols (if available)
ENABLE_FULL_DEBUG_SYMBOLS = 1
endif
_JUNK_ := $(shell \
echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
MAKE_ARGS += ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)
# Due to the multiple sub-make processes that occur this logic gets
# executed multiple times. We reduce the noise by at least checking that
# BUILD_FLAVOR has been set.
ifneq ($(BUILD_FLAVOR),)
ifeq ($(BUILD_FLAVOR), product)
FULL_DEBUG_SYMBOLS ?= 1
ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
else
# debug variants always get Full Debug Symbols (if available)
ENABLE_FULL_DEBUG_SYMBOLS = 1
endif
_JUNK_ := $(shell \
echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
MAKE_ARGS += ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ZIP_DEBUGINFO_FILES ?= 1
else
ZIP_DEBUGINFO_FILES=0
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ZIP_DEBUGINFO_FILES ?= 1
else
ZIP_DEBUGINFO_FILES=0
endif
MAKE_ARGS += ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)
endif
MAKE_ARGS += ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)
MAKE_ARGS += RM="$(RM)"
MAKE_ARGS += ZIPEXE=$(ZIPEXE)

View File

@ -2322,7 +2322,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
// Pre-load a static method's oop into O1. Used both by locking code and
// the normal JNI call code.
if (method->is_static() && !is_critical_native) {
__ set_oop_constant(JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror()), O1);
__ set_oop_constant(JNIHandles::make_local(method->method_holder()->java_mirror()), O1);
// Now handlize the static class mirror in O1. It's known not-null.
__ st_ptr(O1, SP, klass_offset + STACK_BIAS);

View File

@ -1936,7 +1936,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
if (method->is_static() && !is_critical_native) {
// load opp into a register
__ movoop(oop_handle_reg, JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror()));
__ movoop(oop_handle_reg, JNIHandles::make_local(method->method_holder()->java_mirror()));
// Now handlize the static class mirror it's known not-null.
__ movptr(Address(rsp, klass_offset), oop_handle_reg);

View File

@ -2179,7 +2179,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
if (method->is_static() && !is_critical_native) {
// load oop into a register
__ movoop(oop_handle_reg, JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror()));
__ movoop(oop_handle_reg, JNIHandles::make_local(method->method_holder()->java_mirror()));
// Now handlize the static class mirror it's known not-null.
__ movptr(Address(rsp, klass_offset), oop_handle_reg);

View File

@ -488,8 +488,8 @@ void VM_Version::get_processor_features() {
}
// The AES intrinsic stubs require AES instruction support (of course)
// but also require AVX mode for misaligned SSE access
if (UseAES && (UseAVX > 0)) {
// but also require AVX and sse3 modes for instructions it use.
if (UseAES && (UseAVX > 0) && (UseSSE > 2)) {
if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
UseAESIntrinsics = true;
}

View File

@ -1198,19 +1198,20 @@ static bool file_exists(const char* filename) {
return os::stat(filename, &statbuf) == 0;
}
void os::dll_build_name(char* buffer, size_t buflen,
bool os::dll_build_name(char* buffer, size_t buflen,
const char* pname, const char* fname) {
bool retval = false;
// Copied from libhpi
const size_t pnamelen = pname ? strlen(pname) : 0;
// Quietly truncate on buffer overflow. Should be an error.
// Return error on buffer overflow.
if (pnamelen + strlen(fname) + strlen(JNI_LIB_PREFIX) + strlen(JNI_LIB_SUFFIX) + 2 > buflen) {
*buffer = '\0';
return;
return retval;
}
if (pnamelen == 0) {
snprintf(buffer, buflen, JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, fname);
retval = true;
} else if (strchr(pname, *os::path_separator()) != NULL) {
int n;
char** pelements = split_path(pname, &n);
@ -1222,6 +1223,7 @@ void os::dll_build_name(char* buffer, size_t buflen,
snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX,
pelements[i], fname);
if (file_exists(buffer)) {
retval = true;
break;
}
}
@ -1236,7 +1238,9 @@ void os::dll_build_name(char* buffer, size_t buflen,
}
} else {
snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, pname, fname);
retval = true;
}
return retval;
}
const char* os::get_current_directory(char *buf, int buflen) {

View File

@ -1650,19 +1650,20 @@ static bool file_exists(const char* filename) {
return os::stat(filename, &statbuf) == 0;
}
void os::dll_build_name(char* buffer, size_t buflen,
bool os::dll_build_name(char* buffer, size_t buflen,
const char* pname, const char* fname) {
bool retval = false;
// Copied from libhpi
const size_t pnamelen = pname ? strlen(pname) : 0;
// Quietly truncate on buffer overflow. Should be an error.
// Return error on buffer overflow.
if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
*buffer = '\0';
return;
return retval;
}
if (pnamelen == 0) {
snprintf(buffer, buflen, "lib%s.so", fname);
retval = true;
} else if (strchr(pname, *os::path_separator()) != NULL) {
int n;
char** pelements = split_path(pname, &n);
@ -1673,6 +1674,7 @@ void os::dll_build_name(char* buffer, size_t buflen,
}
snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname);
if (file_exists(buffer)) {
retval = true;
break;
}
}
@ -1687,7 +1689,9 @@ void os::dll_build_name(char* buffer, size_t buflen,
}
} else {
snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
retval = true;
}
return retval;
}
const char* os::get_current_directory(char *buf, int buflen) {

View File

@ -1894,18 +1894,19 @@ static bool file_exists(const char* filename) {
return os::stat(filename, &statbuf) == 0;
}
void os::dll_build_name(char* buffer, size_t buflen,
bool os::dll_build_name(char* buffer, size_t buflen,
const char* pname, const char* fname) {
bool retval = false;
const size_t pnamelen = pname ? strlen(pname) : 0;
// Quietly truncate on buffer overflow. Should be an error.
// Return error on buffer overflow.
if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
*buffer = '\0';
return;
return retval;
}
if (pnamelen == 0) {
snprintf(buffer, buflen, "lib%s.so", fname);
retval = true;
} else if (strchr(pname, *os::path_separator()) != NULL) {
int n;
char** pelements = split_path(pname, &n);
@ -1916,6 +1917,7 @@ void os::dll_build_name(char* buffer, size_t buflen,
}
snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname);
if (file_exists(buffer)) {
retval = true;
break;
}
}
@ -1930,7 +1932,9 @@ void os::dll_build_name(char* buffer, size_t buflen,
}
} else {
snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
retval = true;
}
return retval;
}
const char* os::get_current_directory(char *buf, int buflen) {

View File

@ -1132,21 +1132,23 @@ static bool file_exists(const char* filename) {
return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES;
}
void os::dll_build_name(char *buffer, size_t buflen,
bool os::dll_build_name(char *buffer, size_t buflen,
const char* pname, const char* fname) {
bool retval = false;
const size_t pnamelen = pname ? strlen(pname) : 0;
const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0;
// Quietly truncates on buffer overflow. Should be an error.
// Return error on buffer overflow.
if (pnamelen + strlen(fname) + 10 > buflen) {
*buffer = '\0';
return;
return retval;
}
if (pnamelen == 0) {
jio_snprintf(buffer, buflen, "%s.dll", fname);
retval = true;
} else if (c == ':' || c == '\\') {
jio_snprintf(buffer, buflen, "%s%s.dll", pname, fname);
retval = true;
} else if (strchr(pname, *os::path_separator()) != NULL) {
int n;
char** pelements = split_path(pname, &n);
@ -1164,6 +1166,7 @@ void os::dll_build_name(char *buffer, size_t buflen,
jio_snprintf(buffer, buflen, "%s\\%s.dll", path, fname);
}
if (file_exists(buffer)) {
retval = true;
break;
}
}
@ -1178,7 +1181,9 @@ void os::dll_build_name(char *buffer, size_t buflen,
}
} else {
jio_snprintf(buffer, buflen, "%s\\%s.dll", pname, fname);
retval = true;
}
return retval;
}
// Needs to be in os specific directory because windows requires another

View File

@ -85,9 +85,11 @@ void end_of_file() { }
#include "dlfcn.h"
#define DECODE_INSTRUCTIONS_NAME "decode_instructions_virtual"
#define DECODE_INSTRUCTIONS_VIRTUAL_NAME "decode_instructions_virtual"
#define DECODE_INSTRUCTIONS_NAME "decode_instructions"
#define HSDIS_NAME "hsdis"
static void* decode_instructions_pv = 0;
static void* decode_instructions_sv = 0;
static const char* hsdis_path[] = {
HSDIS_NAME"-"LIBARCH LIB_EXT,
"./" HSDIS_NAME"-"LIBARCH LIB_EXT,
@ -101,11 +103,12 @@ static const char* load_decode_instructions() {
void* dllib = NULL;
const char* *next_in_path = hsdis_path;
while (1) {
decode_instructions_pv = dlsym(dllib, DECODE_INSTRUCTIONS_NAME);
if (decode_instructions_pv != NULL)
decode_instructions_pv = dlsym(dllib, DECODE_INSTRUCTIONS_VIRTUAL_NAME);
decode_instructions_sv = dlsym(dllib, DECODE_INSTRUCTIONS_NAME);
if (decode_instructions_pv != NULL || decode_instructions_sv != NULL)
return NULL;
if (dllib != NULL)
return "plugin does not defined "DECODE_INSTRUCTIONS_NAME;
return "plugin does not defined "DECODE_INSTRUCTIONS_VIRTUAL_NAME" and "DECODE_INSTRUCTIONS_NAME;
for (dllib = NULL; dllib == NULL; ) {
const char* next_lib = (*next_in_path++);
if (next_lib == NULL)
@ -213,20 +216,44 @@ void disassemble(uintptr_t from, uintptr_t to) {
printf("%s: %s\n", err, dlerror());
exit(1);
}
printf("Decoding from %p to %p...\n", from, to);
decode_instructions_ftype decode_instructions
= (decode_instructions_ftype) decode_instructions_pv;
decode_func_vtype decode_instructions_v
= (decode_func_vtype) decode_instructions_pv;
decode_func_stype decode_instructions_s
= (decode_func_stype) decode_instructions_sv;
void* res;
if (raw && xml) {
res = (*decode_instructions)(from, to, (unsigned char*)from, to - from, simple_handle_event, stdout, NULL, stdout, options);
} else if (raw) {
res = (*decode_instructions)(from, to, (unsigned char*)from, to - from, simple_handle_event, stdout, NULL, stdout, options);
} else {
res = (*decode_instructions)(from, to, (unsigned char*)from, to - from,
handle_event, (void*) event_cookie,
fprintf_callback, stdout,
options);
if (decode_instructions_pv != NULL) {
printf("\nDecoding from %p to %p...with %s\n", from, to, DECODE_INSTRUCTIONS_VIRTUAL_NAME);
if (raw) {
res = (*decode_instructions_v)(from, to,
(unsigned char*)from, to - from,
simple_handle_event, stdout,
NULL, stdout,
options, 0);
} else {
res = (*decode_instructions_v)(from, to,
(unsigned char*)from, to - from,
handle_event, (void*) event_cookie,
fprintf_callback, stdout,
options, 0);
}
if (res != (void*)to)
printf("*** Result was %p!\n", res);
}
void* sres;
if (decode_instructions_sv != NULL) {
printf("\nDecoding from %p to %p...with old decode_instructions\n", from, to, DECODE_INSTRUCTIONS_NAME);
if (raw) {
sres = (*decode_instructions_s)(from, to,
simple_handle_event, stdout,
NULL, stdout,
options);
} else {
sres = (*decode_instructions_s)(from, to,
handle_event, (void*) event_cookie,
fprintf_callback, stdout,
options);
}
if (sres != (void *)to)
printf("*** Result of decode_instructions %p!\n", sres);
}
if (res != (void*)to)
printf("*** Result was %p!\n", res);
}

View File

@ -99,7 +99,7 @@ decode_instructions_virtual(uintptr_t start_va, uintptr_t end_va,
unsigned char* buffer, uintptr_t length,
event_callback_t event_callback_arg, void* event_stream_arg,
printf_callback_t printf_callback_arg, void* printf_stream_arg,
const char* options) {
const char* options, int newline) {
struct hsdis_app_data app_data;
memset(&app_data, 0, sizeof(app_data));
app_data.start_va = start_va;
@ -110,7 +110,7 @@ decode_instructions_virtual(uintptr_t start_va, uintptr_t end_va,
app_data.event_stream = event_stream_arg;
app_data.printf_callback = printf_callback_arg;
app_data.printf_stream = printf_stream_arg;
app_data.do_newline = false;
app_data.do_newline = newline == 0 ? false : true;
return decode(&app_data, options);
}
@ -132,7 +132,7 @@ decode_instructions(void* start_pv, void* end_pv,
event_stream_arg,
printf_callback_arg,
printf_stream_arg,
options);
options, false);
}
static void* decode(struct hsdis_app_data* app_data, const char* options) {
@ -173,7 +173,7 @@ static void* decode(struct hsdis_app_data* app_data, const char* options) {
if (!app_data->losing) {
const char* insn_close = format_insn_close("/insn", &app_data->dinfo,
buf, sizeof(buf));
(*event_callback)(event_stream, insn_close, (void*) p) != NULL;
(*event_callback)(event_stream, insn_close, (void*) p);
if (app_data->do_newline) {
/* follow each complete insn by a nice newline */
@ -182,13 +182,14 @@ static void* decode(struct hsdis_app_data* app_data, const char* options) {
}
}
(*event_callback)(event_stream, "/insns", (void*) p);
if (app_data->losing) (*event_callback)(event_stream, "/insns", (void*) p);
return (void*) p;
}
}
/* take the address of the function, for luck, and also test the typedef: */
const decode_instructions_ftype decode_instructions_address = &decode_instructions_virtual;
const decode_func_vtype decode_func_virtual_address = &decode_instructions_virtual;
const decode_func_stype decode_func_address = &decode_instructions;
static const char* format_insn_close(const char* close,
disassemble_info* dinfo,

View File

@ -47,6 +47,9 @@
where tag is a simple identifier, signifying (as in XML) a element start,
element end, and standalone element. (To render as XML, add angle brackets.)
*/
#ifndef SHARED_TOOLS_HSDIS_H
#define SHARED_TOOLS_HSDIS_H
extern
#ifdef DLL_EXPORT
DLL_EXPORT
@ -57,16 +60,37 @@ void* decode_instructions_virtual(uintptr_t start_va, uintptr_t end_va,
void* event_stream,
int (*printf_callback)(void*, const char*, ...),
void* printf_stream,
const char* options);
const char* options,
int newline /* bool value for nice new line */);
/* This is the compatability interface for older versions of hotspot */
extern
#ifdef DLL_ENTRY
DLL_ENTRY
#endif
void* decode_instructions(void* start_pv, void* end_pv,
void* (*event_callback)(void*, const char*, void*),
void* event_stream,
int (*printf_callback)(void*, const char*, ...),
void* printf_stream,
const char* options);
/* convenience typedefs */
typedef void* (*decode_instructions_event_callback_ftype) (void*, const char*, void*);
typedef int (*decode_instructions_printf_callback_ftype) (void*, const char*, ...);
typedef void* (*decode_instructions_ftype) (uintptr_t start_va, uintptr_t end_va,
unsigned char* buffer, uintptr_t length,
decode_instructions_event_callback_ftype event_callback,
void* event_stream,
decode_instructions_printf_callback_ftype printf_callback,
void* printf_stream,
const char* options);
typedef void* (*decode_func_vtype) (uintptr_t start_va, uintptr_t end_va,
unsigned char* buffer, uintptr_t length,
decode_instructions_event_callback_ftype event_callback,
void* event_stream,
decode_instructions_printf_callback_ftype printf_callback,
void* printf_stream,
const char* options,
int newline);
typedef void* (*decode_func_stype) (void* start_pv, void* end_pv,
decode_instructions_event_callback_ftype event_callback,
void* event_stream,
decode_instructions_printf_callback_ftype printf_callback,
void* printf_stream,
const char* options);
#endif /* SHARED_TOOLS_HSDIS_H */

View File

@ -1836,7 +1836,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
// check if we could do inlining
if (!PatchALot && Inline && klass->is_loaded() &&
(klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
&& target->will_link(klass, callee_holder, code)) {
&& target->is_loaded()) {
// callee is known => check if we have static binding
assert(target->is_loaded(), "callee must be known");
if (code == Bytecodes::_invokestatic ||

View File

@ -374,7 +374,7 @@ JRT_END
JRT_ENTRY(void, Runtime1::throw_array_store_exception(JavaThread* thread, oopDesc* obj))
ResourceMark rm(thread);
const char* klass_name = Klass::cast(obj->klass())->external_name();
const char* klass_name = obj->klass()->external_name();
SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArrayStoreException(), klass_name);
JRT_END
@ -631,7 +631,7 @@ JRT_ENTRY(void, Runtime1::throw_class_cast_exception(JavaThread* thread, oopDesc
NOT_PRODUCT(_throw_class_cast_exception_count++;)
ResourceMark rm(thread);
char* message = SharedRuntime::generate_class_cast_message(
thread, Klass::cast(object->klass())->external_name());
thread, object->klass()->external_name());
SharedRuntime::throw_and_post_jvmti_exception(
thread, vmSymbols::java_lang_ClassCastException(), message);
JRT_END
@ -876,7 +876,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
case Bytecodes::_anewarray:
{ Bytecode_anewarray anew(caller_method(), caller_method->bcp_from(bci));
Klass* ek = caller_method->constants()->klass_at(anew.index(), CHECK);
k = Klass::cast(ek)->array_klass(CHECK);
k = ek->array_klass(CHECK);
}
break;
case Bytecodes::_ldc:
@ -1236,7 +1236,7 @@ template <class T> int obj_arraycopy_work(oopDesc* src, T* src_addr,
} else {
Klass* bound = ObjArrayKlass::cast(dst->klass())->element_klass();
Klass* stype = ObjArrayKlass::cast(src->klass())->element_klass();
if (stype == bound || Klass::cast(stype)->is_subtype_of(bound)) {
if (stype == bound || stype->is_subtype_of(bound)) {
// Elements are guaranteed to be subtypes, so no check necessary
bs->write_ref_array_pre(dst_addr, length);
Copy::conjoint_oops_atomic(src_addr, dst_addr, length);

View File

@ -282,7 +282,7 @@ void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod*
ciMethod* inline_target = NULL;
if (target->is_loaded() && klass->is_loaded()
&& (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
&& target->will_link(klass, callee_holder, code)) {
&& target->is_loaded()) {
if (code == Bytecodes::_invokestatic
|| code == Bytecodes::_invokespecial
|| code == Bytecodes::_invokevirtual && target->is_final_method()) {

View File

@ -106,6 +106,7 @@ friend class ciSymbol; \
friend class ciArray; \
friend class ciObjArray; \
friend class ciMetadata; \
friend class ciReplay; \
friend class ciTypeArray; \
friend class ciType; \
friend class ciReturnAddress; \

View File

@ -30,6 +30,7 @@
#include "ci/ciInstanceKlass.hpp"
#include "ci/ciMethod.hpp"
#include "ci/ciNullObject.hpp"
#include "ci/ciReplay.hpp"
#include "ci/ciUtilities.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
@ -426,7 +427,7 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,
for (int i = cpool->length() - 1; i >= 1; i--) {
if (cpool->tag_at(i).is_klass()) {
Klass* kls = cpool->resolved_klass_at(i);
if (Klass::cast(kls)->name() == sym) {
if (kls->name() == sym) {
found_klass = KlassHandle(THREAD, kls);
break;
}
@ -768,10 +769,15 @@ ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool,
Method* m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc);
if (m != NULL &&
(bc == Bytecodes::_invokestatic
? InstanceKlass::cast(m->method_holder())->is_not_initialized()
: !InstanceKlass::cast(m->method_holder())->is_loaded())) {
? m->method_holder()->is_not_initialized()
: !m->method_holder()->is_loaded())) {
m = NULL;
}
#ifdef ASSERT
if (m != NULL && ReplayCompiles && !ciReplay::is_loaded(m)) {
m = NULL;
}
#endif
if (m != NULL) {
// We found the method.
return get_method(m);
@ -1056,7 +1062,7 @@ void ciEnv::register_method(ciMethod* target,
method_name,
entry_bci);
}
InstanceKlass::cast(method->method_holder())->add_osr_nmethod(nm);
method->method_holder()->add_osr_nmethod(nm);
}
}
@ -1144,3 +1150,43 @@ void ciEnv::record_out_of_memory_failure() {
// If memory is low, we stop compiling methods.
record_method_not_compilable("out of memory");
}
fileStream* ciEnv::_replay_data_stream = NULL;
void ciEnv::dump_replay_data() {
VM_ENTRY_MARK;
MutexLocker ml(Compile_lock);
if (_replay_data_stream == NULL) {
_replay_data_stream = new (ResourceObj::C_HEAP, mtCompiler) fileStream(ReplayDataFile);
if (_replay_data_stream == NULL) {
fatal(err_msg("Can't open %s for replay data", ReplayDataFile));
}
}
dump_replay_data(_replay_data_stream);
}
void ciEnv::dump_replay_data(outputStream* out) {
ASSERT_IN_VM;
#if INCLUDE_JVMTI
out->print_cr("JvmtiExport can_access_local_variables %d", _jvmti_can_access_local_variables);
out->print_cr("JvmtiExport can_hotswap_or_post_breakpoint %d", _jvmti_can_hotswap_or_post_breakpoint);
out->print_cr("JvmtiExport can_post_on_exceptions %d", _jvmti_can_post_on_exceptions);
#endif // INCLUDE_JVMTI
GrowableArray<ciMetadata*>* objects = _factory->get_ci_metadata();
out->print_cr("# %d ciObject found", objects->length());
for (int i = 0; i < objects->length(); i++) {
objects->at(i)->dump_replay_data(out);
}
Method* method = task()->method();
int entry_bci = task()->osr_bci();
// Klass holder = method->method_holder();
out->print_cr("compile %s %s %s %d",
method->klass_name()->as_quoted_ascii(),
method->name()->as_quoted_ascii(),
method->signature()->as_quoted_ascii(),
entry_bci);
out->flush();
}

View File

@ -46,6 +46,8 @@ class ciEnv : StackObj {
friend class CompileBroker;
friend class Dependencies; // for get_object, during logging
static fileStream* _replay_data_stream;
private:
Arena* _arena; // Alias for _ciEnv_arena except in init_shared_objects()
Arena _ciEnv_arena;
@ -448,6 +450,13 @@ public:
// RedefineClasses support
void metadata_do(void f(Metadata*)) { _factory->metadata_do(f); }
// Dump the compilation replay data for this ciEnv to
// ReplayDataFile, creating the file if needed.
void dump_replay_data();
// Dump the compilation replay data for the ciEnv to the stream.
void dump_replay_data(outputStream* out);
};
#endif // SHARE_VM_CI_CIENV_HPP

View File

@ -561,3 +561,114 @@ ciInstanceKlass* ciInstanceKlass::implementor() {
}
return impl;
}
// Utility class for printing of the contents of the static fields for
// use by compilation replay. It only prints out the information that
// could be consumed by the compiler, so for primitive types it prints
// out the actual value. For Strings it's the actual string value.
// For array types it it's first level array size since that's the
// only value which statically unchangeable. For all other reference
// types it simply prints out the dynamic type.
class StaticFinalFieldPrinter : public FieldClosure {
outputStream* _out;
const char* _holder;
public:
StaticFinalFieldPrinter(outputStream* out, const char* holder) :
_out(out),
_holder(holder) {
}
void do_field(fieldDescriptor* fd) {
if (fd->is_final() && !fd->has_initial_value()) {
oop mirror = fd->field_holder()->java_mirror();
_out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii());
switch (fd->field_type()) {
case T_BYTE: _out->print_cr("%d", mirror->byte_field(fd->offset())); break;
case T_BOOLEAN: _out->print_cr("%d", mirror->bool_field(fd->offset())); break;
case T_SHORT: _out->print_cr("%d", mirror->short_field(fd->offset())); break;
case T_CHAR: _out->print_cr("%d", mirror->char_field(fd->offset())); break;
case T_INT: _out->print_cr("%d", mirror->int_field(fd->offset())); break;
case T_LONG: _out->print_cr(INT64_FORMAT, mirror->long_field(fd->offset())); break;
case T_FLOAT: {
float f = mirror->float_field(fd->offset());
_out->print_cr("%d", *(int*)&f);
break;
}
case T_DOUBLE: {
double d = mirror->double_field(fd->offset());
_out->print_cr(INT64_FORMAT, *(jlong*)&d);
break;
}
case T_ARRAY: {
oop value = mirror->obj_field_acquire(fd->offset());
if (value == NULL) {
_out->print_cr("null");
} else {
typeArrayOop ta = (typeArrayOop)value;
_out->print("%d", ta->length());
if (value->is_objArray()) {
objArrayOop oa = (objArrayOop)value;
const char* klass_name = value->klass()->name()->as_quoted_ascii();
_out->print(" %s", klass_name);
}
_out->cr();
}
break;
}
case T_OBJECT: {
oop value = mirror->obj_field_acquire(fd->offset());
if (value == NULL) {
_out->print_cr("null");
} else if (value->is_instance()) {
if (value->is_a(SystemDictionary::String_klass())) {
_out->print("\"");
_out->print_raw(java_lang_String::as_quoted_ascii(value));
_out->print_cr("\"");
} else {
const char* klass_name = value->klass()->name()->as_quoted_ascii();
_out->print_cr(klass_name);
}
} else {
ShouldNotReachHere();
}
break;
}
default:
ShouldNotReachHere();
}
}
}
};
void ciInstanceKlass::dump_replay_data(outputStream* out) {
ASSERT_IN_VM;
InstanceKlass* ik = get_instanceKlass();
ConstantPool* cp = ik->constants();
// Try to record related loaded classes
Klass* sub = ik->subklass();
while (sub != NULL) {
if (sub->oop_is_instance()) {
out->print_cr("instanceKlass %s", sub->name()->as_quoted_ascii());
}
sub = sub->next_sibling();
}
// Dump out the state of the constant pool tags. During replay the
// tags will be validated for things which shouldn't change and
// classes will be resolved if the tags indicate that they were
// resolved at compile time.
out->print("ciInstanceKlass %s %d %d %d", ik->name()->as_quoted_ascii(),
is_linked(), is_initialized(), cp->length());
for (int index = 1; index < cp->length(); index++) {
out->print(" %d", cp->tags()->at(index));
}
out->cr();
if (is_initialized()) {
// Dump out the static final fields in case the compilation relies
// on their value for correct replay.
StaticFinalFieldPrinter sffp(out, ik->name()->as_quoted_ascii());
ik->do_local_static_fields(&sffp);
}
}

View File

@ -230,6 +230,9 @@ public:
// What kind of ciObject is this?
bool is_instance_klass() const { return true; }
bool is_java_klass() const { return true; }
// Dump the current state of this klass for compilation replay.
virtual void dump_replay_data(outputStream* out);
};
#endif // SHARE_VM_CI_CIINSTANCEKLASS_HPP

View File

@ -61,6 +61,7 @@ class ciMetadata: public ciBaseObject {
virtual bool is_array_klass() const { return false; }
virtual bool is_obj_array_klass() const { return false; }
virtual bool is_type_array_klass() const { return false; }
virtual void dump_replay_data(outputStream* st) { /* do nothing */ }
ciMethod* as_method() {
assert(is_method(), "bad cast");

View File

@ -31,6 +31,7 @@
#include "ci/ciMethodData.hpp"
#include "ci/ciStreams.hpp"
#include "ci/ciSymbol.hpp"
#include "ci/ciReplay.hpp"
#include "ci/ciUtilities.hpp"
#include "classfile/systemDictionary.hpp"
#include "compiler/abstractCompiler.hpp"
@ -105,7 +106,7 @@ ciMethod::ciMethod(methodHandle h_m) : ciMetadata(h_m()) {
CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
}
if (InstanceKlass::cast(h_m()->method_holder())->is_linked()) {
if (h_m()->method_holder()->is_linked()) {
_can_be_statically_bound = h_m()->can_be_statically_bound();
} else {
// Have to use a conservative value in this case.
@ -139,6 +140,12 @@ ciMethod::ciMethod(methodHandle h_m) : ciMetadata(h_m()) {
}
if (_interpreter_invocation_count == 0)
_interpreter_invocation_count = 1;
_instructions_size = -1;
#ifdef ASSERT
if (ReplayCompiles) {
ciReplay::initialize(this);
}
#endif
}
@ -161,7 +168,8 @@ ciMethod::ciMethod(ciInstanceKlass* holder,
#if defined(COMPILER2) || defined(SHARK)
,
_flow( NULL),
_bcea( NULL)
_bcea( NULL),
_instructions_size(-1)
#endif // COMPILER2 || SHARK
{
// Usually holder and accessor are the same type but in some cases
@ -188,7 +196,7 @@ void ciMethod::load_code() {
// Revert any breakpoint bytecodes in ci's copy
if (me->number_of_breakpoints() > 0) {
BreakpointInfo* bp = InstanceKlass::cast(me->method_holder())->breakpoints();
BreakpointInfo* bp = me->method_holder()->breakpoints();
for (; bp != NULL; bp = bp->next()) {
if (bp->match(me)) {
code_at_put(bp->bci(), bp->orig_bytecode());
@ -867,25 +875,6 @@ ciMethodData* ciMethod::method_data_or_null() {
return md;
}
// ------------------------------------------------------------------
// ciMethod::will_link
//
// Will this method link in a specific calling context?
bool ciMethod::will_link(ciKlass* accessing_klass,
ciKlass* declared_method_holder,
Bytecodes::Code bc) {
if (!is_loaded()) {
// Method lookup failed.
return false;
}
// The link checks have been front-loaded into the get_method
// call. This method (ciMethod::will_link()) will be removed
// in the future.
return true;
}
// ------------------------------------------------------------------
// ciMethod::should_exclude
//
@ -1000,8 +989,7 @@ bool ciMethod::can_be_osr_compiled(int entry_bci) {
// ------------------------------------------------------------------
// ciMethod::has_compiled_code
bool ciMethod::has_compiled_code() {
VM_ENTRY_MARK;
return get_Method()->code() != NULL;
return instructions_size() > 0;
}
int ciMethod::comp_level() {
@ -1039,14 +1027,18 @@ int ciMethod::code_size_for_inlining() {
// junk like exception handler, stubs, and constant table, which are
// not highly relevant to an inlined method. So we use the more
// specific accessor nmethod::insts_size.
int ciMethod::instructions_size(int comp_level) {
GUARDED_VM_ENTRY(
nmethod* code = get_Method()->code();
if (code != NULL && (comp_level == CompLevel_any || comp_level == code->comp_level())) {
return code->insts_end() - code->verified_entry_point();
}
return 0;
)
int ciMethod::instructions_size() {
if (_instructions_size == -1) {
GUARDED_VM_ENTRY(
nmethod* code = get_Method()->code();
if (code != NULL && (code->comp_level() == CompLevel_full_optimization)) {
_instructions_size = code->insts_end() - code->verified_entry_point();
} else {
_instructions_size = 0;
}
);
}
return _instructions_size;
}
// ------------------------------------------------------------------
@ -1166,6 +1158,20 @@ ciMethodBlocks *ciMethod::get_method_blocks() {
#undef FETCH_FLAG_FROM_VM
void ciMethod::dump_replay_data(outputStream* st) {
ASSERT_IN_VM;
Method* method = get_Method();
Klass* holder = method->method_holder();
st->print_cr("ciMethod %s %s %s %d %d %d %d %d",
holder->name()->as_quoted_ascii(),
method->name()->as_quoted_ascii(),
method->signature()->as_quoted_ascii(),
method->invocation_counter()->raw_counter(),
method->backedge_counter()->raw_counter(),
interpreter_invocation_count(),
interpreter_throwout_count(),
_instructions_size);
}
// ------------------------------------------------------------------
// ciMethod::print_codes

View File

@ -51,6 +51,7 @@ class ciMethod : public ciMetadata {
friend class ciExceptionHandlerStream;
friend class ciBytecodeStream;
friend class ciMethodHandle;
friend class ciReplay;
private:
// General method information.
@ -69,6 +70,7 @@ class ciMethod : public ciMetadata {
int _handler_count;
int _interpreter_invocation_count;
int _interpreter_throwout_count;
int _instructions_size;
bool _uses_monitors;
bool _balanced_monitors;
@ -239,9 +241,6 @@ class ciMethod : public ciMetadata {
int resolve_vtable_index(ciKlass* caller, ciKlass* receiver);
// Compilation directives
bool will_link(ciKlass* accessing_klass,
ciKlass* declared_method_holder,
Bytecodes::Code bc);
bool should_exclude();
bool should_inline();
bool should_not_inline();
@ -252,7 +251,6 @@ class ciMethod : public ciMetadata {
bool can_be_osr_compiled(int entry_bci);
void set_not_compilable();
bool has_compiled_code();
int instructions_size(int comp_level = CompLevel_any);
void log_nmethod_identity(xmlStream* log);
bool is_not_reached(int bci);
bool was_executed_more_than(int times);
@ -260,6 +258,7 @@ class ciMethod : public ciMetadata {
bool is_klass_loaded(int refinfo_index, bool must_be_resolved) const;
bool check_call(int refinfo_index, bool is_static) const;
bool ensure_method_data(); // make sure it exists in the VM also
int instructions_size();
int scale_count(int count, float prof_factor = 1.); // make MDO count commensurate with IIC
// JSR 292 support
@ -291,6 +290,7 @@ class ciMethod : public ciMetadata {
bool is_accessor () const;
bool is_initializer () const;
bool can_be_statically_bound() const { return _can_be_statically_bound; }
void dump_replay_data(outputStream* st);
// Print the bytecodes of this method.
void print_codes_on(outputStream* st);

View File

@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "ci/ciMetadata.hpp"
#include "ci/ciMethodData.hpp"
#include "ci/ciReplay.hpp"
#include "ci/ciUtilities.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
@ -115,6 +116,11 @@ void ciMethodData::load_data() {
_arg_local = mdo->arg_local();
_arg_stack = mdo->arg_stack();
_arg_returned = mdo->arg_returned();
#ifndef PRODUCT
if (ReplayCompiles) {
ciReplay::initialize(this);
}
#endif
}
void ciReceiverTypeData::translate_receiver_data_from(ProfileData* data) {
@ -366,6 +372,79 @@ void ciMethodData::print_impl(outputStream* st) {
ciMetadata::print_impl(st);
}
void ciMethodData::dump_replay_data(outputStream* out) {
ASSERT_IN_VM;
MethodData* mdo = get_MethodData();
Method* method = mdo->method();
Klass* holder = method->method_holder();
out->print("ciMethodData %s %s %s %d %d",
holder->name()->as_quoted_ascii(),
method->name()->as_quoted_ascii(),
method->signature()->as_quoted_ascii(),
_state,
current_mileage());
// dump the contents of the MDO header as raw data
unsigned char* orig = (unsigned char*)&_orig;
int length = sizeof(_orig);
out->print(" orig %d", length);
for (int i = 0; i < length; i++) {
out->print(" %d", orig[i]);
}
// dump the MDO data as raw data
int elements = data_size() / sizeof(intptr_t);
out->print(" data %d", elements);
for (int i = 0; i < elements; i++) {
// We could use INTPTR_FORMAT here but that's a zero justified
// which makes comparing it with the SA version of this output
// harder.
#ifdef _LP64
out->print(" 0x%" FORMAT64_MODIFIER "x", data()[i]);
#else
out->print(" 0x%x", data()[i]);
#endif
}
// The MDO contained oop references as ciObjects, so scan for those
// and emit pairs of offset and klass name so that they can be
// reconstructed at runtime. The first round counts the number of
// oop references and the second actually emits them.
int count = 0;
for (int round = 0; round < 2; round++) {
if (round == 1) out->print(" oops %d", count);
ProfileData* pdata = first_data();
for ( ; is_valid(pdata); pdata = next_data(pdata)) {
if (pdata->is_ReceiverTypeData()) {
ciReceiverTypeData* vdata = (ciReceiverTypeData*)pdata;
for (uint i = 0; i < vdata->row_limit(); i++) {
ciKlass* k = vdata->receiver(i);
if (k != NULL) {
if (round == 0) {
count++;
} else {
out->print(" %d %s", dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t), k->name()->as_quoted_ascii());
}
}
}
} else if (pdata->is_VirtualCallData()) {
ciVirtualCallData* vdata = (ciVirtualCallData*)pdata;
for (uint i = 0; i < vdata->row_limit(); i++) {
ciKlass* k = vdata->receiver(i);
if (k != NULL) {
if (round == 0) {
count++;
} else {
out->print(" %d %s", dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t), k->name()->as_quoted_ascii());
}
}
}
}
}
}
out->cr();
}
#ifndef PRODUCT
void ciMethodData::print() {
print_data_on(tty);

View File

@ -144,6 +144,7 @@ public:
class ciMethodData : public ciMetadata {
CI_PACKAGE_ACCESS
friend class ciReplay;
private:
// Size in bytes
@ -320,6 +321,7 @@ public:
void print();
void print_data_on(outputStream* st);
#endif
void dump_replay_data(outputStream* out);
};
#endif // SHARE_VM_CI_CIMETHODDATA_HPP

View File

@ -131,6 +131,7 @@ public:
// Is this a type or value which has no associated class?
// It is true of primitive types and null objects.
virtual bool is_classless() const { return false; }
virtual void dump_replay_data(outputStream* st) { /* do nothing */ }
// Note: some ciObjects refer to oops which have yet to be created.
// We refer to these as "unloaded". Specifically, there are

View File

@ -137,6 +137,7 @@ public:
ciReturnAddress* get_return_address(int bci);
GrowableArray<ciMetadata*>* get_ci_metadata() const { return _ci_metadata; }
// RedefineClasses support
void metadata_do(void f(Metadata*));

View File

@ -0,0 +1,942 @@
/* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "ci/ciMethodData.hpp"
#include "ci/ciReplay.hpp"
#include "ci/ciUtilities.hpp"
#include "compiler/compileBroker.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "utilities/copy.hpp"
#ifdef ASSERT
// ciReplay
typedef struct _ciMethodDataRecord {
const char* klass;
const char* method;
const char* signature;
int state;
int current_mileage;
intptr_t* data;
int data_length;
char* orig_data;
int orig_data_length;
int oops_length;
jobject* oops_handles;
int* oops_offsets;
} ciMethodDataRecord;
typedef struct _ciMethodRecord {
const char* klass;
const char* method;
const char* signature;
int instructions_size;
int interpreter_invocation_count;
int interpreter_throwout_count;
int invocation_counter;
int backedge_counter;
} ciMethodRecord;
class CompileReplay;
static CompileReplay* replay_state;
class CompileReplay : public StackObj {
private:
FILE* stream;
Thread* thread;
Handle protection_domain;
Handle loader;
GrowableArray<ciMethodRecord*> ci_method_records;
GrowableArray<ciMethodDataRecord*> ci_method_data_records;
const char* _error_message;
char* bufptr;
char* buffer;
int buffer_length;
int buffer_end;
int line_no;
public:
CompileReplay(const char* filename, TRAPS) {
thread = THREAD;
loader = Handle(thread, SystemDictionary::java_system_loader());
stream = fopen(filename, "rt");
if (stream == NULL) {
fprintf(stderr, "Can't open replay file %s\n", filename);
}
buffer_length = 32;
buffer = NEW_RESOURCE_ARRAY(char, buffer_length);
_error_message = NULL;
test();
}
~CompileReplay() {
if (stream != NULL) fclose(stream);
}
void test() {
strcpy(buffer, "1 2 foo 4 bar 0x9 \"this is it\"");
bufptr = buffer;
assert(parse_int("test") == 1, "what");
assert(parse_int("test") == 2, "what");
assert(strcmp(parse_string(), "foo") == 0, "what");
assert(parse_int("test") == 4, "what");
assert(strcmp(parse_string(), "bar") == 0, "what");
assert(parse_intptr_t("test") == 9, "what");
assert(strcmp(parse_quoted_string(), "this is it") == 0, "what");
}
bool had_error() {
return _error_message != NULL || thread->has_pending_exception();
}
bool can_replay() {
return !(stream == NULL || had_error());
}
void report_error(const char* msg) {
_error_message = msg;
// Restore the buffer contents for error reporting
for (int i = 0; i < buffer_end; i++) {
if (buffer[i] == '\0') buffer[i] = ' ';
}
}
int parse_int(const char* label) {
if (had_error()) {
return 0;
}
int v = 0;
int read;
if (sscanf(bufptr, "%i%n", &v, &read) != 1) {
report_error(label);
} else {
bufptr += read;
}
return v;
}
intptr_t parse_intptr_t(const char* label) {
if (had_error()) {
return 0;
}
intptr_t v = 0;
int read;
if (sscanf(bufptr, INTPTR_FORMAT "%n", &v, &read) != 1) {
report_error(label);
} else {
bufptr += read;
}
return v;
}
void skip_ws() {
// Skip any leading whitespace
while (*bufptr == ' ' || *bufptr == '\t') {
bufptr++;
}
}
char* scan_and_terminate(char delim) {
char* str = bufptr;
while (*bufptr != delim && *bufptr != '\0') {
bufptr++;
}
if (*bufptr != '\0') {
*bufptr++ = '\0';
}
if (bufptr == str) {
// nothing here
return NULL;
}
return str;
}
char* parse_string() {
if (had_error()) return NULL;
skip_ws();
return scan_and_terminate(' ');
}
char* parse_quoted_string() {
if (had_error()) return NULL;
skip_ws();
if (*bufptr == '"') {
bufptr++;
return scan_and_terminate('"');
} else {
return scan_and_terminate(' ');
}
}
const char* parse_escaped_string() {
char* result = parse_quoted_string();
if (result != NULL) {
unescape_string(result);
}
return result;
}
// Look for the tag 'tag' followed by an
bool parse_tag_and_count(const char* tag, int& length) {
const char* t = parse_string();
if (t == NULL) {
return false;
}
if (strcmp(tag, t) != 0) {
report_error(tag);
return false;
}
length = parse_int("parse_tag_and_count");
return !had_error();
}
// Parse a sequence of raw data encoded as bytes and return the
// resulting data.
char* parse_data(const char* tag, int& length) {
if (!parse_tag_and_count(tag, length)) {
return NULL;
}
char * result = NEW_RESOURCE_ARRAY(char, length);
for (int i = 0; i < length; i++) {
int val = parse_int("data");
result[i] = val;
}
return result;
}
// Parse a standard chunk of data emitted as:
// 'tag' <length> # # ...
// Where each # is an intptr_t item
intptr_t* parse_intptr_data(const char* tag, int& length) {
if (!parse_tag_and_count(tag, length)) {
return NULL;
}
intptr_t* result = NEW_RESOURCE_ARRAY(intptr_t, length);
for (int i = 0; i < length; i++) {
skip_ws();
intptr_t val = parse_intptr_t("data");
result[i] = val;
}
return result;
}
// Parse a possibly quoted version of a symbol into a symbolOop
Symbol* parse_symbol(TRAPS) {
const char* str = parse_escaped_string();
if (str != NULL) {
Symbol* sym = SymbolTable::lookup(str, (int)strlen(str), CHECK_NULL);
return sym;
}
return NULL;
}
// Parse a valid klass name and look it up
Klass* parse_klass(TRAPS) {
const char* str = parse_escaped_string();
Symbol* klass_name = SymbolTable::lookup(str, (int)strlen(str), CHECK_NULL);
if (klass_name != NULL) {
Klass* k = SystemDictionary::resolve_or_fail(klass_name, loader, protection_domain, true, THREAD);
if (HAS_PENDING_EXCEPTION) {
oop throwable = PENDING_EXCEPTION;
java_lang_Throwable::print(throwable, tty);
tty->cr();
report_error(str);
return NULL;
}
return k;
}
return NULL;
}
// Lookup a klass
Klass* resolve_klass(const char* klass, TRAPS) {
Symbol* klass_name = SymbolTable::lookup(klass, (int)strlen(klass), CHECK_NULL);
return SystemDictionary::resolve_or_fail(klass_name, loader, protection_domain, true, CHECK_NULL);
}
// Parse the standard tuple of <klass> <name> <signature>
Method* parse_method(TRAPS) {
InstanceKlass* k = (InstanceKlass*)parse_klass(CHECK_NULL);
Symbol* method_name = parse_symbol(CHECK_NULL);
Symbol* method_signature = parse_symbol(CHECK_NULL);
Method* m = k->find_method(method_name, method_signature);
if (m == NULL) {
report_error("can't find method");
}
return m;
}
// Process each line of the replay file executing each command until
// the file ends.
void process(TRAPS) {
line_no = 1;
int pos = 0;
int c = getc(stream);
while(c != EOF) {
if (pos + 1 >= buffer_length) {
int newl = buffer_length * 2;
char* newb = NEW_RESOURCE_ARRAY(char, newl);
memcpy(newb, buffer, pos);
buffer = newb;
buffer_length = newl;
}
if (c == '\n') {
// null terminate it, reset the pointer and process the line
buffer[pos] = '\0';
buffer_end = pos++;
bufptr = buffer;
process_command(CHECK);
if (had_error()) {
tty->print_cr("Error while parsing line %d: %s\n", line_no, _error_message);
tty->print_cr("%s", buffer);
assert(false, "error");
return;
}
pos = 0;
buffer_end = 0;
line_no++;
} else if (c == '\r') {
// skip LF
} else {
buffer[pos++] = c;
}
c = getc(stream);
}
}
void process_command(TRAPS) {
char* cmd = parse_string();
if (cmd == NULL) {
return;
}
if (strcmp("#", cmd) == 0) {
// ignore
} else if (strcmp("compile", cmd) == 0) {
process_compile(CHECK);
} else if (strcmp("ciMethod", cmd) == 0) {
process_ciMethod(CHECK);
} else if (strcmp("ciMethodData", cmd) == 0) {
process_ciMethodData(CHECK);
} else if (strcmp("staticfield", cmd) == 0) {
process_staticfield(CHECK);
} else if (strcmp("ciInstanceKlass", cmd) == 0) {
process_ciInstanceKlass(CHECK);
} else if (strcmp("instanceKlass", cmd) == 0) {
process_instanceKlass(CHECK);
#if INCLUDE_JVMTI
} else if (strcmp("JvmtiExport", cmd) == 0) {
process_JvmtiExport(CHECK);
#endif // INCLUDE_JVMTI
} else {
report_error("unknown command");
}
}
// compile <klass> <name> <signature> <entry_bci>
void process_compile(TRAPS) {
// methodHandle method;
Method* method = parse_method(CHECK);
int entry_bci = parse_int("entry_bci");
Klass* k = method->method_holder();
((InstanceKlass*)k)->initialize(THREAD);
if (HAS_PENDING_EXCEPTION) {
oop throwable = PENDING_EXCEPTION;
java_lang_Throwable::print(throwable, tty);
tty->cr();
if (ReplayIgnoreInitErrors) {
CLEAR_PENDING_EXCEPTION;
((InstanceKlass*)k)->set_init_state(InstanceKlass::fully_initialized);
} else {
return;
}
}
// Make sure the existence of a prior compile doesn't stop this one
nmethod* nm = (entry_bci != InvocationEntryBci) ? method->lookup_osr_nmethod_for(entry_bci, CompLevel_full_optimization, true) : method->code();
if (nm != NULL) {
nm->make_not_entrant();
}
replay_state = this;
CompileBroker::compile_method(method, entry_bci, CompLevel_full_optimization,
methodHandle(), 0, "replay", THREAD);
replay_state = NULL;
reset();
}
// ciMethod <klass> <name> <signature> <invocation_counter> <backedge_counter> <interpreter_invocation_count> <interpreter_throwout_count> <instructions_size>
//
//
void process_ciMethod(TRAPS) {
Method* method = parse_method(CHECK);
ciMethodRecord* rec = new_ciMethod(method);
rec->invocation_counter = parse_int("invocation_counter");
rec->backedge_counter = parse_int("backedge_counter");
rec->interpreter_invocation_count = parse_int("interpreter_invocation_count");
rec->interpreter_throwout_count = parse_int("interpreter_throwout_count");
rec->instructions_size = parse_int("instructions_size");
}
// ciMethodData <klass> <name> <signature> <state> <current mileage> orig <length> # # ... data <length> # # ... oops <length>
void process_ciMethodData(TRAPS) {
Method* method = parse_method(CHECK);
/* jsut copied from Method, to build interpret data*/
if (InstanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) {
return;
}
// methodOopDesc::build_interpreter_method_data(method, CHECK);
{
// Grab a lock here to prevent multiple
// MethodData*s from being created.
MutexLocker ml(MethodData_lock, THREAD);
if (method->method_data() == NULL) {
ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
MethodData* method_data = MethodData::allocate(loader_data, method, CHECK);
method->set_method_data(method_data);
}
}
// collect and record all the needed information for later
ciMethodDataRecord* rec = new_ciMethodData(method);
rec->state = parse_int("state");
rec->current_mileage = parse_int("current_mileage");
rec->orig_data = parse_data("orig", rec->orig_data_length);
if (rec->orig_data == NULL) {
return;
}
rec->data = parse_intptr_data("data", rec->data_length);
if (rec->data == NULL) {
return;
}
if (!parse_tag_and_count("oops", rec->oops_length)) {
return;
}
rec->oops_handles = NEW_RESOURCE_ARRAY(jobject, rec->oops_length);
rec->oops_offsets = NEW_RESOURCE_ARRAY(int, rec->oops_length);
for (int i = 0; i < rec->oops_length; i++) {
int offset = parse_int("offset");
if (had_error()) {
return;
}
Klass* k = parse_klass(CHECK);
rec->oops_offsets[i] = offset;
rec->oops_handles[i] = (jobject)(new KlassHandle(THREAD, k));
}
}
// instanceKlass <name>
//
// Loads and initializes the klass 'name'. This can be used to
// create particular class loading environments
void process_instanceKlass(TRAPS) {
// just load the referenced class
Klass* k = parse_klass(CHECK);
}
// ciInstanceKlass <name> <is_linked> <is_initialized> <length> tag # # # ...
//
// Load the klass 'name' and link or initialize it. Verify that the
// constant pool is the same length as 'length' and make sure the
// constant pool tags are in the same state.
void process_ciInstanceKlass(TRAPS) {
InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
int is_linked = parse_int("is_linked");
int is_initialized = parse_int("is_initialized");
int length = parse_int("length");
if (is_initialized) {
k->initialize(THREAD);
if (HAS_PENDING_EXCEPTION) {
oop throwable = PENDING_EXCEPTION;
java_lang_Throwable::print(throwable, tty);
tty->cr();
if (ReplayIgnoreInitErrors) {
CLEAR_PENDING_EXCEPTION;
k->set_init_state(InstanceKlass::fully_initialized);
} else {
return;
}
}
} else if (is_linked) {
k->link_class(CHECK);
}
ConstantPool* cp = k->constants();
if (length != cp->length()) {
report_error("constant pool length mismatch: wrong class files?");
return;
}
int parsed_two_word = 0;
for (int i = 1; i < length; i++) {
int tag = parse_int("tag");
if (had_error()) {
return;
}
switch (cp->tag_at(i).value()) {
case JVM_CONSTANT_UnresolvedClass: {
if (tag == JVM_CONSTANT_Class) {
tty->print_cr("Resolving klass %s at %d", cp->unresolved_klass_at(i)->as_utf8(), i);
Klass* k = cp->klass_at(i, CHECK);
}
break;
}
case JVM_CONSTANT_Long:
case JVM_CONSTANT_Double:
parsed_two_word = i + 1;
case JVM_CONSTANT_ClassIndex:
case JVM_CONSTANT_StringIndex:
case JVM_CONSTANT_String:
case JVM_CONSTANT_UnresolvedClassInError:
case JVM_CONSTANT_Fieldref:
case JVM_CONSTANT_Methodref:
case JVM_CONSTANT_InterfaceMethodref:
case JVM_CONSTANT_NameAndType:
case JVM_CONSTANT_Utf8:
case JVM_CONSTANT_Integer:
case JVM_CONSTANT_Float:
if (tag != cp->tag_at(i).value()) {
report_error("tag mismatch: wrong class files?");
return;
}
break;
case JVM_CONSTANT_Class:
if (tag == JVM_CONSTANT_Class) {
} else if (tag == JVM_CONSTANT_UnresolvedClass) {
tty->print_cr("Warning: entry was unresolved in the replay data");
} else {
report_error("Unexpected tag");
return;
}
break;
case 0:
if (parsed_two_word == i) continue;
default:
ShouldNotReachHere();
break;
}
}
}
// Initialize a class and fill in the value for a static field.
// This is useful when the compile was dependent on the value of
// static fields but it's impossible to properly rerun the static
// initiailizer.
void process_staticfield(TRAPS) {
InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
if (ReplaySuppressInitializers == 0 ||
ReplaySuppressInitializers == 2 && k->class_loader() == NULL) {
return;
}
assert(k->is_initialized(), "must be");
const char* field_name = parse_escaped_string();;
const char* field_signature = parse_string();
fieldDescriptor fd;
Symbol* name = SymbolTable::lookup(field_name, (int)strlen(field_name), CHECK);
Symbol* sig = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK);
if (!k->find_local_field(name, sig, &fd) ||
!fd.is_static() ||
fd.has_initial_value()) {
report_error(field_name);
return;
}
oop java_mirror = k->java_mirror();
if (field_signature[0] == '[') {
int length = parse_int("array length");
oop value = NULL;
if (field_signature[1] == '[') {
// multi dimensional array
ArrayKlass* kelem = (ArrayKlass *)parse_klass(CHECK);
int rank = 0;
while (field_signature[rank] == '[') {
rank++;
}
int* dims = NEW_RESOURCE_ARRAY(int, rank);
dims[0] = length;
for (int i = 1; i < rank; i++) {
dims[i] = 1; // These aren't relevant to the compiler
}
value = kelem->multi_allocate(rank, dims, CHECK);
} else {
if (strcmp(field_signature, "[B") == 0) {
value = oopFactory::new_byteArray(length, CHECK);
} else if (strcmp(field_signature, "[Z") == 0) {
value = oopFactory::new_boolArray(length, CHECK);
} else if (strcmp(field_signature, "[C") == 0) {
value = oopFactory::new_charArray(length, CHECK);
} else if (strcmp(field_signature, "[S") == 0) {
value = oopFactory::new_shortArray(length, CHECK);
} else if (strcmp(field_signature, "[F") == 0) {
value = oopFactory::new_singleArray(length, CHECK);
} else if (strcmp(field_signature, "[D") == 0) {
value = oopFactory::new_doubleArray(length, CHECK);
} else if (strcmp(field_signature, "[I") == 0) {
value = oopFactory::new_intArray(length, CHECK);
} else if (strcmp(field_signature, "[J") == 0) {
value = oopFactory::new_longArray(length, CHECK);
} else if (field_signature[0] == '[' && field_signature[1] == 'L') {
KlassHandle kelem = resolve_klass(field_signature + 1, CHECK);
value = oopFactory::new_objArray(kelem(), length, CHECK);
} else {
report_error("unhandled array staticfield");
}
}
java_mirror->obj_field_put(fd.offset(), value);
} else {
const char* string_value = parse_escaped_string();
if (strcmp(field_signature, "I") == 0) {
int value = atoi(string_value);
java_mirror->int_field_put(fd.offset(), value);
} else if (strcmp(field_signature, "B") == 0) {
int value = atoi(string_value);
java_mirror->byte_field_put(fd.offset(), value);
} else if (strcmp(field_signature, "C") == 0) {
int value = atoi(string_value);
java_mirror->char_field_put(fd.offset(), value);
} else if (strcmp(field_signature, "S") == 0) {
int value = atoi(string_value);
java_mirror->short_field_put(fd.offset(), value);
} else if (strcmp(field_signature, "Z") == 0) {
int value = atol(string_value);
java_mirror->bool_field_put(fd.offset(), value);
} else if (strcmp(field_signature, "J") == 0) {
jlong value;
if (sscanf(string_value, INT64_FORMAT, &value) != 1) {
fprintf(stderr, "Error parsing long: %s\n", string_value);
return;
}
java_mirror->long_field_put(fd.offset(), value);
} else if (strcmp(field_signature, "F") == 0) {
float value = atof(string_value);
java_mirror->float_field_put(fd.offset(), value);
} else if (strcmp(field_signature, "D") == 0) {
double value = atof(string_value);
java_mirror->double_field_put(fd.offset(), value);
} else if (strcmp(field_signature, "Ljava/lang/String;") == 0) {
Handle value = java_lang_String::create_from_str(string_value, CHECK);
java_mirror->obj_field_put(fd.offset(), value());
} else if (field_signature[0] == 'L') {
Symbol* klass_name = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK);
KlassHandle kelem = resolve_klass(field_signature, CHECK);
oop value = ((InstanceKlass*)kelem())->allocate_instance(CHECK);
java_mirror->obj_field_put(fd.offset(), value);
} else {
report_error("unhandled staticfield");
}
}
}
#if INCLUDE_JVMTI
void process_JvmtiExport(TRAPS) {
const char* field = parse_string();
bool value = parse_int("JvmtiExport flag") != 0;
if (strcmp(field, "can_access_local_variables") == 0) {
JvmtiExport::set_can_access_local_variables(value);
} else if (strcmp(field, "can_hotswap_or_post_breakpoint") == 0) {
JvmtiExport::set_can_hotswap_or_post_breakpoint(value);
} else if (strcmp(field, "can_post_on_exceptions") == 0) {
JvmtiExport::set_can_post_on_exceptions(value);
} else {
report_error("Unrecognized JvmtiExport directive");
}
}
#endif // INCLUDE_JVMTI
// Create and initialize a record for a ciMethod
ciMethodRecord* new_ciMethod(Method* method) {
ciMethodRecord* rec = NEW_RESOURCE_OBJ(ciMethodRecord);
rec->klass = method->method_holder()->name()->as_utf8();
rec->method = method->name()->as_utf8();
rec->signature = method->signature()->as_utf8();
ci_method_records.append(rec);
return rec;
}
// Lookup data for a ciMethod
ciMethodRecord* find_ciMethodRecord(Method* method) {
const char* klass_name = method->method_holder()->name()->as_utf8();
const char* method_name = method->name()->as_utf8();
const char* signature = method->signature()->as_utf8();
for (int i = 0; i < ci_method_records.length(); i++) {
ciMethodRecord* rec = ci_method_records.at(i);
if (strcmp(rec->klass, klass_name) == 0 &&
strcmp(rec->method, method_name) == 0 &&
strcmp(rec->signature, signature) == 0) {
return rec;
}
}
return NULL;
}
// Create and initialize a record for a ciMethodData
ciMethodDataRecord* new_ciMethodData(Method* method) {
ciMethodDataRecord* rec = NEW_RESOURCE_OBJ(ciMethodDataRecord);
rec->klass = method->method_holder()->name()->as_utf8();
rec->method = method->name()->as_utf8();
rec->signature = method->signature()->as_utf8();
ci_method_data_records.append(rec);
return rec;
}
// Lookup data for a ciMethodData
ciMethodDataRecord* find_ciMethodDataRecord(Method* method) {
const char* klass_name = method->method_holder()->name()->as_utf8();
const char* method_name = method->name()->as_utf8();
const char* signature = method->signature()->as_utf8();
for (int i = 0; i < ci_method_data_records.length(); i++) {
ciMethodDataRecord* rec = ci_method_data_records.at(i);
if (strcmp(rec->klass, klass_name) == 0 &&
strcmp(rec->method, method_name) == 0 &&
strcmp(rec->signature, signature) == 0) {
return rec;
}
}
return NULL;
}
const char* error_message() {
return _error_message;
}
void reset() {
_error_message = NULL;
ci_method_records.clear();
ci_method_data_records.clear();
}
// Take an ascii string contain \u#### escapes and convert it to utf8
// in place.
static void unescape_string(char* value) {
char* from = value;
char* to = value;
while (*from != '\0') {
if (*from != '\\') {
*from++ = *to++;
} else {
switch (from[1]) {
case 'u': {
from += 2;
jchar value=0;
for (int i=0; i<4; i++) {
char c = *from++;
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
value = (value << 4) + c - '0';
break;
case 'a': case 'b': case 'c':
case 'd': case 'e': case 'f':
value = (value << 4) + 10 + c - 'a';
break;
case 'A': case 'B': case 'C':
case 'D': case 'E': case 'F':
value = (value << 4) + 10 + c - 'A';
break;
default:
ShouldNotReachHere();
}
}
UNICODE::convert_to_utf8(&value, 1, to);
to++;
break;
}
case 't': *to++ = '\t'; from += 2; break;
case 'n': *to++ = '\n'; from += 2; break;
case 'r': *to++ = '\r'; from += 2; break;
case 'f': *to++ = '\f'; from += 2; break;
default:
ShouldNotReachHere();
}
}
}
*from = *to;
}
};
void ciReplay::replay(TRAPS) {
int exit_code = replay_impl(THREAD);
Threads::destroy_vm();
vm_exit(exit_code);
}
int ciReplay::replay_impl(TRAPS) {
HandleMark hm;
ResourceMark rm;
// Make sure we don't run with background compilation
BackgroundCompilation = false;
if (ReplaySuppressInitializers > 2) {
// ReplaySuppressInitializers > 2 means that we want to allow
// normal VM bootstrap but once we get into the replay itself
// don't allow any intializers to be run.
ReplaySuppressInitializers = 1;
}
// Load and parse the replay data
CompileReplay rp(ReplayDataFile, THREAD);
int exit_code = 0;
if (rp.can_replay()) {
rp.process(THREAD);
} else {
exit_code = 1;
return exit_code;
}
if (HAS_PENDING_EXCEPTION) {
oop throwable = PENDING_EXCEPTION;
CLEAR_PENDING_EXCEPTION;
java_lang_Throwable::print(throwable, tty);
tty->cr();
java_lang_Throwable::print_stack_trace(throwable, tty);
tty->cr();
exit_code = 2;
}
if (rp.had_error()) {
tty->print_cr("Failed on %s", rp.error_message());
exit_code = 1;
}
return exit_code;
}
void ciReplay::initialize(ciMethodData* m) {
if (replay_state == NULL) {
return;
}
ASSERT_IN_VM;
ResourceMark rm;
Method* method = m->get_MethodData()->method();
ciMethodDataRecord* rec = replay_state->find_ciMethodDataRecord(method);
if (rec == NULL) {
// This indicates some mismatch with the original environment and
// the replay environment though it's not always enough to
// interfere with reproducing a bug
tty->print_cr("Warning: requesting ciMethodData record for method with no data: ");
method->print_name(tty);
tty->cr();
} else {
m->_state = rec->state;
m->_current_mileage = rec->current_mileage;
if (rec->data_length != 0) {
assert(m->_data_size == rec->data_length * (int)sizeof(rec->data[0]), "must agree");
// Write the correct ciObjects back into the profile data
ciEnv* env = ciEnv::current();
for (int i = 0; i < rec->oops_length; i++) {
KlassHandle *h = (KlassHandle *)rec->oops_handles[i];
*(ciMetadata**)(rec->data + rec->oops_offsets[i]) =
env->get_metadata((*h)());
}
// Copy the updated profile data into place as intptr_ts
#ifdef _LP64
Copy::conjoint_jlongs_atomic((jlong *)rec->data, (jlong *)m->_data, rec->data_length);
#else
Copy::conjoint_jints_atomic((jint *)rec->data, (jint *)m->_data, rec->data_length);
#endif
}
// copy in the original header
Copy::conjoint_jbytes(rec->orig_data, (char*)&m->_orig, rec->orig_data_length);
}
}
bool ciReplay::should_not_inline(ciMethod* method) {
if (replay_state == NULL) {
return false;
}
VM_ENTRY_MARK;
// ciMethod without a record shouldn't be inlined.
return replay_state->find_ciMethodRecord(method->get_Method()) == NULL;
}
void ciReplay::initialize(ciMethod* m) {
if (replay_state == NULL) {
return;
}
ASSERT_IN_VM;
ResourceMark rm;
Method* method = m->get_Method();
ciMethodRecord* rec = replay_state->find_ciMethodRecord(method);
if (rec == NULL) {
// This indicates some mismatch with the original environment and
// the replay environment though it's not always enough to
// interfere with reproducing a bug
tty->print_cr("Warning: requesting ciMethod record for method with no data: ");
method->print_name(tty);
tty->cr();
} else {
// m->_instructions_size = rec->instructions_size;
m->_instructions_size = -1;
m->_interpreter_invocation_count = rec->interpreter_invocation_count;
m->_interpreter_throwout_count = rec->interpreter_throwout_count;
method->invocation_counter()->_counter = rec->invocation_counter;
method->backedge_counter()->_counter = rec->backedge_counter;
}
}
bool ciReplay::is_loaded(Method* method) {
if (replay_state == NULL) {
return true;
}
ASSERT_IN_VM;
ResourceMark rm;
ciMethodRecord* rec = replay_state->find_ciMethodRecord(method);
return rec != NULL;
}
#endif

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_CI_CIREPLAY_HPP
#define SHARE_VM_CI_CIREPLAY_HPP
#include "ci/ciMethod.hpp"
// ciReplay
class ciReplay {
CI_PACKAGE_ACCESS
#ifdef ASSERT
private:
static int replay_impl(TRAPS);
public:
static void replay(TRAPS);
// These are used by the CI to fill in the cached data from the
// replay file when replaying compiles.
static void initialize(ciMethodData* method);
static void initialize(ciMethod* method);
static bool is_loaded(Method* method);
static bool is_loaded(Klass* klass);
static bool should_not_inline(ciMethod* method);
#endif
};
#endif // SHARE_VM_CI_CIREPLAY_HPP

View File

@ -63,6 +63,11 @@ const char* ciSymbol::as_utf8() {
return s->as_utf8();
}
// The text of the symbol as a null-terminated C string.
const char* ciSymbol::as_quoted_ascii() {
GUARDED_VM_QUICK_ENTRY(return get_symbol()->as_quoted_ascii();)
}
// ------------------------------------------------------------------
// ciSymbol::base
const jbyte* ciSymbol::base() {

View File

@ -73,6 +73,9 @@ public:
const char* as_utf8();
int utf8_length();
// The text of the symbol as ascii with all non-printable characters quoted as \u####
const char* as_quoted_ascii();
// Return the i-th utf8 byte, where i < utf8_length
int byte_at(int i);

View File

@ -45,7 +45,7 @@ ciType::ciType(BasicType basic_type) : ciMetadata() {
}
ciType::ciType(KlassHandle k) : ciMetadata(k()) {
_basic_type = Klass::cast(k())->oop_is_array() ? T_ARRAY : T_OBJECT;
_basic_type = k()->oop_is_array() ? T_ARRAY : T_OBJECT;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2012, 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
@ -80,6 +80,9 @@
#define GUARDED_VM_ENTRY(action) \
{if (IS_IN_VM) { action } else { VM_ENTRY_MARK; { action }}}
#define GUARDED_VM_QUICK_ENTRY(action) \
{if (IS_IN_VM) { action } else { VM_QUICK_ENTRY_MARK; { action }}}
// Redefine this later.
#define KILL_COMPILE_ON_FATAL_(result) \
THREAD); \

View File

@ -0,0 +1,269 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "classfile/bytecodeAssembler.hpp"
#include "interpreter/bytecodes.hpp"
#include "memory/oopFactory.hpp"
#include "oops/constantPool.hpp"
#ifdef TARGET_ARCH_x86
# include "bytes_x86.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "bytes_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "bytes_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "bytes_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "bytes_ppc.hpp"
#endif
u2 BytecodeConstantPool::find_or_add(BytecodeCPEntry const& bcpe) {
u2 index;
u2* probe = _indices.get(bcpe);
if (probe == NULL) {
index = _entries.length();
_entries.append(bcpe);
_indices.put(bcpe, index);
} else {
index = *probe;
}
return index + _orig->length();
}
ConstantPool* BytecodeConstantPool::create_constant_pool(TRAPS) const {
if (_entries.length() == 0) {
return _orig;
}
ConstantPool* cp = ConstantPool::allocate(
_orig->pool_holder()->class_loader_data(),
_orig->length() + _entries.length(), CHECK_NULL);
cp->set_pool_holder(_orig->pool_holder());
_orig->copy_cp_to(1, _orig->length() - 1, cp, 1, CHECK_NULL);
for (int i = 0; i < _entries.length(); ++i) {
BytecodeCPEntry entry = _entries.at(i);
int idx = i + _orig->length();
switch (entry._tag) {
case BytecodeCPEntry::UTF8:
cp->symbol_at_put(idx, entry._u.utf8);
entry._u.utf8->increment_refcount();
break;
case BytecodeCPEntry::KLASS:
cp->unresolved_klass_at_put(
idx, cp->symbol_at(entry._u.klass));
break;
case BytecodeCPEntry::STRING:
cp->unresolved_string_at_put(
idx, cp->symbol_at(entry._u.string));
break;
case BytecodeCPEntry::NAME_AND_TYPE:
cp->name_and_type_at_put(idx,
entry._u.name_and_type.name_index,
entry._u.name_and_type.type_index);
break;
case BytecodeCPEntry::METHODREF:
cp->method_at_put(idx,
entry._u.methodref.class_index,
entry._u.methodref.name_and_type_index);
break;
default:
ShouldNotReachHere();
}
}
return cp;
}
void BytecodeAssembler::append(u1 imm_u1) {
_code->append(imm_u1);
}
void BytecodeAssembler::append(u2 imm_u2) {
_code->append(0);
_code->append(0);
Bytes::put_Java_u2(_code->adr_at(_code->length() - 2), imm_u2);
}
void BytecodeAssembler::append(u4 imm_u4) {
_code->append(0);
_code->append(0);
_code->append(0);
_code->append(0);
Bytes::put_Java_u4(_code->adr_at(_code->length() - 4), imm_u4);
}
void BytecodeAssembler::xload(u4 index, u1 onebyteop, u1 twobyteop) {
if (index < 4) {
_code->append(onebyteop + index);
} else {
_code->append(twobyteop);
_code->append((u2)index);
}
}
void BytecodeAssembler::dup() {
_code->append(Bytecodes::_dup);
}
void BytecodeAssembler::_new(Symbol* sym) {
u2 cpool_index = _cp->klass(sym);
_code->append(Bytecodes::_new);
append(cpool_index);
}
void BytecodeAssembler::load_string(Symbol* sym) {
u2 cpool_index = _cp->string(sym);
if (cpool_index < 0x100) {
ldc(cpool_index);
} else {
ldc_w(cpool_index);
}
}
void BytecodeAssembler::ldc(u1 index) {
_code->append(Bytecodes::_ldc);
append(index);
}
void BytecodeAssembler::ldc_w(u2 index) {
_code->append(Bytecodes::_ldc_w);
append(index);
}
void BytecodeAssembler::athrow() {
_code->append(Bytecodes::_athrow);
}
void BytecodeAssembler::iload(u4 index) {
xload(index, Bytecodes::_iload_0, Bytecodes::_iload);
}
void BytecodeAssembler::lload(u4 index) {
xload(index, Bytecodes::_lload_0, Bytecodes::_lload);
}
void BytecodeAssembler::fload(u4 index) {
xload(index, Bytecodes::_fload_0, Bytecodes::_fload);
}
void BytecodeAssembler::dload(u4 index) {
xload(index, Bytecodes::_dload_0, Bytecodes::_dload);
}
void BytecodeAssembler::aload(u4 index) {
xload(index, Bytecodes::_aload_0, Bytecodes::_aload);
}
void BytecodeAssembler::load(BasicType bt, u4 index) {
switch (bt) {
case T_BOOLEAN:
case T_CHAR:
case T_BYTE:
case T_SHORT:
case T_INT: iload(index); break;
case T_FLOAT: fload(index); break;
case T_DOUBLE: dload(index); break;
case T_LONG: lload(index); break;
case T_OBJECT:
case T_ARRAY: aload(index); break;
default:
ShouldNotReachHere();
}
}
void BytecodeAssembler::checkcast(Symbol* sym) {
u2 cpool_index = _cp->klass(sym);
_code->append(Bytecodes::_checkcast);
append(cpool_index);
}
void BytecodeAssembler::invokespecial(Method* method) {
invokespecial(method->klass_name(), method->name(), method->signature());
}
void BytecodeAssembler::invokespecial(Symbol* klss, Symbol* name, Symbol* sig) {
u2 methodref_index = _cp->methodref(klss, name, sig);
_code->append(Bytecodes::_invokespecial);
append(methodref_index);
}
void BytecodeAssembler::invokevirtual(Method* method) {
invokevirtual(method->klass_name(), method->name(), method->signature());
}
void BytecodeAssembler::invokevirtual(Symbol* klss, Symbol* name, Symbol* sig) {
u2 methodref_index = _cp->methodref(klss, name, sig);
_code->append(Bytecodes::_invokevirtual);
append(methodref_index);
}
void BytecodeAssembler::ireturn() {
_code->append(Bytecodes::_ireturn);
}
void BytecodeAssembler::lreturn() {
_code->append(Bytecodes::_lreturn);
}
void BytecodeAssembler::freturn() {
_code->append(Bytecodes::_freturn);
}
void BytecodeAssembler::dreturn() {
_code->append(Bytecodes::_dreturn);
}
void BytecodeAssembler::areturn() {
_code->append(Bytecodes::_areturn);
}
void BytecodeAssembler::_return() {
_code->append(Bytecodes::_return);
}
void BytecodeAssembler::_return(BasicType bt) {
switch (bt) {
case T_BOOLEAN:
case T_CHAR:
case T_BYTE:
case T_SHORT:
case T_INT: ireturn(); break;
case T_FLOAT: freturn(); break;
case T_DOUBLE: dreturn(); break;
case T_LONG: lreturn(); break;
case T_OBJECT:
case T_ARRAY: areturn(); break;
case T_VOID: _return(); break;
default:
ShouldNotReachHere();
}
}

View File

@ -0,0 +1,214 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP
#define SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP
#include "memory/allocation.hpp"
#include "oops/method.hpp"
#include "oops/symbol.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/resourceHash.hpp"
/**
* Bytecode Assembler
*
* These classes are used to synthesize code for creating new methods from
* within the VM. This is only a partial implementation of an assembler;
* only the bytecodes that are needed by clients are implemented at this time.
* This is used during default method analysis to create overpass methods
* and add them to a call during parsing. Other uses (such as creating
* bridges) may come later. Any missing bytecodes can be implemented on an
* as-need basis.
*/
class BytecodeBuffer : public GrowableArray<u1> {
public:
BytecodeBuffer() : GrowableArray<u1>(20) {}
};
// Entries in a yet-to-be-created constant pool. Limited types for now.
class BytecodeCPEntry VALUE_OBJ_CLASS_SPEC {
public:
enum tag {
ERROR_TAG,
UTF8,
KLASS,
STRING,
NAME_AND_TYPE,
METHODREF
};
u1 _tag;
union {
Symbol* utf8;
u2 klass;
u2 string;
struct {
u2 name_index;
u2 type_index;
} name_and_type;
struct {
u2 class_index;
u2 name_and_type_index;
} methodref;
uintptr_t hash;
} _u;
BytecodeCPEntry() : _tag(ERROR_TAG) { _u.hash = 0; }
BytecodeCPEntry(u1 tag) : _tag(tag) { _u.hash = 0; }
static BytecodeCPEntry utf8(Symbol* symbol) {
BytecodeCPEntry bcpe(UTF8);
bcpe._u.utf8 = symbol;
return bcpe;
}
static BytecodeCPEntry klass(u2 index) {
BytecodeCPEntry bcpe(KLASS);
bcpe._u.klass = index;
return bcpe;
}
static BytecodeCPEntry string(u2 index) {
BytecodeCPEntry bcpe(STRING);
bcpe._u.string = index;
return bcpe;
}
static BytecodeCPEntry name_and_type(u2 name, u2 type) {
BytecodeCPEntry bcpe(NAME_AND_TYPE);
bcpe._u.name_and_type.name_index = name;
bcpe._u.name_and_type.type_index = type;
return bcpe;
}
static BytecodeCPEntry methodref(u2 class_index, u2 nat) {
BytecodeCPEntry bcpe(METHODREF);
bcpe._u.methodref.class_index = class_index;
bcpe._u.methodref.name_and_type_index = nat;
return bcpe;
}
static bool equals(BytecodeCPEntry const& e0, BytecodeCPEntry const& e1) {
return e0._tag == e1._tag && e0._u.hash == e1._u.hash;
}
static unsigned hash(BytecodeCPEntry const& e0) {
return (unsigned)(e0._tag ^ e0._u.hash);
}
};
class BytecodeConstantPool : ResourceObj {
private:
typedef ResourceHashtable<BytecodeCPEntry, u2,
&BytecodeCPEntry::hash, &BytecodeCPEntry::equals> IndexHash;
ConstantPool* _orig;
GrowableArray<BytecodeCPEntry> _entries;
IndexHash _indices;
u2 find_or_add(BytecodeCPEntry const& bcpe);
public:
BytecodeConstantPool(ConstantPool* orig) : _orig(orig) {}
BytecodeCPEntry const& at(u2 index) const { return _entries.at(index); }
InstanceKlass* pool_holder() const {
return InstanceKlass::cast(_orig->pool_holder());
}
u2 utf8(Symbol* sym) {
return find_or_add(BytecodeCPEntry::utf8(sym));
}
u2 klass(Symbol* class_name) {
return find_or_add(BytecodeCPEntry::klass(utf8(class_name)));
}
u2 string(Symbol* str) {
return find_or_add(BytecodeCPEntry::string(utf8(str)));
}
u2 name_and_type(Symbol* name, Symbol* sig) {
return find_or_add(BytecodeCPEntry::name_and_type(utf8(name), utf8(sig)));
}
u2 methodref(Symbol* class_name, Symbol* name, Symbol* sig) {
return find_or_add(BytecodeCPEntry::methodref(
klass(class_name), name_and_type(name, sig)));
}
ConstantPool* create_constant_pool(TRAPS) const;
};
// Partial bytecode assembler - only what we need for creating
// overpass methods for default methods is implemented
class BytecodeAssembler : StackObj {
private:
BytecodeBuffer* _code;
BytecodeConstantPool* _cp;
void append(u1 imm_u1);
void append(u2 imm_u2);
void append(u4 imm_u4);
void xload(u4 index, u1 quick, u1 twobyte);
public:
BytecodeAssembler(BytecodeBuffer* buffer, BytecodeConstantPool* cp)
: _code(buffer), _cp(cp) {}
void aload(u4 index);
void areturn();
void athrow();
void checkcast(Symbol* sym);
void dload(u4 index);
void dreturn();
void dup();
void fload(u4 index);
void freturn();
void iload(u4 index);
void invokespecial(Method* method);
void invokespecial(Symbol* cls, Symbol* name, Symbol* sig);
void invokevirtual(Method* method);
void invokevirtual(Symbol* cls, Symbol* name, Symbol* sig);
void ireturn();
void ldc(u1 index);
void ldc_w(u2 index);
void lload(u4 index);
void lreturn();
void _new(Symbol* sym);
void _return();
void load_string(Symbol* sym);
void load(BasicType bt, u4 index);
void _return(BasicType bt);
};
#endif // SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP

View File

@ -27,6 +27,8 @@
#include "classfile/classLoader.hpp"
#include "classfile/classLoaderData.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/defaultMethods.hpp"
#include "classfile/genericSignatures.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
@ -84,6 +86,9 @@
// - to check NameAndType_info signatures more aggressively
#define JAVA_7_VERSION 51
// Extension method support.
#define JAVA_8_VERSION 52
void ClassFileParser::parse_constant_pool_entries(ClassLoaderData* loader_data, constantPoolHandle cp, int length, TRAPS) {
// Use a local copy of ClassFileStream. It helps the C++ compiler to optimize
@ -785,6 +790,7 @@ Array<Klass*>* ClassFileParser::parse_interfaces(constantPoolHandle cp,
ClassLoaderData* loader_data,
Handle protection_domain,
Symbol* class_name,
bool* has_default_methods,
TRAPS) {
ClassFileStream* cfs = stream();
assert(length > 0, "only called for length>0");
@ -818,9 +824,12 @@ Array<Klass*>* ClassFileParser::parse_interfaces(constantPoolHandle cp,
interf = KlassHandle(THREAD, k);
}
if (!Klass::cast(interf())->is_interface()) {
if (!interf()->is_interface()) {
THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", NULL);
}
if (InstanceKlass::cast(interf())->has_default_methods()) {
*has_default_methods = true;
}
interfaces->at_put(index, interf());
}
@ -1928,7 +1937,8 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
if (method_attribute_name == vmSymbols::tag_code()) {
// Parse Code attribute
if (_need_verify) {
guarantee_property(!access_flags.is_native() && !access_flags.is_abstract(),
guarantee_property(
!access_flags.is_native() && !access_flags.is_abstract(),
"Code attribute in native or abstract methods in class file %s",
CHECK_(nullHandle));
}
@ -2125,7 +2135,9 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
runtime_visible_annotations_length = method_attribute_length;
runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations");
parse_annotations(runtime_visible_annotations, runtime_visible_annotations_length, cp, &parsed_annotations, CHECK_(nullHandle));
parse_annotations(runtime_visible_annotations,
runtime_visible_annotations_length, cp, &parsed_annotations,
CHECK_(nullHandle));
cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle));
} else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
runtime_invisible_annotations_length = method_attribute_length;
@ -2169,12 +2181,10 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
}
// All sizing information for a Method* is finally available, now create it
Method* m = Method::allocate(loader_data, code_length, access_flags,
linenumber_table_length,
total_lvt_length,
exception_table_length,
checked_exceptions_length,
CHECK_(nullHandle));
Method* m = Method::allocate(
loader_data, code_length, access_flags, linenumber_table_length,
total_lvt_length, exception_table_length, checked_exceptions_length,
ConstMethod::NORMAL, CHECK_(nullHandle));
ClassLoadingService::add_class_method_size(m->size()*HeapWordSize);
@ -2204,7 +2214,6 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
// Fill in code attribute information
m->set_max_stack(max_stack);
m->set_max_locals(max_locals);
m->constMethod()->set_stackmap_data(stackmap_data);
// Copy byte codes
@ -2356,6 +2365,7 @@ Array<Method*>* ClassFileParser::parse_methods(ClassLoaderData* loader_data,
Array<AnnotationArray*>** methods_annotations,
Array<AnnotationArray*>** methods_parameter_annotations,
Array<AnnotationArray*>** methods_default_annotations,
bool* has_default_methods,
TRAPS) {
ClassFileStream* cfs = stream();
AnnotationArray* method_annotations = NULL;
@ -2382,6 +2392,10 @@ Array<Method*>* ClassFileParser::parse_methods(ClassLoaderData* loader_data,
if (method->is_final()) {
*has_final_method = true;
}
if (is_interface && !method->is_abstract() && !method->is_static()) {
// default method
*has_default_methods = true;
}
methods->at_put(index, method());
if (*methods_annotations == NULL) {
*methods_annotations =
@ -2907,6 +2921,34 @@ AnnotationArray* ClassFileParser::assemble_annotations(ClassLoaderData* loader_d
}
#ifndef PRODUCT
static void parseAndPrintGenericSignatures(
instanceKlassHandle this_klass, TRAPS) {
assert(ParseAllGenericSignatures == true, "Shouldn't call otherwise");
ResourceMark rm;
if (this_klass->generic_signature() != NULL) {
using namespace generic;
ClassDescriptor* spec = ClassDescriptor::parse_generic_signature(this_klass(), CHECK);
tty->print_cr("Parsing %s", this_klass->generic_signature()->as_C_string());
spec->print_on(tty);
for (int i = 0; i < this_klass->methods()->length(); ++i) {
Method* m = this_klass->methods()->at(i);
MethodDescriptor* method_spec = MethodDescriptor::parse_generic_signature(m, spec);
Symbol* sig = m->generic_signature();
if (sig == NULL) {
sig = m->signature();
}
tty->print_cr("Parsing %s", sig->as_C_string());
method_spec->print_on(tty);
}
}
}
#endif // ndef PRODUCT
instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
Handle class_loader,
Handle protection_domain,
@ -2923,6 +2965,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
unsigned char *cached_class_file_bytes = NULL;
jint cached_class_file_length;
ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
bool has_default_methods = false;
ResourceMark rm(THREAD);
ClassFileStream* cfs = stream();
// Timing
@ -3138,7 +3182,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
if (itfs_len == 0) {
local_interfaces = Universe::the_empty_klass_array();
} else {
local_interfaces = parse_interfaces(cp, itfs_len, loader_data, protection_domain, _class_name, CHECK_(nullHandle));
local_interfaces = parse_interfaces(
cp, itfs_len, loader_data, protection_domain, _class_name,
&has_default_methods, CHECK_(nullHandle));
}
u2 java_fields_count = 0;
@ -3164,6 +3210,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
&methods_annotations,
&methods_parameter_annotations,
&methods_default_annotations,
&has_default_methods,
CHECK_(nullHandle));
// Additional attributes
@ -3193,6 +3240,11 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
super_klass = instanceKlassHandle(THREAD, kh());
}
if (super_klass.not_null()) {
if (super_klass->has_default_methods()) {
has_default_methods = true;
}
if (super_klass->is_interface()) {
ResourceMark rm(THREAD);
Exceptions::fthrow(
@ -3229,14 +3281,11 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
int itable_size = 0;
int num_miranda_methods = 0;
klassVtable::compute_vtable_size_and_num_mirandas(vtable_size,
num_miranda_methods,
super_klass(),
methods,
access_flags,
class_loader,
class_name,
local_interfaces,
GrowableArray<Method*> all_mirandas(20);
klassVtable::compute_vtable_size_and_num_mirandas(
&vtable_size, &num_miranda_methods, &all_mirandas, super_klass(), methods,
access_flags, class_loader, class_name, local_interfaces,
CHECK_(nullHandle));
// Size of Java itable (in words)
@ -3656,6 +3705,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
this_klass->set_minor_version(minor_version);
this_klass->set_major_version(major_version);
this_klass->set_has_default_methods(has_default_methods);
// Set up Method*::intrinsic_id as soon as we know the names of methods.
// (We used to do this lazily, but now we query it in Rewriter,
@ -3673,6 +3723,16 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
cached_class_file_length);
}
// Fill in field values obtained by parse_classfile_attributes
if (parsed_annotations.has_any_annotations())
parsed_annotations.apply_to(this_klass);
// Create annotations
if (_annotations != NULL && this_klass->annotations() == NULL) {
Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL);
this_klass->set_annotations(anno);
}
apply_parsed_class_attributes(this_klass);
// Miranda methods
if ((num_miranda_methods > 0) ||
// if this class introduced new miranda methods or
@ -3682,18 +3742,6 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
this_klass->set_has_miranda_methods(); // then set a flag
}
// Fill in field values obtained by parse_classfile_attributes
if (parsed_annotations.has_any_annotations()) {
parsed_annotations.apply_to(this_klass);
}
// Create annotations
if (_annotations != NULL && this_klass->annotations() == NULL) {
Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL);
this_klass->set_annotations(anno);
}
apply_parsed_class_attributes(this_klass);
// Compute transitive closure of interfaces this class implements
this_klass->set_transitive_interfaces(transitive_interfaces);
// Fill in information needed to compute superclasses.
@ -3702,6 +3750,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
// Initialize itable offset tables
klassItable::setup_itable_offset_table(this_klass);
// Compute transitive closure of interfaces this class implements
// Do final class setup
fill_oop_maps(this_klass, nonstatic_oop_map_count, nonstatic_oop_offsets, nonstatic_oop_counts);
@ -3726,6 +3775,21 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
check_illegal_static_method(this_klass, CHECK_(nullHandle));
}
#ifdef ASSERT
if (ParseAllGenericSignatures) {
parseAndPrintGenericSignatures(this_klass, CHECK_(nullHandle));
}
#endif
// Generate any default methods - default methods are interface methods
// that have a default implementation. This is new with Lambda project.
if (has_default_methods && !access_flags.is_interface() &&
local_interfaces->length() > 0) {
DefaultMethods::generate_default_methods(
this_klass(), &all_mirandas, CHECK_(nullHandle));
}
// Allocate mirror and initialize static fields
java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle));
@ -3744,6 +3808,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
false /* not shared class */);
if (TraceClassLoading) {
ResourceMark rm;
// print in a single call to reduce interleaving of output
if (cfs->source() != NULL) {
tty->print("[Loaded %s from %s]\n", this_klass->external_name(),
@ -3758,15 +3823,15 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
tty->print("[Loaded %s]\n", this_klass->external_name());
}
} else {
ResourceMark rm;
tty->print("[Loaded %s from %s]\n", this_klass->external_name(),
InstanceKlass::cast(class_loader->klass())->external_name());
}
}
if (TraceClassResolution) {
ResourceMark rm;
// print out the superclass.
const char * from = Klass::cast(this_klass())->external_name();
const char * from = this_klass()->external_name();
if (this_klass->java_super() != NULL) {
tty->print("RESOLVE %s %s (super)\n", from, InstanceKlass::cast(this_klass->java_super())->external_name());
}
@ -3785,6 +3850,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
#ifndef PRODUCT
if( PrintCompactFieldsSavings ) {
ResourceMark rm;
if( nonstatic_field_size < orig_nonstatic_field_size ) {
tty->print("[Saved %d of %d bytes in %s]\n",
(orig_nonstatic_field_size - nonstatic_field_size)*heapOopSize,
@ -3811,7 +3877,6 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
return this_klass;
}
unsigned int
ClassFileParser::compute_oop_map_count(instanceKlassHandle super,
unsigned int nonstatic_oop_map_count,
@ -3917,13 +3982,13 @@ void ClassFileParser::set_precomputed_flags(instanceKlassHandle k) {
// java.lang.Object has empty default constructor
k->set_has_vanilla_constructor();
} else {
if (Klass::cast(super)->has_vanilla_constructor() &&
if (super->has_vanilla_constructor() &&
_has_vanilla_constructor) {
k->set_has_vanilla_constructor();
}
#ifdef ASSERT
bool v = false;
if (Klass::cast(super)->has_vanilla_constructor()) {
if (super->has_vanilla_constructor()) {
Method* constructor = k->find_method(vmSymbols::object_initializer_name(
), vmSymbols::void_method_signature());
if (constructor != NULL && constructor->is_vanilla_constructor()) {
@ -4065,7 +4130,7 @@ void ClassFileParser::check_super_interface_access(instanceKlassHandle this_klas
int lng = local_interfaces->length();
for (int i = lng - 1; i >= 0; i--) {
Klass* k = local_interfaces->at(i);
assert (k != NULL && Klass::cast(k)->is_interface(), "invalid interface");
assert (k != NULL && k->is_interface(), "invalid interface");
if (!Reflection::verify_class_access(this_klass(), k, false)) {
ResourceMark rm(THREAD);
Exceptions::fthrow(
@ -4128,7 +4193,7 @@ void ClassFileParser::check_final_method_override(instanceKlassHandle this_klass
}
// continue to look from super_m's holder's super.
k = InstanceKlass::cast(super_m->method_holder())->super();
k = super_m->method_holder()->super();
continue;
}
@ -4263,13 +4328,16 @@ void ClassFileParser::verify_legal_method_modifiers(
const bool is_strict = (flags & JVM_ACC_STRICT) != 0;
const bool is_synchronized = (flags & JVM_ACC_SYNCHRONIZED) != 0;
const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION;
const bool major_gte_8 = _major_version >= JAVA_8_VERSION;
const bool is_initializer = (name == vmSymbols::object_initializer_name());
bool is_illegal = false;
if (is_interface) {
if (!is_abstract || !is_public || is_static || is_final ||
is_native || (major_gte_15 && (is_synchronized || is_strict))) {
if (!is_public || is_static || is_final || is_native ||
((is_synchronized || is_strict) && major_gte_15 &&
(!major_gte_8 || is_abstract)) ||
(!major_gte_8 && !is_abstract)) {
is_illegal = true;
}
} else { // not interface

View File

@ -151,6 +151,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
ClassLoaderData* loader_data,
Handle protection_domain,
Symbol* class_name,
bool* has_default_methods,
TRAPS);
void record_defined_class_dependencies(instanceKlassHandle defined_klass, TRAPS);
@ -188,6 +189,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
Array<AnnotationArray*>** methods_annotations,
Array<AnnotationArray*>** methods_parameter_annotations,
Array<AnnotationArray*>** methods_default_annotations,
bool* has_default_method,
TRAPS);
Array<int>* sort_methods(ClassLoaderData* loader_data,
Array<Method*>* methods,

View File

@ -605,8 +605,10 @@ void ClassLoader::load_zip_library() {
// Load zip library
char path[JVM_MAXPATHLEN];
char ebuf[1024];
os::dll_build_name(path, sizeof(path), Arguments::get_dll_dir(), "zip");
void* handle = os::dll_load(path, ebuf, sizeof ebuf);
void* handle = NULL;
if (os::dll_build_name(path, sizeof(path), Arguments::get_dll_dir(), "zip")) {
handle = os::dll_load(path, ebuf, sizeof ebuf);
}
if (handle == NULL) {
vm_exit_during_initialization("Unable to load ZIP library", path);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP
#define SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP
#include "runtime/handles.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/exceptions.hpp"
class InstanceKlass;
class Symbol;
class Method;
class DefaultMethods : AllStatic {
public:
// Analyzes class and determines which default methods are inherited
// from interfaces (and has no other implementation). For each method
// (and each different signature the method could have), create an
// "overpass" method that is an instance method that redirects to the
// default method. Overpass methods are added to the methods lists for
// the class.
static void generate_default_methods(
InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS);
// Called during linking when an invokespecial to an direct interface
// method is found. Selects and returns a method if there is a unique
// default method in the 'super_iface' part of the hierarchy which is
// also a candidate default for 'this_klass'. Otherwise throws an AME.
static Method* find_super_default(
Klass* this_klass, Klass* super_iface,
Symbol* method_name, Symbol* method_sig, TRAPS);
};
#endif // SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP

View File

@ -346,7 +346,7 @@ void Dictionary::add_klass(Symbol* class_name, ClassLoaderData* loader_data,
KlassHandle obj) {
assert_locked_or_safepoint(SystemDictionary_lock);
assert(obj() != NULL, "adding NULL obj");
assert(Klass::cast(obj())->name() == class_name, "sanity check on name");
assert(obj()->name() == class_name, "sanity check on name");
unsigned int hash = compute_hash(class_name, loader_data);
int index = hash_to_index(hash);
@ -553,7 +553,7 @@ void Dictionary::print() {
bool is_defining_class =
(loader_data == InstanceKlass::cast(e)->class_loader_data());
tty->print("%s%s", is_defining_class ? " " : "^",
Klass::cast(e)->external_name());
e->external_name());
tty->print(", loader ");
loader_data->print_value();
@ -575,7 +575,7 @@ void Dictionary::verify() {
probe = probe->next()) {
Klass* e = probe->klass();
ClassLoaderData* loader_data = probe->loader_data();
guarantee(Klass::cast(e)->oop_is_instance(),
guarantee(e->oop_is_instance(),
"Verify of system dictionary failed");
// class loader must be present; a null class loader is the
// boostrap loader

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,467 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP
#define SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP
#include "classfile/symbolTable.hpp"
#include "memory/allocation.hpp"
#include "runtime/signature.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/resourceHash.hpp"
class stringStream;
namespace generic {
class Identifier;
class ClassDescriptor;
class MethodDescriptor;
class TypeParameter; // a formal type parameter declared in generic signatures
class TypeArgument; // The "type value" passed to fill parameters in supertypes
class TypeVariable; // A usage of a type parameter as a value
/**
* Example:
*
* <T, V> class Foo extends Bar<String> { int m(V v) {} }
* ^^^^^^ ^^^^^^ ^^
* type parameters type argument type variable
*
* Note that a type variable could be passed as an argument too:
* <T, V> class Foo extends Bar<T> { int m(V v) {} }
* ^^^
* type argument's value is a type variable
*/
class Type;
class ClassType;
class ArrayType;
class PrimitiveType;
class Context;
class DescriptorCache;
class DescriptorStream;
class Identifier : public ResourceObj {
private:
Symbol* _sym;
int _begin;
int _end;
public:
Identifier(Symbol* sym, int begin, int end) :
_sym(sym), _begin(begin), _end(end) {}
bool equals(Identifier* other);
bool equals(Symbol* sym);
#ifndef PRODUCT
void print_on(outputStream* str) const;
#endif // ndef PRODUCT
};
class Descriptor : public ResourceObj {
protected:
GrowableArray<TypeParameter*> _type_parameters;
ClassDescriptor* _outer_class;
Descriptor(GrowableArray<TypeParameter*>& params,
ClassDescriptor* outer)
: _type_parameters(params), _outer_class(outer) {}
public:
ClassDescriptor* outer_class() { return _outer_class; }
void set_outer_class(ClassDescriptor* sig) { _outer_class = sig; }
virtual ClassDescriptor* as_class_signature() { return NULL; }
virtual MethodDescriptor* as_method_signature() { return NULL; }
bool is_class_signature() { return as_class_signature() != NULL; }
bool is_method_signature() { return as_method_signature() != NULL; }
GrowableArray<TypeParameter*>& type_parameters() {
return _type_parameters;
}
TypeParameter* find_type_parameter(Identifier* id, int* param_depth);
virtual void bind_variables_to_parameters() = 0;
#ifndef PRODUCT
virtual void print_on(outputStream* str) const = 0;
#endif
};
class ClassDescriptor : public Descriptor {
private:
ClassType* _super;
GrowableArray<ClassType*> _interfaces;
MethodDescriptor* _outer_method;
ClassDescriptor(GrowableArray<TypeParameter*>& ftp, ClassType* scs,
GrowableArray<ClassType*>& sis, ClassDescriptor* outer_class = NULL,
MethodDescriptor* outer_method = NULL)
: Descriptor(ftp, outer_class), _super(scs), _interfaces(sis),
_outer_method(outer_method) {}
static u2 get_outer_class_index(InstanceKlass* k, TRAPS);
static ClassDescriptor* parse_generic_signature(Klass* k, Symbol* original_name, TRAPS);
public:
virtual ClassDescriptor* as_class_signature() { return this; }
MethodDescriptor* outer_method() { return _outer_method; }
void set_outer_method(MethodDescriptor* m) { _outer_method = m; }
ClassType* super() { return _super; }
ClassType* interface_desc(Symbol* sym);
static ClassDescriptor* parse_generic_signature(Klass* k, TRAPS);
static ClassDescriptor* parse_generic_signature(Symbol* sym);
// For use in superclass chains in positions where this is no generic info
static ClassDescriptor* placeholder(InstanceKlass* klass);
#ifndef PRODUCT
void print_on(outputStream* str) const;
#endif
ClassDescriptor* canonicalize(Context* ctx);
// Linking sets the position index in any contained TypeVariable type
// to correspond to the location of that identifier in the formal type
// parameters.
void bind_variables_to_parameters();
};
class MethodDescriptor : public Descriptor {
private:
GrowableArray<Type*> _parameters;
Type* _return_type;
GrowableArray<Type*> _throws;
MethodDescriptor(GrowableArray<TypeParameter*>& ftp, ClassDescriptor* outer,
GrowableArray<Type*>& sigs, Type* rt, GrowableArray<Type*>& throws)
: Descriptor(ftp, outer), _parameters(sigs), _return_type(rt),
_throws(throws) {}
public:
static MethodDescriptor* parse_generic_signature(Method* m, ClassDescriptor* outer);
static MethodDescriptor* parse_generic_signature(Symbol* sym, ClassDescriptor* outer);
MethodDescriptor* as_method_signature() { return this; }
// Performs generic analysis on the method parameters to determine
// if both methods refer to the same argument types.
bool covariant_match(MethodDescriptor* other, Context* ctx);
// Returns a new method descriptor with all generic variables
// removed and replaced with whatever is indicated using the Context.
MethodDescriptor* canonicalize(Context* ctx);
void bind_variables_to_parameters();
#ifndef PRODUCT
TempNewSymbol reify_signature(Context* ctx, TRAPS);
void print_on(outputStream* str) const;
#endif
};
class TypeParameter : public ResourceObj {
private:
Identifier* _identifier;
ClassType* _class_bound;
GrowableArray<ClassType*> _interface_bounds;
// The position is the ordinal location of the parameter within the
// formal parameter list (excluding outer classes). It is only set for
// formal type parameters that are associated with a class -- method
// type parameters are left as -1. When resolving a generic variable to
// find the actual type, this index is used to access the generic type
// argument in the provided context object.
int _position; // Assigned during variable linking
TypeParameter(Identifier* id, ClassType* class_bound,
GrowableArray<ClassType*>& interface_bounds) :
_identifier(id), _class_bound(class_bound),
_interface_bounds(interface_bounds), _position(-1) {}
public:
static TypeParameter* parse_generic_signature(DescriptorStream* str);
ClassType* bound();
int position() { return _position; }
void bind_variables_to_parameters(Descriptor* sig, int position);
Identifier* identifier() { return _identifier; }
Type* resolve(Context* ctx, int inner_depth, int ctx_depth);
TypeParameter* canonicalize(Context* ctx, int ctx_depth);
#ifndef PRODUCT
void print_on(outputStream* str) const;
#endif
};
class Type : public ResourceObj {
public:
static Type* parse_generic_signature(DescriptorStream* str);
virtual ClassType* as_class() { return NULL; }
virtual TypeVariable* as_variable() { return NULL; }
virtual ArrayType* as_array() { return NULL; }
virtual PrimitiveType* as_primitive() { return NULL; }
virtual bool covariant_match(Type* gt, Context* ctx) = 0;
virtual Type* canonicalize(Context* ctx, int ctx_depth) = 0;
virtual void bind_variables_to_parameters(Descriptor* sig) = 0;
#ifndef PRODUCT
virtual void reify_signature(stringStream* ss, Context* ctx) = 0;
virtual void print_on(outputStream* str) const = 0;
#endif
};
class ClassType : public Type {
friend class ClassDescriptor;
protected:
Identifier* _identifier;
GrowableArray<TypeArgument*> _type_arguments;
ClassType* _outer_class;
ClassType(Identifier* identifier,
GrowableArray<TypeArgument*>& args,
ClassType* outer)
: _identifier(identifier), _type_arguments(args), _outer_class(outer) {}
// Returns true if there are inner classes to read
static Identifier* parse_generic_signature_simple(
GrowableArray<TypeArgument*>* args,
bool* has_inner, DescriptorStream* str);
static ClassType* parse_generic_signature(ClassType* outer,
DescriptorStream* str);
static ClassType* from_symbol(Symbol* sym);
public:
ClassType* as_class() { return this; }
static ClassType* parse_generic_signature(DescriptorStream* str);
static ClassType* java_lang_Object();
Identifier* identifier() { return _identifier; }
int type_arguments_length() { return _type_arguments.length(); }
TypeArgument* type_argument_at(int i);
virtual ClassType* outer_class() { return _outer_class; }
bool covariant_match(Type* gt, Context* ctx);
ClassType* canonicalize(Context* ctx, int context_depth);
void bind_variables_to_parameters(Descriptor* sig);
#ifndef PRODUCT
void reify_signature(stringStream* ss, Context* ctx);
void print_on(outputStream* str) const;
#endif
};
class TypeVariable : public Type {
private:
Identifier* _id;
TypeParameter* _parameter; // assigned during linking
// how many steps "out" from inner classes, -1 if method
int _inner_depth;
TypeVariable(Identifier* id)
: _id(id), _parameter(NULL), _inner_depth(0) {}
public:
TypeVariable* as_variable() { return this; }
static TypeVariable* parse_generic_signature(DescriptorStream* str);
Identifier* identifier() { return _id; }
TypeParameter* parameter() { return _parameter; }
int inner_depth() { return _inner_depth; }
void bind_variables_to_parameters(Descriptor* sig);
Type* resolve(Context* ctx, int ctx_depth);
bool covariant_match(Type* gt, Context* ctx);
Type* canonicalize(Context* ctx, int ctx_depth);
#ifndef PRODUCT
void reify_signature(stringStream* ss, Context* ctx);
void print_on(outputStream* str) const;
#endif
};
class ArrayType : public Type {
private:
Type* _base;
ArrayType(Type* base) : _base(base) {}
public:
ArrayType* as_array() { return this; }
static ArrayType* parse_generic_signature(DescriptorStream* str);
bool covariant_match(Type* gt, Context* ctx);
ArrayType* canonicalize(Context* ctx, int ctx_depth);
void bind_variables_to_parameters(Descriptor* sig);
#ifndef PRODUCT
void reify_signature(stringStream* ss, Context* ctx);
void print_on(outputStream* str) const;
#endif
};
class PrimitiveType : public Type {
friend class Type;
private:
char _type; // includes V for void
PrimitiveType(char& type) : _type(type) {}
public:
PrimitiveType* as_primitive() { return this; }
bool covariant_match(Type* gt, Context* ctx);
PrimitiveType* canonicalize(Context* ctx, int ctx_depth);
void bind_variables_to_parameters(Descriptor* sig);
#ifndef PRODUCT
void reify_signature(stringStream* ss, Context* ctx);
void print_on(outputStream* str) const;
#endif
};
class TypeArgument : public ResourceObj {
private:
Type* _lower_bound;
Type* _upper_bound; // may be null or == _lower_bound
TypeArgument(Type* lower_bound, Type* upper_bound)
: _lower_bound(lower_bound), _upper_bound(upper_bound) {}
public:
static TypeArgument* parse_generic_signature(DescriptorStream* str);
Type* lower_bound() { return _lower_bound; }
Type* upper_bound() { return _upper_bound; }
void bind_variables_to_parameters(Descriptor* sig);
TypeArgument* canonicalize(Context* ctx, int ctx_depth);
bool covariant_match(TypeArgument* a, Context* ctx);
#ifndef PRODUCT
void print_on(outputStream* str) const;
#endif
};
class Context : public ResourceObj {
private:
DescriptorCache* _cache;
GrowableArray<ClassType*> _type_arguments;
void reset_to_mark(int size);
public:
// When this object goes out of scope or 'destroy' is
// called, then the application of the type to the
// context is wound-back (unless it's been deactivated).
class Mark : public StackObj {
private:
mutable Context* _context;
int _marked_size;
bool is_active() const { return _context != NULL; }
void deactivate() const { _context = NULL; }
public:
Mark() : _context(NULL), _marked_size(0) {}
Mark(Context* ctx, int sz) : _context(ctx), _marked_size(sz) {}
Mark(const Mark& m) : _context(m._context), _marked_size(m._marked_size) {
m.deactivate(); // Ownership is transferred
}
Mark& operator=(const Mark& cm) {
destroy();
_context = cm._context;
_marked_size = cm._marked_size;
cm.deactivate();
return *this;
}
void destroy();
~Mark() { destroy(); }
};
Context(DescriptorCache* cache) : _cache(cache) {}
Mark mark() { return Mark(this, _type_arguments.length()); }
void apply_type_arguments(InstanceKlass* current, InstanceKlass* super,TRAPS);
ClassType* at_depth(int i) const;
#ifndef PRODUCT
void print_on(outputStream* str) const;
#endif
};
/**
* Contains a cache of descriptors for classes and methods so they can be
* looked-up instead of reparsing each time they are needed.
*/
class DescriptorCache : public ResourceObj {
private:
ResourceHashtable<InstanceKlass*, ClassDescriptor*> _class_descriptors;
ResourceHashtable<Method*, MethodDescriptor*> _method_descriptors;
public:
ClassDescriptor* descriptor_for(InstanceKlass* ikh, TRAPS);
MethodDescriptor* descriptor_for(Method* mh, ClassDescriptor* cd, TRAPS);
// Class descriptor derived from method holder
MethodDescriptor* descriptor_for(Method* mh, TRAPS);
};
} // namespace generic
#endif // SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP

View File

@ -348,6 +348,22 @@ unsigned int java_lang_String::to_hash(oop java_string) {
return java_lang_String::to_hash(value->char_at_addr(offset), length);
}
char* java_lang_String::as_quoted_ascii(oop java_string) {
typeArrayOop value = java_lang_String::value(java_string);
int offset = java_lang_String::offset(java_string);
int length = java_lang_String::length(java_string);
jchar* base = (length == 0) ? NULL : value->char_at_addr(offset);
if (base == NULL) return NULL;
int result_length = UNICODE::quoted_ascii_length(base, length) + 1;
char* result = NEW_RESOURCE_ARRAY(char, result_length);
UNICODE::as_quoted_ascii(base, length, result, result_length);
assert(result_length >= length + 1, "must not be shorter");
assert(result_length == (int)strlen(result) + 1, "must match");
return result;
}
unsigned int java_lang_String::hash_string(oop java_string) {
int length = java_lang_String::length(java_string);
// Zero length string doesn't hash necessarily hash to zero.
@ -545,7 +561,7 @@ oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
assert(k->oop_is_objArray(), "Must be");
Klass* element_klass = ObjArrayKlass::cast(k())->element_klass();
assert(element_klass != NULL, "Must have an element klass");
comp_mirror = Klass::cast(element_klass)->java_mirror();
comp_mirror = element_klass->java_mirror();
}
assert(comp_mirror.not_null(), "must have a mirror");
@ -628,8 +644,8 @@ void java_lang_Class::print_signature(oop java_class, outputStream* st) {
name = vmSymbols::type_signature(primitive_type(java_class));
} else {
Klass* k = as_Klass(java_class);
is_instance = Klass::cast(k)->oop_is_instance();
name = Klass::cast(k)->name();
is_instance = k->oop_is_instance();
name = k->name();
}
if (name == NULL) {
st->print("<null>");
@ -651,12 +667,12 @@ Symbol* java_lang_Class::as_signature(oop java_class, bool intern_if_not_found,
name->increment_refcount();
} else {
Klass* k = as_Klass(java_class);
if (!Klass::cast(k)->oop_is_instance()) {
name = Klass::cast(k)->name();
if (!k->oop_is_instance()) {
name = k->name();
name->increment_refcount();
} else {
ResourceMark rm;
const char* sigstr = Klass::cast(k)->signature_name();
const char* sigstr = k->signature_name();
int siglen = (int) strlen(sigstr);
if (!intern_if_not_found) {
name = SymbolTable::probe(sigstr, siglen);
@ -671,13 +687,13 @@ Symbol* java_lang_Class::as_signature(oop java_class, bool intern_if_not_found,
Klass* java_lang_Class::array_klass(oop java_class) {
Klass* k = ((Klass*)java_class->metadata_field(_array_klass_offset));
assert(k == NULL || k->is_klass() && Klass::cast(k)->oop_is_array(), "should be array klass");
assert(k == NULL || k->is_klass() && k->oop_is_array(), "should be array klass");
return k;
}
void java_lang_Class::set_array_klass(oop java_class, Klass* klass) {
assert(klass->is_klass() && Klass::cast(klass)->oop_is_array(), "should be array klass");
assert(klass->is_klass() && klass->oop_is_array(), "should be array klass");
java_class->metadata_field_put(_array_klass_offset, klass);
}
@ -1156,7 +1172,7 @@ void java_lang_Throwable::print(Handle throwable, outputStream* st) {
// Print stack trace element to resource allocated buffer
char* java_lang_Throwable::print_stack_element_to_buffer(Method* method, int bci) {
// Get strings and string lengths
InstanceKlass* klass = InstanceKlass::cast(method->method_holder());
InstanceKlass* klass = method->method_holder();
const char* klass_name = klass->external_name();
int buf_len = (int)strlen(klass_name);
char* source_file_name;
@ -1747,14 +1763,14 @@ oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) {
Handle element = ik->allocate_instance_handle(CHECK_0);
// Fill in class name
ResourceMark rm(THREAD);
const char* str = InstanceKlass::cast(method->method_holder())->external_name();
const char* str = method->method_holder()->external_name();
oop classname = StringTable::intern((char*) str, CHECK_0);
java_lang_StackTraceElement::set_declaringClass(element(), classname);
// Fill in method name
oop methodname = StringTable::intern(method->name(), CHECK_0);
java_lang_StackTraceElement::set_methodName(element(), methodname);
// Fill in source file name
Symbol* source = InstanceKlass::cast(method->method_holder())->source_file_name();
Symbol* source = method->method_holder()->source_file_name();
if (ShowHiddenFrames && source == NULL)
source = vmSymbols::unknown_class_name();
oop filename = StringTable::intern(source, CHECK_0);

View File

@ -154,6 +154,8 @@ class java_lang_String : AllStatic {
static char* as_utf8_string(oop java_string, int start, int len);
static char* as_platform_dependent_str(Handle java_string, TRAPS);
static jchar* as_unicode_string(oop java_string, int& length);
// produce an ascii string with all other values quoted using \u####
static char* as_quoted_ascii(oop java_string);
// Compute the hash value for a java.lang.String object which would
// contain the characters passed in.
@ -912,7 +914,7 @@ class java_lang_invoke_MethodHandle: AllStatic {
// Testers
static bool is_subclass(Klass* klass) {
return Klass::cast(klass)->is_subclass_of(SystemDictionary::MethodHandle_klass());
return klass->is_subclass_of(SystemDictionary::MethodHandle_klass());
}
static bool is_instance(oop obj) {
return obj != NULL && is_subclass(obj->klass());
@ -942,7 +944,7 @@ class java_lang_invoke_LambdaForm: AllStatic {
// Testers
static bool is_subclass(Klass* klass) {
return SystemDictionary::LambdaForm_klass() != NULL &&
Klass::cast(klass)->is_subclass_of(SystemDictionary::LambdaForm_klass());
klass->is_subclass_of(SystemDictionary::LambdaForm_klass());
}
static bool is_instance(oop obj) {
return obj != NULL && is_subclass(obj->klass());
@ -1004,7 +1006,7 @@ class java_lang_invoke_MemberName: AllStatic {
// Testers
static bool is_subclass(Klass* klass) {
return Klass::cast(klass)->is_subclass_of(SystemDictionary::MemberName_klass());
return klass->is_subclass_of(SystemDictionary::MemberName_klass());
}
static bool is_instance(oop obj) {
return obj != NULL && is_subclass(obj->klass());
@ -1090,7 +1092,7 @@ public:
// Testers
static bool is_subclass(Klass* klass) {
return Klass::cast(klass)->is_subclass_of(SystemDictionary::CallSite_klass());
return klass->is_subclass_of(SystemDictionary::CallSite_klass());
}
static bool is_instance(oop obj) {
return obj != NULL && is_subclass(obj->klass());
@ -1160,7 +1162,7 @@ class java_lang_ClassLoader : AllStatic {
// Testers
static bool is_subclass(Klass* klass) {
return Klass::cast(klass)->is_subclass_of(SystemDictionary::ClassLoader_klass());
return klass->is_subclass_of(SystemDictionary::ClassLoader_klass());
}
static bool is_instance(oop obj) {
return obj != NULL && is_subclass(obj->klass());

View File

@ -320,7 +320,7 @@ Klass* LoaderConstraintTable::find_constrained_klass(Symbol* name,
Handle loader) {
LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
if (p != NULL && p->klass() != NULL) {
if (Klass::cast(p->klass())->oop_is_instance() && !InstanceKlass::cast(p->klass())->is_loaded()) {
if (p->klass()->oop_is_instance() && !InstanceKlass::cast(p->klass())->is_loaded()) {
// Only return fully loaded classes. Classes found through the
// constraints might still be in the process of loading.
return NULL;

View File

@ -45,7 +45,7 @@ PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name,
entry->set_loadInstanceThreadQ(NULL);
entry->set_defineThreadQ(NULL);
entry->set_definer(NULL);
entry->set_instanceKlass(NULL);
entry->set_instance_klass(NULL);
return entry;
}
@ -188,7 +188,7 @@ void PlaceholderTable::classes_do(KlassClosure* f) {
void PlaceholderEntry::classes_do(KlassClosure* closure) {
assert(klassname() != NULL, "should have a non-null klass");
if (_instanceKlass != NULL) {
closure->do_klass(InstanceKlass());
closure->do_klass(instance_klass());
}
}
@ -220,9 +220,9 @@ void PlaceholderEntry::print() const {
tty->print(", definer ");
definer()->print_value();
}
if (InstanceKlass() != NULL) {
if (instance_klass() != NULL) {
tty->print(", InstanceKlass ");
InstanceKlass()->print_value();
instance_klass()->print_value();
}
tty->print("\n");
tty->print("loadInstanceThreadQ threads:");
@ -241,9 +241,9 @@ void PlaceholderEntry::verify() const {
guarantee(loader_data() != NULL, "Must have been setup.");
guarantee(loader_data()->class_loader() == NULL || loader_data()->class_loader()->is_instance(),
"checking type of _loader");
guarantee(InstanceKlass() == NULL
|| Klass::cast(InstanceKlass())->oop_is_instance(),
"checking type of InstanceKlass result");
guarantee(instance_klass() == NULL
|| instance_klass()->oop_is_instance(),
"checking type of instance_klass result");
}
void PlaceholderTable::verify() {

View File

@ -191,8 +191,8 @@ class PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> {
Thread* definer() const {return _definer; }
void set_definer(Thread* definer) { _definer = definer; }
Klass* InstanceKlass() const {return _instanceKlass; }
void set_instanceKlass(Klass* InstanceKlass) { _instanceKlass = InstanceKlass; }
Klass* instance_klass() const {return _instanceKlass; }
void set_instance_klass(Klass* ik) { _instanceKlass = ik; }
SeenThread* superThreadQ() const { return _superThreadQ; }
void set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }

View File

@ -262,19 +262,14 @@ public:
// The string table
static StringTable* the_table() { return _the_table; }
// Size of one bucket in the string table. Used when checking for rollover.
static uint bucket_size() { return sizeof(HashtableBucket<mtSymbol>); }
static void create_table() {
assert(_the_table == NULL, "One string table allowed.");
_the_table = new StringTable();
}
static void create_table(HashtableBucket<mtSymbol>* t, int length,
int number_of_entries) {
assert(_the_table == NULL, "One string table allowed.");
assert((size_t)length == StringTableSize * sizeof(HashtableBucket<mtSymbol>),
"bad shared string size.");
_the_table = new StringTable(t, number_of_entries);
}
// GC support
// Delete pointers to otherwise-unreachable objects.
static void unlink(BoolObjectClosure* cl);

View File

@ -240,7 +240,7 @@ Klass* SystemDictionary::resolve_array_class_or_null(Symbol* class_name,
protection_domain,
CHECK_NULL);
if (k != NULL) {
k = Klass::cast(k)->array_klass(fd.dimension(), CHECK_NULL);
k = k->array_klass(fd.dimension(), CHECK_NULL);
}
} else {
k = Universe::typeArrayKlassObj(t);
@ -328,8 +328,8 @@ Klass* SystemDictionary::resolve_super_or_fail(Symbol* child_name,
if ((childk != NULL ) && (is_superclass) &&
((quicksuperk = InstanceKlass::cast(childk)->super()) != NULL) &&
((Klass::cast(quicksuperk)->name() == class_name) &&
(Klass::cast(quicksuperk)->class_loader() == class_loader()))) {
((quicksuperk->name() == class_name) &&
(quicksuperk->class_loader() == class_loader()))) {
return quicksuperk;
} else {
PlaceholderEntry* probe = placeholders()->get_entry(p_index, p_hash, child_name, loader_data);
@ -928,7 +928,7 @@ Klass* SystemDictionary::find_instance_or_array_klass(Symbol* class_name,
k = SystemDictionary::find(fd.object_key(), class_loader, protection_domain, THREAD);
}
if (k != NULL) {
k = Klass::cast(k)->array_klass_or_null(fd.dimension());
k = k->array_klass_or_null(fd.dimension());
}
} else {
k = find(class_name, class_loader, protection_domain, THREAD);
@ -1537,7 +1537,7 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(Symbol* clas
// Only special cases allow parallel defines and can use other thread's results
// Other cases fall through, and may run into duplicate defines
// caught by finding an entry in the SystemDictionary
if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->InstanceKlass() != NULL)) {
if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instance_klass() != NULL)) {
probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, THREAD);
SystemDictionary_lock->notify_all();
@ -1545,7 +1545,7 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(Symbol* clas
Klass* check = find_class(d_index, d_hash, name_h, loader_data);
assert(check != NULL, "definer missed recording success");
#endif
return(instanceKlassHandle(THREAD, probe->InstanceKlass()));
return(instanceKlassHandle(THREAD, probe->instance_klass()));
} else {
// This thread will define the class (even if earlier thread tried and had an error)
probe->set_definer(THREAD);
@ -1566,7 +1566,7 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(Symbol* clas
linkage_exception = Handle(THREAD,PENDING_EXCEPTION);
CLEAR_PENDING_EXCEPTION;
} else {
probe->set_instanceKlass(k());
probe->set_instance_klass(k());
}
probe->set_definer(NULL);
probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
@ -2149,7 +2149,7 @@ Klass* SystemDictionary::find_constrained_instance_or_array_klass(
}
// If element class already loaded, allocate array klass
if (klass != NULL) {
klass = Klass::cast(klass)->array_klass_or_null(fd.dimension());
klass = klass->array_klass_or_null(fd.dimension());
}
} else {
MutexLocker mu(SystemDictionary_lock, THREAD);
@ -2466,9 +2466,9 @@ Handle SystemDictionary::find_method_handle_type(Symbol* signature,
Klass* sel_klass = java_lang_Class::as_Klass(mirror);
mirror = NULL; // safety
// Emulate ConstantPool::verify_constant_pool_resolve.
if (Klass::cast(sel_klass)->oop_is_objArray())
if (sel_klass->oop_is_objArray())
sel_klass = ObjArrayKlass::cast(sel_klass)->bottom_klass();
if (Klass::cast(sel_klass)->oop_is_instance()) {
if (sel_klass->oop_is_instance()) {
KlassHandle sel_kh(THREAD, sel_klass);
LinkResolver::check_klass_accessability(accessing_klass, sel_kh, CHECK_(empty));
}

View File

@ -137,6 +137,7 @@ class SymbolPropertyTable;
/* NOTE: needed too early in bootstrapping process to have checks based on JDK version */ \
/* Universe::is_gte_jdk14x_version() is not set up by this point. */ \
/* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \
do_klass(lambda_MagicLambdaImpl_klass, java_lang_invoke_MagicLambdaImpl, Opt ) \
do_klass(reflect_MagicAccessorImpl_klass, sun_reflect_MagicAccessorImpl, Opt ) \
do_klass(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef) \
do_klass(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef) \

View File

@ -446,7 +446,7 @@ void ErrorContext::location_details(outputStream* ss, Method* method) const {
bytecode_name = "<illegal>";
}
}
InstanceKlass* ik = InstanceKlass::cast(method->method_holder());
InstanceKlass* ik = method->method_holder();
ss->indent().print_cr("Location:");
streamIndentor si2(ss);
ss->indent().print_cr("%s.%s%s @%d: %s",
@ -555,9 +555,10 @@ void ClassVerifier::verify_class(TRAPS) {
if (was_recursively_verified()) return;
Method* m = methods->at(index);
if (m->is_native() || m->is_abstract()) {
if (m->is_native() || m->is_abstract() || m->is_overpass()) {
// If m is native or abstract, skip it. It is checked in class file
// parser that methods do not override a final method.
// parser that methods do not override a final method. Overpass methods
// are trusted since the VM generates them.
continue;
}
verify_method(methodHandle(THREAD, m), CHECK_VERIFY(this));
@ -1849,7 +1850,7 @@ void ClassVerifier::verify_cp_index(
if ((index <= 0) || (index >= nconstants)) {
verify_error(ErrorContext::bad_cp_index(bci, index),
"Illegal constant pool index %d in class %s",
index, InstanceKlass::cast(cp->pool_holder())->external_name());
index, cp->pool_holder()->external_name());
return;
}
}
@ -1868,7 +1869,7 @@ void ClassVerifier::verify_cp_type(
if ((types & (1 << tag)) == 0) {
verify_error(ErrorContext::bad_cp_index(bci, index),
"Illegal type at constant pool entry %d in class %s",
index, InstanceKlass::cast(cp->pool_holder())->external_name());
index, cp->pool_holder()->external_name());
return;
}
}
@ -1880,7 +1881,7 @@ void ClassVerifier::verify_cp_class_type(
if (!tag.is_klass() && !tag.is_unresolved_klass()) {
verify_error(ErrorContext::bad_cp_index(bci, index),
"Illegal type at constant pool entry %d in class %s",
index, InstanceKlass::cast(cp->pool_holder())->external_name());
index, cp->pool_holder()->external_name());
return;
}
}
@ -2304,11 +2305,21 @@ void ClassVerifier::verify_invoke_instructions(
// Make sure the constant pool item is the right type
u2 index = bcs->get_index_u2();
Bytecodes::Code opcode = bcs->raw_code();
unsigned int types = (opcode == Bytecodes::_invokeinterface
? 1 << JVM_CONSTANT_InterfaceMethodref
: opcode == Bytecodes::_invokedynamic
? 1 << JVM_CONSTANT_InvokeDynamic
: 1 << JVM_CONSTANT_Methodref);
unsigned int types;
switch (opcode) {
case Bytecodes::_invokeinterface:
types = 1 << JVM_CONSTANT_InterfaceMethodref;
break;
case Bytecodes::_invokedynamic:
types = 1 << JVM_CONSTANT_InvokeDynamic;
break;
case Bytecodes::_invokespecial:
types = (1 << JVM_CONSTANT_InterfaceMethodref) |
(1 << JVM_CONSTANT_Methodref);
break;
default:
types = 1 << JVM_CONSTANT_Methodref;
}
verify_cp_type(bcs->bci(), index, cp, types, CHECK_VERIFY(this));
// Get method name and signature

View File

@ -507,7 +507,7 @@ static vmIntrinsics::ID match_method_with_klass(Method* m, Symbol* mk) {
}
void vmIntrinsics::verify_method(ID actual_id, Method* m) {
Symbol* mk = Klass::cast(m->method_holder())->name();
Symbol* mk = m->method_holder()->name();
ID declared_id = match_method_with_klass(m, mk);
if (declared_id == actual_id) return; // success

View File

@ -259,6 +259,7 @@
template(java_lang_invoke_DontInline_signature, "Ljava/lang/invoke/DontInline;") \
template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \
template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \
template(java_lang_invoke_MagicLambdaImpl, "java/lang/invoke/MagicLambdaImpl") \
/* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */ \
template(findMethodHandleType_name, "findMethodHandleType") \
template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \

View File

@ -191,8 +191,8 @@ void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod
int index = klassItable::compute_itable_index(call_info->resolved_method()());
entry = VtableStubs::create_stub(false, index, method());
assert(entry != NULL, "entry not computed");
Klass* k = call_info->resolved_method()->method_holder();
assert(Klass::cast(k)->is_interface(), "sanity check");
InstanceKlass* k = call_info->resolved_method()->method_holder();
assert(k->is_interface(), "sanity check");
InlineCacheBuffer::create_transition_stub(this, k, entry);
} else {
// Can be different than method->vtable_index(), due to package-private etc.

View File

@ -552,7 +552,7 @@ void Dependencies::print_dependency(DepType dept, int nargs, DepArgument args[],
}
tty->print(" %s = %s", what, (put_star? "*": ""));
if (arg.is_klass())
tty->print("%s", Klass::cast((Klass*)arg.metadata_value())->external_name());
tty->print("%s", ((Klass*)arg.metadata_value())->external_name());
else if (arg.is_method())
((Method*)arg.metadata_value())->print_value();
else
@ -563,12 +563,13 @@ void Dependencies::print_dependency(DepType dept, int nargs, DepArgument args[],
bool put_star = !Dependencies::is_concrete_klass(witness);
tty->print_cr(" witness = %s%s",
(put_star? "*": ""),
Klass::cast(witness)->external_name());
witness->external_name());
}
}
void Dependencies::DepStream::log_dependency(Klass* witness) {
if (_deps == NULL && xtty == NULL) return; // fast cutout for runtime
ResourceMark rm;
int nargs = argument_count();
DepArgument args[max_arg_count];
for (int j = 0; j < nargs; j++) {
@ -808,7 +809,7 @@ class ClassHierarchyWalker {
if (!(m->is_public() || m->is_protected()))
// The override story is complex when packages get involved.
return true; // Must punt the assertion to true.
Klass* k = Klass::cast(ctxk);
Klass* k = ctxk;
Method* lm = k->lookup_method(m->name(), m->signature());
if (lm == NULL && k->oop_is_instance()) {
// It might be an abstract interface method, devoid of mirandas.
@ -829,13 +830,13 @@ class ClassHierarchyWalker {
}
if ( !Dependencies::is_concrete_method(lm)
&& !Dependencies::is_concrete_method(m)
&& Klass::cast(lm->method_holder())->is_subtype_of(m->method_holder()))
&& lm->method_holder()->is_subtype_of(m->method_holder()))
// Method m is overridden by lm, but both are non-concrete.
return true;
}
ResourceMark rm;
tty->print_cr("Dependency method not found in the associated context:");
tty->print_cr(" context = %s", Klass::cast(ctxk)->external_name());
tty->print_cr(" context = %s", ctxk->external_name());
tty->print( " method = "); m->print_short_name(tty); tty->cr();
if (lm != NULL) {
tty->print( " found = "); lm->print_short_name(tty); tty->cr();
@ -1010,7 +1011,7 @@ Klass* ClassHierarchyWalker::find_witness_in(KlassDepChange& changes,
for (int i = 0; i < num_participants(); i++) {
Klass* part = participant(i);
if (part == NULL) continue;
assert(changes.involves_context(part) == Klass::cast(new_type)->is_subtype_of(part),
assert(changes.involves_context(part) == new_type->is_subtype_of(part),
"correct marking of participants, b/c new_type is unique");
if (changes.involves_context(part)) {
// new guy is protected from this check by previous participant
@ -1146,7 +1147,7 @@ Klass* ClassHierarchyWalker::find_witness_anywhere(Klass* context_type,
bool Dependencies::is_concrete_klass(Klass* k) {
if (Klass::cast(k)->is_abstract()) return false;
if (k->is_abstract()) return false;
// %%% We could treat classes which are concrete but
// have not yet been instantiated as virtually abstract.
// This would require a deoptimization barrier on first instantiation.
@ -1160,7 +1161,11 @@ bool Dependencies::is_concrete_method(Method* m) {
// We could also return false if m does not yet appear to be
// executed, if the VM version supports this distinction also.
return !m->is_abstract();
return !m->is_abstract() &&
!InstanceKlass::cast(m->method_holder())->is_interface();
// TODO: investigate whether default methods should be
// considered as "concrete" in this situation. For now they
// are not.
}
@ -1701,12 +1706,12 @@ KlassDepChange::~KlassDepChange() {
}
bool KlassDepChange::involves_context(Klass* k) {
if (k == NULL || !Klass::cast(k)->oop_is_instance()) {
if (k == NULL || !k->oop_is_instance()) {
return false;
}
InstanceKlass* ik = InstanceKlass::cast(k);
bool is_contained = ik->is_marked_dependent();
assert(is_contained == Klass::cast(new_type())->is_subtype_of(k),
assert(is_contained == new_type()->is_subtype_of(k),
"correct marking of potential context types");
return is_contained;
}

View File

@ -1263,7 +1263,7 @@ void nmethod::invalidate_osr_method() {
assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod");
// Remove from list of active nmethods
if (method() != NULL)
InstanceKlass::cast(method()->method_holder())->remove_osr_nmethod(this);
method()->method_holder()->remove_osr_nmethod(this);
// Set entry as invalid
_entry_bci = InvalidOSREntryBci;
}
@ -2568,9 +2568,8 @@ void nmethod::print_dependencies() {
deps.print_dependency();
Klass* ctxk = deps.context_type();
if (ctxk != NULL) {
Klass* k = Klass::cast(ctxk);
if (k->oop_is_instance() && ((InstanceKlass*)k)->is_dependent_nmethod(this)) {
tty->print_cr(" [nmethod<=klass]%s", k->external_name());
if (ctxk->oop_is_instance() && ((InstanceKlass*)ctxk)->is_dependent_nmethod(this)) {
tty->print_cr(" [nmethod<=klass]%s", ctxk->external_name());
}
}
deps.log_dependency(); // put it into the xml log also

View File

@ -1051,7 +1051,7 @@ void CompileBroker::compile_method_base(methodHandle method,
guarantee(!method->is_abstract(), "cannot compile abstract methods");
assert(method->method_holder()->oop_is_instance(),
"sanity check");
assert(!InstanceKlass::cast(method->method_holder())->is_not_initialized(),
assert(!method->method_holder()->is_not_initialized(),
"method holder must be initialized");
assert(!method->is_method_handle_intrinsic(), "do not enqueue these guys");
@ -1206,7 +1206,7 @@ nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci,
assert(method->method_holder()->oop_is_instance(), "not an instance method");
assert(osr_bci == InvocationEntryBci || (0 <= osr_bci && osr_bci < method->code_size()), "bci out of range");
assert(!method->is_abstract() && (osr_bci == InvocationEntryBci || !method->is_native()), "cannot compile abstract/native methods");
assert(!InstanceKlass::cast(method->method_holder())->is_not_initialized(), "method holder must be initialized");
assert(!method->method_holder()->is_not_initialized(), "method holder must be initialized");
if (!TieredCompilation) {
comp_level = CompLevel_highest_tier;

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