This commit is contained in:
Lana Steuck 2012-11-14 16:41:12 -08:00
commit 42ad69505d
415 changed files with 23879 additions and 10444 deletions

View File

@ -184,3 +184,5 @@ ffe6bce5a521be40146af2ac03c509b7bac30595 jdk8-b56
5e3adc681779037a2d33b7be6f75680619085492 jdk8-b60
cdaa6122185f9bf512dcd6600f56bfccc4824e8c jdk8-b61
8d9d430b4244b95f5cf1ebe719f834a1ac5d6cd5 jdk8-b62
21ee1dd7b809639284900a128b9b656a592ebc7a jdk8-b63
70fa4b11f26522e69b51fd652215f60ce350bac3 jdk8-b64

View File

@ -184,3 +184,5 @@ dae9821589ccd2611bdf7084269b98e819091770 jdk8-b59
e07f499b9dccb529ecf74172cf6ac11a195ec57a jdk8-b60
20ff117b509075c3aec4ee3a57990ecd5db5df9c jdk8-b61
8a3fe0ae06a8cc21347da5a18384b0aa6c2349f5 jdk8-b62
3229597524cab4239325bc3602df6c486397a511 jdk8-b63
1c8370a55b305d35353346202bde042ba9e8a9fd jdk8-b64

View File

@ -373,7 +373,11 @@ else
# If we have a spec.gmk, we have run here before and we are OK. Otherwise, check for
# other files
files_present=`$LS $OUTPUT_ROOT`
if test "x$files_present" != x; then
# Configure has already touched config.log and confdefs.h in the current dir when this check
# is performed.
filtered_files=`$ECHO "$files_present" | $SED -e 's/config.log//g' -e 's/confdefs.h//g' -e 's/ //g' \
| $TR -d '\n'`
if test "x$filtered_files" != x; then
AC_MSG_NOTICE([Current directory is $CURDIR.])
AC_MSG_NOTICE([Since this is not the source root, configure will output the configuration here])
AC_MSG_NOTICE([(as opposed to creating a configuration in <src_root>/build/<conf-name>).])

View File

@ -172,6 +172,13 @@ AC_DEFUN([BASIC_FIXUP_EXECUTABLE_CYGWIN],
# Now try to locate executable using which
new_path=`$WHICH "$new_path" 2> /dev/null`
# bat and cmd files are not always considered executable in cygwin causing which
# to not find them
if test "x$new_path" = x \
&& test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \
&& test "x`$LS \"$path\" 2>/dev/null`" != x; then
new_path=`$CYGPATH -u "$path"`
fi
if test "x$new_path" = x; then
# Oops. Which didn't find the executable.
# The splitting of arguments from the executable at a space might have been incorrect,
@ -181,6 +188,13 @@ AC_DEFUN([BASIC_FIXUP_EXECUTABLE_CYGWIN],
arguments="EOL"
new_path=`$CYGPATH -u "$path"`
new_path=`$WHICH "$new_path" 2> /dev/null`
# bat and cmd files are not always considered executable in cygwin causing which
# to not find them
if test "x$new_path" = x \
&& test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \
&& test "x`$LS \"$path\" 2>/dev/null`" != x; then
new_path=`$CYGPATH -u "$path"`
fi
if test "x$new_path" = x; then
# It's still not found. Now this is an unrecoverable error.
AC_MSG_NOTICE([The path of $1, which resolves as "$complete", is not found.])

View File

@ -60,6 +60,7 @@ STAT="@STAT@"
STRIP="@POST_STRIP_CMD@"
TEE="@TEE@"
UNIQ="@UNIQ@"
UNPACK200="@FIXPATH@ @BOOT_JDK@/bin/unpack200"
UNZIP="@UNZIP@"
SRC_ROOT="@SRC_ROOT@"

File diff suppressed because it is too large Load Diff

View File

@ -393,7 +393,9 @@ else
# AC_CHECK_LIB does not support use of cl.exe
PREV_LDFLAGS="$LDFLAGS"
LDFLAGS="$FREETYPE2_LIBS"
AC_CHECK_LIB(freetype, FT_Init_FreeType, [], AC_MSG_ERROR([Could not find freetype2! $HELP_MSG ]))
AC_CHECK_LIB(freetype, FT_Init_FreeType,
FREETYPE2_FOUND=true,
AC_MSG_ERROR([Could not find freetype2! $HELP_MSG ]))
LDFLAGS="$PREV_LDFLAGS"
fi
fi

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

@ -352,6 +352,29 @@ compare_zip_file() {
(cd $THIS_UNZIPDIR && $UNARCHIVE $THIS_ZIP)
(cd $OTHER_UNZIPDIR && $UNARCHIVE $OTHER_ZIP)
# Find all archives inside and unzip them as well to compare the contents rather than
# the archives.
EXCEPTIONS=""
for pack in $($FIND $THIS_UNZIPDIR -name "*.pack" -o -name "*.pack.gz"); do
($UNPACK200 $pack $pack.jar)
# Filter out the unzipped archives from the diff below.
EXCEPTIONS="$EXCEPTIONS $pack $pack.jar"
done
for pack in $($FIND $OTHER_UNZIPDIR -name "*.pack" -o -name "*.pack.gz"); do
($UNPACK200 $pack $pack.jar)
EXCEPTIONS="$EXCEPTIONS $pack $pack.jar"
done
for zip in $($FIND $THIS_UNZIPDIR -name "*.jar" -o -name "*.zip"); do
$MKDIR $zip.unzip
(cd $zip.unzip && $UNARCHIVE $zip)
EXCEPTIONS="$EXCEPTIONS $zip"
done
for zip in $($FIND $OTHER_UNZIPDIR -name "*.jar" -o -name "*.zip"); do
$MKDIR $zip.unzip
(cd $zip.unzip && $UNARCHIVE $zip)
EXCEPTIONS="$EXCEPTIONS $zip"
done
CONTENTS_DIFF_FILE=$WORK_DIR/$ZIP_FILE.diff
# On solaris, there is no -q option.
if [ "$OPENJDK_TARGET_OS" = "solaris" ]; then
@ -389,7 +412,7 @@ compare_zip_file() {
$RM -f $WORK_DIR/$ZIP_FILE.diffs
for file in $DIFFING_FILES; do
if [[ "$ACCEPTED_JARZIP_CONTENTS" != *"$file"* ]]; then
if [[ "$ACCEPTED_JARZIP_CONTENTS $EXCEPTIONS" != *"$file"* ]]; then
diff_text $OTHER_UNZIPDIR/$file $THIS_UNZIPDIR/$file >> $WORK_DIR/$ZIP_FILE.diffs
fi
done
@ -664,8 +687,8 @@ compare_bin_file() {
# Check dependencies
if [ -n "$LDD_CMD" ]; then
(cd $FILE_WORK_DIR && $CP $OTHER_FILE . && $LDD_CMD $NAME | $AWK '{ print $1;}' | $SORT | $TEE $WORK_FILE_BASE.deps.other | $UNIQ > $WORK_FILE_BASE.deps.other.uniq)
(cd $FILE_WORK_DIR && $CP $THIS_FILE . && $LDD_CMD $NAME | $AWK '{ print $1;}' | $SORT | $TEE $WORK_FILE_BASE.deps.this | $UNIQ > $WORK_FILE_BASE.deps.this.uniq)
(cd $FILE_WORK_DIR && $CP $OTHER_FILE . && $LDD_CMD $NAME 2>/dev/null | $AWK '{ print $1;}' | $SORT | $TEE $WORK_FILE_BASE.deps.other | $UNIQ > $WORK_FILE_BASE.deps.other.uniq)
(cd $FILE_WORK_DIR && $CP $THIS_FILE . && $LDD_CMD $NAME 2</dev/null | $AWK '{ print $1;}' | $SORT | $TEE $WORK_FILE_BASE.deps.this | $UNIQ > $WORK_FILE_BASE.deps.this.uniq)
(cd $FILE_WORK_DIR && $RM -f $NAME)
LANG=C $DIFF $WORK_FILE_BASE.deps.other $WORK_FILE_BASE.deps.this > $WORK_FILE_BASE.deps.diff
@ -846,7 +869,12 @@ compare_all_execs() {
if [ "$OPENJDK_TARGET_OS" = "windows" ]; then
EXECS=$(cd $THIS_DIR && $FIND . -type f -name '*.exe' | $SORT | $FILTER)
else
EXECS=$(cd $THIS_DIR && $FIND . -name db -prune -o -type f -perm -100 \! \( -name '*.so' -o -name '*.dylib' -o -name '*.dll' -o -name '*.cgi' -o -name '*.jar' -o -name '*.diz' \) | $SORT | $FILTER)
EXECS=$(cd $THIS_DIR && $FIND . -name db -prune -o -type f -perm -100 \! \
\( -name '*.so' -o -name '*.dylib' -o -name '*.dll' -o -name '*.cgi' \
-o -name '*.jar' -o -name '*.diz' -o -name 'jcontrol' -o -name '*.properties' \
-o -name '*.data' -o -name '*.bfc' -o -name '*.src' -o -name '*.txt' \
-o -name '*.cfg' -o -name 'meta-index' -o -name '*.properties.ja' \
-o -name 'classlist' \) | $SORT | $FILTER)
fi
if [ -n "$EXECS" ]; then
@ -1022,6 +1050,7 @@ fi
if [ -d "$THIS/deploy/j2sdk-image" ]; then
THIS_J2SDK="$THIS/deploy/j2sdk-image"
THIS_J2RE="$THIS/deploy/j2re-image"
echo "Comparing deploy images"
elif [ -d "$THIS/images/j2sdk-image" ]; then
THIS_J2SDK="$THIS/images/j2sdk-image"
THIS_J2RE="$THIS/images/j2re-image"

View File

@ -282,6 +282,14 @@ ACCEPTED_SMALL_SIZE_DIFF="
./jre/lib/i386/libunpack.so
./jre/lib/i386/libverify.so
./jre/lib/i386/libzip.so
./jre/lib/i386/libdeploy.so
./jre/lib/i386/libjavaplugin.so
./jre/lib/i386/libjavaplugin_jni.so
./jre/lib/i386/libjavaplugin_nscp.so
./jre/lib/i386/libjavaplugin_oji.so
./jre/lib/i386/libnpjp2.so
./jre/plugin/i386/ns4/libjavaplugin.so
./jre/plugin/i386/ns7/libjavaplugin_oji.so
./jre/lib/i386/server/libjvm.so
./bin/appletviewer
./bin/extcheck
@ -293,6 +301,7 @@ ACCEPTED_SMALL_SIZE_DIFF="
./bin/javadoc
./bin/javah
./bin/javap
./bin/javaws
./bin/jcmd
./bin/jconsole
./bin/jdb
@ -322,6 +331,8 @@ ACCEPTED_SMALL_SIZE_DIFF="
./bin/wsimport
./bin/xjc
./jre/bin/java
./jre/bin/java_vm
./jre/bin/javaws
./jre/bin/keytool
./jre/bin/orbd
./jre/bin/pack200
@ -561,6 +572,14 @@ ACCEPTED_SMALL_SIZE_DIFF="
./jre/lib/sparc/libunpack.so
./jre/lib/sparc/libverify.so
./jre/lib/sparc/libzip.so
./jre/lib/sparc/libdeploy.so
./jre/lib/sparc/libjavaplugin.so
./jre/lib/sparc/libjavaplugin_jni.so
./jre/lib/sparc/libjavaplugin_nscp.so
./jre/lib/sparc/libjavaplugin_oji.so
./jre/lib/sparc/libnpjp2.so
./jre/plugin/sparc/ns4/libjavaplugin.so
./jre/plugin/sparc/ns7/libjavaplugin_oji.so
./jre/lib/sparc/server/libjvm.so
./bin/appletviewer
./bin/extcheck
@ -572,6 +591,7 @@ ACCEPTED_SMALL_SIZE_DIFF="
./bin/javadoc
./bin/javah
./bin/javap
./bin/javaws
./bin/jcmd
./bin/jconsole
./bin/jdb
@ -601,6 +621,8 @@ ACCEPTED_SMALL_SIZE_DIFF="
./bin/wsimport
./bin/xjc
./jre/bin/java
./jre/bin/java_vm
./jre/bin/javaws
./jre/bin/keytool
./jre/bin/orbd
./jre/bin/pack200

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))
@ -480,19 +481,24 @@ define SetupJavaCompilation
$1_SJAVAC:=$$(word 1,$$($1_JAVAC)) -cp $$(word 3,$$($1_JAVAC)) com.sun.tools.sjavac.Main
# Set the $1_REMOTE to spawn a background javac server.
$1_REMOTE:=--server:portfile=$$($1_SJAVAC_PORTFILE),poolsize=$(SJAVAC_SERVER_CORES),id=$1,sjavac=$$(subst $$(SPACE),%20,$$(subst $$(COMMA),%2C,$$(strip $$($1_SERVER_JVM) $$($1_SJAVAC))))
$1_REMOTE:=--server:portfile=$$($1_SJAVAC_PORTFILE),id=$1,sjavac=$$(subst $$(SPACE),%20,$$(subst $$(COMMA),%2C,$$(strip $$($1_SERVER_JVM) $$($1_SJAVAC))))
$$($1_BIN)/javac_state: $$($1_SRCS) $$($1_DEPENDS)
$(MKDIR) -p $$(@D)
$$(call ListPathsSafely,$1_SRCS,\n, >> $$($1_BIN)/_the.batch.tmp)
$(ECHO) Compiling $1
$$($1_JVM) $$($1_SJAVAC) \
$$($1_REMOTE) $$($1_SJAVAC_ARGS) \
($$($1_JVM) $$($1_SJAVAC) \
$$($1_REMOTE) \
-j $(NUM_CORES) \
--permit-unidentified-artifacts \
--permit-sources-without-package \
--compare-found-sources $$($1_BIN)/_the.batch.tmp \
--log=$(LOG) \
$$($1_SJAVAC_ARGS) \
$$($1_FLAGS) \
-implicit:none -d $$($1_BIN) $$($1_HEADERS_ARG)
$$($1_HEADERS_ARG) \
-d $$($1_BIN) && \
$(MV) $$($1_BIN)/_the.batch.tmp $$($1_BIN)/_the.batch)
else
# Using plain javac to batch compile everything.
$1 := $$($1_ALL_COPY_TARGETS) $$($1_ALL_COPY_CLEAN_TARGETS) $$($1_BIN)/_the.batch

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

View File

@ -65,7 +65,7 @@ endef
# The \n argument means translate spaces into \n
# if instead , , (a space) is supplied, then spaces remain spaces.
define ListPathsSafely
$(if $(word 10001,$($1)),$(error Cannot list safely more than 10000 paths. $1 has $(words $($1)) paths!))
$(if $(word 16001,$($1)),$(error Cannot list safely more than 16000 paths. $1 has $(words $($1)) paths!))
$(call ListPathsSafely_If,$1,$2,1,250)
$(call ListPathsSafely_If,$1,$2,251,500)
$(call ListPathsSafely_If,$1,$2,501,750)
@ -116,6 +116,36 @@ define ListPathsSafely
$(call ListPathsSafely_If,$1,$2,9501,9750)
$(call ListPathsSafely_If,$1,$2,9751,10000)
$(call ListPathsSafely_If,$1,$2,10001,10250)
$(call ListPathsSafely_If,$1,$2,10251,10500)
$(call ListPathsSafely_If,$1,$2,10501,10750)
$(call ListPathsSafely_If,$1,$2,10751,11000)
$(call ListPathsSafely_If,$1,$2,11001,11250)
$(call ListPathsSafely_If,$1,$2,11251,11500)
$(call ListPathsSafely_If,$1,$2,11501,11750)
$(call ListPathsSafely_If,$1,$2,11751,12000)
$(call ListPathsSafely_If,$1,$2,12001,12250)
$(call ListPathsSafely_If,$1,$2,12251,12500)
$(call ListPathsSafely_If,$1,$2,12501,12750)
$(call ListPathsSafely_If,$1,$2,12751,13000)
$(call ListPathsSafely_If,$1,$2,13001,13250)
$(call ListPathsSafely_If,$1,$2,13251,13500)
$(call ListPathsSafely_If,$1,$2,13501,13750)
$(call ListPathsSafely_If,$1,$2,13751,14000)
$(call ListPathsSafely_If,$1,$2,14001,14250)
$(call ListPathsSafely_If,$1,$2,14251,14500)
$(call ListPathsSafely_If,$1,$2,14501,14750)
$(call ListPathsSafely_If,$1,$2,14751,15000)
$(call ListPathsSafely_If,$1,$2,15001,15250)
$(call ListPathsSafely_If,$1,$2,15251,15500)
$(call ListPathsSafely_If,$1,$2,15501,15750)
$(call ListPathsSafely_If,$1,$2,15751,16000)
$(call ListPathsSafely_Printf,$1,$2,$3,1)
$(call ListPathsSafely_Printf,$1,$2,$3,251)
$(call ListPathsSafely_Printf,$1,$2,$3,501)
@ -165,6 +195,36 @@ define ListPathsSafely
$(call ListPathsSafely_Printf,$1,$2,$3,9251)
$(call ListPathsSafely_Printf,$1,$2,$3,9501)
$(call ListPathsSafely_Printf,$1,$2,$3,9751)
$(call ListPathsSafely_Printf,$1,$2,$3,10001)
$(call ListPathsSafely_Printf,$1,$2,$3,10251)
$(call ListPathsSafely_Printf,$1,$2,$3,10501)
$(call ListPathsSafely_Printf,$1,$2,$3,10751)
$(call ListPathsSafely_Printf,$1,$2,$3,11001)
$(call ListPathsSafely_Printf,$1,$2,$3,11251)
$(call ListPathsSafely_Printf,$1,$2,$3,11501)
$(call ListPathsSafely_Printf,$1,$2,$3,11751)
$(call ListPathsSafely_Printf,$1,$2,$3,12001)
$(call ListPathsSafely_Printf,$1,$2,$3,12251)
$(call ListPathsSafely_Printf,$1,$2,$3,12501)
$(call ListPathsSafely_Printf,$1,$2,$3,12751)
$(call ListPathsSafely_Printf,$1,$2,$3,13001)
$(call ListPathsSafely_Printf,$1,$2,$3,13251)
$(call ListPathsSafely_Printf,$1,$2,$3,13501)
$(call ListPathsSafely_Printf,$1,$2,$3,13751)
$(call ListPathsSafely_Printf,$1,$2,$3,14001)
$(call ListPathsSafely_Printf,$1,$2,$3,14251)
$(call ListPathsSafely_Printf,$1,$2,$3,14501)
$(call ListPathsSafely_Printf,$1,$2,$3,14751)
$(call ListPathsSafely_Printf,$1,$2,$3,15001)
$(call ListPathsSafely_Printf,$1,$2,$3,15251)
$(call ListPathsSafely_Printf,$1,$2,$3,15501)
$(call ListPathsSafely_Printf,$1,$2,$3,15751)
endef
define ListPathsSafelyNow_IfPrintf

View File

@ -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

@ -184,3 +184,5 @@ d54dc53e223ed9ce7d5f4d2cd02ad9d5def3c2db jdk8-b59
207ef43ba69ead6cbbab415d81834545e4d46747 jdk8-b60
0e08ba7648fb3faa0986cb217887d7c4990977f3 jdk8-b61
08afb9c6f44f11c3595b01fd0985db64b29834dd jdk8-b62
6ccbf67b68bfed1ab9c44ab8748a5bdc7df33506 jdk8-b63
54d599a5b4aad83c235d590652fc81f41c2824fb jdk8-b64

View File

@ -42,16 +42,6 @@ import java.util.NoSuchElementException;
* instead, it uses the System.identityHashcode() method and pointer comparison.
* In addition, all synchronization has been removed.
*/
/**
* IdentityHashtable collision list.
*/
class IdentityHashtableEntry {
int hash;
Object key;
Object value;
IdentityHashtableEntry next;
}
public final class IdentityHashtable extends Dictionary {
/**
* The hash table data.

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Licensed Materials - Property of IBM
* RMI-IIOP v1.0
* Copyright IBM Corp. 1998 1999 All Rights Reserved
*
*/
package com.sun.corba.se.impl.util;
/**
* IdentityHashtable collision list.
*/
class IdentityHashtableEntry {
int hash;
Object key;
Object value;
IdentityHashtableEntry next;
}

View File

@ -289,3 +289,7 @@ b261523fe66c40a02968f0aa7e73602491bb3386 hs25-b05
d0337c31c8be7716369b4e7c3bd5f352983c6a06 hs25-b06
dccd40de8db1fa96f186e6179907818d75320440 jdk8-b62
dc16fe422c535ecd4e9f80fb814a1bb9704da6f5 hs25-b07
acabb5c282f59be7e3238920b2ea06b684ab68f7 jdk8-b63
8cb93eadfb6dcab88d91b8e2cd3e0e07d0ac4048 hs25-b08
5920f72e799c8133d1066c4a62fa1fafcb729966 jdk8-b64
b4ee7b773144a88af8b6b92e4384dea82cb948d8 hs25-b09

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

@ -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(); }

View File

@ -453,14 +453,30 @@ ifneq ($(OSNAME),windows)
ifeq ($(JVM_VARIANT_ZEROSHARK), true)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo): $(SHARK_DIR)/%.debuginfo
$(install-file)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(SHARK_DIR)/%.diz
$(install-file)
$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
$(EXPORT_SERVER_DIR)/%.debuginfo: $(SHARK_DIR)/%.debuginfo
$(install-file)
$(EXPORT_SERVER_DIR)/%.diz: $(SHARK_DIR)/%.diz
$(install-file)
endif
ifeq ($(JVM_VARIANT_ZERO), true)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(ZERO_DIR)/%.debuginfo
$(install-file)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(ZERO_DIR)/%.diz
$(install-file)
$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
$(EXPORT_SERVER_DIR)/%.debuginfo: $(ZERO_DIR)/%.debuginfo
$(install-file)
$(EXPORT_SERVER_DIR)/%.diz: $(ZERO_DIR)/%.diz
$(install-file)
endif
ifeq ($(JVM_VARIANT_MINIMAL1), true)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(MINIMAL1_DIR)/%.$(LIBRARY_SUFFIX)

View File

@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2012
HS_MAJOR_VER=25
HS_MINOR_VER=0
HS_BUILD_NUMBER=07
HS_BUILD_NUMBER=09
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

@ -31,12 +31,17 @@
return _masm;
}
protected:
address generate_entry(address entry_point) {
ZeroEntry *entry = (ZeroEntry *) assembler()->pc();
assembler()->advance(sizeof(ZeroEntry));
public:
static address generate_entry_impl(MacroAssembler* masm, address entry_point) {
ZeroEntry *entry = (ZeroEntry *) masm->pc();
masm->advance(sizeof(ZeroEntry));
entry->set_entry_point(entry_point);
return (address) entry;
}
protected:
address generate_entry(address entry_point) {
return generate_entry_impl(assembler(), entry_point);
}
#endif // CPU_ZERO_VM_CPPINTERPRETERGENERATOR_ZERO_HPP

View File

@ -180,25 +180,6 @@ void CppInterpreter::main_loop(int recurse, TRAPS) {
method, istate->osr_entry(), istate->osr_buf(), THREAD);
return;
}
else if (istate->msg() == BytecodeInterpreter::call_method_handle) {
oop method_handle = istate->callee();
// Trim back the stack to put the parameters at the top
stack->set_sp(istate->stack() + 1);
// Make the call
process_method_handle(method_handle, THREAD);
fixup_after_potential_safepoint();
// Convert the result
istate->set_stack(stack->sp() - 1);
// Restore the stack
stack->set_sp(istate->stack_limit() + 1);
// Resume the interpreter
istate->set_msg(BytecodeInterpreter::method_resume);
}
else {
ShouldNotReachHere();
}
@ -535,35 +516,35 @@ int CppInterpreter::accessor_entry(Method* method, intptr_t UNUSED, TRAPS) {
if (entry->is_volatile()) {
switch (entry->flag_state()) {
case ctos:
SET_LOCALS_INT(object->char_field_acquire(entry->f2()), 0);
SET_LOCALS_INT(object->char_field_acquire(entry->f2_as_index()), 0);
break;
case btos:
SET_LOCALS_INT(object->byte_field_acquire(entry->f2()), 0);
SET_LOCALS_INT(object->byte_field_acquire(entry->f2_as_index()), 0);
break;
case stos:
SET_LOCALS_INT(object->short_field_acquire(entry->f2()), 0);
SET_LOCALS_INT(object->short_field_acquire(entry->f2_as_index()), 0);
break;
case itos:
SET_LOCALS_INT(object->int_field_acquire(entry->f2()), 0);
SET_LOCALS_INT(object->int_field_acquire(entry->f2_as_index()), 0);
break;
case ltos:
SET_LOCALS_LONG(object->long_field_acquire(entry->f2()), 0);
SET_LOCALS_LONG(object->long_field_acquire(entry->f2_as_index()), 0);
break;
case ftos:
SET_LOCALS_FLOAT(object->float_field_acquire(entry->f2()), 0);
SET_LOCALS_FLOAT(object->float_field_acquire(entry->f2_as_index()), 0);
break;
case dtos:
SET_LOCALS_DOUBLE(object->double_field_acquire(entry->f2()), 0);
SET_LOCALS_DOUBLE(object->double_field_acquire(entry->f2_as_index()), 0);
break;
case atos:
SET_LOCALS_OBJECT(object->obj_field_acquire(entry->f2()), 0);
SET_LOCALS_OBJECT(object->obj_field_acquire(entry->f2_as_index()), 0);
break;
default:
@ -573,35 +554,35 @@ int CppInterpreter::accessor_entry(Method* method, intptr_t UNUSED, TRAPS) {
else {
switch (entry->flag_state()) {
case ctos:
SET_LOCALS_INT(object->char_field(entry->f2()), 0);
SET_LOCALS_INT(object->char_field(entry->f2_as_index()), 0);
break;
case btos:
SET_LOCALS_INT(object->byte_field(entry->f2()), 0);
SET_LOCALS_INT(object->byte_field(entry->f2_as_index()), 0);
break;
case stos:
SET_LOCALS_INT(object->short_field(entry->f2()), 0);
SET_LOCALS_INT(object->short_field(entry->f2_as_index()), 0);
break;
case itos:
SET_LOCALS_INT(object->int_field(entry->f2()), 0);
SET_LOCALS_INT(object->int_field(entry->f2_as_index()), 0);
break;
case ltos:
SET_LOCALS_LONG(object->long_field(entry->f2()), 0);
SET_LOCALS_LONG(object->long_field(entry->f2_as_index()), 0);
break;
case ftos:
SET_LOCALS_FLOAT(object->float_field(entry->f2()), 0);
SET_LOCALS_FLOAT(object->float_field(entry->f2_as_index()), 0);
break;
case dtos:
SET_LOCALS_DOUBLE(object->double_field(entry->f2()), 0);
SET_LOCALS_DOUBLE(object->double_field(entry->f2_as_index()), 0);
break;
case atos:
SET_LOCALS_OBJECT(object->obj_field(entry->f2()), 0);
SET_LOCALS_OBJECT(object->obj_field(entry->f2_as_index()), 0);
break;
default:
@ -629,516 +610,6 @@ int CppInterpreter::empty_entry(Method* method, intptr_t UNUSED, TRAPS) {
return 0;
}
int CppInterpreter::method_handle_entry(Method* method,
intptr_t UNUSED, TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
ZeroStack *stack = thread->zero_stack();
int argument_slots = method->size_of_parameters();
int result_slots = type2size[result_type_of(method)];
intptr_t *vmslots = stack->sp();
intptr_t *unwind_sp = vmslots + argument_slots;
// Find the MethodType
address p = (address) method;
for (jint* pc = method->method_type_offsets_chain(); (*pc) != -1; pc++) {
p = *(address*)(p + (*pc));
}
oop method_type = (oop) p;
// The MethodHandle is in the slot after the arguments
int num_vmslots = argument_slots - 1;
oop method_handle = VMSLOTS_OBJECT(num_vmslots);
// InvokeGeneric requires some extra shuffling
oop mhtype = java_lang_invoke_MethodHandle::type(method_handle);
bool is_exact = mhtype == method_type;
if (!is_exact) {
if (true || // FIXME
method->intrinsic_id() == vmIntrinsics::_invokeExact) {
CALL_VM_NOCHECK_NOFIX(
SharedRuntime::throw_WrongMethodTypeException(
thread, method_type, mhtype));
// NB all oops trashed!
assert(HAS_PENDING_EXCEPTION, "should do");
stack->set_sp(unwind_sp);
return 0;
}
assert(method->intrinsic_id() == vmIntrinsics::_invokeGeneric, "should be");
// Load up an adapter from the calling type
// NB the x86 code for this (in methodHandles_x86.cpp, search for
// "genericInvoker") is really really odd. I'm hoping it's trying
// to accomodate odd VM/class library combinations I can ignore.
oop adapter = NULL; //FIXME: load the adapter from the CP cache
IF (adapter == NULL) {
CALL_VM_NOCHECK_NOFIX(
SharedRuntime::throw_WrongMethodTypeException(
thread, method_type, mhtype));
// NB all oops trashed!
assert(HAS_PENDING_EXCEPTION, "should do");
stack->set_sp(unwind_sp);
return 0;
}
// Adapters are shared among form-families of method-type. The
// type being called is passed as a trusted first argument so that
// the adapter knows the actual types of its arguments and return
// values.
insert_vmslots(num_vmslots + 1, 1, THREAD);
if (HAS_PENDING_EXCEPTION) {
// NB all oops trashed!
stack->set_sp(unwind_sp);
return 0;
}
vmslots = stack->sp();
num_vmslots++;
SET_VMSLOTS_OBJECT(method_type, num_vmslots);
method_handle = adapter;
}
// Start processing
process_method_handle(method_handle, THREAD);
if (HAS_PENDING_EXCEPTION)
result_slots = 0;
// If this is an invokeExact then the eventual callee will not
// have unwound the method handle argument so we have to do it.
// If a result is being returned the it will be above the method
// handle argument we're unwinding.
if (is_exact) {
intptr_t result[2];
for (int i = 0; i < result_slots; i++)
result[i] = stack->pop();
stack->pop();
for (int i = result_slots - 1; i >= 0; i--)
stack->push(result[i]);
}
// Check
assert(stack->sp() == unwind_sp - result_slots, "should be");
// No deoptimized frames on the stack
return 0;
}
void CppInterpreter::process_method_handle(oop method_handle, TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
ZeroStack *stack = thread->zero_stack();
intptr_t *vmslots = stack->sp();
bool direct_to_method = false;
BasicType src_rtype = T_ILLEGAL;
BasicType dst_rtype = T_ILLEGAL;
MethodHandleEntry *entry =
java_lang_invoke_MethodHandle::vmentry(method_handle);
MethodHandles::EntryKind entry_kind =
(MethodHandles::EntryKind) (((intptr_t) entry) & 0xffffffff);
Method* method = NULL;
switch (entry_kind) {
case MethodHandles::_invokestatic_mh:
direct_to_method = true;
break;
case MethodHandles::_invokespecial_mh:
case MethodHandles::_invokevirtual_mh:
case MethodHandles::_invokeinterface_mh:
{
oop receiver =
VMSLOTS_OBJECT(
java_lang_invoke_MethodHandle::vmslots(method_handle) - 1);
if (receiver == NULL) {
stack->set_sp(calculate_unwind_sp(stack, method_handle));
CALL_VM_NOCHECK_NOFIX(
throw_exception(
thread, vmSymbols::java_lang_NullPointerException()));
// NB all oops trashed!
assert(HAS_PENDING_EXCEPTION, "should do");
return;
}
if (entry_kind != MethodHandles::_invokespecial_mh) {
intptr_t index = java_lang_invoke_DirectMethodHandle::vmindex(method_handle);
InstanceKlass* rcvrKlass =
(InstanceKlass *) receiver->klass();
if (entry_kind == MethodHandles::_invokevirtual_mh) {
method = (Method*) rcvrKlass->start_of_vtable()[index];
}
else {
oop iclass = java_lang_invoke_MethodHandle::next_target(method_handle);
itableOffsetEntry* ki =
(itableOffsetEntry *) rcvrKlass->start_of_itable();
int i, length = rcvrKlass->itable_length();
for (i = 0; i < length; i++, ki++ ) {
if (ki->interface_klass() == iclass)
break;
}
if (i == length) {
stack->set_sp(calculate_unwind_sp(stack, method_handle));
CALL_VM_NOCHECK_NOFIX(
throw_exception(
thread, vmSymbols::java_lang_IncompatibleClassChangeError()));
// NB all oops trashed!
assert(HAS_PENDING_EXCEPTION, "should do");
return;
}
itableMethodEntry* im = ki->first_method_entry(receiver->klass());
method = im[index].method();
if (method == NULL) {
stack->set_sp(calculate_unwind_sp(stack, method_handle));
CALL_VM_NOCHECK_NOFIX(
throw_exception(
thread, vmSymbols::java_lang_AbstractMethodError()));
// NB all oops trashed!
assert(HAS_PENDING_EXCEPTION, "should do");
return;
}
}
}
}
direct_to_method = true;
break;
case MethodHandles::_bound_ref_direct_mh:
case MethodHandles::_bound_int_direct_mh:
case MethodHandles::_bound_long_direct_mh:
direct_to_method = true;
// fall through
case MethodHandles::_bound_ref_mh:
case MethodHandles::_bound_int_mh:
case MethodHandles::_bound_long_mh:
{
BasicType arg_type = T_ILLEGAL;
int arg_mask = -1;
int arg_slots = -1;
MethodHandles::get_ek_bound_mh_info(
entry_kind, arg_type, arg_mask, arg_slots);
int arg_slot =
java_lang_invoke_BoundMethodHandle::vmargslot(method_handle);
// Create the new slot(s)
intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle);
insert_vmslots(arg_slot, arg_slots, THREAD);
if (HAS_PENDING_EXCEPTION) {
// all oops trashed
stack->set_sp(unwind_sp);
return;
}
vmslots = stack->sp();
// Store bound argument into new stack slot
oop arg = java_lang_invoke_BoundMethodHandle::argument(method_handle);
if (arg_type == T_OBJECT) {
assert(arg_slots == 1, "should be");
SET_VMSLOTS_OBJECT(arg, arg_slot);
}
else {
jvalue arg_value;
arg_type = java_lang_boxing_object::get_value(arg, &arg_value);
switch (arg_type) {
case T_BOOLEAN:
SET_VMSLOTS_INT(arg_value.z, arg_slot);
break;
case T_CHAR:
SET_VMSLOTS_INT(arg_value.c, arg_slot);
break;
case T_BYTE:
SET_VMSLOTS_INT(arg_value.b, arg_slot);
break;
case T_SHORT:
SET_VMSLOTS_INT(arg_value.s, arg_slot);
break;
case T_INT:
SET_VMSLOTS_INT(arg_value.i, arg_slot);
break;
case T_FLOAT:
SET_VMSLOTS_FLOAT(arg_value.f, arg_slot);
break;
case T_LONG:
SET_VMSLOTS_LONG(arg_value.j, arg_slot + 1);
break;
case T_DOUBLE:
SET_VMSLOTS_DOUBLE(arg_value.d, arg_slot + 1);
break;
default:
tty->print_cr("unhandled type %s", type2name(arg_type));
ShouldNotReachHere();
}
}
}
break;
case MethodHandles::_adapter_retype_only:
case MethodHandles::_adapter_retype_raw:
src_rtype = result_type_of_handle(
java_lang_invoke_MethodHandle::next_target(method_handle));
dst_rtype = result_type_of_handle(method_handle);
break;
case MethodHandles::_adapter_check_cast:
{
int arg_slot =
java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
oop arg = VMSLOTS_OBJECT(arg_slot);
if (arg != NULL) {
Klass* objKlassOop = arg->klass();
Klass* klassOf = java_lang_Class::as_Klass(
java_lang_invoke_AdapterMethodHandle::argument(method_handle));
if (objKlassOop != klassOf &&
!objKlassOop->is_subtype_of(klassOf)) {
ResourceMark rm(THREAD);
const char* objName = Klass::cast(objKlassOop)->external_name();
const char* klassName = Klass::cast(klassOf)->external_name();
char* message = SharedRuntime::generate_class_cast_message(
objName, klassName);
stack->set_sp(calculate_unwind_sp(stack, method_handle));
CALL_VM_NOCHECK_NOFIX(
throw_exception(
thread, vmSymbols::java_lang_ClassCastException(), message));
// NB all oops trashed!
assert(HAS_PENDING_EXCEPTION, "should do");
return;
}
}
}
break;
case MethodHandles::_adapter_dup_args:
{
int arg_slot =
java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
int conv =
java_lang_invoke_AdapterMethodHandle::conversion(method_handle);
int num_slots = -MethodHandles::adapter_conversion_stack_move(conv);
assert(num_slots > 0, "should be");
// Create the new slot(s)
intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle);
stack->overflow_check(num_slots, THREAD);
if (HAS_PENDING_EXCEPTION) {
// all oops trashed
stack->set_sp(unwind_sp);
return;
}
// Duplicate the arguments
for (int i = num_slots - 1; i >= 0; i--)
stack->push(*VMSLOTS_SLOT(arg_slot + i));
vmslots = stack->sp(); // unused, but let the compiler figure that out
}
break;
case MethodHandles::_adapter_drop_args:
{
int arg_slot =
java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
int conv =
java_lang_invoke_AdapterMethodHandle::conversion(method_handle);
int num_slots = MethodHandles::adapter_conversion_stack_move(conv);
assert(num_slots > 0, "should be");
remove_vmslots(arg_slot, num_slots, THREAD); // doesn't trap
vmslots = stack->sp(); // unused, but let the compiler figure that out
}
break;
case MethodHandles::_adapter_opt_swap_1:
case MethodHandles::_adapter_opt_swap_2:
case MethodHandles::_adapter_opt_rot_1_up:
case MethodHandles::_adapter_opt_rot_1_down:
case MethodHandles::_adapter_opt_rot_2_up:
case MethodHandles::_adapter_opt_rot_2_down:
{
int arg1 =
java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
int conv =
java_lang_invoke_AdapterMethodHandle::conversion(method_handle);
int arg2 = MethodHandles::adapter_conversion_vminfo(conv);
int swap_bytes = 0, rotate = 0;
MethodHandles::get_ek_adapter_opt_swap_rot_info(
entry_kind, swap_bytes, rotate);
int swap_slots = swap_bytes >> LogBytesPerWord;
intptr_t tmp;
switch (rotate) {
case 0: // swap
for (int i = 0; i < swap_slots; i++) {
tmp = *VMSLOTS_SLOT(arg1 + i);
SET_VMSLOTS_SLOT(VMSLOTS_SLOT(arg2 + i), arg1 + i);
SET_VMSLOTS_SLOT(&tmp, arg2 + i);
}
break;
case 1: // up
assert(arg1 - swap_slots > arg2, "should be");
tmp = *VMSLOTS_SLOT(arg1);
for (int i = arg1 - swap_slots; i >= arg2; i--)
SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i), i + swap_slots);
SET_VMSLOTS_SLOT(&tmp, arg2);
break;
case -1: // down
assert(arg2 - swap_slots > arg1, "should be");
tmp = *VMSLOTS_SLOT(arg1);
for (int i = arg1 + swap_slots; i <= arg2; i++)
SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i), i - swap_slots);
SET_VMSLOTS_SLOT(&tmp, arg2);
break;
default:
ShouldNotReachHere();
}
}
break;
case MethodHandles::_adapter_opt_i2l:
{
int arg_slot =
java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
int arg = VMSLOTS_INT(arg_slot);
intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle);
insert_vmslots(arg_slot, 1, THREAD);
if (HAS_PENDING_EXCEPTION) {
// all oops trashed
stack->set_sp(unwind_sp);
return;
}
vmslots = stack->sp();
arg_slot++;
SET_VMSLOTS_LONG(arg, arg_slot);
}
break;
case MethodHandles::_adapter_opt_unboxi:
case MethodHandles::_adapter_opt_unboxl:
{
int arg_slot =
java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
oop arg = VMSLOTS_OBJECT(arg_slot);
jvalue arg_value;
if (arg == NULL) {
// queue a nullpointer exception for the caller
stack->set_sp(calculate_unwind_sp(stack, method_handle));
CALL_VM_NOCHECK_NOFIX(
throw_exception(
thread, vmSymbols::java_lang_NullPointerException()));
// NB all oops trashed!
assert(HAS_PENDING_EXCEPTION, "should do");
return;
}
BasicType arg_type = java_lang_boxing_object::get_value(arg, &arg_value);
if (arg_type == T_LONG || arg_type == T_DOUBLE) {
intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle);
insert_vmslots(arg_slot, 1, THREAD);
if (HAS_PENDING_EXCEPTION) {
// all oops trashed
stack->set_sp(unwind_sp);
return;
}
vmslots = stack->sp();
arg_slot++;
}
switch (arg_type) {
case T_BOOLEAN:
SET_VMSLOTS_INT(arg_value.z, arg_slot);
break;
case T_CHAR:
SET_VMSLOTS_INT(arg_value.c, arg_slot);
break;
case T_BYTE:
SET_VMSLOTS_INT(arg_value.b, arg_slot);
break;
case T_SHORT:
SET_VMSLOTS_INT(arg_value.s, arg_slot);
break;
case T_INT:
SET_VMSLOTS_INT(arg_value.i, arg_slot);
break;
case T_FLOAT:
SET_VMSLOTS_FLOAT(arg_value.f, arg_slot);
break;
case T_LONG:
SET_VMSLOTS_LONG(arg_value.j, arg_slot);
break;
case T_DOUBLE:
SET_VMSLOTS_DOUBLE(arg_value.d, arg_slot);
break;
default:
tty->print_cr("unhandled type %s", type2name(arg_type));
ShouldNotReachHere();
}
}
break;
default:
tty->print_cr("unhandled entry_kind %s",
MethodHandles::entry_name(entry_kind));
ShouldNotReachHere();
}
// Continue along the chain
if (direct_to_method) {
if (method == NULL) {
method =
(Method*) java_lang_invoke_MethodHandle::vmtarget(method_handle);
}
address entry_point = method->from_interpreted_entry();
Interpreter::invoke_method(method, entry_point, THREAD);
}
else {
process_method_handle(
java_lang_invoke_MethodHandle::next_target(method_handle), THREAD);
}
// NB all oops now trashed
// Adapt the result type, if necessary
if (src_rtype != dst_rtype && !HAS_PENDING_EXCEPTION) {
switch (dst_rtype) {
case T_VOID:
for (int i = 0; i < type2size[src_rtype]; i++)
stack->pop();
return;
case T_INT:
switch (src_rtype) {
case T_VOID:
stack->overflow_check(1, CHECK);
stack->push(0);
return;
case T_BOOLEAN:
case T_CHAR:
case T_BYTE:
case T_SHORT:
return;
}
// INT results sometimes need narrowing
case T_BOOLEAN:
case T_CHAR:
case T_BYTE:
case T_SHORT:
switch (src_rtype) {
case T_INT:
return;
}
}
tty->print_cr("unhandled conversion:");
tty->print_cr("src_rtype = %s", type2name(src_rtype));
tty->print_cr("dst_rtype = %s", type2name(dst_rtype));
ShouldNotReachHere();
}
}
// The new slots will be inserted before slot insert_before.
// Slots < insert_before will have the same slot number after the insert.
// Slots >= insert_before will become old_slot + num_slots.
@ -1380,10 +851,6 @@ address AbstractInterpreterGenerator::generate_method_entry(
entry_point = ((InterpreterGenerator*) this)->generate_abstract_entry();
break;
case Interpreter::method_handle:
entry_point = ((InterpreterGenerator*) this)->generate_method_handle_entry();
break;
case Interpreter::java_lang_math_sin:
case Interpreter::java_lang_math_cos:
case Interpreter::java_lang_math_tan:
@ -1391,6 +858,8 @@ address AbstractInterpreterGenerator::generate_method_entry(
case Interpreter::java_lang_math_log:
case Interpreter::java_lang_math_log10:
case Interpreter::java_lang_math_sqrt:
case Interpreter::java_lang_math_pow:
case Interpreter::java_lang_math_exp:
entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind);
break;

View File

@ -36,7 +36,6 @@
static int native_entry(Method* method, intptr_t UNUSED, TRAPS);
static int accessor_entry(Method* method, intptr_t UNUSED, TRAPS);
static int empty_entry(Method* method, intptr_t UNUSED, TRAPS);
static int method_handle_entry(Method* method, intptr_t UNUSED, TRAPS);
public:
// Main loop of normal_entry
@ -44,7 +43,6 @@
private:
// Helpers for method_handle_entry
static void process_method_handle(oop method_handle, TRAPS);
static void insert_vmslots(int insert_before, int num_slots, TRAPS);
static void remove_vmslots(int first_slot, int num_slots, TRAPS);
static BasicType result_type_of_handle(oop method_handle);

View File

@ -351,7 +351,7 @@ void SharkFrame::identify_word(int frame_index,
switch (offset) {
case pc_off:
strncpy(fieldbuf, "pc", buflen);
if (method()->is_oop()) {
if (method()->is_method()) {
nmethod *code = method()->code();
if (code && code->pc_desc_at(pc())) {
SimpleScopeDesc ssd(code, pc());
@ -367,7 +367,7 @@ void SharkFrame::identify_word(int frame_index,
case method_off:
strncpy(fieldbuf, "method", buflen);
if (method()->is_oop()) {
if (method()->is_method()) {
method()->name_and_sig_as_C_string(valuebuf, buflen);
}
return;
@ -378,7 +378,7 @@ void SharkFrame::identify_word(int frame_index,
}
// Variable part
if (method()->is_oop()) {
if (method()->is_method()) {
identify_vp_word(frame_index, addr_of_word(offset),
addr_of_word(header_words + 1),
unextended_sp() + method()->max_stack(),
@ -430,4 +430,3 @@ intptr_t *frame::initial_deoptimization_info() {
// unused... but returns fp() to minimize changes introduced by 7087445
return fp();
}

View File

@ -36,6 +36,8 @@ inline frame::frame() {
_deopt_state = unknown;
}
inline address frame::sender_pc() const { ShouldNotCallThis(); }
inline frame::frame(ZeroFrame* zf, intptr_t* sp) {
_zeroframe = zf;
_sp = sp;

View File

@ -40,7 +40,7 @@ int InlineCacheBuffer::ic_stub_code_size() {
}
void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin,
Metadata* cached_oop,
void* cached_oop,
address entry_point) {
// NB ic_stub_code_size() must return the size of the code we generate
ShouldNotCallThis();
@ -51,7 +51,6 @@ address InlineCacheBuffer::ic_buffer_entry_point(address code_begin) {
ShouldNotCallThis();
}
Metadata* InlineCacheBuffer::ic_buffer_cached_oop(address code_begin) {
// NB ic_stub_code_size() must return the size of the code we generate
void* InlineCacheBuffer::ic_buffer_cached_value(address code_begin) {
ShouldNotCallThis();
}

View File

@ -24,26 +24,159 @@
*/
#include "precompiled.hpp"
#include "interpreter/interpreterGenerator.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/allocation.inline.hpp"
#include "prims/methodHandles.hpp"
int MethodHandles::adapter_conversion_ops_supported_mask() {
return ((1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS)
//|(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG!
);
// FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS.
void MethodHandles::invoke_target(Method* method, TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
ZeroStack *stack = thread->zero_stack();
InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
interpreterState istate = frame->interpreter_state();
// Trim back the stack to put the parameters at the top
stack->set_sp(istate->stack() + 1);
Interpreter::invoke_method(method, method->from_interpreted_entry(), THREAD);
// Convert the result
istate->set_stack(stack->sp() - 1);
}
void MethodHandles::generate_method_handle_stub(MacroAssembler* masm,
MethodHandles::EntryKind ek) {
init_entry(ek, (MethodHandleEntry *) ek);
oop MethodHandles::popFromStack(TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
interpreterState istate = frame->interpreter_state();
intptr_t* topOfStack = istate->stack();
oop top = STACK_OBJECT(-1);
MORE_STACK(-1);
istate->set_stack(topOfStack);
return top;
}
int MethodHandles::method_handle_entry_invokeBasic(Method* method, intptr_t UNUSED, TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
interpreterState istate = frame->interpreter_state();
intptr_t* topOfStack = istate->stack();
// 'this' is a MethodHandle. We resolve the target method by accessing this.form.vmentry.vmtarget.
int numArgs = method->size_of_parameters();
oop lform1 = java_lang_invoke_MethodHandle::form(STACK_OBJECT(-numArgs)); // this.form
oop vmEntry1 = java_lang_invoke_LambdaForm::vmentry(lform1);
Method* vmtarget = (Method*) java_lang_invoke_MemberName::vmtarget(vmEntry1);
invoke_target(vmtarget, THREAD);
// No deoptimized frames on the stack
return 0;
}
int MethodHandles::method_handle_entry_linkToStaticOrSpecial(Method* method, intptr_t UNUSED, TRAPS) {
// Pop appendix argument from stack. This is a MemberName which we resolve to the
// target method.
oop vmentry = popFromStack(THREAD);
Method* vmtarget = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry);
invoke_target(vmtarget, THREAD);
return 0;
}
int MethodHandles::method_handle_entry_linkToInterface(Method* method, intptr_t UNUSED, TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
interpreterState istate = frame->interpreter_state();
// Pop appendix argument from stack. This is a MemberName which we resolve to the
// target method.
oop vmentry = popFromStack(THREAD);
intptr_t* topOfStack = istate->stack();
// Resolve target method by looking up in the receiver object's itable.
Klass* clazz = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(vmentry));
intptr_t vmindex = java_lang_invoke_MemberName::vmindex(vmentry);
Method* target = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry);
int numArgs = target->size_of_parameters();
oop recv = STACK_OBJECT(-numArgs);
InstanceKlass* klass_part = InstanceKlass::cast(recv->klass());
itableOffsetEntry* ki = (itableOffsetEntry*) klass_part->start_of_itable();
int i;
for ( i = 0 ; i < klass_part->itable_length() ; i++, ki++ ) {
if (ki->interface_klass() == clazz) break;
}
itableMethodEntry* im = ki->first_method_entry(recv->klass());
Method* vmtarget = im[vmindex].method();
invoke_target(vmtarget, THREAD);
return 0;
}
int MethodHandles::method_handle_entry_linkToVirtual(Method* method, intptr_t UNUSED, TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
interpreterState istate = frame->interpreter_state();
// Pop appendix argument from stack. This is a MemberName which we resolve to the
// target method.
oop vmentry = popFromStack(THREAD);
intptr_t* topOfStack = istate->stack();
// Resolve target method by looking up in the receiver object's vtable.
intptr_t vmindex = java_lang_invoke_MemberName::vmindex(vmentry);
Method* target = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry);
int numArgs = target->size_of_parameters();
oop recv = STACK_OBJECT(-numArgs);
Klass* clazz = recv->klass();
Klass* klass_part = InstanceKlass::cast(clazz);
klassVtable* vtable = klass_part->vtable();
Method* vmtarget = vtable->method_at(vmindex);
invoke_target(vmtarget, THREAD);
return 0;
}
int MethodHandles::method_handle_entry_invalid(Method* method, intptr_t UNUSED, TRAPS) {
ShouldNotReachHere();
return 0;
}
address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* masm,
vmIntrinsics::ID iid) {
switch (iid) {
case vmIntrinsics::_invokeGeneric:
case vmIntrinsics::_compiledLambdaForm:
// Perhaps surprisingly, the symbolic references visible to Java are not directly used.
// They are linked to Java-generated adapters via MethodHandleNatives.linkMethod.
// They all allow an appendix argument.
return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_invalid);
case vmIntrinsics::_invokeBasic:
return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_invokeBasic);
case vmIntrinsics::_linkToStatic:
case vmIntrinsics::_linkToSpecial:
return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_linkToStaticOrSpecial);
case vmIntrinsics::_linkToInterface:
return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_linkToInterface);
case vmIntrinsics::_linkToVirtual:
return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_linkToVirtual);
default:
ShouldNotReachHere();
return NULL;
}
}

View File

@ -26,6 +26,14 @@
// Adapters
enum /* platform_dependent_constants */ {
adapter_code_size = 0
adapter_code_size = sizeof(ZeroEntry) * (Interpreter::method_handle_invoke_LAST - Interpreter::method_handle_invoke_FIRST + 1)
};
private:
static oop popFromStack(TRAPS);
static void invoke_target(Method* method, TRAPS);
static int method_handle_entry_invokeBasic(Method* method, intptr_t UNUSED, TRAPS);
static int method_handle_entry_linkToStaticOrSpecial(Method* method, intptr_t UNUSED, TRAPS);
static int method_handle_entry_linkToVirtual(Method* method, intptr_t UNUSED, TRAPS);
static int method_handle_entry_linkToInterface(Method* method, intptr_t UNUSED, TRAPS);
static int method_handle_entry_invalid(Method* method, intptr_t UNUSED, TRAPS);

View File

@ -114,5 +114,8 @@ class ConcreteRegisterImpl : public AbstractRegisterImpl {
};
CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1));
#ifndef DONT_USE_REGISTER_DEFINES
#define noreg ((Register)(noreg_RegisterEnumValue))
#endif
#endif // CPU_ZERO_VM_REGISTER_ZERO_HPP

View File

@ -77,3 +77,7 @@ void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src,
CodeBuffer* dst) {
ShouldNotCallThis();
}
void metadata_Relocation::pd_fix_value(address x) {
ShouldNotCallThis();
}

View File

@ -35,6 +35,7 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "vmreg_zero.inline.hpp"
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
#endif
@ -47,6 +48,12 @@
#endif
static address zero_null_code_stub() {
address start = ShouldNotCallThisStub();
return start;
}
int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
VMRegPair *regs,
int total_args_passed,
@ -63,16 +70,14 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(
AdapterFingerPrint *fingerprint) {
return AdapterHandlerLibrary::new_entry(
fingerprint,
ShouldNotCallThisStub(),
ShouldNotCallThisStub(),
ShouldNotCallThisStub());
CAST_FROM_FN_PTR(address,zero_null_code_stub),
CAST_FROM_FN_PTR(address,zero_null_code_stub),
CAST_FROM_FN_PTR(address,zero_null_code_stub));
}
nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
methodHandle method,
int compile_id,
int total_args_passed,
int max_arg,
BasicType *sig_bt,
VMRegPair *regs,
BasicType ret_type) {
@ -96,19 +101,20 @@ uint SharedRuntime::out_preserve_stack_slots() {
ShouldNotCallThis();
}
JRT_LEAF(void, zero_stub())
ShouldNotCallThis();
JRT_END
static RuntimeStub* generate_empty_runtime_stub(const char* name) {
CodeBuffer buffer(name, 0, 0);
return RuntimeStub::new_runtime_stub(name, &buffer, 0, 0, NULL, false);
return CAST_FROM_FN_PTR(RuntimeStub*,zero_stub);
}
static SafepointBlob* generate_empty_safepoint_blob() {
CodeBuffer buffer("handler_blob", 0, 0);
return SafepointBlob::create(&buffer, NULL, 0);
return CAST_FROM_FN_PTR(SafepointBlob*,zero_stub);
}
static DeoptimizationBlob* generate_empty_deopt_blob() {
CodeBuffer buffer("handler_blob", 0, 0);
return DeoptimizationBlob::create(&buffer, NULL, 0, 0, 0, 0);
return CAST_FROM_FN_PTR(DeoptimizationBlob*,zero_stub);
}
@ -116,7 +122,7 @@ void SharedRuntime::generate_deopt_blob() {
_deopt_blob = generate_empty_deopt_blob();
}
SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause_return) {
SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) {
return generate_empty_safepoint_blob();
}
@ -124,6 +130,7 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const cha
return generate_empty_runtime_stub("resolve_blob");
}
int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
VMRegPair *regs,
int total_args_passed) {

View File

@ -342,7 +342,6 @@ BsdAttachOperation* BsdAttachListener::dequeue() {
// get the credentials of the peer and check the effective uid/guid
// - check with jeff on this.
#ifdef _ALLBSD_SOURCE
uid_t puid;
gid_t pgid;
if (::getpeereid(s, &puid, &pgid) != 0) {
@ -350,17 +349,6 @@ BsdAttachOperation* BsdAttachListener::dequeue() {
RESTARTABLE(::close(s), res);
continue;
}
#else
struct ucred cred_info;
socklen_t optlen = sizeof(cred_info);
if (::getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void*)&cred_info, &optlen) == -1) {
int res;
RESTARTABLE(::close(s), res);
continue;
}
uid_t puid = cred_info.uid;
gid_t pgid = cred_info.gid;
#endif
uid_t euid = geteuid();
gid_t egid = getegid();

View File

@ -39,18 +39,12 @@
private:
#ifdef _ALLBSD_SOURCE
#ifdef __APPLE__
typedef thread_t thread_id_t;
#else
typedef pthread_t thread_id_t;
#endif
#else
typedef pid_t thread_id_t;
#endif
// _pthread_id is the pthread id, which is used by library calls
// (e.g. pthread_kill).
pthread_t _pthread_id;

File diff suppressed because it is too large Load Diff

View File

@ -56,19 +56,6 @@ class Bsd {
static int sigflags[MAXSIGNUM];
static int (*_clock_gettime)(clockid_t, struct timespec *);
#ifndef _ALLBSD_SOURCE
static int (*_pthread_getcpuclockid)(pthread_t, clockid_t *);
static address _initial_thread_stack_bottom;
static uintptr_t _initial_thread_stack_size;
static const char *_glibc_version;
static const char *_libpthread_version;
static bool _is_floating_stack;
static bool _is_NPTL;
static bool _supports_fast_thread_cpu_time;
#endif
static GrowableArray<int>* _cpu_to_node;
@ -76,28 +63,14 @@ class Bsd {
static julong _physical_memory;
static pthread_t _main_thread;
#ifndef _ALLBSD_SOURCE
static Mutex* _createThread_lock;
#endif
static int _page_size;
static julong available_memory();
static julong physical_memory() { return _physical_memory; }
static void initialize_system_info();
#ifndef _ALLBSD_SOURCE
static void set_glibc_version(const char *s) { _glibc_version = s; }
static void set_libpthread_version(const char *s) { _libpthread_version = s; }
#endif
static bool supports_variable_stack_size();
#ifndef _ALLBSD_SOURCE
static void set_is_NPTL() { _is_NPTL = true; }
static void set_is_BsdThreads() { _is_NPTL = false; }
static void set_is_floating_stack() { _is_floating_stack = true; }
#endif
static void rebuild_cpu_to_node_map();
static GrowableArray<int>* cpu_to_node() { return _cpu_to_node; }
@ -106,25 +79,10 @@ class Bsd {
public:
static void init_thread_fpu_state();
#ifndef _ALLBSD_SOURCE
static int get_fpu_control_word();
static void set_fpu_control_word(int fpu_control);
#endif
static pthread_t main_thread(void) { return _main_thread; }
#ifndef _ALLBSD_SOURCE
// returns kernel thread id (similar to LWP id on Solaris), which can be
// used to access /proc
static pid_t gettid();
static void set_createThread_lock(Mutex* lk) { _createThread_lock = lk; }
static Mutex* createThread_lock(void) { return _createThread_lock; }
#endif
static void hotspot_sigmask(Thread* thread);
#ifndef _ALLBSD_SOURCE
static address initial_thread_stack_bottom(void) { return _initial_thread_stack_bottom; }
static uintptr_t initial_thread_stack_size(void) { return _initial_thread_stack_size; }
#endif
static bool is_initial_thread(void);
static int page_size(void) { return _page_size; }
@ -161,23 +119,6 @@ class Bsd {
static struct sigaction *get_chained_signal_action(int sig);
static bool chained_handler(int sig, siginfo_t* siginfo, void* context);
#ifndef _ALLBSD_SOURCE
// GNU libc and libpthread version strings
static const char *glibc_version() { return _glibc_version; }
static const char *libpthread_version() { return _libpthread_version; }
// NPTL or BsdThreads?
static bool is_BsdThreads() { return !_is_NPTL; }
static bool is_NPTL() { return _is_NPTL; }
// NPTL is always floating stack. BsdThreads could be using floating
// stack or fixed stack.
static bool is_floating_stack() { return _is_floating_stack; }
static void libpthread_init();
static bool libnuma_init();
static void* libnuma_dlsym(void* handle, const char* name);
#endif
// Minimum stack size a thread can be created with (allowing
// the VM to completely create the thread and enter user code)
static size_t min_stack_allowed;
@ -186,22 +127,9 @@ class Bsd {
static size_t default_stack_size(os::ThreadType thr_type);
static size_t default_guard_size(os::ThreadType thr_type);
#ifndef _ALLBSD_SOURCE
static void capture_initial_stack(size_t max_size);
// Stack overflow handling
static bool manually_expand_stack(JavaThread * t, address addr);
static int max_register_window_saves_before_flushing();
#endif
// Real-time clock functions
static void clock_init(void);
#ifndef _ALLBSD_SOURCE
// fast POSIX clocks support
static void fast_thread_clock_init(void);
#endif
static inline bool supports_monotonic_clock() {
return _clock_gettime != NULL;
}
@ -210,18 +138,6 @@ class Bsd {
return _clock_gettime ? _clock_gettime(clock_id, tp) : -1;
}
#ifndef _ALLBSD_SOURCE
static int pthread_getcpuclockid(pthread_t tid, clockid_t *clock_id) {
return _pthread_getcpuclockid ? _pthread_getcpuclockid(tid, clock_id) : -1;
}
static bool supports_fast_thread_cpu_time() {
return _supports_fast_thread_cpu_time;
}
static jlong fast_thread_cpu_time(clockid_t clockid);
#endif
// Stack repair handling
// none present

View File

@ -22,7 +22,7 @@
*
*/
// Must be at least Windows 2000 or XP to use VectoredExceptions and IsDebuggerPresent
// Must be at least Windows 2000 or XP to use IsDebuggerPresent
#define _WIN32_WINNT 0x500
// no precompiled headers
@ -110,10 +110,6 @@ static FILETIME process_exit_time;
static FILETIME process_user_time;
static FILETIME process_kernel_time;
#ifdef _WIN64
PVOID topLevelVectoredExceptionHandler = NULL;
#endif
#ifdef _M_IA64
#define __CPU__ ia64
#elif _M_AMD64
@ -136,12 +132,6 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
case DLL_PROCESS_DETACH:
if(ForceTimeHighResolution)
timeEndPeriod(1L);
#ifdef _WIN64
if (topLevelVectoredExceptionHandler != NULL) {
RemoveVectoredExceptionHandler(topLevelVectoredExceptionHandler);
topLevelVectoredExceptionHandler = NULL;
}
#endif
break;
default:
break;
@ -408,20 +398,14 @@ static unsigned __stdcall java_start(Thread* thread) {
}
if (UseVectoredExceptions) {
// If we are using vectored exception we don't need to set a SEH
thread->run();
}
else {
// Install a win32 structured exception handler around every thread created
// by VM, so VM can genrate error dump when an exception occurred in non-
// Java thread (e.g. VM thread).
__try {
thread->run();
} __except(topLevelExceptionFilter(
(_EXCEPTION_POINTERS*)_exception_info())) {
// Nothing to do.
}
// Install a win32 structured exception handler around every thread created
// by VM, so VM can genrate error dump when an exception occurred in non-
// Java thread (e.g. VM thread).
__try {
thread->run();
} __except(topLevelExceptionFilter(
(_EXCEPTION_POINTERS*)_exception_info())) {
// Nothing to do.
}
// One less thread is executing
@ -2489,16 +2473,6 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
}
#endif
#ifdef _WIN64
// Windows will sometimes generate an access violation
// when we call malloc. Since we use VectoredExceptions
// on 64 bit platforms, we see this exception. We must
// pass this exception on so Windows can recover.
// We check to see if the pc of the fault is in NTDLL.DLL
// if so, we pass control on to Windows for handling.
if (UseVectoredExceptions && _addr_in_ntdll(pc)) return EXCEPTION_CONTINUE_SEARCH;
#endif
// Stack overflow or null pointer exception in native code.
report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
exceptionInfo->ContextRecord);
@ -2527,30 +2501,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
}
if (exception_code != EXCEPTION_BREAKPOINT) {
#ifndef _WIN64
report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
exceptionInfo->ContextRecord);
#else
// Itanium Windows uses a VectoredExceptionHandler
// Which means that C++ programatic exception handlers (try/except)
// will get here. Continue the search for the right except block if
// the exception code is not a fatal code.
switch ( exception_code ) {
case EXCEPTION_ACCESS_VIOLATION:
case EXCEPTION_STACK_OVERFLOW:
case EXCEPTION_ILLEGAL_INSTRUCTION:
case EXCEPTION_ILLEGAL_INSTRUCTION_2:
case EXCEPTION_INT_OVERFLOW:
case EXCEPTION_INT_DIVIDE_BY_ZERO:
case EXCEPTION_UNCAUGHT_CXX_EXCEPTION:
{ report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
exceptionInfo->ContextRecord);
}
break;
default:
break;
}
#endif
}
return EXCEPTION_CONTINUE_SEARCH;
}
@ -3706,18 +3658,6 @@ jint os::init_2(void) {
// Setup Windows Exceptions
// On Itanium systems, Structured Exception Handling does not
// work since stack frames must be walkable by the OS. Since
// much of our code is dynamically generated, and we do not have
// proper unwind .xdata sections, the system simply exits
// rather than delivering the exception. To work around
// this we use VectorExceptions instead.
#ifdef _WIN64
if (UseVectoredExceptions) {
topLevelVectoredExceptionHandler = AddVectoredExceptionHandler( 1, topLevelExceptionFilter);
}
#endif
// for debugging float code generation bugs
if (ForceFloatExceptions) {
#ifndef _WIN64

View File

@ -25,10 +25,6 @@
#ifndef OS_CPU_BSD_X86_VM_BYTES_BSD_X86_INLINE_HPP
#define OS_CPU_BSD_X86_VM_BYTES_BSD_X86_INLINE_HPP
#ifndef _ALLBSD_SOURCE
#include <byteswap.h>
#endif
#ifdef __APPLE__
#include <libkern/OSByteOrder.h>
#endif

View File

@ -48,7 +48,5 @@ define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
// Used on 64 bit platforms for UseCompressedOops base address or CDS
define_pd_global(uintx, HeapBaseMinAddress, 2*G);
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);
#endif // OS_CPU_BSD_X86_VM_GLOBALS_BSD_X86_HPP

View File

@ -76,7 +76,7 @@
# include <ucontext.h>
#endif
#if defined(_ALLBSD_SOURCE) && !defined(__APPLE__) && !defined(__NetBSD__)
#if !defined(__APPLE__) && !defined(__NetBSD__)
# include <pthread_np.h>
#endif
@ -489,23 +489,6 @@ JVM_handle_bsd_signal(int sig,
// to handle_unexpected_exception way down below.
thread->disable_stack_red_zone();
tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
#ifndef _ALLBSD_SOURCE
} else {
// Accessing stack address below sp may cause SEGV if current
// thread has MAP_GROWSDOWN stack. This should only happen when
// current thread was created by user code with MAP_GROWSDOWN flag
// and then attached to VM. See notes in os_bsd.cpp.
if (thread->osthread()->expanding_stack() == 0) {
thread->osthread()->set_expanding_stack();
if (os::Bsd::manually_expand_stack(thread, addr)) {
thread->osthread()->clear_expanding_stack();
return 1;
}
thread->osthread()->clear_expanding_stack();
} else {
fatal("recursive segv. expanding stack.");
}
#endif
}
}
}
@ -744,61 +727,21 @@ JVM_handle_bsd_signal(int sig,
ShouldNotReachHere();
}
#ifdef _ALLBSD_SOURCE
// From solaris_i486.s ported to bsd_i486.s
extern "C" void fixcw();
#endif
void os::Bsd::init_thread_fpu_state(void) {
#ifndef AMD64
# ifdef _ALLBSD_SOURCE
// Set fpu to 53 bit precision. This happens too early to use a stub.
fixcw();
# else
// set fpu to 53 bit precision
set_fpu_control_word(0x27f);
# endif
#endif // !AMD64
}
#ifndef _ALLBSD_SOURCE
int os::Bsd::get_fpu_control_word(void) {
#ifdef AMD64
return 0;
#else
int fpu_control;
_FPU_GETCW(fpu_control);
return fpu_control & 0xffff;
#endif // AMD64
}
void os::Bsd::set_fpu_control_word(int fpu_control) {
#ifndef AMD64
_FPU_SETCW(fpu_control);
#endif // !AMD64
}
#endif
// Check that the bsd kernel version is 2.4 or higher since earlier
// versions do not support SSE without patches.
bool os::supports_sse() {
#if defined(AMD64) || defined(_ALLBSD_SOURCE)
return true;
#else
struct utsname uts;
if( uname(&uts) != 0 ) return false; // uname fails?
char *minor_string;
int major = strtol(uts.release,&minor_string,10);
int minor = strtol(minor_string+1,NULL,10);
bool result = (major > 2 || (major==2 && minor >= 4));
#ifndef PRODUCT
if (PrintMiscellaneous && Verbose) {
tty->print("OS version is %d.%d, which %s support SSE/SSE2\n",
major,minor, result ? "DOES" : "does NOT");
}
#endif
return result;
#endif // AMD64
}
bool os::is_allocatable(size_t bytes) {
@ -836,46 +779,7 @@ size_t os::Bsd::min_stack_allowed = (48 DEBUG_ONLY(+4))*K;
#define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;})
#endif
#ifdef _ALLBSD_SOURCE
bool os::Bsd::supports_variable_stack_size() { return true; }
#else
// Test if pthread library can support variable thread stack size. BsdThreads
// in fixed stack mode allocates 2M fixed slot for each thread. BsdThreads
// in floating stack mode and NPTL support variable stack size.
bool os::Bsd::supports_variable_stack_size() {
if (os::Bsd::is_NPTL()) {
// NPTL, yes
return true;
} else {
// Note: We can't control default stack size when creating a thread.
// If we use non-default stack size (pthread_attr_setstacksize), both
// floating stack and non-floating stack BsdThreads will return the
// same value. This makes it impossible to implement this function by
// detecting thread stack size directly.
//
// An alternative approach is to check %gs. Fixed-stack BsdThreads
// do not use %gs, so its value is 0. Floating-stack BsdThreads use
// %gs (either as LDT selector or GDT selector, depending on kernel)
// to access thread specific data.
//
// Note that %gs is a reserved glibc register since early 2001, so
// applications are not allowed to change its value (Ulrich Drepper from
// Redhat confirmed that all known offenders have been modified to use
// either %fs or TSD). In the worst case scenario, when VM is embedded in
// a native application that plays with %gs, we might see non-zero %gs
// even BsdThreads is running in fixed stack mode. As the result, we'll
// return true and skip _thread_safety_check(), so we may not be able to
// detect stack-heap collisions. But otherwise it's harmless.
//
#ifdef __GNUC__
return (GET_GS() != 0);
#else
return false;
#endif
}
}
#endif
#endif // AMD64
// return default stack size for thr_type
@ -943,7 +847,7 @@ static void current_stack_region(address * bottom, size_t * size) {
*bottom = (address)((char *)ss.ss_sp - ss.ss_size);
*size = ss.ss_size;
#elif defined(_ALLBSD_SOURCE)
#else
pthread_attr_t attr;
int rslt = pthread_attr_init(&attr);
@ -963,33 +867,6 @@ static void current_stack_region(address * bottom, size_t * size) {
}
pthread_attr_destroy(&attr);
#else
if (os::Bsd::is_initial_thread()) {
// initial thread needs special handling because pthread_getattr_np()
// may return bogus value.
*bottom = os::Bsd::initial_thread_stack_bottom();
*size = os::Bsd::initial_thread_stack_size();
} else {
pthread_attr_t attr;
int rslt = pthread_getattr_np(pthread_self(), &attr);
// JVM needs to know exact stack location, abort if it fails
if (rslt != 0) {
if (rslt == ENOMEM) {
vm_exit_out_of_memory(0, "pthread_getattr_np");
} else {
fatal(err_msg("pthread_getattr_np failed with errno = %d", rslt));
}
}
if (pthread_attr_getstack(&attr, (void **)bottom, size) != 0) {
fatal("Can not locate current stack attributes!");
}
pthread_attr_destroy(&attr);
}
#endif
assert(os::current_stack_pointer() >= *bottom &&
os::current_stack_pointer() < *bottom + *size, "just checking");

View File

@ -41,7 +41,6 @@ define_pd_global(intx, VMThreadStackSize, 512);
define_pd_global(intx, CompilerThreadStackSize, 0);
define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
define_pd_global(bool, UseVectoredExceptions, false);
// Used on 64 bit platforms for UseCompressedOops base address or CDS
define_pd_global(uintx, HeapBaseMinAddress, 2*G);

View File

@ -23,7 +23,7 @@
*
*/
#if defined(_ALLBSD_SOURCE) && !defined(__APPLE__) && !defined(__NetBSD__)
#if !defined(__APPLE__) && !defined(__NetBSD__)
#include <pthread.h>
# include <pthread_np.h> /* For pthread_attr_get_np */
#endif
@ -178,26 +178,6 @@ JVM_handle_bsd_signal(int sig,
thread->disable_stack_red_zone();
ShouldNotCallThis();
}
#ifndef _ALLBSD_SOURCE
else {
// Accessing stack address below sp may cause SEGV if
// current thread has MAP_GROWSDOWN stack. This should
// only happen when current thread was created by user
// code with MAP_GROWSDOWN flag and then attached to VM.
// See notes in os_bsd.cpp.
if (thread->osthread()->expanding_stack() == 0) {
thread->osthread()->set_expanding_stack();
if (os::Bsd::manually_expand_stack(thread, addr)) {
thread->osthread()->clear_expanding_stack();
return true;
}
thread->osthread()->clear_expanding_stack();
}
else {
fatal("recursive segv. expanding stack.");
}
}
#endif
}
}
@ -266,16 +246,6 @@ void os::Bsd::init_thread_fpu_state(void) {
// Nothing to do
}
#ifndef _ALLBSD_SOURCE
int os::Bsd::get_fpu_control_word() {
ShouldNotCallThis();
}
void os::Bsd::set_fpu_control_word(int fpu) {
ShouldNotCallThis();
}
#endif
bool os::is_allocatable(size_t bytes) {
#ifdef _LP64
return true;
@ -339,7 +309,7 @@ static void current_stack_region(address *bottom, size_t *size) {
stack_top = (address) ss.ss_sp;
stack_bytes = ss.ss_size;
stack_bottom = stack_top - stack_bytes;
#elif defined(_ALLBSD_SOURCE)
#else
pthread_attr_t attr;
int rslt = pthread_attr_init(&attr);
@ -362,67 +332,6 @@ static void current_stack_region(address *bottom, size_t *size) {
pthread_attr_destroy(&attr);
stack_top = stack_bottom + stack_bytes;
#else /* Linux */
pthread_attr_t attr;
int res = pthread_getattr_np(pthread_self(), &attr);
if (res != 0) {
if (res == ENOMEM) {
vm_exit_out_of_memory(0, "pthread_getattr_np");
}
else {
fatal(err_msg("pthread_getattr_np failed with errno = " INT32_FORMAT,
res));
}
}
res = pthread_attr_getstack(&attr, (void **) &stack_bottom, &stack_bytes);
if (res != 0) {
fatal(err_msg("pthread_attr_getstack failed with errno = " INT32_FORMAT,
res));
}
stack_top = stack_bottom + stack_bytes;
// The block of memory returned by pthread_attr_getstack() includes
// guard pages where present. We need to trim these off.
size_t page_bytes = os::Bsd::page_size();
assert(((intptr_t) stack_bottom & (page_bytes - 1)) == 0, "unaligned stack");
size_t guard_bytes;
res = pthread_attr_getguardsize(&attr, &guard_bytes);
if (res != 0) {
fatal(err_msg(
"pthread_attr_getguardsize failed with errno = " INT32_FORMAT, res));
}
int guard_pages = align_size_up(guard_bytes, page_bytes) / page_bytes;
assert(guard_bytes == guard_pages * page_bytes, "unaligned guard");
#ifdef IA64
// IA64 has two stacks sharing the same area of memory, a normal
// stack growing downwards and a register stack growing upwards.
// Guard pages, if present, are in the centre. This code splits
// the stack in two even without guard pages, though in theory
// there's nothing to stop us allocating more to the normal stack
// or more to the register stack if one or the other were found
// to grow faster.
int total_pages = align_size_down(stack_bytes, page_bytes) / page_bytes;
stack_bottom += (total_pages - guard_pages) / 2 * page_bytes;
#endif // IA64
stack_bottom += guard_bytes;
pthread_attr_destroy(&attr);
// The initial thread has a growable stack, and the size reported
// by pthread_attr_getstack is the maximum size it could possibly
// be given what currently mapped. This can be huge, so we cap it.
if (os::Bsd::is_initial_thread()) {
stack_bytes = stack_top - stack_bottom;
if (stack_bytes > JavaThread::stack_size_at_create())
stack_bytes = JavaThread::stack_size_at_create();
stack_bottom = stack_top - stack_bytes;
}
#endif
assert(os::current_stack_pointer() >= stack_bottom, "should do");

View File

@ -35,7 +35,5 @@ define_pd_global(intx, CompilerThreadStackSize, 0);
// Used on 64 bit platforms for UseCompressedOops base address or CDS
define_pd_global(uintx, HeapBaseMinAddress, CONST64(4)*G);
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);
#endif // OS_CPU_LINUX_SPARC_VM_GLOBALS_LINUX_SPARC_HPP

View File

@ -46,7 +46,5 @@ define_pd_global(uintx,JVMInvokeMethodSlack, 8192);
// Used on 64 bit platforms for UseCompressedOops base address or CDS
define_pd_global(uintx,HeapBaseMinAddress, 2*G);
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);
#endif // OS_CPU_LINUX_X86_VM_GLOBALS_LINUX_X86_HPP

View File

@ -41,7 +41,6 @@ define_pd_global(intx, VMThreadStackSize, 512);
define_pd_global(intx, CompilerThreadStackSize, 0);
define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
define_pd_global(bool, UseVectoredExceptions, false);
// Used on 64 bit platforms for UseCompressedOops base address or CDS
define_pd_global(uintx, HeapBaseMinAddress, 2*G);

View File

@ -39,8 +39,6 @@ define_pd_global(uintx, HeapBaseMinAddress, CONST64(4)*G);
#else
define_pd_global(uintx, HeapBaseMinAddress, 2*G);
#endif
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);

View File

@ -45,7 +45,5 @@ define_pd_global(intx, CompilerThreadStackSize, 0);
// Used on 64 bit platforms for UseCompressedOops base address or CDS
define_pd_global(uintx,HeapBaseMinAddress, 256*M);
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);
#endif // OS_CPU_SOLARIS_X86_VM_GLOBALS_SOLARIS_X86_HPP

View File

@ -47,7 +47,5 @@ define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
// Used on 64 bit platforms for UseCompressedOops base address or CDS
define_pd_global(uintx, HeapBaseMinAddress, 2*G);
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);
#endif // OS_CPU_WINDOWS_X86_VM_GLOBALS_WINDOWS_X86_HPP

View File

@ -175,9 +175,6 @@ bool os::register_code_area(char *low, char *high) {
PRUNTIME_FUNCTION prt;
PUNWIND_INFO_EH_ONLY punwind;
// If we are using Vectored Exceptions we don't need this registration
if (UseVectoredExceptions) return true;
BufferBlob* blob = BufferBlob::create("CodeCache Exception Handler", sizeof(DynamicCodeData));
CodeBuffer cb(blob);
MacroAssembler* masm = new MacroAssembler(&cb);

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

@ -758,7 +758,7 @@ void CodeBuffer::relocate_code_to(CodeBuffer* dest) const {
}
}
if (dest->blob() == NULL) {
if (dest->blob() == NULL && dest_filled != NULL) {
// Destination is a final resting place, not just another buffer.
// Normalize uninitialized bytes in the final padding.
Copy::fill_to_bytes(dest_filled, dest_end - dest_filled,

View File

@ -768,8 +768,8 @@ 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;
}
if (m != NULL) {
@ -1056,7 +1056,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);
}
}

View File

@ -105,7 +105,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.
@ -188,7 +188,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());

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");
@ -821,6 +827,9 @@ Array<Klass*>* ClassFileParser::parse_interfaces(constantPoolHandle cp,
if (!Klass::cast(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,13 +3823,13 @@ 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();
if (this_klass->java_super() != NULL) {
@ -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,
@ -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,

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

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

@ -1156,7 +1156,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 +1747,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

@ -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

@ -115,6 +115,7 @@
/* Java runtime version access */ \
template(sun_misc_Version, "sun/misc/Version") \
template(java_runtime_name_name, "java_runtime_name") \
template(java_runtime_version_name, "java_runtime_version") \
\
/* class file format tags */ \
template(tag_source_file, "SourceFile") \
@ -258,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

@ -829,7 +829,7 @@ 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;
}
@ -1160,7 +1160,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.
}

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;
}

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;

View File

@ -67,7 +67,7 @@ class MethodMatcher : public CHeapObj<mtCompiler> {
// utility method
MethodMatcher* find(methodHandle method) {
Symbol* class_name = Klass::cast(method->method_holder())->name();
Symbol* class_name = method->method_holder()->name();
Symbol* method_name = method->name();
for (MethodMatcher* current = this; current != NULL; current = current->_next) {
if (match(class_name, current->class_name(), current->_class_mode) &&
@ -624,7 +624,7 @@ void CompilerOracle::append_exclude_to_file(methodHandle method) {
assert(has_command_file(), "command file must be specified");
fileStream stream(fopen(cc_file(), "at"));
stream.print("exclude ");
Klass::cast(method->method_holder())->name()->print_symbol_on(&stream);
method->method_holder()->name()->print_symbol_on(&stream);
stream.print(".");
method->name()->print_symbol_on(&stream);
method->signature()->print_symbol_on(&stream);

View File

@ -55,16 +55,18 @@ void* Disassembler::_library = NULL;
bool Disassembler::_tried_to_load_library = false;
// This routine is in the shared library:
Disassembler::decode_func_virtual Disassembler::_decode_instructions_virtual = NULL;
Disassembler::decode_func Disassembler::_decode_instructions = NULL;
static const char hsdis_library_name[] = "hsdis-"HOTSPOT_LIB_ARCH;
static const char decode_instructions_name[] = "decode_instructions_virtual";
static const char decode_instructions_virtual_name[] = "decode_instructions_virtual";
static const char decode_instructions_name[] = "decode_instructions";
static bool use_new_version = true;
#define COMMENT_COLUMN 40 LP64_ONLY(+8) /*could be an option*/
#define BYTES_COMMENT ";..." /* funky byte display comment */
bool Disassembler::load_library() {
if (_decode_instructions != NULL) {
if (_decode_instructions_virtual != NULL || _decode_instructions != NULL) {
// Already succeeded.
return true;
}
@ -123,11 +125,19 @@ bool Disassembler::load_library() {
_library = os::dll_load(buf, ebuf, sizeof ebuf);
}
if (_library != NULL) {
_decode_instructions_virtual = CAST_TO_FN_PTR(Disassembler::decode_func_virtual,
os::dll_lookup(_library, decode_instructions_virtual_name));
}
if (_decode_instructions_virtual == NULL) {
// could not spot in new version, try old version
_decode_instructions = CAST_TO_FN_PTR(Disassembler::decode_func,
os::dll_lookup(_library, decode_instructions_name));
use_new_version = false;
} else {
use_new_version = true;
}
_tried_to_load_library = true;
if (_decode_instructions == NULL) {
if (_decode_instructions_virtual == NULL && _decode_instructions == NULL) {
tty->print_cr("Could not load %s; %s; %s", buf,
((_library != NULL)
? "entry point is missing"
@ -450,17 +460,31 @@ address decode_env::decode_instructions(address start, address end) {
// This is mainly for debugging the library itself.
FILE* out = stdout;
FILE* xmlout = (_print_raw > 1 ? out : NULL);
return (address)
(*Disassembler::_decode_instructions)((uintptr_t)start, (uintptr_t)end,
start, end - start,
return use_new_version ?
(address)
(*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end,
start, end - start,
NULL, (void*) xmlout,
NULL, (void*) out,
options(), 0/*nice new line*/)
:
(address)
(*Disassembler::_decode_instructions)(start, end,
NULL, (void*) xmlout,
NULL, (void*) out,
options());
}
return (address)
(*Disassembler::_decode_instructions)((uintptr_t)start, (uintptr_t)end,
start, end - start,
return use_new_version ?
(address)
(*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end,
start, end - start,
&event_to_env, (void*) this,
&printf_to_env, (void*) this,
options(), 0/*nice new line*/)
:
(address)
(*Disassembler::_decode_instructions)(start, end,
&event_to_env, (void*) this,
&printf_to_env, (void*) this,
options());

View File

@ -49,8 +49,16 @@ class Disassembler {
friend class decode_env;
private:
// this is the type of the dll entry point:
typedef void* (*decode_func)(uintptr_t start_va, uintptr_t end_va,
typedef void* (*decode_func_virtual)(uintptr_t start_va, uintptr_t end_va,
unsigned char* buffer, uintptr_t length,
void* (*event_callback)(void*, const char*, void*),
void* event_stream,
int (*printf_callback)(void*, const char*, ...),
void* printf_stream,
const char* options,
int newline);
// this is the type of the dll entry point for old version:
typedef void* (*decode_func)(void* start_va, void* end_va,
void* (*event_callback)(void*, const char*, void*),
void* event_stream,
int (*printf_callback)(void*, const char*, ...),
@ -61,6 +69,7 @@ class Disassembler {
// bailout
static bool _tried_to_load_library;
// points to the decode function.
static decode_func_virtual _decode_instructions_virtual;
static decode_func _decode_instructions;
// tries to load library and return whether it succedded.
static bool load_library();
@ -85,7 +94,9 @@ class Disassembler {
public:
static bool can_decode() {
return (_decode_instructions != NULL) || load_library();
return (_decode_instructions_virtual != NULL) ||
(_decode_instructions != NULL) ||
load_library();
}
static void decode(CodeBlob *cb, outputStream* st = NULL);
static void decode(nmethod* nm, outputStream* st = NULL);

View File

@ -320,6 +320,7 @@ class AbstractInterpreterGenerator: public StackObj {
void bang_stack_shadow_pages(bool native_call);
void generate_all();
void initialize_method_handle_entries();
public:
AbstractInterpreterGenerator(StubQueue* _code);

View File

@ -235,10 +235,6 @@
#endif
#endif
// JavaStack Implementation
#define MORE_STACK(count) \
(topOfStack -= ((count) * Interpreter::stackElementWords))
#define UPDATE_PC(opsize) {pc += opsize; }
/*
@ -575,7 +571,7 @@ BytecodeInterpreter::run(interpreterState istate) {
/* 0xE0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default,
/* 0xE4 */ &&opc_default, &&opc_fast_aldc, &&opc_fast_aldc_w, &&opc_return_register_finalizer,
/* 0xE8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default,
/* 0xE8 */ &&opc_invokehandle,&&opc_default, &&opc_default, &&opc_default,
/* 0xEC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default,
/* 0xF0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default,
@ -1773,7 +1769,7 @@ run:
oop obj;
if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) {
Klass* k = (Klass*) cache->f1();
Klass* k = cache->f1_as_klass();
obj = k->java_mirror();
MORE_STACK(1); // Assume single slot push
} else {
@ -1885,7 +1881,7 @@ run:
--count;
}
if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) {
Klass* k = (Klass*) cache->f1();
Klass* k = cache->f1_as_klass();
obj = k->java_mirror();
} else {
--count;
@ -2190,6 +2186,7 @@ run:
}
CASE(_invokedynamic): {
if (!EnableInvokeDynamic) {
// We should not encounter this bytecode if !EnableInvokeDynamic.
// The verifier will stop it. However, if we get past the verifier,
@ -2199,30 +2196,68 @@ run:
ShouldNotReachHere();
}
int index = Bytes::get_native_u4(pc+1);
u4 index = Bytes::get_native_u4(pc+1);
ConstantPoolCacheEntry* cache = cp->constant_pool()->invokedynamic_cp_cache_entry_at(index);
// We are resolved if the resolved_references field contains a non-null object (CallSite, etc.)
// This kind of CP cache entry does not need to match the flags byte, because
// there is a 1-1 relation between bytecode type and CP entry type.
ConstantPool* constants = METHOD->constants();
oop result = constants->resolved_references()->obj_at(index);
if (result == NULL) {
if (! cache->is_resolved((Bytecodes::Code) opcode)) {
CALL_VM(InterpreterRuntime::resolve_invokedynamic(THREAD),
handle_exception);
result = THREAD->vm_result();
cache = cp->constant_pool()->invokedynamic_cp_cache_entry_at(index);
}
VERIFY_OOP(result);
oop method_handle = java_lang_invoke_CallSite::target(result);
CHECK_NULL(method_handle);
Method* method = cache->f1_as_method();
VERIFY_OOP(method);
istate->set_msg(call_method_handle);
istate->set_callee((Method*) method_handle);
if (cache->has_appendix()) {
ConstantPool* constants = METHOD->constants();
SET_STACK_OBJECT(cache->appendix_if_resolved(constants), 0);
MORE_STACK(1);
}
istate->set_msg(call_method);
istate->set_callee(method);
istate->set_callee_entry_point(method->from_interpreted_entry());
istate->set_bcp_advance(5);
UPDATE_PC_AND_RETURN(0); // I'll be back...
}
CASE(_invokehandle): {
if (!EnableInvokeDynamic) {
ShouldNotReachHere();
}
u2 index = Bytes::get_native_u2(pc+1);
ConstantPoolCacheEntry* cache = cp->entry_at(index);
if (! cache->is_resolved((Bytecodes::Code) opcode)) {
CALL_VM(InterpreterRuntime::resolve_invokehandle(THREAD),
handle_exception);
cache = cp->entry_at(index);
}
Method* method = cache->f1_as_method();
VERIFY_OOP(method);
if (cache->has_appendix()) {
ConstantPool* constants = METHOD->constants();
SET_STACK_OBJECT(cache->appendix_if_resolved(constants), 0);
MORE_STACK(1);
}
istate->set_msg(call_method);
istate->set_callee(method);
istate->set_callee_entry_point(method->from_interpreted_entry());
istate->set_bcp_advance(3);
UPDATE_PC_AND_RETURN(0); // I'll be back...
}
CASE(_invokeinterface): {
u2 index = Bytes::get_native_u2(pc+1);

View File

@ -50,6 +50,10 @@
#ifdef CC_INTERP
// JavaStack Implementation
#define MORE_STACK(count) \
(topOfStack -= ((count) * Interpreter::stackElementWords))
// CVM definitions find hotspot equivalents...
union VMJavaVal64 {
@ -107,7 +111,6 @@ public:
rethrow_exception, // unwinding and throwing exception
// requests to frame manager from C++ interpreter
call_method, // request for new frame from interpreter, manager responds with method_entry
call_method_handle, // like the above, except the callee is a method handle
return_from_method, // request from interpreter to unwind, manager responds with method_continue
more_monitors, // need a new monitor
throwing_exception, // unwind stack and rethrow

View File

@ -117,7 +117,6 @@ void CppInterpreterGenerator::generate_all() {
method_entry(empty);
method_entry(accessor);
method_entry(abstract);
method_entry(method_handle);
method_entry(java_lang_math_sin );
method_entry(java_lang_math_cos );
method_entry(java_lang_math_tan );
@ -125,7 +124,12 @@ void CppInterpreterGenerator::generate_all() {
method_entry(java_lang_math_sqrt );
method_entry(java_lang_math_log );
method_entry(java_lang_math_log10 );
method_entry(java_lang_math_pow );
method_entry(java_lang_math_exp );
method_entry(java_lang_ref_reference_get);
initialize_method_handle_entries();
Interpreter::_native_entry_begin = Interpreter::code()->code_end();
method_entry(native);
method_entry(native_synchronized);

View File

@ -464,3 +464,11 @@ void AbstractInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
}
}
}
void AbstractInterpreterGenerator::initialize_method_handle_entries() {
// method handle entry kinds are generated later in MethodHandlesAdapterGenerator::generate:
for (int i = Interpreter::method_handle_invoke_FIRST; i <= Interpreter::method_handle_invoke_LAST; i++) {
Interpreter::MethodKind kind = (Interpreter::MethodKind) i;
Interpreter::_entry_table[kind] = Interpreter::_entry_table[Interpreter::abstract];
}
}

View File

@ -733,12 +733,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invokehandle(JavaThread* thread)) {
get_index_u2_cpcache(thread, bytecode), bytecode, CHECK);
} // end JvmtiHideSingleStepping
cache_entry(thread)->set_method_handle(
pool,
info.resolved_method(),
info.resolved_appendix(),
info.resolved_method_type(),
pool->resolved_references());
cache_entry(thread)->set_method_handle(pool, info);
}
IRT_END
@ -762,12 +757,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) {
} // end JvmtiHideSingleStepping
ConstantPoolCacheEntry* cp_cache_entry = pool->invokedynamic_cp_cache_entry_at(index);
cp_cache_entry->set_dynamic_call(
pool,
info.resolved_method(),
info.resolved_appendix(),
info.resolved_method_type(),
pool->resolved_references());
cp_cache_entry->set_dynamic_call(pool, info);
}
IRT_END

View File

@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
#include "classfile/defaultMethods.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "compiler/compileBroker.hpp"
@ -132,7 +133,7 @@ void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass
// don't force compilation, resolve was on behalf of compiler
return;
}
if (InstanceKlass::cast(selected_method->method_holder())->is_not_initialized()) {
if (selected_method->method_holder()->is_not_initialized()) {
// 'is_not_initialized' means not only '!is_initialized', but also that
// initialization has not been started yet ('!being_initialized')
// Do not force compilation of methods in uninitialized classes.
@ -404,21 +405,13 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
Symbol* method_name, Symbol* method_signature,
KlassHandle current_klass, bool check_access, TRAPS) {
// 1. check if klass is not interface
if (resolved_klass->is_interface()) {
ResourceMark rm(THREAD);
char buf[200];
jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", Klass::cast(resolved_klass())->external_name());
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
Handle nested_exception;
// 2. lookup method in resolved klass and its super klasses
// 1. lookup method in resolved klass and its super klasses
lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
if (resolved_method.is_null()) { // not found in the class hierarchy
// 3. lookup method in all the interfaces implemented by the resolved klass
// 2. lookup method in all the interfaces implemented by the resolved klass
lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
if (resolved_method.is_null()) {
@ -432,7 +425,7 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
}
if (resolved_method.is_null()) {
// 4. method lookup failed
// 3. method lookup failed
ResourceMark rm(THREAD);
THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
@ -442,6 +435,15 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
}
}
// 4. check if klass is not interface
if (resolved_klass->is_interface() && resolved_method->is_abstract()) {
ResourceMark rm(THREAD);
char buf[200];
jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
resolved_klass()->external_name());
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
// 5. check if method is concrete
if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) {
ResourceMark rm(THREAD);
@ -464,7 +466,7 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
// check loader constraints
Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
Handle class_loader (THREAD, InstanceKlass::cast(resolved_method->method_holder())->class_loader());
Handle class_loader (THREAD, resolved_method->method_holder()->class_loader());
{
ResourceMark rm(THREAD);
char* failed_type_name =
@ -526,7 +528,7 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
if (check_access) {
HandleMark hm(THREAD);
Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
Handle class_loader (THREAD, InstanceKlass::cast(resolved_method->method_holder())->class_loader());
Handle class_loader (THREAD, resolved_method->method_holder()->class_loader());
{
ResourceMark rm(THREAD);
char* failed_type_name =
@ -743,6 +745,27 @@ void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method
Symbol* method_name, Symbol* method_signature,
KlassHandle current_klass, bool check_access, TRAPS) {
if (resolved_klass->is_interface() && current_klass() != NULL) {
// If the target class is a direct interface, treat this as a "super"
// default call.
//
// If the current method is an overpass that happens to call a direct
// super-interface's method, then we'll end up rerunning the default method
// analysis even though we don't need to, but that's ok since it will end
// up with the same answer.
InstanceKlass* ik = InstanceKlass::cast(current_klass());
Array<Klass*>* interfaces = ik->local_interfaces();
int num_interfaces = interfaces->length();
for (int index = 0; index < num_interfaces; index++) {
if (interfaces->at(index) == resolved_klass()) {
Method* method = DefaultMethods::find_super_default(current_klass(),
resolved_klass(), method_name, method_signature, CHECK);
resolved_method = methodHandle(THREAD, method);
return;
}
}
}
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
// check if method name is <init>, that it is found in same klass as static type
@ -784,11 +807,17 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle
{ KlassHandle method_klass = KlassHandle(THREAD,
resolved_method->method_holder());
if (check_access &&
const bool direct_calling_default_method =
resolved_klass() != NULL && resolved_method() != NULL &&
resolved_klass->is_interface() && !resolved_method->is_abstract();
if (!direct_calling_default_method &&
check_access &&
// a) check if ACC_SUPER flag is set for the current class
current_klass->is_super() &&
// b) check if the method class is a superclass of the current class (superclass relation is not reflexive!)
current_klass->is_subtype_of(method_klass()) && current_klass() != method_klass() &&
current_klass->is_subtype_of(method_klass()) &&
current_klass() != method_klass() &&
// c) check if the method is not <init>
resolved_method->name() != vmSymbols::object_initializer_name()) {
// Lookup super method
@ -881,12 +910,12 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
// Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s
// has not been rewritten, and the vtable initialized.
assert(InstanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked");
assert(resolved_method->method_holder()->is_linked(), "must be linked");
// Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s
// has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since
// a missing receiver might result in a bogus lookup.
assert(InstanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked");
assert(resolved_method->method_holder()->is_linked(), "must be linked");
// do lookup based on receiver klass using the vtable index
if (resolved_method->method_holder()->is_interface()) { // miranda method

View File

@ -373,11 +373,7 @@ void TemplateInterpreterGenerator::generate_all() {
method_entry(java_lang_math_pow )
method_entry(java_lang_ref_reference_get)
// method handle entry kinds are generated later in MethodHandlesAdapterGenerator::generate:
for (int i = Interpreter::method_handle_invoke_FIRST; i <= Interpreter::method_handle_invoke_LAST; i++) {
Interpreter::MethodKind kind = (Interpreter::MethodKind) i;
Interpreter::_entry_table[kind] = Interpreter::_entry_table[Interpreter::abstract];
}
initialize_method_handle_entries();
// all native method kinds (must be one contiguous block)
Interpreter::_native_entry_begin = Interpreter::code()->code_end();

View File

@ -742,6 +742,8 @@ MetaWord* CollectorPolicy::satisfy_failed_metadata_allocation(
uint gc_count = 0;
uint full_gc_count = 0;
assert(!Heap_lock->owned_by_self(), "Should not be holding the Heap_lock");
do {
MetaWord* result = NULL;
if (GC_locker::is_active_and_needs_gc()) {
@ -756,7 +758,6 @@ MetaWord* CollectorPolicy::satisfy_failed_metadata_allocation(
}
JavaThread* jthr = JavaThread::current();
if (!jthr->in_critical()) {
MutexUnlocker mul(Heap_lock);
// Wait for JNI critical section to be exited
GC_locker::stall_until_clear();
// The GC invoked by the last thread leaving the critical

View File

@ -34,29 +34,30 @@ const u2 ConstMethod::MAX_IDNUM = 0xFFFE;
const u2 ConstMethod::UNSET_IDNUM = 0xFFFF;
ConstMethod* ConstMethod::allocate(ClassLoaderData* loader_data,
int byte_code_size,
int compressed_line_number_size,
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
TRAPS) {
int byte_code_size,
int compressed_line_number_size,
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
MethodType method_type,
TRAPS) {
int size = ConstMethod::size(byte_code_size,
compressed_line_number_size,
localvariable_table_length,
exception_table_length,
checked_exceptions_length);
return new (loader_data, size, true, THREAD) ConstMethod(
byte_code_size, compressed_line_number_size,
localvariable_table_length, exception_table_length,
checked_exceptions_length, size);
byte_code_size, compressed_line_number_size, localvariable_table_length,
exception_table_length, checked_exceptions_length, method_type, size);
}
ConstMethod::ConstMethod(int byte_code_size,
int compressed_line_number_size,
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
int size) {
int compressed_line_number_size,
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
MethodType method_type,
int size) {
No_Safepoint_Verifier no_safepoint;
set_interpreter_kind(Interpreter::invalid);
@ -69,6 +70,7 @@ ConstMethod::ConstMethod(int byte_code_size,
compressed_line_number_size,
localvariable_table_length,
exception_table_length);
set_method_type(method_type);
assert(this->size() == size, "wrong size for object");
}
@ -111,8 +113,7 @@ int ConstMethod::size(int code_size,
}
Method* ConstMethod::method() const {
return InstanceKlass::cast(_constants->pool_holder())->method_with_idnum(
_method_idnum);
return _constants->pool_holder()->method_with_idnum(_method_idnum);
}
// linenumber table - note that length is unknown until decompression,

View File

@ -108,12 +108,17 @@ class ExceptionTableElement VALUE_OBJ_CLASS_SPEC {
class ConstMethod : public MetaspaceObj {
friend class VMStructs;
public:
typedef enum { NORMAL, OVERPASS } MethodType;
private:
enum {
_has_linenumber_table = 1,
_has_checked_exceptions = 2,
_has_localvariable_table = 4,
_has_exception_table = 8
_has_exception_table = 8,
_is_overpass = 16
};
// Bit vector of signature
@ -145,19 +150,22 @@ private:
// Constructor
ConstMethod(int byte_code_size,
int compressed_line_number_size,
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
int size);
int compressed_line_number_size,
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
MethodType is_overpass,
int size);
public:
static ConstMethod* allocate(ClassLoaderData* loader_data,
int byte_code_size,
int compressed_line_number_size,
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
TRAPS);
int byte_code_size,
int compressed_line_number_size,
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
MethodType mt,
TRAPS);
bool is_constMethod() const { return true; }
@ -179,6 +187,19 @@ public:
bool has_exception_handler() const
{ return (_flags & _has_exception_table) != 0; }
MethodType method_type() const {
return ((_flags & _is_overpass) == 0) ? NORMAL : OVERPASS;
}
void set_method_type(MethodType mt) {
if (mt == NORMAL) {
_flags &= ~(_is_overpass);
} else {
_flags |= _is_overpass;
}
}
void set_interpreter_kind(int kind) { _interpreter_kind = kind; }
int interpreter_kind(void) const { return _interpreter_kind; }

View File

@ -228,7 +228,7 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS
} else {
do_resolve = true;
name = this_oop->unresolved_klass_at(which);
loader = Handle(THREAD, InstanceKlass::cast(this_oop->pool_holder())->class_loader());
loader = Handle(THREAD, this_oop->pool_holder()->class_loader());
}
}
} // unlocking constantPool
@ -247,7 +247,7 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS
if (do_resolve) {
// this_oop must be unlocked during resolve_or_fail
oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain();
oop protection_domain = this_oop->pool_holder()->protection_domain();
Handle h_prot (THREAD, protection_domain);
Klass* k_oop = SystemDictionary::resolve_or_fail(name, loader, h_prot, true, THREAD);
KlassHandle k;
@ -315,7 +315,7 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS
vframeStream vfst(JavaThread::current());
if (!vfst.at_end()) {
line_number = vfst.method()->line_number_from_bci(vfst.bci());
Symbol* s = InstanceKlass::cast(vfst.method()->method_holder())->source_file_name();
Symbol* s = vfst.method()->method_holder()->source_file_name();
if (s != NULL) {
source_file = s->as_C_string();
}
@ -325,11 +325,11 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS
// only print something if the classes are different
if (source_file != NULL) {
tty->print("RESOLVE %s %s %s:%d\n",
InstanceKlass::cast(this_oop->pool_holder())->external_name(),
this_oop->pool_holder()->external_name(),
InstanceKlass::cast(k())->external_name(), source_file, line_number);
} else {
tty->print("RESOLVE %s %s\n",
InstanceKlass::cast(this_oop->pool_holder())->external_name(),
this_oop->pool_holder()->external_name(),
InstanceKlass::cast(k())->external_name());
}
}
@ -339,7 +339,7 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS
// Only updated constant pool - if it is resolved.
do_resolve = this_oop->tag_at(which).is_unresolved_klass();
if (do_resolve) {
ClassLoaderData* this_key = InstanceKlass::cast(this_oop->pool_holder())->class_loader_data();
ClassLoaderData* this_key = this_oop->pool_holder()->class_loader_data();
if (!this_key->is_the_null_class_loader_data()) {
this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM
}
@ -367,8 +367,8 @@ Klass* ConstantPool::klass_at_if_loaded(constantPoolHandle this_oop, int which)
assert(entry.is_unresolved(), "must be either symbol or klass");
Thread *thread = Thread::current();
Symbol* name = entry.get_symbol();
oop loader = InstanceKlass::cast(this_oop->pool_holder())->class_loader();
oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain();
oop loader = this_oop->pool_holder()->class_loader();
oop protection_domain = this_oop->pool_holder()->protection_domain();
Handle h_prot (thread, protection_domain);
Handle h_loader (thread, loader);
Klass* k = SystemDictionary::find(name, h_loader, h_prot, thread);
@ -409,8 +409,8 @@ Klass* ConstantPool::klass_ref_at_if_loaded_check(constantPoolHandle this_oop, i
} else {
assert(entry.is_unresolved(), "must be either symbol or klass");
Symbol* name = entry.get_symbol();
oop loader = InstanceKlass::cast(this_oop->pool_holder())->class_loader();
oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain();
oop loader = this_oop->pool_holder()->class_loader();
oop protection_domain = this_oop->pool_holder()->protection_domain();
Handle h_loader(THREAD, loader);
Handle h_prot (THREAD, protection_domain);
KlassHandle k(THREAD, SystemDictionary::find(name, h_loader, h_prot, THREAD));
@ -1143,16 +1143,21 @@ void ConstantPool::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int
int from_oplen = operand_array_length(from_cp->operands());
int old_oplen = operand_array_length(to_cp->operands());
if (from_oplen != 0) {
ClassLoaderData* loader_data = to_cp->pool_holder()->class_loader_data();
// append my operands to the target's operands array
if (old_oplen == 0) {
to_cp->set_operands(from_cp->operands()); // reuse; do not merge
// Can't just reuse from_cp's operand list because of deallocation issues
int len = from_cp->operands()->length();
Array<u2>* new_ops = MetadataFactory::new_array<u2>(loader_data, len, CHECK);
Copy::conjoint_memory_atomic(
from_cp->operands()->adr_at(0), new_ops->adr_at(0), len * sizeof(u2));
to_cp->set_operands(new_ops);
} else {
int old_len = to_cp->operands()->length();
int from_len = from_cp->operands()->length();
int old_off = old_oplen * sizeof(u2);
int from_off = from_oplen * sizeof(u2);
// Use the metaspace for the destination constant pool
ClassLoaderData* loader_data = to_cp->pool_holder()->class_loader_data();
Array<u2>* new_operands = MetadataFactory::new_array<u2>(loader_data, old_len + from_len, CHECK);
int fillp = 0, len = 0;
// first part of dest
@ -1785,7 +1790,7 @@ void ConstantPool::patch_resolved_references(
assert(cp_patches->at(index).is_null(),
err_msg("Unused constant pool patch at %d in class file %s",
index,
InstanceKlass::cast(pool_holder())->external_name()));
pool_holder()->external_name()));
}
#endif // ASSERT
}
@ -1943,7 +1948,7 @@ void ConstantPool::print_value_on(outputStream* st) const {
st->print(" for ");
pool_holder()->print_value_on(st);
if (pool_holder() != NULL) {
bool extra = (InstanceKlass::cast(pool_holder())->constants() != this);
bool extra = (pool_holder()->constants() != this);
if (extra) st->print(" (extra)");
}
if (cache() != NULL) {

View File

@ -86,8 +86,8 @@ class ConstantPool : public Metadata {
friend class Universe; // For null constructor
private:
Array<u1>* _tags; // the tag array describing the constant pool's contents
ConstantPoolCache* _cache; // the cache holding interpreter runtime information
Klass* _pool_holder; // the corresponding class
ConstantPoolCache* _cache; // the cache holding interpreter runtime information
InstanceKlass* _pool_holder; // the corresponding class
Array<u2>* _operands; // for variable-sized (InvokeDynamic) nodes, usually empty
// Array of resolved objects from the constant pool and map from resolved
@ -193,9 +193,9 @@ class ConstantPool : public Metadata {
void set_on_stack(const bool value);
// Klass holding pool
Klass* pool_holder() const { return _pool_holder; }
void set_pool_holder(Klass* k) { _pool_holder = k; }
Klass** pool_holder_addr() { return &_pool_holder; }
InstanceKlass* pool_holder() const { return _pool_holder; }
void set_pool_holder(InstanceKlass* k) { _pool_holder = k; }
InstanceKlass** pool_holder_addr() { return &_pool_holder; }
// Interpreter runtime support
ConstantPoolCache* cache() const { return _cache; }

View File

@ -231,8 +231,8 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index) {
Klass* interf = method->method_holder();
assert(InstanceKlass::cast(interf)->is_interface(), "must be an interface");
InstanceKlass* interf = method->method_holder();
assert(interf->is_interface(), "must be an interface");
assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here");
set_f1(interf);
set_f2(index);
@ -243,25 +243,17 @@ void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index)
}
void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool,
methodHandle adapter,
Handle appendix, Handle method_type,
objArrayHandle resolved_references) {
set_method_handle_common(cpool, Bytecodes::_invokehandle, adapter, appendix, method_type, resolved_references);
void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool, const CallInfo &call_info) {
set_method_handle_common(cpool, Bytecodes::_invokehandle, call_info);
}
void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool,
methodHandle adapter,
Handle appendix, Handle method_type,
objArrayHandle resolved_references) {
set_method_handle_common(cpool, Bytecodes::_invokedynamic, adapter, appendix, method_type, resolved_references);
void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool, const CallInfo &call_info) {
set_method_handle_common(cpool, Bytecodes::_invokedynamic, call_info);
}
void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
Bytecodes::Code invoke_code,
methodHandle adapter,
Handle appendix, Handle method_type,
objArrayHandle resolved_references) {
const CallInfo &call_info) {
// NOTE: This CPCE can be the subject of data races.
// There are three words to update: flags, refs[f2], f1 (in that order).
// Writers must store all other values before f1.
@ -276,6 +268,9 @@ void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
return;
}
const methodHandle adapter = call_info.resolved_method();
const Handle appendix = call_info.resolved_appendix();
const Handle method_type = call_info.resolved_method_type();
const bool has_appendix = appendix.not_null();
const bool has_method_type = method_type.not_null();
@ -315,6 +310,7 @@ void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
// This allows us to create fewer method oops, while keeping type safety.
//
objArrayHandle resolved_references = cpool->resolved_references();
// Store appendix, if any.
if (has_appendix) {
const int appendix_index = f2_as_index() + _indy_resolved_references_appendix_offset;
@ -421,7 +417,7 @@ bool ConstantPoolCacheEntry::adjust_method_entry(Method* old_method,
if (!(*trace_name_printed)) {
// RC_TRACE_MESG macro has an embedded ResourceMark
RC_TRACE_MESG(("adjust: name=%s",
Klass::cast(old_method->method_holder())->external_name()));
old_method->method_holder()->external_name()));
*trace_name_printed = true;
}
// RC_TRACE macro has an embedded ResourceMark
@ -449,7 +445,7 @@ bool ConstantPoolCacheEntry::adjust_method_entry(Method* old_method,
if (!(*trace_name_printed)) {
// RC_TRACE_MESG macro has an embedded ResourceMark
RC_TRACE_MESG(("adjust: name=%s",
Klass::cast(old_method->method_holder())->external_name()));
old_method->method_holder()->external_name()));
*trace_name_printed = true;
}
// RC_TRACE macro has an embedded ResourceMark

View File

@ -117,6 +117,8 @@ class PSPromotionManager;
// The fields are volatile so that they are stored in the order written in the
// source code. The _indices field with the bytecode must be written last.
class CallInfo;
class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
friend class constantPoolCacheKlass;
@ -223,18 +225,12 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
void set_method_handle(
constantPoolHandle cpool, // holding constant pool (required for locking)
methodHandle method, // adapter for invokeExact, etc.
Handle appendix, // stored in refs[f2+0]; could be a java.lang.invoke.MethodType
Handle method_type, // stored in refs[f2+1]; is a java.lang.invoke.MethodType
objArrayHandle resolved_references
const CallInfo &call_info // Call link information
);
void set_dynamic_call(
constantPoolHandle cpool, // holding constant pool (required for locking)
methodHandle method, // adapter for this call site
Handle appendix, // stored in refs[f2+0]; could be a java.lang.invoke.CallSite
Handle method_type, // stored in refs[f2+1]; is a java.lang.invoke.MethodType
objArrayHandle resolved_references
const CallInfo &call_info // Call link information
);
// Common code for invokedynamic and MH invocations.
@ -255,10 +251,7 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
void set_method_handle_common(
constantPoolHandle cpool, // holding constant pool (required for locking)
Bytecodes::Code invoke_code, // _invokehandle or _invokedynamic
methodHandle adapter, // invoker method (f1)
Handle appendix, // appendix such as CallSite, MethodType, etc. (refs[f2+0])
Handle method_type, // MethodType (refs[f2+1])
objArrayHandle resolved_references
const CallInfo &call_info // Call link information
);
// invokedynamic and invokehandle call sites have two entries in the

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