diff --git a/.hgtags b/.hgtags
index 88b9530dfc8..25e7a3c7d92 100644
--- a/.hgtags
+++ b/.hgtags
@@ -211,3 +211,5 @@ da9a4c9312816451884aa6db6f18be51a07bff13 jdk8-b86
5ebf6c63714de2c9dcf831074086d31daec819df jdk8-b87
e517701a4d0e25ae9c7945bca6e1762a8c5d8aa6 jdk8-b88
4dec41b3c5e3bb616f0c6f15830d940905aa5d16 jdk8-b89
+f09ab0c416185e3cba371e81bcb6a16060c90f44 jdk8-b90
+80b6c3172dc2cfceb022411292d290a967f9c728 jdk8-b91
diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index 3d22910518e..dc47bb707b1 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -211,3 +211,5 @@ df9b5240f0a76c91cfe1a5b39da4d08df56e05be jdk8-b86
b9415faa7066a4d3b16d466556d5428446918d95 jdk8-b87
e1a929afcfc492470d50be0b6b0e8dc77d3760b9 jdk8-b88
892a0196d10c67f3a12f0eefb0bb536e423d8868 jdk8-b89
+69b773a221b956a3386933ecdbfeccee0edeac47 jdk8-b90
+cb51fb4789ac0b8be4056482077ddfb8f3bd3805 jdk8-b91
diff --git a/NewMakefile.gmk b/NewMakefile.gmk
index b02e37f6a4d..033183289ff 100644
--- a/NewMakefile.gmk
+++ b/NewMakefile.gmk
@@ -73,7 +73,7 @@ else
grep ^.PHONY: | head -n 1 | cut -d " " -f 2-)))
$(all_phony_targets):
- @$(foreach spec,$(SPEC),($(MAKE) -f NewMakefile.gmk SPEC=$(spec) $(VERBOSE) VERBOSE=$(VERBOSE) $@) &&) true
+ @$(foreach spec,$(SPEC),($(MAKE) -f NewMakefile.gmk SPEC=$(spec) $(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) $@) &&) true
endif
endif
diff --git a/common/autoconf/basics.m4 b/common/autoconf/basics.m4
index 20f444ff702..305424db718 100644
--- a/common/autoconf/basics.m4
+++ b/common/autoconf/basics.m4
@@ -23,14 +23,23 @@
# questions.
#
+# Test if $1 is a valid argument to $3 (often is $JAVA passed as $3)
+# If so, then append $1 to $2\
+# Also set JVM_ARG_OK to true/false depending on outcome.
AC_DEFUN([ADD_JVM_ARG_IF_OK],
[
- # Test if $1 is a valid argument to $3 (often is $JAVA passed as $3)
- # If so, then append $1 to $2
- FOUND_WARN=`$3 $1 -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$3 $1 -version 2>&1 | grep " version \""`
+ $ECHO "Check if jvm arg is ok: $1" >&AS_MESSAGE_LOG_FD
+ $ECHO "Command: $3 $1 -version" >&AS_MESSAGE_LOG_FD
+ OUTPUT=`$3 $1 -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
$2="[$]$2 $1"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&AS_MESSAGE_LOG_FD
+ $ECHO "$OUTPUT" >&AS_MESSAGE_LOG_FD
+ JVM_ARG_OK=false
fi
])
@@ -51,16 +60,19 @@ AC_DEFUN([BASIC_FIXUP_PATH],
else
# We're on a posix platform. Hooray! :)
path="[$]$1"
-
- if test ! -f "$path" && test ! -d "$path"; then
- AC_MSG_ERROR([The path of $1, which resolves as "$path", is not found.])
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
AC_MSG_NOTICE([The path of $1, which resolves as "$path", is invalid.])
AC_MSG_ERROR([Spaces are not allowed in this path.])
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ AC_MSG_ERROR([The path of $1, which resolves as "$path", is not found.])
+ fi
+
+ $1="`cd "$path"; $THEPWDCMD`"
fi
])
diff --git a/common/autoconf/build-performance.m4 b/common/autoconf/build-performance.m4
index 12075413070..e7d6364edff 100644
--- a/common/autoconf/build-performance.m4
+++ b/common/autoconf/build-performance.m4
@@ -278,60 +278,37 @@ else
fi
AC_SUBST(SJAVAC_SERVER_JAVA)
-AC_ARG_WITH(sjavac-server-cores, [AS_HELP_STRING([--with-sjavac-server-cores],
- [use at most this number of concurrent threads on the sjavac server @<:@probed@:>@])])
-if test "x$with_sjavac_server_cores" != x; then
- SJAVAC_SERVER_CORES="$with_sjavac_server_cores"
-else
- if test "$NUM_CORES" -gt 16; then
- # We set this arbitrary limit because we want to limit the heap
- # size of the javac server.
- # In the future we will make the javac compilers in the server
- # share more and more state, thus enabling us to use more and
- # more concurrent threads in the server.
- SJAVAC_SERVER_CORES="16"
- else
- SJAVAC_SERVER_CORES="$NUM_CORES"
+if test "$MEMORY_SIZE" -gt "2500"; then
+ ADD_JVM_ARG_IF_OK([-d64],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
+ if test "$JVM_ARG_OK" = true; then
+ JVM_64BIT=true
+ JVM_ARG_OK=false
+ fi
fi
+if test "$JVM_64BIT" = true; then
if test "$MEMORY_SIZE" -gt "17000"; then
- MAX_HEAP_MEM=10000
- ADD_JVM_ARG_IF_OK([-d64],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
ADD_JVM_ARG_IF_OK([-Xms10G -Xmx10G],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
- elif test "$MEMORY_SIZE" -gt "10000"; then
- MAX_HEAP_MEM=6000
- ADD_JVM_ARG_IF_OK([-d64],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
+ fi
+ if test "$MEMORY_SIZE" -gt "10000" && test "$JVM_ARG_OK" = false; then
ADD_JVM_ARG_IF_OK([-Xms6G -Xmx6G],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
- elif test "$MEMORY_SIZE" -gt "5000"; then
- MAX_HEAP_MEM=3000
- ADD_JVM_ARG_IF_OK([-d64],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
+ fi
+ if test "$MEMORY_SIZE" -gt "5000" && test "$JVM_ARG_OK" = false; then
ADD_JVM_ARG_IF_OK([-Xms1G -Xmx3G],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
- elif test "$MEMORY_SIZE" -gt "3800"; then
- MAX_HEAP_MEM=2500
+ fi
+ if test "$MEMORY_SIZE" -gt "3800" && test "$JVM_ARG_OK" = false; then
ADD_JVM_ARG_IF_OK([-Xms1G -Xmx2500M],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
- elif test "$MEMORY_SIZE" -gt "1900"; then
- MAX_HEAP_MEM=1200
- ADD_JVM_ARG_IF_OK([-Xms700M -Xmx1400M],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
- elif test "$MEMORY_SIZE" -gt "1000"; then
- MAX_HEAP_MEM=900
- ADD_JVM_ARG_IF_OK([-Xms400M -Xmx1100M],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
- else
- MAX_HEAP_MEM=512
- ADD_JVM_ARG_IF_OK([-Xms256M -Xmx512M],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
fi
-
- ADD_JVM_ARG_IF_OK([-XX:PermSize=32m],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
- ADD_JVM_ARG_IF_OK([-XX:MaxPermSize=160m],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
- ADD_JVM_ARG_IF_OK([-XX:ThreadStackSize=$STACK_SIZE],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
-
- MAX_COMPILERS_IN_HEAP=`expr $MAX_HEAP_MEM / 501`
- if test "$SJAVAC_SERVER_CORES" -gt "$MAX_COMPILERS_IN_HEAP"; then
- AC_MSG_CHECKING([if number of server cores must be reduced])
- SJAVAC_SERVER_CORES="$MAX_COMPILERS_IN_HEAP"
- AC_MSG_RESULT([yes, to $SJAVAC_SERVER_CORES with max heap size $MAX_HEAP_MEM MB])
- fi
-fi
-AC_SUBST(SJAVAC_SERVER_CORES)
+fi
+if test "$MEMORY_SIZE" -gt "2500" && test "$JVM_ARG_OK" = false; then
+ ADD_JVM_ARG_IF_OK([-Xms1000M -Xmx1500M],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
+fi
+if test "$MEMORY_SIZE" -gt "1000" && test "$JVM_ARG_OK" = false; then
+ ADD_JVM_ARG_IF_OK([-Xms400M -Xmx1100M],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
+fi
+if test "$JVM_ARG_OK" = false; then
+ ADD_JVM_ARG_IF_OK([-Xms256M -Xmx512M],SJAVAC_SERVER_JAVA,[$SJAVAC_SERVER_JAVA])
+fi
AC_MSG_CHECKING([whether to use sjavac])
AC_ARG_ENABLE([sjavac], [AS_HELP_STRING([--enable-sjavac],
diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh
index 832b6410016..87b75cb6cd7 100644
--- a/common/autoconf/generated-configure.sh
+++ b/common/autoconf/generated-configure.sh
@@ -599,7 +599,6 @@ CCACHE
USE_PRECOMPILED_HEADER
SJAVAC_SERVER_DIR
ENABLE_SJAVAC
-SJAVAC_SERVER_CORES
SJAVAC_SERVER_JAVA
JOBS
MEMORY_SIZE
@@ -682,6 +681,8 @@ STATIC_LIBRARY
SHARED_LIBRARY
OBJ_SUFFIX
COMPILER_NAME
+JTREGEXE
+JT_HOME
LIPO
ac_ct_OBJDUMP
OBJDUMP
@@ -1005,6 +1006,7 @@ with_msvcr_dll
with_dxsdk
with_dxsdk_lib
with_dxsdk_include
+with_jtreg
with_extra_cflags
with_extra_cxxflags
with_extra_ldflags
@@ -1025,7 +1027,6 @@ with_num_cores
with_memory_size
with_jobs
with_sjavac_server_java
-with_sjavac_server_cores
enable_sjavac
enable_precompiled_headers
enable_ccache
@@ -1764,6 +1765,7 @@ Optional Packages:
[probed]
--with-dxsdk-include the DirectX SDK include directory (Windows only)
[probed]
+ --with-jtreg Regression Test Harness [probed]
--with-extra-cflags extra flags to be used when compiling jdk c-files
--with-extra-cxxflags extra flags to be used when compiling jdk c++-files
--with-extra-ldflags extra flags to be used when linking jdk
@@ -1796,9 +1798,6 @@ Optional Packages:
--with-sjavac-server-java
use this java binary for running the sjavac
background server [Boot JDK java]
- --with-sjavac-server-cores
- use at most this number of concurrent threads on the
- sjavac server [probed]
--with-ccache-dir where to store ccache files [~/.ccache]
Some influential environment variables:
@@ -3077,6 +3076,9 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
# questions.
#
+# Test if $1 is a valid argument to $3 (often is $JAVA passed as $3)
+# If so, then append $1 to $2\
+# Also set JVM_ARG_OK to true/false depending on outcome.
# This will make sure the given variable points to a full and proper
@@ -3725,6 +3727,9 @@ fi
+# Setup the JTREG paths
+
+
#
# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -3775,7 +3780,7 @@ fi
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1367502949
+DATE_WHEN_GENERATED=1369723814
###############################################################################
#
@@ -7389,17 +7394,20 @@ $as_echo "$as_me: Rewriting SRC_ROOT to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$SRC_ROOT"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of SRC_ROOT, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of SRC_ROOT, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of SRC_ROOT, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of SRC_ROOT, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ SRC_ROOT="`cd "$path"; $THEPWDCMD`"
fi
@@ -7508,17 +7516,20 @@ $as_echo "$as_me: Rewriting CURDIR to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$CURDIR"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of CURDIR, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of CURDIR, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of CURDIR, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of CURDIR, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ CURDIR="`cd "$path"; $THEPWDCMD`"
fi
@@ -8104,17 +8115,20 @@ $as_echo "$as_me: Rewriting OUTPUT_ROOT to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$OUTPUT_ROOT"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of OUTPUT_ROOT, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of OUTPUT_ROOT, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of OUTPUT_ROOT, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of OUTPUT_ROOT, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ OUTPUT_ROOT="`cd "$path"; $THEPWDCMD`"
fi
@@ -11161,17 +11175,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -11490,17 +11507,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -11633,17 +11653,20 @@ $as_echo "$as_me: Rewriting JAVA_HOME_PROCESSED to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$JAVA_HOME_PROCESSED"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of JAVA_HOME_PROCESSED, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of JAVA_HOME_PROCESSED, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of JAVA_HOME_PROCESSED, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of JAVA_HOME_PROCESSED, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ JAVA_HOME_PROCESSED="`cd "$path"; $THEPWDCMD`"
fi
if test ! -d "$JAVA_HOME_PROCESSED"; then
@@ -11802,17 +11825,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -11987,17 +12013,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -12312,17 +12341,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -12524,17 +12556,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -12701,17 +12736,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -12906,17 +12944,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -13083,17 +13124,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -13288,17 +13332,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -13465,17 +13512,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -13670,17 +13720,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -13847,17 +13900,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -14039,17 +14095,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -14214,17 +14273,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -14407,17 +14469,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -14582,17 +14647,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -14774,17 +14842,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -14949,17 +15020,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -15142,17 +15216,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -15317,17 +15394,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -15491,17 +15571,20 @@ $as_echo "$as_me: Rewriting BOOT_JDK to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$BOOT_JDK"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ BOOT_JDK="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Boot JDK" >&5
@@ -15705,73 +15788,115 @@ if test "x$with_boot_jdk_jvmargs" = x; then
# Minimum amount of heap memory.
- # Test if -Xms64M is a valid argument to $JAVA (often is $JAVA passed as $JAVA)
- # If so, then append -Xms64M to boot_jdk_jvmargs
- FOUND_WARN=`$JAVA -Xms64M -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$JAVA -Xms64M -version 2>&1 | grep " version \""`
+ $ECHO "Check if jvm arg is ok: -Xms64M" >&5
+ $ECHO "Command: $JAVA -Xms64M -version" >&5
+ OUTPUT=`$JAVA -Xms64M -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
boot_jdk_jvmargs="$boot_jdk_jvmargs -Xms64M"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
fi
if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
# Why does macosx need more heap? Its the huge JDK batch.
- # Test if -Xmx1600M is a valid argument to $JAVA (often is $JAVA passed as $JAVA)
- # If so, then append -Xmx1600M to boot_jdk_jvmargs
- FOUND_WARN=`$JAVA -Xmx1600M -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$JAVA -Xmx1600M -version 2>&1 | grep " version \""`
+ $ECHO "Check if jvm arg is ok: -Xmx1600M" >&5
+ $ECHO "Command: $JAVA -Xmx1600M -version" >&5
+ OUTPUT=`$JAVA -Xmx1600M -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
boot_jdk_jvmargs="$boot_jdk_jvmargs -Xmx1600M"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
fi
else
- # Test if -Xmx1100M is a valid argument to $JAVA (often is $JAVA passed as $JAVA)
- # If so, then append -Xmx1100M to boot_jdk_jvmargs
- FOUND_WARN=`$JAVA -Xmx1100M -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$JAVA -Xmx1100M -version 2>&1 | grep " version \""`
+ $ECHO "Check if jvm arg is ok: -Xmx1100M" >&5
+ $ECHO "Command: $JAVA -Xmx1100M -version" >&5
+ OUTPUT=`$JAVA -Xmx1100M -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
boot_jdk_jvmargs="$boot_jdk_jvmargs -Xmx1100M"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
fi
fi
# When is adding -client something that speeds up the JVM?
# ADD_JVM_ARG_IF_OK([-client],boot_jdk_jvmargs,[$JAVA])
- # Test if -XX:PermSize=32m is a valid argument to $JAVA (often is $JAVA passed as $JAVA)
- # If so, then append -XX:PermSize=32m to boot_jdk_jvmargs
- FOUND_WARN=`$JAVA -XX:PermSize=32m -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$JAVA -XX:PermSize=32m -version 2>&1 | grep " version \""`
+ $ECHO "Check if jvm arg is ok: -XX:PermSize=32m" >&5
+ $ECHO "Command: $JAVA -XX:PermSize=32m -version" >&5
+ OUTPUT=`$JAVA -XX:PermSize=32m -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
boot_jdk_jvmargs="$boot_jdk_jvmargs -XX:PermSize=32m"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
fi
- # Test if -XX:MaxPermSize=160m is a valid argument to $JAVA (often is $JAVA passed as $JAVA)
- # If so, then append -XX:MaxPermSize=160m to boot_jdk_jvmargs
- FOUND_WARN=`$JAVA -XX:MaxPermSize=160m -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$JAVA -XX:MaxPermSize=160m -version 2>&1 | grep " version \""`
+ $ECHO "Check if jvm arg is ok: -XX:MaxPermSize=160m" >&5
+ $ECHO "Command: $JAVA -XX:MaxPermSize=160m -version" >&5
+ OUTPUT=`$JAVA -XX:MaxPermSize=160m -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
boot_jdk_jvmargs="$boot_jdk_jvmargs -XX:MaxPermSize=160m"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
fi
- # Test if -XX:ThreadStackSize=$STACK_SIZE is a valid argument to $JAVA (often is $JAVA passed as $JAVA)
- # If so, then append -XX:ThreadStackSize=$STACK_SIZE to boot_jdk_jvmargs
- FOUND_WARN=`$JAVA -XX:ThreadStackSize=$STACK_SIZE -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$JAVA -XX:ThreadStackSize=$STACK_SIZE -version 2>&1 | grep " version \""`
+ $ECHO "Check if jvm arg is ok: -XX:ThreadStackSize=$STACK_SIZE" >&5
+ $ECHO "Command: $JAVA -XX:ThreadStackSize=$STACK_SIZE -version" >&5
+ OUTPUT=`$JAVA -XX:ThreadStackSize=$STACK_SIZE -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
boot_jdk_jvmargs="$boot_jdk_jvmargs -XX:ThreadStackSize=$STACK_SIZE"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
fi
# Disable special log output when a debug build is used as Boot JDK...
- # Test if -XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput is a valid argument to $JAVA (often is $JAVA passed as $JAVA)
- # If so, then append -XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput to boot_jdk_jvmargs
- FOUND_WARN=`$JAVA -XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$JAVA -XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput -version 2>&1 | grep " version \""`
+ $ECHO "Check if jvm arg is ok: -XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput" >&5
+ $ECHO "Command: $JAVA -XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput -version" >&5
+ OUTPUT=`$JAVA -XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
boot_jdk_jvmargs="$boot_jdk_jvmargs -XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
fi
fi
@@ -16132,6 +16257,157 @@ AR_OUT_OPTION='rcs$(SPACE)'
# Locate the actual tools
+
+# Check whether --with-jtreg was given.
+if test "${with_jtreg+set}" = set; then :
+ withval=$with_jtreg;
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JTReg Regression Test Harness" >&5
+$as_echo_n "checking for JTReg Regression Test Harness... " >&6; }
+
+ if test "x$with_jtreg" != x; then
+ JT_HOME="$with_jtreg"
+
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+
+ # Input might be given as Windows format, start by converting to
+ # unix format.
+ path="$JT_HOME"
+ new_path=`$CYGPATH -u "$path"`
+
+ # Cygwin tries to hide some aspects of the Windows file system, such that binaries are
+ # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
+ # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
+ # "foo.exe" is OK but "foo" is an error.
+ #
+ # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # It is also a way to make sure we got the proper file name for the real test later on.
+ test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
+ if test "x$test_shortpath" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of JT_HOME, which resolves as \"$path\", is invalid." >&5
+$as_echo "$as_me: The path of JT_HOME, which resolves as \"$path\", is invalid." >&6;}
+ as_fn_error $? "Cannot locate the the path of JT_HOME" "$LINENO" 5
+ fi
+
+ # Call helper function which possibly converts this using DOS-style short mode.
+ # If so, the updated path is stored in $new_path.
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ shortmode_path=`$CYGPATH -s -m -a "$input_path"`
+ path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
+ if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
+ # Going to short mode and back again did indeed matter. Since short mode is
+ # case insensitive, let's make it lowercase to improve readability.
+ shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Now convert it back to Unix-stile (cygpath)
+ input_path=`$CYGPATH -u "$shortmode_path"`
+ new_path="$input_path"
+ fi
+ fi
+
+ test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
+ if test "x$test_cygdrive_prefix" = x; then
+ # As a simple fix, exclude /usr/bin since it's not a real path.
+ if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then
+ # The path is in a Cygwin special directory (e.g. /home). We need this converted to
+ # a path prefixed by /cygdrive for fixpath to work.
+ new_path="$CYGWIN_ROOT_PATH$input_path"
+ fi
+ fi
+
+
+ if test "x$path" != "x$new_path"; then
+ JT_HOME="$new_path"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting JT_HOME to \"$new_path\"" >&5
+$as_echo "$as_me: Rewriting JT_HOME to \"$new_path\"" >&6;}
+ fi
+
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+
+ path="$JT_HOME"
+ has_colon=`$ECHO $path | $GREP ^.:`
+ new_path="$path"
+ if test "x$has_colon" = x; then
+ # Not in mixed or Windows style, start by that.
+ new_path=`cmd //c echo $path`
+ fi
+
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ fi
+
+
+ windows_path="$new_path"
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ unix_path=`$CYGPATH -u "$windows_path"`
+ new_path="$unix_path"
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
+ new_path="$unix_path"
+ fi
+
+ if test "x$path" != "x$new_path"; then
+ JT_HOME="$new_path"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting JT_HOME to \"$new_path\"" >&5
+$as_echo "$as_me: Rewriting JT_HOME to \"$new_path\"" >&6;}
+ fi
+
+ # Save the first 10 bytes of this path to the storage, so fixpath can work.
+ all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
+
+ else
+ # We're on a posix platform. Hooray! :)
+ path="$JT_HOME"
+ has_space=`$ECHO "$path" | $GREP " "`
+ if test "x$has_space" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of JT_HOME, which resolves as \"$path\", is invalid." >&5
+$as_echo "$as_me: The path of JT_HOME, which resolves as \"$path\", is invalid." >&6;}
+ as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
+ fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of JT_HOME, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ JT_HOME="`cd "$path"; $THEPWDCMD`"
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JT_HOME" >&5
+$as_echo "$JT_HOME" >&6; }
+
+ # jtreg win32 script works for everybody
+ JTREGEXE="$JT_HOME/win32/bin/jtreg"
+ if test ! -f "$JTREGEXE"; then
+ as_fn_error $? "JTReg executable does not exist: $JTREGEXE" "$LINENO" 5
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+
+
+
+
+
if test "x$OPENJDK_TARGET_OS" = "xwindows"; then
# Store path to cygwin link.exe to help excluding it when searching for
@@ -17088,17 +17364,20 @@ $as_echo "$as_me: Rewriting MSVCR_DLL to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$MSVCR_DLL"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of MSVCR_DLL, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of MSVCR_DLL, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of MSVCR_DLL, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of MSVCR_DLL, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ MSVCR_DLL="`cd "$path"; $THEPWDCMD`"
fi
@@ -17242,17 +17521,20 @@ $as_echo "$as_me: Rewriting dxsdk_path to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$dxsdk_path"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of dxsdk_path, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of dxsdk_path, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ dxsdk_path="`cd "$path"; $THEPWDCMD`"
fi
@@ -17377,17 +17659,20 @@ $as_echo "$as_me: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$DXSDK_LIB_PATH"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of DXSDK_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of DXSDK_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ DXSDK_LIB_PATH="`cd "$path"; $THEPWDCMD`"
fi
@@ -17510,17 +17795,20 @@ $as_echo "$as_me: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$DXSDK_INCLUDE_PATH"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ DXSDK_INCLUDE_PATH="`cd "$path"; $THEPWDCMD`"
fi
@@ -28199,6 +28487,8 @@ $as_echo "$as_me: Rewriting LIPO to \"$new_complete\"" >&6;}
fi
+
+
# Restore old path without tools dir
PATH="$OLD_PATH"
@@ -30828,17 +31118,20 @@ $as_echo "$as_me: Rewriting with_freetype to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$with_freetype"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of with_freetype, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of with_freetype, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of with_freetype, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of with_freetype, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ with_freetype="`cd "$path"; $THEPWDCMD`"
fi
FREETYPE2_LIBS="-L$with_freetype/lib -lfreetype"
@@ -31127,17 +31420,20 @@ $as_echo "$as_me: Rewriting FREETYPELOCATION to \"$new_path\"" >&6;}
else
# We're on a posix platform. Hooray! :)
path="$FREETYPELOCATION"
-
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of FREETYPELOCATION, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of FREETYPELOCATION, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of FREETYPELOCATION, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of FREETYPELOCATION, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ FREETYPELOCATION="`cd "$path"; $THEPWDCMD`"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for freetype in some standard windows locations" >&5
@@ -32664,192 +32960,183 @@ else
SJAVAC_SERVER_JAVA=""
# Hotspot specific options.
- # Test if -verbosegc is a valid argument to $JAVA (often is $JAVA passed as $JAVA)
- # If so, then append -verbosegc to SJAVAC_SERVER_JAVA
- FOUND_WARN=`$JAVA -verbosegc -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$JAVA -verbosegc -version 2>&1 | grep " version \""`
+ $ECHO "Check if jvm arg is ok: -verbosegc" >&5
+ $ECHO "Command: $JAVA -verbosegc -version" >&5
+ OUTPUT=`$JAVA -verbosegc -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -verbosegc"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
fi
# JRockit specific options.
- # Test if -Xverbose:gc is a valid argument to $JAVA (often is $JAVA passed as $JAVA)
- # If so, then append -Xverbose:gc to SJAVAC_SERVER_JAVA
- FOUND_WARN=`$JAVA -Xverbose:gc -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$JAVA -Xverbose:gc -version 2>&1 | grep " version \""`
+ $ECHO "Check if jvm arg is ok: -Xverbose:gc" >&5
+ $ECHO "Command: $JAVA -Xverbose:gc -version" >&5
+ OUTPUT=`$JAVA -Xverbose:gc -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -Xverbose:gc"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
fi
SJAVAC_SERVER_JAVA="$JAVA $SJAVAC_SERVER_JAVA"
fi
+if test "$MEMORY_SIZE" -gt "2500"; then
-# Check whether --with-sjavac-server-cores was given.
-if test "${with_sjavac_server_cores+set}" = set; then :
- withval=$with_sjavac_server_cores;
-fi
-
-if test "x$with_sjavac_server_cores" != x; then
- SJAVAC_SERVER_CORES="$with_sjavac_server_cores"
-else
- if test "$NUM_CORES" -gt 16; then
- # We set this arbitrary limit because we want to limit the heap
- # size of the javac server.
- # In the future we will make the javac compilers in the server
- # share more and more state, thus enabling us to use more and
- # more concurrent threads in the server.
- SJAVAC_SERVER_CORES="16"
- else
- SJAVAC_SERVER_CORES="$NUM_CORES"
- fi
-
- if test "$MEMORY_SIZE" -gt "17000"; then
- MAX_HEAP_MEM=10000
-
- # Test if -d64 is a valid argument to $SJAVAC_SERVER_JAVA (often is $JAVA passed as $SJAVAC_SERVER_JAVA)
- # If so, then append -d64 to SJAVAC_SERVER_JAVA
- FOUND_WARN=`$SJAVAC_SERVER_JAVA -d64 -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$SJAVAC_SERVER_JAVA -d64 -version 2>&1 | grep " version \""`
+ $ECHO "Check if jvm arg is ok: -d64" >&5
+ $ECHO "Command: $SJAVAC_SERVER_JAVA -d64 -version" >&5
+ OUTPUT=`$SJAVAC_SERVER_JAVA -d64 -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -d64"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
fi
+ if test "$JVM_ARG_OK" = true; then
+ JVM_64BIT=true
+ JVM_ARG_OK=false
+ fi
+ fi
- # Test if -Xms10G -Xmx10G is a valid argument to $SJAVAC_SERVER_JAVA (often is $JAVA passed as $SJAVAC_SERVER_JAVA)
- # If so, then append -Xms10G -Xmx10G to SJAVAC_SERVER_JAVA
- FOUND_WARN=`$SJAVAC_SERVER_JAVA -Xms10G -Xmx10G -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$SJAVAC_SERVER_JAVA -Xms10G -Xmx10G -version 2>&1 | grep " version \""`
+if test "$JVM_64BIT" = true; then
+ if test "$MEMORY_SIZE" -gt "17000"; then
+
+ $ECHO "Check if jvm arg is ok: -Xms10G -Xmx10G" >&5
+ $ECHO "Command: $SJAVAC_SERVER_JAVA -Xms10G -Xmx10G -version" >&5
+ OUTPUT=`$SJAVAC_SERVER_JAVA -Xms10G -Xmx10G -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -Xms10G -Xmx10G"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
fi
- elif test "$MEMORY_SIZE" -gt "10000"; then
- MAX_HEAP_MEM=6000
-
- # Test if -d64 is a valid argument to $SJAVAC_SERVER_JAVA (often is $JAVA passed as $SJAVAC_SERVER_JAVA)
- # If so, then append -d64 to SJAVAC_SERVER_JAVA
- FOUND_WARN=`$SJAVAC_SERVER_JAVA -d64 -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$SJAVAC_SERVER_JAVA -d64 -version 2>&1 | grep " version \""`
- if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
- SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -d64"
fi
+ if test "$MEMORY_SIZE" -gt "10000" && test "$JVM_ARG_OK" = false; then
-
- # Test if -Xms6G -Xmx6G is a valid argument to $SJAVAC_SERVER_JAVA (often is $JAVA passed as $SJAVAC_SERVER_JAVA)
- # If so, then append -Xms6G -Xmx6G to SJAVAC_SERVER_JAVA
- FOUND_WARN=`$SJAVAC_SERVER_JAVA -Xms6G -Xmx6G -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$SJAVAC_SERVER_JAVA -Xms6G -Xmx6G -version 2>&1 | grep " version \""`
+ $ECHO "Check if jvm arg is ok: -Xms6G -Xmx6G" >&5
+ $ECHO "Command: $SJAVAC_SERVER_JAVA -Xms6G -Xmx6G -version" >&5
+ OUTPUT=`$SJAVAC_SERVER_JAVA -Xms6G -Xmx6G -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -Xms6G -Xmx6G"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
fi
- elif test "$MEMORY_SIZE" -gt "5000"; then
- MAX_HEAP_MEM=3000
-
- # Test if -d64 is a valid argument to $SJAVAC_SERVER_JAVA (often is $JAVA passed as $SJAVAC_SERVER_JAVA)
- # If so, then append -d64 to SJAVAC_SERVER_JAVA
- FOUND_WARN=`$SJAVAC_SERVER_JAVA -d64 -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$SJAVAC_SERVER_JAVA -d64 -version 2>&1 | grep " version \""`
- if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
- SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -d64"
fi
+ if test "$MEMORY_SIZE" -gt "5000" && test "$JVM_ARG_OK" = false; then
-
- # Test if -Xms1G -Xmx3G is a valid argument to $SJAVAC_SERVER_JAVA (often is $JAVA passed as $SJAVAC_SERVER_JAVA)
- # If so, then append -Xms1G -Xmx3G to SJAVAC_SERVER_JAVA
- FOUND_WARN=`$SJAVAC_SERVER_JAVA -Xms1G -Xmx3G -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$SJAVAC_SERVER_JAVA -Xms1G -Xmx3G -version 2>&1 | grep " version \""`
+ $ECHO "Check if jvm arg is ok: -Xms1G -Xmx3G" >&5
+ $ECHO "Command: $SJAVAC_SERVER_JAVA -Xms1G -Xmx3G -version" >&5
+ OUTPUT=`$SJAVAC_SERVER_JAVA -Xms1G -Xmx3G -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -Xms1G -Xmx3G"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
fi
- elif test "$MEMORY_SIZE" -gt "3800"; then
- MAX_HEAP_MEM=2500
+ fi
+ if test "$MEMORY_SIZE" -gt "3800" && test "$JVM_ARG_OK" = false; then
- # Test if -Xms1G -Xmx2500M is a valid argument to $SJAVAC_SERVER_JAVA (often is $JAVA passed as $SJAVAC_SERVER_JAVA)
- # If so, then append -Xms1G -Xmx2500M to SJAVAC_SERVER_JAVA
- FOUND_WARN=`$SJAVAC_SERVER_JAVA -Xms1G -Xmx2500M -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$SJAVAC_SERVER_JAVA -Xms1G -Xmx2500M -version 2>&1 | grep " version \""`
+ $ECHO "Check if jvm arg is ok: -Xms1G -Xmx2500M" >&5
+ $ECHO "Command: $SJAVAC_SERVER_JAVA -Xms1G -Xmx2500M -version" >&5
+ OUTPUT=`$SJAVAC_SERVER_JAVA -Xms1G -Xmx2500M -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -Xms1G -Xmx2500M"
- fi
-
- elif test "$MEMORY_SIZE" -gt "1900"; then
- MAX_HEAP_MEM=1200
-
- # Test if -Xms700M -Xmx1400M is a valid argument to $SJAVAC_SERVER_JAVA (often is $JAVA passed as $SJAVAC_SERVER_JAVA)
- # If so, then append -Xms700M -Xmx1400M to SJAVAC_SERVER_JAVA
- FOUND_WARN=`$SJAVAC_SERVER_JAVA -Xms700M -Xmx1400M -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$SJAVAC_SERVER_JAVA -Xms700M -Xmx1400M -version 2>&1 | grep " version \""`
- if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
- SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -Xms700M -Xmx1400M"
- fi
-
- elif test "$MEMORY_SIZE" -gt "1000"; then
- MAX_HEAP_MEM=900
-
- # Test if -Xms400M -Xmx1100M is a valid argument to $SJAVAC_SERVER_JAVA (often is $JAVA passed as $SJAVAC_SERVER_JAVA)
- # If so, then append -Xms400M -Xmx1100M to SJAVAC_SERVER_JAVA
- FOUND_WARN=`$SJAVAC_SERVER_JAVA -Xms400M -Xmx1100M -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$SJAVAC_SERVER_JAVA -Xms400M -Xmx1100M -version 2>&1 | grep " version \""`
- if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
- SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -Xms400M -Xmx1100M"
- fi
-
+ JVM_ARG_OK=true
else
- MAX_HEAP_MEM=512
-
- # Test if -Xms256M -Xmx512M is a valid argument to $SJAVAC_SERVER_JAVA (often is $JAVA passed as $SJAVAC_SERVER_JAVA)
- # If so, then append -Xms256M -Xmx512M to SJAVAC_SERVER_JAVA
- FOUND_WARN=`$SJAVAC_SERVER_JAVA -Xms256M -Xmx512M -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$SJAVAC_SERVER_JAVA -Xms256M -Xmx512M -version 2>&1 | grep " version \""`
- if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
- SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -Xms256M -Xmx512M"
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
fi
fi
-
-
- # Test if -XX:PermSize=32m is a valid argument to $SJAVAC_SERVER_JAVA (often is $JAVA passed as $SJAVAC_SERVER_JAVA)
- # If so, then append -XX:PermSize=32m to SJAVAC_SERVER_JAVA
- FOUND_WARN=`$SJAVAC_SERVER_JAVA -XX:PermSize=32m -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$SJAVAC_SERVER_JAVA -XX:PermSize=32m -version 2>&1 | grep " version \""`
- if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
- SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -XX:PermSize=32m"
- fi
-
-
- # Test if -XX:MaxPermSize=160m is a valid argument to $SJAVAC_SERVER_JAVA (often is $JAVA passed as $SJAVAC_SERVER_JAVA)
- # If so, then append -XX:MaxPermSize=160m to SJAVAC_SERVER_JAVA
- FOUND_WARN=`$SJAVAC_SERVER_JAVA -XX:MaxPermSize=160m -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$SJAVAC_SERVER_JAVA -XX:MaxPermSize=160m -version 2>&1 | grep " version \""`
- if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
- SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -XX:MaxPermSize=160m"
- fi
-
-
- # Test if -XX:ThreadStackSize=$STACK_SIZE is a valid argument to $SJAVAC_SERVER_JAVA (often is $JAVA passed as $SJAVAC_SERVER_JAVA)
- # If so, then append -XX:ThreadStackSize=$STACK_SIZE to SJAVAC_SERVER_JAVA
- FOUND_WARN=`$SJAVAC_SERVER_JAVA -XX:ThreadStackSize=$STACK_SIZE -version 2>&1 | grep -i warn`
- FOUND_VERSION=`$SJAVAC_SERVER_JAVA -XX:ThreadStackSize=$STACK_SIZE -version 2>&1 | grep " version \""`
- if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
- SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -XX:ThreadStackSize=$STACK_SIZE"
- fi
-
-
- MAX_COMPILERS_IN_HEAP=`expr $MAX_HEAP_MEM / 501`
- if test "$SJAVAC_SERVER_CORES" -gt "$MAX_COMPILERS_IN_HEAP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if number of server cores must be reduced" >&5
-$as_echo_n "checking if number of server cores must be reduced... " >&6; }
- SJAVAC_SERVER_CORES="$MAX_COMPILERS_IN_HEAP"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, to $SJAVAC_SERVER_CORES with max heap size $MAX_HEAP_MEM MB" >&5
-$as_echo "yes, to $SJAVAC_SERVER_CORES with max heap size $MAX_HEAP_MEM MB" >&6; }
- fi
fi
+if test "$MEMORY_SIZE" -gt "2500" && test "$JVM_ARG_OK" = false; then
+ $ECHO "Check if jvm arg is ok: -Xms1000M -Xmx1500M" >&5
+ $ECHO "Command: $SJAVAC_SERVER_JAVA -Xms1000M -Xmx1500M -version" >&5
+ OUTPUT=`$SJAVAC_SERVER_JAVA -Xms1000M -Xmx1500M -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+ if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+ SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -Xms1000M -Xmx1500M"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
+ fi
+
+fi
+if test "$MEMORY_SIZE" -gt "1000" && test "$JVM_ARG_OK" = false; then
+
+ $ECHO "Check if jvm arg is ok: -Xms400M -Xmx1100M" >&5
+ $ECHO "Command: $SJAVAC_SERVER_JAVA -Xms400M -Xmx1100M -version" >&5
+ OUTPUT=`$SJAVAC_SERVER_JAVA -Xms400M -Xmx1100M -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+ if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+ SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -Xms400M -Xmx1100M"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
+ fi
+
+fi
+if test "$JVM_ARG_OK" = false; then
+
+ $ECHO "Check if jvm arg is ok: -Xms256M -Xmx512M" >&5
+ $ECHO "Command: $SJAVAC_SERVER_JAVA -Xms256M -Xmx512M -version" >&5
+ OUTPUT=`$SJAVAC_SERVER_JAVA -Xms256M -Xmx512M -version 2>&1`
+ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+ if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+ SJAVAC_SERVER_JAVA="$SJAVAC_SERVER_JAVA -Xms256M -Xmx512M"
+ JVM_ARG_OK=true
+ else
+ $ECHO "Arg failed:" >&5
+ $ECHO "$OUTPUT" >&5
+ JVM_ARG_OK=false
+ fi
+
+fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use sjavac" >&5
$as_echo_n "checking whether to use sjavac... " >&6; }
diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in
index 2172ee8ef68..8705a2a0114 100644
--- a/common/autoconf/spec.gmk.in
+++ b/common/autoconf/spec.gmk.in
@@ -54,9 +54,9 @@ MAKE_ARGS="SPEC=$(SPEC)"
MAKE:=@MAKE@
-# Pass along the verbosity setting.
+# Pass along the verbosity and log level settings.
ifeq (,$(findstring VERBOSE=,$(MAKE)))
- MAKE:=$(MAKE) $(VERBOSE) VERBOSE="$(VERBOSE)"
+ MAKE:=$(MAKE) $(VERBOSE) VERBOSE="$(VERBOSE)" LOG_LEVEL="$(LOG_LEVEL)"
endif
# No implicit variables or rules!
@@ -528,6 +528,8 @@ HG:=@HG@
OBJCOPY:=@OBJCOPY@
SETFILE:=@SETFILE@
XATTR:=@XATTR@
+JT_HOME:=@JT_HOME@
+JTREGEXE:=@JTREGEXE@
FIXPATH:=@FIXPATH@
diff --git a/common/autoconf/toolchain.m4 b/common/autoconf/toolchain.m4
index 779f86117ab..723d96a22e1 100644
--- a/common/autoconf/toolchain.m4
+++ b/common/autoconf/toolchain.m4
@@ -479,6 +479,8 @@ if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
BASIC_FIXUP_EXECUTABLE(LIPO)
fi
+TOOLCHAIN_SETUP_JTREG
+
# Restore old path without tools dir
PATH="$OLD_PATH"
])
@@ -1089,3 +1091,29 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_COMPILER_FLAGS_MISC],
[COMPILER_SUPPORTS_TARGET_BITS_FLAG=false])
AC_SUBST(COMPILER_SUPPORTS_TARGET_BITS_FLAG)
])
+
+# Setup the JTREG paths
+AC_DEFUN_ONCE([TOOLCHAIN_SETUP_JTREG],
+[
+ AC_ARG_WITH(jtreg, [AS_HELP_STRING([--with-jtreg],
+ [Regression Test Harness @<:@probed@:>@])])
+
+ AC_MSG_CHECKING([for JTReg Regression Test Harness])
+
+ if test "x$with_jtreg" != x; then
+ JT_HOME="$with_jtreg"
+ BASIC_FIXUP_PATH([JT_HOME])
+ AC_MSG_RESULT($JT_HOME)
+
+ # jtreg win32 script works for everybody
+ JTREGEXE="$JT_HOME/win32/bin/jtreg"
+ if test ! -f "$JTREGEXE"; then
+ AC_MSG_ERROR([JTReg executable does not exist: $JTREGEXE])
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+
+ AC_SUBST(JT_HOME)
+ AC_SUBST(JTREGEXE)
+])
diff --git a/common/makefiles/Main.gmk b/common/makefiles/Main.gmk
index 145fbad91b2..d07f3e2b386 100644
--- a/common/makefiles/Main.gmk
+++ b/common/makefiles/Main.gmk
@@ -240,10 +240,10 @@ clean-docs:
clean-test:
$(call CleanComponent,testoutput)
-.PHONY: langtools corba jaxp jaxws hotspot jdk nashorn images overlay-images install
-.PHONY: langtools-only corba-only jaxp-only jaxws-only hotspot-only jdk-only nashorn-only images-only overlay-images-only install-only
-.PHONY: all test clean dist-clean bootcycle-images start-make
-.PHONY: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-nashorn clean-images clean-overlay-images clean-bootcycle-build
+.PHONY: langtools corba jaxp jaxws hotspot jdk nashorn images overlay-images install test docs
+.PHONY: langtools-only corba-only jaxp-only jaxws-only hotspot-only jdk-only nashorn-only images-only overlay-images-only install-only test-only docs-only
+.PHONY: all clean dist-clean bootcycle-images start-make
+.PHONY: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-nashorn clean-images clean-docs clean-test clean-overlay-images clean-bootcycle-build
.PHONY: profiles profiles-only profiles-oscheck
FRC: # Force target
diff --git a/common/makefiles/NativeCompilation.gmk b/common/makefiles/NativeCompilation.gmk
index 2e084ea410c..c3b276609c3 100644
--- a/common/makefiles/NativeCompilation.gmk
+++ b/common/makefiles/NativeCompilation.gmk
@@ -321,11 +321,17 @@ define SetupNativeCompilation
ifneq (,$$($1_DEBUG_SYMBOLS))
ifeq ($(ENABLE_DEBUG_SYMBOLS), true)
- # Programs don't get the debug symbols added in the old build. It's not clear if
- # this is intentional.
- ifeq ($$($1_PROGRAM),)
+ ifdef OPENJDK
+ # Always add debug symbols
$1_EXTRA_CFLAGS+=$(CFLAGS_DEBUG_SYMBOLS)
$1_EXTRA_CXXFLAGS+=$(CXXFLAGS_DEBUG_SYMBOLS)
+ else
+ # Programs don't get the debug symbols added in the old build. It's not clear if
+ # this is intentional.
+ ifeq ($$($1_PROGRAM),)
+ $1_EXTRA_CFLAGS+=$(CFLAGS_DEBUG_SYMBOLS)
+ $1_EXTRA_CXXFLAGS+=$(CXXFLAGS_DEBUG_SYMBOLS)
+ endif
endif
endif
endif
diff --git a/corba/.hgtags b/corba/.hgtags
index 45d7f0a02bd..af3629045ae 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -211,3 +211,5 @@ a45bb25a67c7517b45f00c9682e317f46fecbba9 jdk8-b83
f1709874d55a06bc3d5dfa02dbcdfbc59f4cba34 jdk8-b87
4e3a881ebb1ee96ce0872508b0066d74f310dbfa jdk8-b88
fe4150590ee597f4e125fea950aa3b352622cc2d jdk8-b89
+c8286839d0df04aba819ec4bef12b86babccf30e jdk8-b90
+8f7ffb296385f85a4a6d53f9f2d4a7b13a8fa1ff jdk8-b91
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index fb98d2c5ed1..f2fb4715f13 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -341,3 +341,7 @@ c4af77d2045476c56fbf3f914b336bb1b7cd18af hs25-b30
4ec91349972255650f97bedfd07e6423e02428cf hs25-b31
9c1fe0b419b40a9ecdd1653cc9af1b6d67a12c46 jdk8-b89
69494caf57908ba2c8efa9eaaa472b4d1875588a hs25-b32
+1ae0472ff3a0117b5b019d380ad59fface2fde14 jdk8-b90
+b19517cecc2e91636d7c16ba2f35e3d3dc628099 hs25-b33
+7cbdf0e3725c0c56a2ff7540fc70b6d4b5890d04 jdk8-b91
+38da9f4f67096745f851318d792d6468aa1f6cf8 hs25-b34
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java
index 3468b0d6514..d50e36c2a74 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java
@@ -97,8 +97,8 @@ public class ciMethod extends ciMetadata {
holder.getName().asString() + " " +
OopUtilities.escapeString(method.getName().asString()) + " " +
method.getSignature().asString() + " " +
- method.getInvocationCounter() + " " +
- method.getBackedgeCounter() + " " +
+ method.getInvocationCount() + " " +
+ method.getBackedgeCount() + " " +
interpreterInvocationCount() + " " +
interpreterThrowoutCount() + " " +
instructionsSize());
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgCDebugger.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgCDebugger.java
index 0cfb3c53fba..04c4abbe0a9 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgCDebugger.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgCDebugger.java
@@ -28,10 +28,10 @@ import java.io.*;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.debugger.cdbg.basic.x86.*;
-import sun.jvm.hotspot.debugger.cdbg.basic.amd64.*;
import sun.jvm.hotspot.debugger.x86.*;
import sun.jvm.hotspot.debugger.amd64.*;
+import sun.jvm.hotspot.debugger.windows.x86.*;
+import sun.jvm.hotspot.debugger.windows.amd64.*;
import sun.jvm.hotspot.utilities.AddressOps;
class WindbgCDebugger implements CDebugger {
@@ -75,14 +75,14 @@ class WindbgCDebugger implements CDebugger {
if (ebp == null) return null;
Address pc = context.getRegisterAsAddress(X86ThreadContext.EIP);
if (pc == null) return null;
- return new X86CFrame(this, ebp, pc);
+ return new WindowsX86CFrame(dbg, ebp, pc);
} else if (dbg.getCPU().equals("amd64")) {
AMD64ThreadContext context = (AMD64ThreadContext) thread.getContext();
Address rbp = context.getRegisterAsAddress(AMD64ThreadContext.RBP);
if (rbp == null) return null;
Address pc = context.getRegisterAsAddress(AMD64ThreadContext.RIP);
if (pc == null) return null;
- return new AMD64CFrame(this, rbp, pc);
+ return new WindowsAMD64CFrame(dbg, rbp, pc);
} else {
// unsupported CPU!
return null;
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/cdbg/basic/amd64/AMD64CFrame.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windows/amd64/WindowsAMD64CFrame.java
similarity index 78%
rename from hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/cdbg/basic/amd64/AMD64CFrame.java
rename to hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windows/amd64/WindowsAMD64CFrame.java
index d6ec6b45003..fe4052f3512 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/cdbg/basic/amd64/AMD64CFrame.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windows/amd64/WindowsAMD64CFrame.java
@@ -22,26 +22,26 @@
*
*/
-package sun.jvm.hotspot.debugger.cdbg.basic.amd64;
+package sun.jvm.hotspot.debugger.windows.amd64;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.amd64.*;
import sun.jvm.hotspot.debugger.cdbg.*;
import sun.jvm.hotspot.debugger.cdbg.basic.*;
+import sun.jvm.hotspot.debugger.windbg.*;
-/** Basic AMD64 frame functionality providing sender() functionality. */
-
-public class AMD64CFrame extends BasicCFrame {
+public class WindowsAMD64CFrame extends BasicCFrame {
private Address rbp;
private Address pc;
private static final int ADDRESS_SIZE = 8;
/** Constructor for topmost frame */
- public AMD64CFrame(CDebugger dbg, Address rbp, Address pc) {
- super(dbg);
+ public WindowsAMD64CFrame(WindbgDebugger dbg, Address rbp, Address pc) {
+ super(dbg.getCDebugger());
this.rbp = rbp;
this.pc = pc;
+ this.dbg = dbg;
}
public CFrame sender(ThreadProxy thread) {
@@ -52,15 +52,20 @@ public class AMD64CFrame extends BasicCFrame {
return null;
}
+ // Check alignment of rbp
+ if ( dbg.getAddressValue(rbp) % ADDRESS_SIZE != 0) {
+ return null;
+ }
+
Address nextRBP = rbp.getAddressAt( 0 * ADDRESS_SIZE);
- if (nextRBP == null) {
+ if (nextRBP == null || nextRBP.lessThanOrEqual(rbp)) {
return null;
}
Address nextPC = rbp.getAddressAt( 1 * ADDRESS_SIZE);
if (nextPC == null) {
return null;
}
- return new AMD64CFrame(dbg(), nextRBP, nextPC);
+ return new WindowsAMD64CFrame(dbg, nextRBP, nextPC);
}
public Address pc() {
@@ -70,4 +75,6 @@ public class AMD64CFrame extends BasicCFrame {
public Address localVariableBase() {
return rbp;
}
+
+ private WindbgDebugger dbg;
}
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/cdbg/basic/x86/X86CFrame.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windows/x86/WindowsX86CFrame.java
similarity index 78%
rename from hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/cdbg/basic/x86/X86CFrame.java
rename to hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windows/x86/WindowsX86CFrame.java
index 76b101bef97..5c5f1f161e7 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/cdbg/basic/x86/X86CFrame.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windows/x86/WindowsX86CFrame.java
@@ -22,26 +22,26 @@
*
*/
-package sun.jvm.hotspot.debugger.cdbg.basic.x86;
+package sun.jvm.hotspot.debugger.windows.x86;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.x86.*;
import sun.jvm.hotspot.debugger.cdbg.*;
import sun.jvm.hotspot.debugger.cdbg.basic.*;
+import sun.jvm.hotspot.debugger.windbg.*;
-/** Basic X86 frame functionality providing sender() functionality. */
-
-public class X86CFrame extends BasicCFrame {
+public class WindowsX86CFrame extends BasicCFrame {
private Address ebp;
private Address pc;
private static final int ADDRESS_SIZE = 4;
/** Constructor for topmost frame */
- public X86CFrame(CDebugger dbg, Address ebp, Address pc) {
- super(dbg);
+ public WindowsX86CFrame(WindbgDebugger dbg, Address ebp, Address pc) {
+ super(dbg.getCDebugger());
this.ebp = ebp;
this.pc = pc;
+ this.dbg = dbg;
}
public CFrame sender(ThreadProxy thread) {
@@ -52,15 +52,20 @@ public class X86CFrame extends BasicCFrame {
return null;
}
+ // Check alignment of ebp
+ if ( dbg.getAddressValue(ebp) % ADDRESS_SIZE != 0) {
+ return null;
+ }
+
Address nextEBP = ebp.getAddressAt( 0 * ADDRESS_SIZE);
- if (nextEBP == null) {
+ if (nextEBP == null || nextEBP.lessThanOrEqual(ebp)) {
return null;
}
Address nextPC = ebp.getAddressAt( 1 * ADDRESS_SIZE);
if (nextPC == null) {
return null;
}
- return new X86CFrame(dbg(), nextEBP, nextPC);
+ return new WindowsX86CFrame(dbg, nextEBP, nextPC);
}
public Address pc() {
@@ -70,4 +75,6 @@ public class X86CFrame extends BasicCFrame {
public Address localVariableBase() {
return ebp;
}
+
+ private WindbgDebugger dbg;
}
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java
index c61d58dc429..e039470f801 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java
@@ -24,15 +24,21 @@
package sun.jvm.hotspot.oops;
-import java.io.*;
-import java.util.*;
-import sun.jvm.hotspot.code.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.interpreter.*;
-import sun.jvm.hotspot.memory.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-import sun.jvm.hotspot.utilities.*;
+import java.io.PrintStream;
+import java.util.Observable;
+import java.util.Observer;
+
+import sun.jvm.hotspot.code.NMethod;
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.interpreter.OopMapCacheEntry;
+import sun.jvm.hotspot.runtime.SignatureConverter;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObjectFactory;
+import sun.jvm.hotspot.types.AddressField;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+import sun.jvm.hotspot.types.WrongTypeException;
+import sun.jvm.hotspot.utilities.Assert;
// A Method represents a Java method
@@ -132,11 +138,13 @@ public class Method extends Metadata {
public long getAccessFlags() { return accessFlags.getValue(this); }
public long getCodeSize() { return getConstMethod().getCodeSize(); }
public long getVtableIndex() { return vtableIndex.getValue(this); }
- public long getInvocationCounter() {
- return getMethodCounters().getInvocationCounter();
+ public long getInvocationCount() {
+ MethodCounters mc = getMethodCounters();
+ return mc == null ? 0 : mc.getInvocationCounter();
}
- public long getBackedgeCounter() {
- return getMethodCounters().getBackedgeCounter();
+ public long getBackedgeCount() {
+ MethodCounters mc = getMethodCounters();
+ return mc == null ? 0 : mc.getBackedgeCounter();
}
// get associated compiled native method, if available, else return null.
@@ -349,8 +357,8 @@ public class Method extends Metadata {
holder.getName().asString() + " " +
OopUtilities.escapeString(getName().asString()) + " " +
getSignature().asString() + " " +
- getInvocationCounter() + " " +
- getBackedgeCounter() + " " +
+ getInvocationCount() + " " +
+ getBackedgeCount() + " " +
interpreterInvocationCount() + " " +
interpreterThrowoutCount() + " " +
code_size);
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java
index a397ec353ac..eb643483fe5 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java
@@ -316,8 +316,8 @@ public class MethodData extends Metadata {
int iic = method.interpreterInvocationCount();
if (mileage < iic) mileage = iic;
- long ic = method.getInvocationCounter();
- long bc = method.getBackedgeCounter();
+ long ic = method.getInvocationCount();
+ long bc = method.getBackedgeCount();
long icval = ic >> 3;
if ((ic & 4) != 0) icval += CompileThreshold;
diff --git a/hotspot/make/Makefile b/hotspot/make/Makefile
index e0d9826e468..526ed2393f2 100644
--- a/hotspot/make/Makefile
+++ b/hotspot/make/Makefile
@@ -151,32 +151,43 @@ else
$(MAKE_ARGS) BUILD_FLAVOR=product docs
endif
+# Output directories
+C1_DIR =$(OUTPUTDIR)/$(VM_PLATFORM)_compiler1
+C2_DIR =$(OUTPUTDIR)/$(VM_PLATFORM)_compiler2
+MINIMAL1_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_minimal1
+ZERO_DIR =$(OUTPUTDIR)/$(VM_PLATFORM)_zero
+SHARK_DIR =$(OUTPUTDIR)/$(VM_PLATFORM)_shark
+
# Build variation of hotspot
$(C1_VM_TARGETS):
$(CD) $(GAMMADIR)/make; \
- $(MAKE) BUILD_FLAVOR=$(@:%1=%) VM_TARGET=$@ generic_build1 $(ALT_OUT)
+ $(MAKE) BUILD_DIR=$(C1_DIR) BUILD_FLAVOR=$(@:%1=%) VM_TARGET=$@ generic_build1 $(ALT_OUT)
$(C2_VM_TARGETS):
$(CD) $(GAMMADIR)/make; \
- $(MAKE) BUILD_FLAVOR=$@ VM_TARGET=$@ generic_build2 $(ALT_OUT)
+ $(MAKE) BUILD_DIR=$(C2_DIR) BUILD_FLAVOR=$@ VM_TARGET=$@ generic_build2 $(ALT_OUT)
$(ZERO_VM_TARGETS):
$(CD) $(GAMMADIR)/make; \
- $(MAKE) BUILD_FLAVOR=$(@:%zero=%) VM_TARGET=$@ \
- generic_buildzero $(ALT_OUT)
+ $(MAKE) BUILD_DIR=$(ZERO_DIR) BUILD_FLAVOR=$(@:%zero=%) VM_TARGET=$@ generic_buildzero $(ALT_OUT)
$(SHARK_VM_TARGETS):
$(CD) $(GAMMADIR)/make; \
- $(MAKE) BUILD_FLAVOR=$(@:%shark=%) VM_TARGET=$@ \
- generic_buildshark $(ALT_OUT)
+ $(MAKE) BUILD_DIR=$(SHARK_DIR) BUILD_FLAVOR=$(@:%shark=%) VM_TARGET=$@ generic_buildshark $(ALT_OUT)
$(MINIMAL1_VM_TARGETS):
$(CD) $(GAMMADIR)/make; \
- $(MAKE) BUILD_FLAVOR=$(@:%minimal1=%) VM_TARGET=$@ \
- generic_buildminimal1 $(ALT_OUT)
+ $(MAKE) BUILD_DIR=$(MINIMAL1_DIR) BUILD_FLAVOR=$(@:%minimal1=%) VM_TARGET=$@ generic_buildminimal1 $(ALT_OUT)
+
+# Install hotspot script in build directory
+HOTSPOT_SCRIPT=$(BUILD_DIR)/$(BUILD_FLAVOR)/hotspot
+$(HOTSPOT_SCRIPT): $(GAMMADIR)/make/hotspot.script
+ $(QUIETLY) $(MKDIR) -p $(BUILD_DIR)/$(BUILD_FLAVOR)
+ $(QUIETLY) cat $< | sed -e 's|@@LIBARCH@@|$(LIBARCH)|g' | sed -e 's|@@JDK_IMPORT_PATH@@|$(JDK_IMPORT_PATH)|g' > $@
+ $(QUIETLY) chmod +x $@
# Build compiler1 (client) rule, different for platforms
-generic_build1:
+generic_build1: $(HOTSPOT_SCRIPT)
$(MKDIR) -p $(OUTPUTDIR)
ifeq ($(OSNAME),windows)
ifeq ($(ARCH_DATA_MODEL), 32)
@@ -201,7 +212,7 @@ else
endif
# Build compiler2 (server) rule, different for platforms
-generic_build2:
+generic_build2: $(HOTSPOT_SCRIPT)
$(MKDIR) -p $(OUTPUTDIR)
ifeq ($(OSNAME),windows)
$(CD) $(OUTPUTDIR); \
@@ -217,19 +228,19 @@ else
$(MAKE_ARGS) $(VM_TARGET)
endif
-generic_buildzero:
+generic_buildzero: $(HOTSPOT_SCRIPT)
$(MKDIR) -p $(OUTPUTDIR)
$(CD) $(OUTPUTDIR); \
$(MAKE) -f $(ABS_OS_MAKEFILE) \
$(MAKE_ARGS) $(VM_TARGET)
-generic_buildshark:
+generic_buildshark: $(HOTSPOT_SCRIPT)
$(MKDIR) -p $(OUTPUTDIR)
$(CD) $(OUTPUTDIR); \
$(MAKE) -f $(ABS_OS_MAKEFILE) \
$(MAKE_ARGS) $(VM_TARGET)
-generic_buildminimal1:
+generic_buildminimal1: $(HOTSPOT_SCRIPT)
ifeq ($(JVM_VARIANT_MINIMAL1),true)
$(MKDIR) -p $(OUTPUTDIR)
ifeq ($(ARCH_DATA_MODEL), 32)
@@ -252,224 +263,210 @@ endif
# Export file rule
generic_export: $(EXPORT_LIST)
+
export_product:
- $(MAKE) BUILD_FLAVOR=$(@:export_%=%) VM_SUBDIR=$(@:export_%=%) \
- generic_export
+ $(MAKE) BUILD_FLAVOR=$(@:export_%=%) generic_export
export_fastdebug:
- $(MAKE) BUILD_FLAVOR=$(@:export_%=%) VM_SUBDIR=$(@:export_%=%) \
- EXPORT_SUBDIR=/$(@:export_%=%) \
- generic_export
+ $(MAKE) BUILD_FLAVOR=$(@:export_%=%) EXPORT_SUBDIR=/$(@:export_%=%) generic_export
export_debug:
- $(MAKE) BUILD_FLAVOR=$(@:export_%=%) VM_SUBDIR=$(@:export_%=%) \
- EXPORT_SUBDIR=/$(@:export_%=%) \
- generic_export
+ $(MAKE) BUILD_FLAVOR=$(@:export_%=%) EXPORT_SUBDIR=/$(@:export_%=%) generic_export
export_optimized:
- $(MAKE) BUILD_FLAVOR=$(@:export_%=%) VM_SUBDIR=$(@:export_%=%) \
- EXPORT_SUBDIR=/$(@:export_%=%) \
- generic_export
+ $(MAKE) BUILD_FLAVOR=$(@:export_%=%) EXPORT_SUBDIR=/$(@:export_%=%) generic_export
+
export_product_jdk::
- $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) \
- VM_SUBDIR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) \
- generic_export
+ $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) generic_export
export_optimized_jdk::
- $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) \
- VM_SUBDIR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) \
- generic_export
+ $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) generic_export
export_fastdebug_jdk::
- $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) \
- VM_SUBDIR=$(@:export_%_jdk=%) \
- ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) \
- generic_export
+ $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) generic_export
export_debug_jdk::
- $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) VM_SUBDIR=$(@:export_%_jdk=%) \
- ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) \
- generic_export
+ $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) generic_export
# Export file copy rules
XUSAGE=$(HS_SRC_DIR)/share/vm/Xusage.txt
-DOCS_DIR =$(OUTPUTDIR)/$(VM_PLATFORM)_docs
-C1_DIR =$(OUTPUTDIR)/$(VM_PLATFORM)_compiler1/$(VM_SUBDIR)
-C2_DIR =$(OUTPUTDIR)/$(VM_PLATFORM)_compiler2/$(VM_SUBDIR)
-MINIMAL1_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_minimal1/$(VM_SUBDIR)
-ZERO_DIR =$(OUTPUTDIR)/$(VM_PLATFORM)_zero/$(VM_SUBDIR)
-SHARK_DIR =$(OUTPUTDIR)/$(VM_PLATFORM)_shark/$(VM_SUBDIR)
+DOCS_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_docs
+C1_BUILD_DIR =$(C1_DIR)/$(BUILD_FLAVOR)
+C2_BUILD_DIR =$(C2_DIR)/$(BUILD_FLAVOR)
+MINIMAL1_BUILD_DIR=$(MINIMAL1_DIR)/$(BUILD_FLAVOR)
+ZERO_BUILD_DIR =$(ZERO_DIR)/$(BUILD_FLAVOR)
+SHARK_BUILD_DIR =$(SHARK_DIR)/$(BUILD_FLAVOR)
# Server (C2)
ifeq ($(JVM_VARIANT_SERVER), true)
# Common
-$(EXPORT_SERVER_DIR)/%.diz: $(C2_DIR)/%.diz
+$(EXPORT_SERVER_DIR)/%.diz: $(C2_BUILD_DIR)/%.diz
$(install-file)
-$(EXPORT_LIB_DIR)/%.jar: $(C2_DIR)/../generated/%.jar
+$(EXPORT_LIB_DIR)/%.jar: $(C2_BUILD_DIR)/../generated/%.jar
$(install-file)
-$(EXPORT_INCLUDE_DIR)/%: $(C2_DIR)/../generated/jvmtifiles/%
+$(EXPORT_INCLUDE_DIR)/%: $(C2_BUILD_DIR)/../generated/jvmtifiles/%
$(install-file)
# Windows
-$(EXPORT_SERVER_DIR)/%.dll: $(C2_DIR)/%.dll
+$(EXPORT_SERVER_DIR)/%.dll: $(C2_BUILD_DIR)/%.dll
$(install-file)
-$(EXPORT_SERVER_DIR)/%.pdb: $(C2_DIR)/%.pdb
+$(EXPORT_SERVER_DIR)/%.pdb: $(C2_BUILD_DIR)/%.pdb
$(install-file)
-$(EXPORT_SERVER_DIR)/%.map: $(C2_DIR)/%.map
+$(EXPORT_SERVER_DIR)/%.map: $(C2_BUILD_DIR)/%.map
$(install-file)
-$(EXPORT_LIB_DIR)/%.lib: $(C2_DIR)/%.lib
+$(EXPORT_LIB_DIR)/%.lib: $(C2_BUILD_DIR)/%.lib
$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.diz: $(C2_DIR)/%.diz
+$(EXPORT_JRE_BIN_DIR)/%.diz: $(C2_BUILD_DIR)/%.diz
$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.dll: $(C2_DIR)/%.dll
+$(EXPORT_JRE_BIN_DIR)/%.dll: $(C2_BUILD_DIR)/%.dll
$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.pdb: $(C2_DIR)/%.pdb
+$(EXPORT_JRE_BIN_DIR)/%.pdb: $(C2_BUILD_DIR)/%.pdb
$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.map: $(C2_DIR)/%.map
+$(EXPORT_JRE_BIN_DIR)/%.map: $(C2_BUILD_DIR)/%.map
$(install-file)
# Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C2_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
-$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(C2_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
-$(EXPORT_SERVER_DIR)/64/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_SERVER_DIR)/64/%.$(LIBRARY_SUFFIX): $(C2_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C2_DIR)/%.debuginfo
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C2_BUILD_DIR)/%.debuginfo
$(install-file)
-$(EXPORT_SERVER_DIR)/%.debuginfo: $(C2_DIR)/%.debuginfo
+$(EXPORT_SERVER_DIR)/%.debuginfo: $(C2_BUILD_DIR)/%.debuginfo
$(install-file)
-$(EXPORT_SERVER_DIR)/64/%.debuginfo: $(C2_DIR)/%.debuginfo
+$(EXPORT_SERVER_DIR)/64/%.debuginfo: $(C2_BUILD_DIR)/%.debuginfo
$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(C2_DIR)/%.diz
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(C2_BUILD_DIR)/%.diz
$(install-file)
-$(EXPORT_SERVER_DIR)/64/%.diz: $(C2_DIR)/%.diz
+$(EXPORT_SERVER_DIR)/64/%.diz: $(C2_BUILD_DIR)/%.diz
$(install-file)
endif
# Client (C1)
ifeq ($(JVM_VARIANT_CLIENT), true)
# Common
-$(EXPORT_CLIENT_DIR)/%.diz: $(C1_DIR)/%.diz
+$(EXPORT_CLIENT_DIR)/%.diz: $(C1_BUILD_DIR)/%.diz
$(install-file)
-$(EXPORT_LIB_DIR)/%.jar: $(C1_DIR)/../generated/%.jar
+$(EXPORT_LIB_DIR)/%.jar: $(C1_BUILD_DIR)/../generated/%.jar
$(install-file)
-$(EXPORT_INCLUDE_DIR)/%: $(C1_DIR)/../generated/jvmtifiles/%
+$(EXPORT_INCLUDE_DIR)/%: $(C1_BUILD_DIR)/../generated/jvmtifiles/%
$(install-file)
# Windows
-$(EXPORT_CLIENT_DIR)/%.dll: $(C1_DIR)/%.dll
+$(EXPORT_CLIENT_DIR)/%.dll: $(C1_BUILD_DIR)/%.dll
$(install-file)
-$(EXPORT_CLIENT_DIR)/%.pdb: $(C1_DIR)/%.pdb
+$(EXPORT_CLIENT_DIR)/%.pdb: $(C1_BUILD_DIR)/%.pdb
$(install-file)
-$(EXPORT_CLIENT_DIR)/%.map: $(C1_DIR)/%.map
+$(EXPORT_CLIENT_DIR)/%.map: $(C1_BUILD_DIR)/%.map
$(install-file)
-$(EXPORT_LIB_DIR)/%.lib: $(C1_DIR)/%.lib
+$(EXPORT_LIB_DIR)/%.lib: $(C1_BUILD_DIR)/%.lib
$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.diz: $(C1_DIR)/%.diz
+$(EXPORT_JRE_BIN_DIR)/%.diz: $(C1_BUILD_DIR)/%.diz
$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.dll: $(C1_DIR)/%.dll
+$(EXPORT_JRE_BIN_DIR)/%.dll: $(C1_BUILD_DIR)/%.dll
$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.pdb: $(C1_DIR)/%.pdb
+$(EXPORT_JRE_BIN_DIR)/%.pdb: $(C1_BUILD_DIR)/%.pdb
$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.map: $(C1_DIR)/%.map
+$(EXPORT_JRE_BIN_DIR)/%.map: $(C1_BUILD_DIR)/%.map
$(install-file)
# Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
-$(EXPORT_CLIENT_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_CLIENT_DIR)/%.$(LIBRARY_SUFFIX): $(C1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
-$(EXPORT_CLIENT_DIR)/64/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_CLIENT_DIR)/64/%.$(LIBRARY_SUFFIX): $(C1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C1_DIR)/%.debuginfo
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C1_BUILD_DIR)/%.debuginfo
$(install-file)
-$(EXPORT_CLIENT_DIR)/%.debuginfo: $(C1_DIR)/%.debuginfo
+$(EXPORT_CLIENT_DIR)/%.debuginfo: $(C1_BUILD_DIR)/%.debuginfo
$(install-file)
-$(EXPORT_CLIENT_DIR)/64/%.debuginfo: $(C1_DIR)/%.debuginfo
+$(EXPORT_CLIENT_DIR)/64/%.debuginfo: $(C1_BUILD_DIR)/%.debuginfo
$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(C1_DIR)/%.diz
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(C1_BUILD_DIR)/%.diz
$(install-file)
-$(EXPORT_CLIENT_DIR)/64/%.diz: $(C1_DIR)/%.diz
+$(EXPORT_CLIENT_DIR)/64/%.diz: $(C1_BUILD_DIR)/%.diz
$(install-file)
endif
# Minimal1
ifeq ($(JVM_VARIANT_MINIMAL1), true)
# Common
-$(EXPORT_MINIMAL_DIR)/%.diz: $(MINIMAL1_DIR)/%.diz
+$(EXPORT_MINIMAL_DIR)/%.diz: $(MINIMAL1_BUILD_DIR)/%.diz
$(install-file)
-$(EXPORT_LIB_DIR)/%.jar: $(MINIMAL1_DIR)/../generated/%.jar
+$(EXPORT_LIB_DIR)/%.jar: $(MINIMAL1_BUILD_DIR)/../generated/%.jar
$(install-file)
-$(EXPORT_INCLUDE_DIR)/%: $(MINIMAL1_DIR)/../generated/jvmtifiles/%
+$(EXPORT_INCLUDE_DIR)/%: $(MINIMAL1_BUILD_DIR)/../generated/jvmtifiles/%
$(install-file)
# Windows
-$(EXPORT_MINIMAL_DIR)/%.dll: $(MINIMAL1_DIR)/%.dll
+$(EXPORT_MINIMAL_DIR)/%.dll: $(MINIMAL1_BUILD_DIR)/%.dll
$(install-file)
-$(EXPORT_MINIMAL_DIR)/%.pdb: $(MINIMAL1_DIR)/%.pdb
+$(EXPORT_MINIMAL_DIR)/%.pdb: $(MINIMAL1_BUILD_DIR)/%.pdb
$(install-file)
-$(EXPORT_MINIMAL_DIR)/%.map: $(MINIMAL1_DIR)/%.map
+$(EXPORT_MINIMAL_DIR)/%.map: $(MINIMAL1_BUILD_DIR)/%.map
$(install-file)
-$(EXPORT_LIB_DIR)/%.lib: $(MINIMAL1_DIR)/%.lib
+$(EXPORT_LIB_DIR)/%.lib: $(MINIMAL1_BUILD_DIR)/%.lib
$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.diz: $(MINIMAL1_DIR)/%.diz
+$(EXPORT_JRE_BIN_DIR)/%.diz: $(MINIMAL1_BUILD_DIR)/%.diz
$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.dll: $(MINIMAL1_DIR)/%.dll
+$(EXPORT_JRE_BIN_DIR)/%.dll: $(MINIMAL1_BUILD_DIR)/%.dll
$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.pdb: $(MINIMAL1_DIR)/%.pdb
+$(EXPORT_JRE_BIN_DIR)/%.pdb: $(MINIMAL1_BUILD_DIR)/%.pdb
$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.map: $(MINIMAL1_DIR)/%.map
+$(EXPORT_JRE_BIN_DIR)/%.map: $(MINIMAL1_BUILD_DIR)/%.map
$(install-file)
# Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(MINIMAL1_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(MINIMAL1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
-$(EXPORT_MINIMAL_DIR)/%.$(LIBRARY_SUFFIX): $(MINIMAL1_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_MINIMAL_DIR)/%.$(LIBRARY_SUFFIX): $(MINIMAL1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
-$(EXPORT_MINIMAL_DIR)/64/%.$(LIBRARY_SUFFIX): $(MINIMAL1_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_MINIMAL_DIR)/64/%.$(LIBRARY_SUFFIX): $(MINIMAL1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(MINIMAL1_DIR)/%.debuginfo
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(MINIMAL1_BUILD_DIR)/%.debuginfo
$(install-file)
-$(EXPORT_MINIMAL_DIR)/%.debuginfo: $(MINIMAL1_DIR)/%.debuginfo
+$(EXPORT_MINIMAL_DIR)/%.debuginfo: $(MINIMAL1_BUILD_DIR)/%.debuginfo
$(install-file)
-$(EXPORT_MINIMAL_DIR)/64/%.debuginfo: $(MINIMAL1_DIR)/%.debuginfo
+$(EXPORT_MINIMAL_DIR)/64/%.debuginfo: $(MINIMAL1_BUILD_DIR)/%.debuginfo
$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(MINIMAL1_DIR)/%.diz
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(MINIMAL1_BUILD_DIR)/%.diz
$(install-file)
-$(EXPORT_MINIMAL_DIR)/64/%.diz: $(MINIMAL1_DIR)/%.diz
+$(EXPORT_MINIMAL_DIR)/64/%.diz: $(MINIMAL1_BUILD_DIR)/%.diz
$(install-file)
endif
# Zero
ifeq ($(JVM_VARIANT_ZERO), true)
# Common
-$(EXPORT_LIB_DIR)/%.jar: $(ZERO_DIR)/../generated/%.jar
+$(EXPORT_LIB_DIR)/%.jar: $(ZERO_BUILD_DIR)/../generated/%.jar
$(install-file)
-$(EXPORT_INCLUDE_DIR)/%: $(ZERO_DIR)/../generated/jvmtifiles/%
+$(EXPORT_INCLUDE_DIR)/%: $(ZERO_BUILD_DIR)/../generated/jvmtifiles/%
$(install-file)
# Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(ZERO_DIR)/%.debuginfo
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(ZERO_BUILD_DIR)/%.debuginfo
$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(ZERO_DIR)/%.diz
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(ZERO_BUILD_DIR)/%.diz
$(install-file)
-$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
-$(EXPORT_SERVER_DIR)/%.debuginfo: $(ZERO_DIR)/%.debuginfo
+$(EXPORT_SERVER_DIR)/%.debuginfo: $(ZERO_BUILD_DIR)/%.debuginfo
$(install-file)
-$(EXPORT_SERVER_DIR)/%.diz: $(ZERO_DIR)/%.diz
+$(EXPORT_SERVER_DIR)/%.diz: $(ZERO_BUILD_DIR)/%.diz
$(install-file)
endif
# Shark
ifeq ($(JVM_VARIANT_ZEROSHARK), true)
# Common
-$(EXPORT_LIB_DIR)/%.jar: $(SHARK_DIR)/../generated/%.jar
+$(EXPORT_LIB_DIR)/%.jar: $(SHARK_BUILD_DIR)/../generated/%.jar
$(install-file)
-$(EXPORT_INCLUDE_DIR)/%: $(SHARK_DIR)/../generated/jvmtifiles/%
+$(EXPORT_INCLUDE_DIR)/%: $(SHARK_BUILD_DIR)/../generated/jvmtifiles/%
$(install-file)
# Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo): $(SHARK_DIR)/%.debuginfo
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo): $(SHARK_BUILD_DIR)/%.debuginfo
$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(SHARK_DIR)/%.diz
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(SHARK_BUILD_DIR)/%.diz
$(install-file)
-$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
-$(EXPORT_SERVER_DIR)/%.debuginfo: $(SHARK_DIR)/%.debuginfo
+$(EXPORT_SERVER_DIR)/%.debuginfo: $(SHARK_BUILD_DIR)/%.debuginfo
$(install-file)
-$(EXPORT_SERVER_DIR)/%.diz: $(SHARK_DIR)/%.diz
+$(EXPORT_SERVER_DIR)/%.diz: $(SHARK_BUILD_DIR)/%.diz
$(install-file)
endif
diff --git a/hotspot/make/bsd/makefiles/arm.make b/hotspot/make/bsd/makefiles/arm.make
index e22d5c375dc..f35f70a579b 100644
--- a/hotspot/make/bsd/makefiles/arm.make
+++ b/hotspot/make/bsd/makefiles/arm.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,8 @@
Obj_Files += bsd_arm.o
-LIBS += $(EXT_LIBS_PATH)/sflt_glibc.a
+ifneq ($(EXT_LIBS_PATH),)
+ LIBS += $(EXT_LIBS_PATH)/sflt_glibc.a
+endif
CFLAGS += -DVM_LITTLE_ENDIAN
diff --git a/hotspot/make/bsd/makefiles/buildtree.make b/hotspot/make/bsd/makefiles/buildtree.make
index 9d0a2174c54..16a0f9a64ff 100644
--- a/hotspot/make/bsd/makefiles/buildtree.make
+++ b/hotspot/make/bsd/makefiles/buildtree.make
@@ -49,7 +49,6 @@
# adlc.make -
# jvmti.make - generate JVMTI bindings from the spec (JSR-163)
# sa.make - generate SA jar file and natives
-# env.[ck]sh - environment settings
#
# The makefiles are split this way so that "make foo" will run faster by not
# having to read the dependency files for the vm.
@@ -129,9 +128,7 @@ SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
# dtrace.make is used on BSD versions that implement Dtrace (like MacOS X)
-BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make \
- jvmti.make sa.make dtrace.make \
- env.sh env.csh jdkpath.sh
+BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make dtrace.make
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -354,33 +351,6 @@ dtrace.make: $(BUILDTREE_MAKE)
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
) > $@
-env.sh: $(BUILDTREE_MAKE)
- @echo Creating $@ ...
- $(QUIETLY) ( \
- $(BUILDTREE_COMMENT); \
- { echo "JAVA_HOME=$(JDK_IMPORT_PATH)"; }; \
- { \
- echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \
- } | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \
- echo "HOTSPOT_BUILD_USER=\"$${LOGNAME:-$$USER} in `basename $(GAMMADIR)`\""; \
- echo "export JAVA_HOME CLASSPATH HOTSPOT_BUILD_USER"; \
- ) > $@
-
-env.csh: env.sh
- @echo Creating $@ ...
- $(QUIETLY) ( \
- $(BUILDTREE_COMMENT); \
- { echo "setenv JAVA_HOME \"$(JDK_IMPORT_PATH)\""; }; \
- sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \
- ) > $@
-
-jdkpath.sh: $(BUILDTREE_MAKE)
- @echo Creating $@ ...
- $(QUIETLY) ( \
- $(BUILDTREE_COMMENT); \
- echo "JDK=${JAVA_HOME}"; \
- ) > $@
-
FORCE:
.PHONY: all FORCE
diff --git a/hotspot/make/bsd/makefiles/fastdebug.make b/hotspot/make/bsd/makefiles/fastdebug.make
index d7913934083..f2f5dcfb8f2 100644
--- a/hotspot/make/bsd/makefiles/fastdebug.make
+++ b/hotspot/make/bsd/makefiles/fastdebug.make
@@ -58,6 +58,6 @@ CFLAGS$(HOTSPARC_GENERIC) += $(OPT_CFLAGS/BYFILE)
# Linker mapfile
MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug
-VERSION = optimized
+VERSION = fastdebug
SYSDEFS += -DASSERT
PICFLAGS = DEFAULT
diff --git a/hotspot/make/bsd/makefiles/launcher.make b/hotspot/make/bsd/makefiles/launcher.make
deleted file mode 100644
index 588bf9aaebf..00000000000
--- a/hotspot/make/bsd/makefiles/launcher.make
+++ /dev/null
@@ -1,115 +0,0 @@
-#
-# Copyright (c) 2005, 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.
-#
-#
-
-# Rules to build gamma launcher, used by vm.make
-
-
-LAUNCHER_SCRIPT = hotspot
-LAUNCHER = gamma
-
-LAUNCHERDIR := $(GAMMADIR)/src/os/posix/launcher
-LAUNCHERDIR_SHARE := $(GAMMADIR)/src/share/tools/launcher
-LAUNCHERFLAGS := $(ARCHFLAG) \
- -I$(LAUNCHERDIR) -I$(GAMMADIR)/src/share/vm/prims \
- -I$(LAUNCHERDIR_SHARE) \
- -DFULL_VERSION=\"$(HOTSPOT_RELEASE_VERSION)\" \
- -DJDK_MAJOR_VERSION=\"$(JDK_MAJOR_VERSION)\" \
- -DJDK_MINOR_VERSION=\"$(JDK_MINOR_VERSION)\" \
- -DARCH=\"$(LIBARCH)\" \
- -DGAMMA \
- -DLAUNCHER_TYPE=\"gamma\" \
- -DLINK_INTO_$(LINK_INTO) \
- $(TARGET_DEFINES)
-# Give the launcher task_for_pid() privileges so that it can be used to run JStack, JInfo, et al.
-LFLAGS_LAUNCHER += -sectcreate __TEXT __info_plist $(GAMMADIR)/src/os/bsd/launcher/Info-privileged.plist
-
-ifeq ($(LINK_INTO),AOUT)
- LAUNCHER.o = launcher.o $(JVM_OBJ_FILES)
- LAUNCHER_MAPFILE = mapfile_reorder
- LFLAGS_LAUNCHER$(LDNOMAP) += $(MAPFLAG:FILENAME=$(LAUNCHER_MAPFILE))
- LFLAGS_LAUNCHER += $(SONAMEFLAG:SONAME=$(LIBJVM)) $(STATIC_LIBGCC)
- LIBS_LAUNCHER += $(STATIC_STDCXX) $(LIBS)
-else
- LAUNCHER.o = launcher.o
- LFLAGS_LAUNCHER += -L`pwd`
-
- # The gamma launcher runs the JDK from $JAVA_HOME, overriding the JVM with a
- # freshly built JVM at ./libjvm.{so|dylib}. This is accomplished by setting
- # the library searchpath using ({DY}LD_LIBRARY_PATH) to find the local JVM
- # first. Gamma dlopen()s libjava from $JAVA_HOME/jre/lib{/$arch}, which is
- # statically linked with CoreFoundation framework libs. Unfortunately, gamma's
- # unique searchpath results in some unresolved symbols in the framework
- # libraries, because JDK libraries are inadvertently discovered first on the
- # searchpath, e.g. libjpeg. On Mac OS X, filenames are case *insensitive*.
- # So, the actual filename collision is libjpeg.dylib and libJPEG.dylib.
- # To resolve this, gamma needs to also statically link with the CoreFoundation
- # framework libraries.
-
- ifeq ($(OS_VENDOR),Darwin)
- LFLAGS_LAUNCHER += -framework CoreFoundation
- endif
-
- LIBS_LAUNCHER += -l$(JVM) $(LIBS)
-endif
-
-LINK_LAUNCHER = $(LINK.CC)
-
-LINK_LAUNCHER/PRE_HOOK = $(LINK_LIB.CXX/PRE_HOOK)
-LINK_LAUNCHER/POST_HOOK = $(LINK_LIB.CXX/POST_HOOK)
-
-LAUNCHER_OUT = launcher
-
-SUFFIXES += .d
-
-SOURCES := $(shell find $(LAUNCHERDIR) -name "*.c")
-SOURCES_SHARE := $(shell find $(LAUNCHERDIR_SHARE) -name "*.c")
-
-OBJS := $(patsubst $(LAUNCHERDIR)/%.c,$(LAUNCHER_OUT)/%.o,$(SOURCES)) $(patsubst $(LAUNCHERDIR_SHARE)/%.c,$(LAUNCHER_OUT)/%.o,$(SOURCES_SHARE))
-
-DEPFILES := $(patsubst %.o,%.d,$(OBJS))
--include $(DEPFILES)
-
-$(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR_SHARE)/%.c
- $(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); }
- $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS)
-
-$(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR)/%.c
- $(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); }
- $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS)
-
-$(LAUNCHER): $(OBJS) $(LIBJVM) $(LAUNCHER_MAPFILE)
- $(QUIETLY) echo Linking launcher...
- $(QUIETLY) $(LINK_LAUNCHER/PRE_HOOK)
- $(QUIETLY) $(LINK_LAUNCHER) $(LFLAGS_LAUNCHER) -o $@ $(sort $(OBJS)) $(LIBS_LAUNCHER)
- $(QUIETLY) $(LINK_LAUNCHER/POST_HOOK)
- # Sign the launcher with the development certificate (if present) so that it can be used
- # to run JStack, JInfo, et al.
- $(QUIETLY) -codesign -s openjdk_codesign $@
-
-$(LAUNCHER): $(LAUNCHER_SCRIPT)
-
-$(LAUNCHER_SCRIPT): $(LAUNCHERDIR)/launcher.script
- $(QUIETLY) sed -e 's/@@LIBARCH@@/$(LIBARCH)/g' $< > $@
- $(QUIETLY) chmod +x $@
-
diff --git a/hotspot/make/bsd/makefiles/vm.make b/hotspot/make/bsd/makefiles/vm.make
index b9528e101ee..f668b4e5334 100644
--- a/hotspot/make/bsd/makefiles/vm.make
+++ b/hotspot/make/bsd/makefiles/vm.make
@@ -144,6 +144,9 @@ JVM = jvm
ifeq ($(OS_VENDOR), Darwin)
LIBJVM = lib$(JVM).dylib
CFLAGS += -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE
+ ifeq (${VERSION}, $(filter ${VERSION}, debug fastdebug))
+ CFLAGS += -DALLOW_OPERATOR_NEW_USAGE
+ endif
else
LIBJVM = lib$(JVM).so
endif
@@ -328,9 +331,6 @@ install_jvm: $(LIBJVM)
#----------------------------------------------------------------------
# Other files
-# Gamma launcher
-include $(MAKEFILES_DIR)/launcher.make
-
# Signal interposition library
include $(MAKEFILES_DIR)/jsig.make
diff --git a/hotspot/src/os/posix/launcher/launcher.script b/hotspot/make/hotspot.script
similarity index 89%
rename from hotspot/src/os/posix/launcher/launcher.script
rename to hotspot/make/hotspot.script
index e8d4281808a..c6259ba2eee 100644
--- a/hotspot/src/os/posix/launcher/launcher.script
+++ b/hotspot/make/hotspot.script
@@ -72,6 +72,7 @@ EMACS=emacs
REL_MYDIR=`dirname $0`
MYDIR=`cd $REL_MYDIR && pwd`
+#
# Look whether the user wants to run inside gdb
case "$1" in
-gdb)
@@ -95,16 +96,14 @@ case "$1" in
;;
esac
-JDK=
-if [ "${ALT_JAVA_HOME}" = "" ]; then
- . ${MYDIR}/jdkpath.sh
+if [ "${ALT_JAVA_HOME}" != "" ]; then
+ JDK=${ALT_JAVA_HOME%%/jre}
else
- JDK=${ALT_JAVA_HOME%%/jre};
+ JDK=@@JDK_IMPORT_PATH@@
fi
if [ "${JDK}" = "" ]; then
- echo Failed to find JDK. ALT_JAVA_HOME is not set or ./jdkpath.sh is empty or not found.
- exit 1
+ echo "Failed to find JDK. Either ALT_JAVA_HOME is not set or JDK_IMPORT_PATH is empty."
fi
# We will set the LD_LIBRARY_PATH as follows:
@@ -142,12 +141,12 @@ else
export LD_LIBRARY_PATH
fi
-JPARMS="$@ $JAVA_ARGS";
+JPARMS="-Dsun.java.launcher=gamma -XXaltjvm=$MYDIR $@ $JAVA_ARGS";
-# Locate the gamma development launcher
-LAUNCHER=${MYDIR}/gamma
+# Locate the java launcher
+LAUNCHER=$JDK/bin/java
if [ ! -x $LAUNCHER ] ; then
- echo Error: Cannot find the gamma development launcher \"$LAUNCHER\"
+ echo Error: Cannot find the java launcher \"$LAUNCHER\"
exit 1
fi
@@ -166,9 +165,10 @@ set args $JPARMS
file $LAUNCHER
directory $GDBSRCDIR
# Get us to a point where we can set breakpoints in libjvm.so
-break InitializeJVM
+set breakpoint pending on
+break JNI_CreateJavaVM
run
-# Stop in InitializeJVM
+# Stop in JNI_CreateJavaVM
delete 1
# We can now set breakpoints wherever we like
EOF
@@ -199,7 +199,7 @@ case "$MODE" in
rm -f $GDBSCR
;;
dbx)
- $DBX -s $HOME/.dbxrc $LAUNCHER $JPARMS
+ $DBX -s $HOME/.dbxrc -c "loadobject -load libjvm.so; stop in JNI_CreateJavaVM; run $JPARMS; delete all" $LAUNCHER
;;
valgrind)
echo Warning: Defaulting to 16Mb heap to make Valgrind run faster, use -Xmx for larger heap
diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version
index a189566b812..db74b20d81b 100644
--- a/hotspot/make/hotspot_version
+++ b/hotspot/make/hotspot_version
@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=32
+HS_BUILD_NUMBER=34
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
diff --git a/hotspot/make/jprt.properties b/hotspot/make/jprt.properties
index af7f321b722..5971546c6d9 100644
--- a/hotspot/make/jprt.properties
+++ b/hotspot/make/jprt.properties
@@ -134,14 +134,14 @@ jprt.my.windows.x64=${jprt.my.windows.x64.${jprt.tools.default.release}}
jprt.build.targets.standard= \
${jprt.my.solaris.sparc}-{product|fastdebug}, \
- ${jprt.my.solaris.sparcv9}-{product|fastdebug}, \
+ ${jprt.my.solaris.sparcv9}-{product|fastdebug|optimized}, \
${jprt.my.solaris.i586}-{product|fastdebug}, \
${jprt.my.solaris.x64}-{product|fastdebug}, \
${jprt.my.linux.i586}-{product|fastdebug}, \
- ${jprt.my.linux.x64}-{product|fastdebug}, \
+ ${jprt.my.linux.x64}-{product|fastdebug|optimized}, \
${jprt.my.macosx.x64}-{product|fastdebug}, \
${jprt.my.windows.i586}-{product|fastdebug}, \
- ${jprt.my.windows.x64}-{product|fastdebug}, \
+ ${jprt.my.windows.x64}-{product|fastdebug|optimized}, \
${jprt.my.linux.armvh}-{product|fastdebug}
jprt.build.targets.open= \
diff --git a/hotspot/make/linux/makefiles/arm.make b/hotspot/make/linux/makefiles/arm.make
index 6d7079e5619..ff8e3c519f9 100644
--- a/hotspot/make/linux/makefiles/arm.make
+++ b/hotspot/make/linux/makefiles/arm.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,8 @@
Obj_Files += linux_arm.o
-LIBS += $(EXT_LIBS_PATH)/sflt_glibc.a
+ifneq ($(EXT_LIBS_PATH),)
+ LIBS += $(EXT_LIBS_PATH)/sflt_glibc.a
+endif
CFLAGS += -DVM_LITTLE_ENDIAN
diff --git a/hotspot/make/linux/makefiles/buildtree.make b/hotspot/make/linux/makefiles/buildtree.make
index 0b7c12001b3..3b715773554 100644
--- a/hotspot/make/linux/makefiles/buildtree.make
+++ b/hotspot/make/linux/makefiles/buildtree.make
@@ -49,7 +49,6 @@
# adlc.make -
# jvmti.make - generate JVMTI bindings from the spec (JSR-163)
# sa.make - generate SA jar file and natives
-# env.[ck]sh - environment settings
#
# The makefiles are split this way so that "make foo" will run faster by not
# having to read the dependency files for the vm.
@@ -123,8 +122,7 @@ SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
# For dependencies and recursive makes.
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
-BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \
- env.sh env.csh jdkpath.sh
+BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -349,33 +347,6 @@ sa.make: $(BUILDTREE_MAKE)
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
) > $@
-env.sh: $(BUILDTREE_MAKE)
- @echo Creating $@ ...
- $(QUIETLY) ( \
- $(BUILDTREE_COMMENT); \
- { echo "JAVA_HOME=$(JDK_IMPORT_PATH)"; }; \
- { \
- echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \
- } | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \
- echo "HOTSPOT_BUILD_USER=\"$${LOGNAME:-$$USER} in `basename $(GAMMADIR)`\""; \
- echo "export JAVA_HOME CLASSPATH HOTSPOT_BUILD_USER"; \
- ) > $@
-
-env.csh: env.sh
- @echo Creating $@ ...
- $(QUIETLY) ( \
- $(BUILDTREE_COMMENT); \
- { echo "setenv JAVA_HOME \"$(JDK_IMPORT_PATH)\""; }; \
- sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \
- ) > $@
-
-jdkpath.sh: $(BUILDTREE_MAKE)
- @echo Creating $@ ...
- $(QUIETLY) ( \
- $(BUILDTREE_COMMENT); \
- echo "JDK=${JAVA_HOME}"; \
- ) > $@
-
FORCE:
.PHONY: all FORCE
diff --git a/hotspot/make/linux/makefiles/jsig.make b/hotspot/make/linux/makefiles/jsig.make
index a0c72453f54..1064a965249 100644
--- a/hotspot/make/linux/makefiles/jsig.make
+++ b/hotspot/make/linux/makefiles/jsig.make
@@ -54,7 +54,7 @@ endif
$(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
@echo Making signal interposition lib...
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
- $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) -o $@ $< -ldl
+ $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) $(EXTRA_CFLAGS) -o $@ $< -ldl
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJSIG_DEBUGINFO)
$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@
diff --git a/hotspot/make/linux/makefiles/launcher.make b/hotspot/make/linux/makefiles/launcher.make
deleted file mode 100644
index 23f3edad41a..00000000000
--- a/hotspot/make/linux/makefiles/launcher.make
+++ /dev/null
@@ -1,93 +0,0 @@
-#
-# Copyright (c) 2005, 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.
-#
-#
-
-# Rules to build gamma launcher, used by vm.make
-
-
-LAUNCHER_SCRIPT = hotspot
-LAUNCHER = gamma
-
-LAUNCHERDIR := $(GAMMADIR)/src/os/posix/launcher
-LAUNCHERDIR_SHARE := $(GAMMADIR)/src/share/tools/launcher
-LAUNCHERFLAGS := $(ARCHFLAG) \
- -I$(LAUNCHERDIR) -I$(GAMMADIR)/src/share/vm/prims \
- -I$(LAUNCHERDIR_SHARE) \
- -DFULL_VERSION=\"$(HOTSPOT_RELEASE_VERSION)\" \
- -DJDK_MAJOR_VERSION=\"$(JDK_MAJOR_VERSION)\" \
- -DJDK_MINOR_VERSION=\"$(JDK_MINOR_VERSION)\" \
- -DARCH=\"$(LIBARCH)\" \
- -DGAMMA \
- -DLAUNCHER_TYPE=\"gamma\" \
- -DLINK_INTO_$(LINK_INTO) \
- $(TARGET_DEFINES)
-
-ifeq ($(LINK_INTO),AOUT)
- LAUNCHER.o = launcher.o $(JVM_OBJ_FILES)
- LAUNCHER_MAPFILE = mapfile_reorder
- LFLAGS_LAUNCHER$(LDNOMAP) += $(MAPFLAG:FILENAME=$(LAUNCHER_MAPFILE))
- LFLAGS_LAUNCHER += $(SONAMEFLAG:SONAME=$(LIBJVM)) $(STATIC_LIBGCC)
- LIBS_LAUNCHER += $(STATIC_STDCXX) $(LIBS)
-else
- LAUNCHER.o = launcher.o
- LFLAGS_LAUNCHER += -L `pwd`
- LIBS_LAUNCHER += -l$(JVM) $(LIBS)
-endif
-
-LINK_LAUNCHER = $(LINK.CC)
-
-LINK_LAUNCHER/PRE_HOOK = $(LINK_LIB.CXX/PRE_HOOK)
-LINK_LAUNCHER/POST_HOOK = $(LINK_LIB.CXX/POST_HOOK)
-
-LAUNCHER_OUT = launcher
-
-SUFFIXES += .d
-
-SOURCES := $(shell find $(LAUNCHERDIR) -name "*.c")
-SOURCES_SHARE := $(shell find $(LAUNCHERDIR_SHARE) -name "*.c")
-
-OBJS := $(patsubst $(LAUNCHERDIR)/%.c,$(LAUNCHER_OUT)/%.o,$(SOURCES)) $(patsubst $(LAUNCHERDIR_SHARE)/%.c,$(LAUNCHER_OUT)/%.o,$(SOURCES_SHARE))
-
-DEPFILES := $(patsubst %.o,%.d,$(OBJS))
--include $(DEPFILES)
-
-$(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR_SHARE)/%.c
- $(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); }
- $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS)
-
-$(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR)/%.c
- $(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); }
- $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS)
-
-$(LAUNCHER): $(OBJS) $(LIBJVM) $(LAUNCHER_MAPFILE)
- $(QUIETLY) echo Linking launcher...
- $(QUIETLY) $(LINK_LAUNCHER/PRE_HOOK)
- $(QUIETLY) $(LINK_LAUNCHER) $(LFLAGS_LAUNCHER) -o $@ $(sort $(OBJS)) $(LIBS_LAUNCHER)
- $(QUIETLY) $(LINK_LAUNCHER/POST_HOOK)
-
-$(LAUNCHER): $(LAUNCHER_SCRIPT)
-
-$(LAUNCHER_SCRIPT): $(LAUNCHERDIR)/launcher.script
- $(QUIETLY) sed -e 's/@@LIBARCH@@/$(LIBARCH)/g' $< > $@
- $(QUIETLY) chmod +x $@
-
diff --git a/hotspot/make/linux/makefiles/saproc.make b/hotspot/make/linux/makefiles/saproc.make
index c2a82d717c9..90c91136185 100644
--- a/hotspot/make/linux/makefiles/saproc.make
+++ b/hotspot/make/linux/makefiles/saproc.make
@@ -92,6 +92,7 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
$(SASRCFILES) \
$(SA_LFLAGS) \
$(SA_DEBUG_CFLAGS) \
+ $(EXTRA_CFLAGS) \
-o $@ \
-lthread_db
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
diff --git a/hotspot/make/linux/makefiles/vm.make b/hotspot/make/linux/makefiles/vm.make
index af060f8af0b..79a926a8c4f 100644
--- a/hotspot/make/linux/makefiles/vm.make
+++ b/hotspot/make/linux/makefiles/vm.make
@@ -372,9 +372,6 @@ install_jvm: $(LIBJVM)
#----------------------------------------------------------------------
# Other files
-# Gamma launcher
-include $(MAKEFILES_DIR)/launcher.make
-
# Signal interposition library
include $(MAKEFILES_DIR)/jsig.make
diff --git a/hotspot/make/sa.files b/hotspot/make/sa.files
index c4414be60c1..44308c2a217 100644
--- a/hotspot/make/sa.files
+++ b/hotspot/make/sa.files
@@ -48,8 +48,6 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/bsd/amd64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/bsd/x86/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/basic/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/basic/x86/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/basic/amd64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dummy/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/amd64/*.java \
@@ -70,6 +68,8 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/win32/coff/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/amd64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/x86/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windows/x86/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windows/amd64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/x86/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/gc_implementation/g1/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/gc_implementation/parallelScavenge/*.java \
diff --git a/hotspot/make/solaris/makefiles/buildtree.make b/hotspot/make/solaris/makefiles/buildtree.make
index 989470f293f..5827c4ff7d9 100644
--- a/hotspot/make/solaris/makefiles/buildtree.make
+++ b/hotspot/make/solaris/makefiles/buildtree.make
@@ -49,7 +49,6 @@
# adlc.make -
# jvmti.make - generate JVMTI bindings from the spec (JSR-163)
# sa.make - generate SA jar file and natives
-# env.[ck]sh - environment settings
#
# The makefiles are split this way so that "make foo" will run faster by not
# having to read the dependency files for the vm.
@@ -116,8 +115,7 @@ SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
# For dependencies and recursive makes.
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
-BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \
- env.sh env.csh jdkpath.sh
+BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
ARCH=$(ARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -339,33 +337,6 @@ sa.make: $(BUILDTREE_MAKE)
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
) > $@
-env.sh: $(BUILDTREE_MAKE)
- @echo Creating $@ ...
- $(QUIETLY) ( \
- $(BUILDTREE_COMMENT); \
- { echo "JAVA_HOME=$(JDK_IMPORT_PATH)"; }; \
- { \
- echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \
- } | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \
- echo "HOTSPOT_BUILD_USER=\"$${LOGNAME:-$$USER} in `basename $(GAMMADIR)`\""; \
- echo "export JAVA_HOME LD_LIBRARY_PATH CLASSPATH HOTSPOT_BUILD_USER"; \
- ) > $@
-
-env.csh: env.sh
- @echo Creating $@ ...
- $(QUIETLY) ( \
- $(BUILDTREE_COMMENT); \
- { echo "setenv JAVA_HOME \"$(JDK_IMPORT_PATH)\""; }; \
- sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \
- ) > $@
-
-jdkpath.sh: $(BUILDTREE_MAKE)
- @echo Creating $@ ...
- $(QUIETLY) ( \
- $(BUILDTREE_COMMENT); \
- echo "JDK=${JAVA_HOME}"; \
- ) > $@
-
FORCE:
.PHONY: all FORCE
diff --git a/hotspot/make/solaris/makefiles/launcher.make b/hotspot/make/solaris/makefiles/launcher.make
deleted file mode 100644
index 090ff5ea7a6..00000000000
--- a/hotspot/make/solaris/makefiles/launcher.make
+++ /dev/null
@@ -1,108 +0,0 @@
-#
-# Copyright (c) 2005, 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.
-#
-#
-
-# Rules to build gamma launcher, used by vm.make
-
-LAUNCHER_SCRIPT = hotspot
-LAUNCHER = gamma
-
-LAUNCHERDIR = $(GAMMADIR)/src/os/posix/launcher
-LAUNCHERDIR_SHARE := $(GAMMADIR)/src/share/tools/launcher
-LAUNCHERFLAGS = $(ARCHFLAG) \
- -I$(LAUNCHERDIR) -I$(GAMMADIR)/src/share/vm/prims \
- -I$(LAUNCHERDIR_SHARE) \
- -DFULL_VERSION=\"$(HOTSPOT_RELEASE_VERSION)\" \
- -DJDK_MAJOR_VERSION=\"$(JDK_MAJOR_VERSION)\" \
- -DJDK_MINOR_VERSION=\"$(JDK_MINOR_VERSION)\" \
- -DARCH=\"$(LIBARCH)\" \
- -DGAMMA \
- -DLAUNCHER_TYPE=\"gamma\" \
- -DLINK_INTO_$(LINK_INTO) \
- $(TARGET_DEFINES)
-
-ifeq ($(LINK_INTO),AOUT)
- LAUNCHER.o = launcher.o $(JVM_OBJ_FILES)
- LAUNCHER_MAPFILE = mapfile_extended
- LFLAGS_LAUNCHER$(LDNOMAP) += $(MAPFLAG:FILENAME=$(LAUNCHER_MAPFILE))
- LIBS_LAUNCHER += $(LIBS)
-else
- LAUNCHER.o = launcher.o
- LFLAGS_LAUNCHER += -L `pwd`
- LIBS_LAUNCHER += -l$(JVM) $(LIBS)
-endif
-
-LINK_LAUNCHER = $(LINK.CXX)
-
-LINK_LAUNCHER/PRE_HOOK = $(LINK_LIB.CXX/PRE_HOOK)
-LINK_LAUNCHER/POST_HOOK = $(LINK_LIB.CXX/POST_HOOK)
-
-ifeq ("${Platform_compiler}", "sparcWorks")
-# Enable the following LAUNCHERFLAGS addition if you need to compare the
-# built ELF objects.
-#
-# The -g option makes static data global and the "-W0,-noglobal"
-# option tells the compiler to not globalize static data using a unique
-# globalization prefix. Instead force the use of a static globalization
-# prefix based on the source filepath so the objects from two identical
-# compilations are the same.
-#
-# Note: The blog says to use "-W0,-xglobalstatic", but that doesn't
-# seem to work. I got "-W0,-noglobal" from Kelly and that works.
-#LAUNCHERFLAGS += -W0,-noglobal
-endif # Platform_compiler == sparcWorks
-
-LAUNCHER_OUT = launcher
-
-SUFFIXES += .d
-
-SOURCES := $(shell find $(LAUNCHERDIR) -name "*.c")
-SOURCES_SHARE := $(shell find $(LAUNCHERDIR_SHARE) -name "*.c")
-
-OBJS := $(patsubst $(LAUNCHERDIR)/%.c,$(LAUNCHER_OUT)/%.o,$(SOURCES)) $(patsubst $(LAUNCHERDIR_SHARE)/%.c,$(LAUNCHER_OUT)/%.o,$(SOURCES_SHARE))
-
-DEPFILES := $(patsubst %.o,%.d,$(OBJS))
--include $(DEPFILES)
-
-$(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR_SHARE)/%.c
- $(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); }
- $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS)
-
-$(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR)/%.c
- $(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); }
- $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS)
-
-$(LAUNCHER): $(OBJS) $(LIBJVM) $(LAUNCHER_MAPFILE)
-ifeq ($(filter -sbfast -xsbfast, $(CFLAGS_BROWSE)),)
- $(QUIETLY) echo Linking launcher...
- $(QUIETLY) $(LINK_LAUNCHER/PRE_HOOK)
- $(QUIETLY) $(LINK_LAUNCHER) $(LFLAGS_LAUNCHER) -o $@ $(sort $(OBJS)) $(LIBS_LAUNCHER)
- $(QUIETLY) $(LINK_LAUNCHER/POST_HOOK)
-endif # filter -sbfast -xsbfast
-
-$(LAUNCHER): $(LAUNCHER_SCRIPT)
-
-$(LAUNCHER_SCRIPT): $(LAUNCHERDIR)/launcher.script
- $(QUIETLY) sed -e 's/@@LIBARCH@@/$(LIBARCH)/g' $< > $@
- $(QUIETLY) chmod +x $@
-
diff --git a/hotspot/make/solaris/makefiles/vm.make b/hotspot/make/solaris/makefiles/vm.make
index 62146d77f03..855f7f18861 100644
--- a/hotspot/make/solaris/makefiles/vm.make
+++ b/hotspot/make/solaris/makefiles/vm.make
@@ -338,9 +338,6 @@ install_jvm: $(LIBJVM)
#----------------------------------------------------------------------
# Other files
-# Gamma launcher
-include $(MAKEFILES_DIR)/launcher.make
-
# Signal interposition library
include $(MAKEFILES_DIR)/jsig.make
diff --git a/hotspot/make/windows/makefiles/debug.make b/hotspot/make/windows/makefiles/debug.make
index c19f1757b69..2fca2182841 100644
--- a/hotspot/make/windows/makefiles/debug.make
+++ b/hotspot/make/windows/makefiles/debug.make
@@ -33,7 +33,7 @@ GENERATED=../generated
BUILD_PCH_FILE=_build_pch_file.obj
!endif
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
+default:: $(BUILD_PCH_FILE) $(AOUT) checkAndBuildSA
!include ../local.make
!include compile.make
@@ -71,4 +71,3 @@ $(AOUT): $(Res_Files) $(Obj_Files) vm.def
!include $(WorkSpace)/make/windows/makefiles/shared.make
!include $(WorkSpace)/make/windows/makefiles/sa.make
-!include $(WorkSpace)/make/windows/makefiles/launcher.make
diff --git a/hotspot/make/windows/makefiles/fastdebug.make b/hotspot/make/windows/makefiles/fastdebug.make
index 0fc2329dfd9..cde98f214ea 100644
--- a/hotspot/make/windows/makefiles/fastdebug.make
+++ b/hotspot/make/windows/makefiles/fastdebug.make
@@ -33,7 +33,7 @@ GENERATED=../generated
BUILD_PCH_FILE=_build_pch_file.obj
!endif
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
+default:: $(BUILD_PCH_FILE) $(AOUT) checkAndBuildSA
!include ../local.make
!include compile.make
@@ -70,4 +70,3 @@ $(AOUT): $(Res_Files) $(Obj_Files) vm.def
!include $(WorkSpace)/make/windows/makefiles/shared.make
!include $(WorkSpace)/make/windows/makefiles/sa.make
-!include $(WorkSpace)/make/windows/makefiles/launcher.make
diff --git a/hotspot/make/windows/makefiles/launcher.make b/hotspot/make/windows/makefiles/launcher.make
deleted file mode 100644
index 10ad009eef9..00000000000
--- a/hotspot/make/windows/makefiles/launcher.make
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# Copyright (c) 2010, 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.
-#
-#
-
-
-LAUNCHER_FLAGS=$(CXX_FLAGS) $(ARCHFLAG) \
- /D FULL_VERSION=\"$(HOTSPOT_RELEASE_VERSION)\" \
- /D JDK_MAJOR_VERSION=\"$(JDK_MAJOR_VERSION)\" \
- /D JDK_MINOR_VERSION=\"$(JDK_MINOR_VERSION)\" \
- /D GAMMA \
- /D LAUNCHER_TYPE=\"gamma\" \
- /D _CRT_SECURE_NO_WARNINGS \
- /D _CRT_SECURE_NO_DEPRECATE \
- /D LINK_INTO_LIBJVM \
- /I $(WorkSpace)\src\os\windows\launcher \
- /I $(WorkSpace)\src\share\tools\launcher \
- /I $(WorkSpace)\src\share\vm\prims \
- /I $(WorkSpace)\src\share\vm \
- /I $(WorkSpace)\src\cpu\$(Platform_arch)\vm \
- /I $(WorkSpace)\src\os\windows\vm
-
-LD_FLAGS=/manifest $(HS_INTERNAL_NAME).lib kernel32.lib user32.lib /nologo /machine:$(MACHINE) /map /debug /subsystem:console
-
-!if "$(COMPILER_NAME)" == "VS2005"
-# This VS2005 compiler has /GS as a default and requires bufferoverflowU.lib
-# on the link command line, otherwise we get missing __security_check_cookie
-# externals at link time. Even with /GS-, you need bufferoverflowU.lib.
-BUFFEROVERFLOWLIB = bufferoverflowU.lib
-LD_FLAGS = $(LD_FLAGS) $(BUFFEROVERFLOWLIB)
-!endif
-
-!if "$(COMPILER_NAME)" == "VS2010" && "$(BUILDARCH)" == "i486"
-LD_FLAGS = /SAFESEH $(LD_FLAGS)
-!endif
-
-LAUNCHERDIR = $(WorkSpace)/src/os/windows/launcher
-LAUNCHERDIR_SHARE = $(WorkSpace)/src/share/tools/launcher
-
-OUTDIR = launcher
-
-{$(LAUNCHERDIR)}.c{$(OUTDIR)}.obj:
- -mkdir $(OUTDIR) 2>NUL >NUL
- $(CXX) $(LAUNCHER_FLAGS) /c /Fo$@ $<
-
-{$(LAUNCHERDIR_SHARE)}.c{$(OUTDIR)}.obj:
- -mkdir $(OUTDIR) 2>NUL >NUL
- $(CXX) $(LAUNCHER_FLAGS) /c /Fo$@ $<
-
-$(OUTDIR)\*.obj: $(LAUNCHERDIR)\*.c $(LAUNCHERDIR)\*.h $(LAUNCHERDIR_SHARE)\*.c $(LAUNCHERDIR_SHARE)\*.h
-
-launcher: $(OUTDIR)\java.obj $(OUTDIR)\java_md.obj $(OUTDIR)\jli_util.obj
- echo $(JAVA_HOME) > jdkpath.txt
- $(LD) $(LD_FLAGS) /out:hotspot.exe $**
diff --git a/hotspot/make/windows/makefiles/product.make b/hotspot/make/windows/makefiles/product.make
index f166f7377bf..407484cd46e 100644
--- a/hotspot/make/windows/makefiles/product.make
+++ b/hotspot/make/windows/makefiles/product.make
@@ -32,7 +32,7 @@ GENERATED=../generated
BUILD_PCH_FILE=_build_pch_file.obj
!endif
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
+default:: $(BUILD_PCH_FILE) $(AOUT) checkAndBuildSA
!include ../local.make
!include compile.make
@@ -73,4 +73,3 @@ $(AOUT): $(Res_Files) $(Obj_Files) vm.def
!include $(WorkSpace)/make/windows/makefiles/shared.make
!include $(WorkSpace)/make/windows/makefiles/sa.make
-!include $(WorkSpace)/make/windows/makefiles/launcher.make
diff --git a/hotspot/make/windows/makefiles/projectcreator.make b/hotspot/make/windows/makefiles/projectcreator.make
index 68d098d0de3..f142852ed12 100644
--- a/hotspot/make/windows/makefiles/projectcreator.make
+++ b/hotspot/make/windows/makefiles/projectcreator.make
@@ -59,7 +59,6 @@ ProjectCreatorIncludesPRIVATE=\
-relativeSrcInclude src \
-absoluteSrcInclude $(HOTSPOTBUILDSPACE) \
-ignorePath $(HOTSPOTBUILDSPACE) \
- -ignorePath launcher \
-ignorePath share\vm\adlc \
-ignorePath share\vm\shark \
-ignorePath share\tools \
@@ -105,7 +104,6 @@ ProjectCreatorIDEOptions=\
-define ALIGN_STACK_FRAMES \
-define VM_LITTLE_ENDIAN \
-prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) set JAVA_HOME=$(HOTSPOTJDKDIST) $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LD_VER)" \
- -postbuild "" "Building hotspot.exe..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) nmake -f $(HOTSPOTWORKSPACE)\make\windows\projectfiles\common\Makefile LOCAL_MAKE=$(HOTSPOTBUILDSPACE)\%f\local.make JAVA_HOME=$(HOTSPOTJDKDIST) launcher" \
-ignoreFile jsig.c \
-ignoreFile jvmtiEnvRecommended.cpp \
-ignoreFile jvmtiEnvStub.cpp \
diff --git a/hotspot/make/windows/projectfiles/common/Makefile b/hotspot/make/windows/projectfiles/common/Makefile
index 125923e67b2..5556aae5149 100644
--- a/hotspot/make/windows/projectfiles/common/Makefile
+++ b/hotspot/make/windows/projectfiles/common/Makefile
@@ -65,7 +65,6 @@ JvmtiOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\jvmtifiles
!endif
HS_INTERNAL_NAME=jvm
-!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/launcher.make
default:: $(AdditionalTargets) $(JvmtiGeneratedFiles)
diff --git a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp
index ee330c69fa3..35886ce8ea9 100644
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp
@@ -74,7 +74,7 @@ define_pd_global(bool, RewriteFrequentPairs, true);
define_pd_global(bool, UseMembar, false);
// GC Ergo Flags
-define_pd_global(intx, CMSYoungGenPerWorker, 16*M); // default max size of CMS young gen, per GC worker thread
+define_pd_global(uintx, CMSYoungGenPerWorker, 16*M); // default max size of CMS young gen, per GC worker thread
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
\
diff --git a/hotspot/src/cpu/x86/vm/globals_x86.hpp b/hotspot/src/cpu/x86/vm/globals_x86.hpp
index fb44e2db52f..978a1d6eece 100644
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp
@@ -77,7 +77,7 @@ define_pd_global(bool, UseMembar, false);
#endif
// GC Ergo Flags
-define_pd_global(intx, CMSYoungGenPerWorker, 64*M); // default max size of CMS young gen, per GC worker thread
+define_pd_global(uintx, CMSYoungGenPerWorker, 64*M); // default max size of CMS young gen, per GC worker thread
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
\
diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
index f3a91d03c99..7422ed39d24 100644
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
@@ -1498,27 +1498,29 @@ class StubGenerator: public StubCodeGenerator {
__ movptr(elem_klass, elem_klass_addr); // query the object klass
generate_type_check(elem_klass, ckoff_arg, ckval_arg, temp,
&L_store_element, NULL);
- // (On fall-through, we have failed the element type check.)
+ // (On fall-through, we have failed the element type check.)
// ======== end loop ========
// It was a real error; we must depend on the caller to finish the job.
// Register "count" = -1 * number of *remaining* oops, length_arg = *total* oops.
// Emit GC store barriers for the oops we have copied (length_arg + count),
// and report their number to the caller.
+ assert_different_registers(to, count, rax);
+ Label L_post_barrier;
__ addl(count, length_arg); // transfers = (length - remaining)
__ movl2ptr(rax, count); // save the value
- __ notptr(rax); // report (-1^K) to caller
- __ movptr(to, to_arg); // reload
- assert_different_registers(to, count, rax);
- gen_write_ref_array_post_barrier(to, count);
- __ jmpb(L_done);
+ __ notptr(rax); // report (-1^K) to caller (does not affect flags)
+ __ jccb(Assembler::notZero, L_post_barrier);
+ __ jmp(L_done); // K == 0, nothing was copied, skip post barrier
// Come here on success only.
__ BIND(L_do_card_marks);
+ __ xorptr(rax, rax); // return 0 on success
__ movl2ptr(count, length_arg);
- __ movptr(to, to_arg); // reload
+
+ __ BIND(L_post_barrier);
+ __ movptr(to, to_arg); // reload
gen_write_ref_array_post_barrier(to, count);
- __ xorptr(rax, rax); // return 0 on success
// Common exit point (success or failure).
__ BIND(L_done);
diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
index ace545383d7..fb9c1ddd4b9 100644
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
@@ -1217,27 +1217,28 @@ class StubGenerator: public StubCodeGenerator {
//
// Input:
// start - register containing starting address of destination array
- // end - register containing ending address of destination array
+ // count - elements count
// scratch - scratch register
//
// The input registers are overwritten.
- // The ending address is inclusive.
- void gen_write_ref_array_post_barrier(Register start, Register end, Register scratch) {
- assert_different_registers(start, end, scratch);
+ //
+ void gen_write_ref_array_post_barrier(Register start, Register count, Register scratch) {
+ assert_different_registers(start, count, scratch);
BarrierSet* bs = Universe::heap()->barrier_set();
switch (bs->kind()) {
case BarrierSet::G1SATBCT:
case BarrierSet::G1SATBCTLogging:
-
{
- __ pusha(); // push registers (overkill)
- // must compute element count unless barrier set interface is changed (other platforms supply count)
- assert_different_registers(start, end, scratch);
- __ lea(scratch, Address(end, BytesPerHeapOop));
- __ subptr(scratch, start); // subtract start to get #bytes
- __ shrptr(scratch, LogBytesPerHeapOop); // convert to element count
- __ mov(c_rarg0, start);
- __ mov(c_rarg1, scratch);
+ __ pusha(); // push registers (overkill)
+ if (c_rarg0 == count) { // On win64 c_rarg0 == rcx
+ assert_different_registers(c_rarg1, start);
+ __ mov(c_rarg1, count);
+ __ mov(c_rarg0, start);
+ } else {
+ assert_different_registers(c_rarg0, count);
+ __ mov(c_rarg0, start);
+ __ mov(c_rarg1, count);
+ }
__ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
__ popa();
}
@@ -1249,22 +1250,16 @@ class StubGenerator: public StubCodeGenerator {
assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
Label L_loop;
+ const Register end = count;
- __ shrptr(start, CardTableModRefBS::card_shift);
- __ addptr(end, BytesPerHeapOop);
- __ shrptr(end, CardTableModRefBS::card_shift);
- __ subptr(end, start); // number of bytes to copy
+ __ leaq(end, Address(start, count, TIMES_OOP, 0)); // end == start+count*oop_size
+ __ subptr(end, BytesPerHeapOop); // end - 1 to make inclusive
+ __ shrptr(start, CardTableModRefBS::card_shift);
+ __ shrptr(end, CardTableModRefBS::card_shift);
+ __ subptr(end, start); // end --> cards count
- intptr_t disp = (intptr_t) ct->byte_map_base;
- if (Assembler::is_simm32(disp)) {
- Address cardtable(noreg, noreg, Address::no_scale, disp);
- __ lea(scratch, cardtable);
- } else {
- ExternalAddress cardtable((address)disp);
- __ lea(scratch, cardtable);
- }
-
- const Register count = end; // 'end' register contains bytes count now
+ int64_t disp = (int64_t) ct->byte_map_base;
+ __ mov64(scratch, disp);
__ addptr(start, scratch);
__ BIND(L_loop);
__ movb(Address(start, count, Address::times_1), 0);
@@ -1916,8 +1911,7 @@ class StubGenerator: public StubCodeGenerator {
__ BIND(L_exit);
if (is_oop) {
- __ leaq(end_to, Address(saved_to, dword_count, Address::times_4, -4));
- gen_write_ref_array_post_barrier(saved_to, end_to, rax);
+ gen_write_ref_array_post_barrier(saved_to, dword_count, rax);
}
restore_arg_regs();
inc_counter_np(SharedRuntime::_jint_array_copy_ctr); // Update counter after rscratch1 is free
@@ -2012,12 +2006,10 @@ class StubGenerator: public StubCodeGenerator {
// Copy in multi-bytes chunks
copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
- __ bind(L_exit);
- if (is_oop) {
- Register end_to = rdx;
- __ leaq(end_to, Address(to, dword_count, Address::times_4, -4));
- gen_write_ref_array_post_barrier(to, end_to, rax);
- }
+ __ BIND(L_exit);
+ if (is_oop) {
+ gen_write_ref_array_post_barrier(to, dword_count, rax);
+ }
restore_arg_regs();
inc_counter_np(SharedRuntime::_jint_array_copy_ctr); // Update counter after rscratch1 is free
__ xorptr(rax, rax); // return 0
@@ -2055,6 +2047,7 @@ class StubGenerator: public StubCodeGenerator {
const Register end_from = from; // source array end address
const Register end_to = rcx; // destination array end address
const Register saved_to = to;
+ const Register saved_count = r11;
// End pointers are inclusive, and if count is not zero they point
// to the last unit copied: end_to[0] := end_from[0]
@@ -2072,6 +2065,8 @@ class StubGenerator: public StubCodeGenerator {
// r9 and r10 may be used to save non-volatile registers
// 'from', 'to' and 'qword_count' are now valid
if (is_oop) {
+ // Save to and count for store barrier
+ __ movptr(saved_count, qword_count);
// no registers are destroyed by this call
gen_write_ref_array_pre_barrier(to, qword_count, dest_uninitialized);
}
@@ -2104,7 +2099,7 @@ class StubGenerator: public StubCodeGenerator {
if (is_oop) {
__ BIND(L_exit);
- gen_write_ref_array_post_barrier(saved_to, end_to, rax);
+ gen_write_ref_array_post_barrier(saved_to, saved_count, rax);
}
restore_arg_regs();
if (is_oop) {
@@ -2187,8 +2182,7 @@ class StubGenerator: public StubCodeGenerator {
if (is_oop) {
__ BIND(L_exit);
- __ lea(rcx, Address(to, saved_count, Address::times_8, -8));
- gen_write_ref_array_post_barrier(to, rcx, rax);
+ gen_write_ref_array_post_barrier(to, saved_count, rax);
}
restore_arg_regs();
if (is_oop) {
@@ -2375,20 +2369,20 @@ class StubGenerator: public StubCodeGenerator {
// Register rdx = -1 * number of *remaining* oops, r14 = *total* oops.
// Emit GC store barriers for the oops we have copied (r14 + rdx),
// and report their number to the caller.
- assert_different_registers(rax, r14_length, count, to, end_to, rcx);
- __ lea(end_to, to_element_addr);
- __ addptr(end_to, -heapOopSize); // make an inclusive end pointer
- gen_write_ref_array_post_barrier(to, end_to, rscratch1);
- __ movptr(rax, r14_length); // original oops
- __ addptr(rax, count); // K = (original - remaining) oops
- __ notptr(rax); // report (-1^K) to caller
- __ jmp(L_done);
+ assert_different_registers(rax, r14_length, count, to, end_to, rcx, rscratch1);
+ Label L_post_barrier;
+ __ addptr(r14_length, count); // K = (original - remaining) oops
+ __ movptr(rax, r14_length); // save the value
+ __ notptr(rax); // report (-1^K) to caller (does not affect flags)
+ __ jccb(Assembler::notZero, L_post_barrier);
+ __ jmp(L_done); // K == 0, nothing was copied, skip post barrier
// Come here on success only.
__ BIND(L_do_card_marks);
- __ addptr(end_to, -heapOopSize); // make an inclusive end pointer
- gen_write_ref_array_post_barrier(to, end_to, rscratch1);
- __ xorptr(rax, rax); // return 0 on success
+ __ xorptr(rax, rax); // return 0 on success
+
+ __ BIND(L_post_barrier);
+ gen_write_ref_array_post_barrier(to, r14_length, rscratch1);
// Common exit point (success or failure).
__ BIND(L_done);
diff --git a/hotspot/src/cpu/zero/vm/globals_zero.hpp b/hotspot/src/cpu/zero/vm/globals_zero.hpp
index a3c7d244173..71b566fceb0 100644
--- a/hotspot/src/cpu/zero/vm/globals_zero.hpp
+++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp
@@ -55,7 +55,7 @@ define_pd_global(bool, RewriteFrequentPairs, true);
define_pd_global(bool, UseMembar, true);
// GC Ergo Flags
-define_pd_global(intx, CMSYoungGenPerWorker, 16*M); // default max size of CMS young gen, per GC worker thread
+define_pd_global(uintx, CMSYoungGenPerWorker, 16*M); // default max size of CMS young gen, per GC worker thread
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct)
diff --git a/hotspot/src/os/posix/launcher/java_md.c b/hotspot/src/os/posix/launcher/java_md.c
deleted file mode 100644
index b5fc949813c..00000000000
--- a/hotspot/src/os/posix/launcher/java_md.c
+++ /dev/null
@@ -1,1936 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-
-#include "java.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#ifndef GAMMA
-#include "manifest_info.h"
-#include "version_comp.h"
-#endif
-
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
-#include
-#else
-#include
-#endif
-
-#ifdef __APPLE__
-#define JVM_DLL "libjvm.dylib"
-#define JAVA_DLL "libjava.dylib"
-#define LD_LIBRARY_PATH "DYLD_LIBRARY_PATH"
-#else
-#define JVM_DLL "libjvm.so"
-#define JAVA_DLL "libjava.so"
-#define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
-#endif
-
-#ifndef GAMMA /* launcher.make defines ARCH */
-/*
- * If a processor / os combination has the ability to run binaries of
- * two data models and cohabitation of jre/jdk bits with both data
- * models is supported, then DUAL_MODE is defined. When DUAL_MODE is
- * defined, the architecture names for the narrow and wide version of
- * the architecture are defined in LIBARCH64NAME and LIBARCH32NAME. Currently
- * only Solaris on sparc/sparcv9 and i586/amd64 is DUAL_MODE; linux
- * i586/amd64 could be defined as DUAL_MODE but that is not the
- * current policy.
- */
-
-#ifndef LIBARCHNAME
-# error "The macro LIBARCHNAME was not defined on the compile line"
-#endif
-
-#ifdef __sun
-# define DUAL_MODE
-# ifndef LIBARCH32NAME
-# error "The macro LIBARCH32NAME was not defined on the compile line"
-# endif
-# ifndef LIBARCH64NAME
-# error "The macro LIBARCH64NAME was not defined on the compile line"
-# endif
-# include
-# include
-# include
-#endif
-
-#endif /* ifndef GAMMA */
-
-/* pointer to environment */
-extern char **environ;
-
-#ifndef GAMMA
-/*
- * A collection of useful strings. One should think of these as #define
- * entries, but actual strings can be more efficient (with many compilers).
- */
-#ifdef __linux__
-static const char *system_dir = "/usr/java";
-static const char *user_dir = "/java";
-#else /* Solaris */
-static const char *system_dir = "/usr/jdk";
-static const char *user_dir = "/jdk";
-#endif
-
-#endif /* ifndef GAMMA */
-
-/*
- * Flowchart of launcher execs and options processing on unix
- *
- * The selection of the proper vm shared library to open depends on
- * several classes of command line options, including vm "flavor"
- * options (-client, -server) and the data model options, -d32 and
- * -d64, as well as a version specification which may have come from
- * the command line or from the manifest of an executable jar file.
- * The vm selection options are not passed to the running
- * virtual machine; they must be screened out by the launcher.
- *
- * The version specification (if any) is processed first by the
- * platform independent routine SelectVersion. This may result in
- * the exec of the specified launcher version.
- *
- * Typically, the launcher execs at least once to ensure a suitable
- * LD_LIBRARY_PATH is in effect for the process. The first exec
- * screens out all the data model options; leaving the choice of data
- * model implicit in the binary selected to run. However, in case no
- * exec is done, the data model options are screened out before the vm
- * is invoked.
- *
- * incoming argv ------------------------------
- * | |
- * \|/ |
- * CheckJVMType |
- * (removes -client, -server, etc.) |
- * \|/
- * CreateExecutionEnvironment
- * (removes -d32 and -d64,
- * determines desired data model,
- * sets up LD_LIBRARY_PATH,
- * and exec's)
- * |
- * --------------------------------------------
- * |
- * \|/
- * exec child 1 incoming argv -----------------
- * | |
- * \|/ |
- * CheckJVMType |
- * (removes -client, -server, etc.) |
- * | \|/
- * | CreateExecutionEnvironment
- * | (verifies desired data model
- * | is running and acceptable
- * | LD_LIBRARY_PATH;
- * | no-op in child)
- * |
- * \|/
- * TranslateDashJArgs...
- * (Prepare to pass args to vm)
- * |
- * |
- * |
- * \|/
- * ParseArguments
- * (ignores -d32 and -d64,
- * processes version options,
- * creates argument list for vm,
- * etc.)
- *
- */
-
-static char *SetExecname(char **argv);
-static char * GetExecname();
-static jboolean GetJVMPath(const char *jrepath, const char *jvmtype,
- char *jvmpath, jint jvmpathsize, char * arch);
-static jboolean GetJREPath(char *path, jint pathsize, char * arch, jboolean speculative);
-
-#ifndef GAMMA
-const char *
-GetArch()
-{
- return LIBARCHNAME;
-}
-#endif /* ifndef GAMMA */
-
-void
-CreateExecutionEnvironment(int *_argcp,
- char ***_argvp,
- char jrepath[],
- jint so_jrepath,
- char jvmpath[],
- jint so_jvmpath,
- char **original_argv) {
- /*
- * First, determine if we are running the desired data model. If we
- * are running the desired data model, all the error messages
- * associated with calling GetJREPath, ReadKnownVMs, etc. should be
- * output. However, if we are not running the desired data model,
- * some of the errors should be suppressed since it is more
- * informative to issue an error message based on whether or not the
- * os/processor combination has dual mode capabilities.
- */
-
- char *execname = NULL;
- int original_argc = *_argcp;
- jboolean jvmpathExists;
-
- /* Compute the name of the executable */
- execname = SetExecname(*_argvp);
-
-#ifndef GAMMA
- /* Set the LD_LIBRARY_PATH environment variable, check data model
- flags, and exec process, if needed */
- {
- char *arch = (char *)GetArch(); /* like sparc or sparcv9 */
- char * jvmtype = NULL;
- int argc = *_argcp;
- char **argv = original_argv;
-
- char *runpath = NULL; /* existing effective LD_LIBRARY_PATH
- setting */
-
- int running = /* What data model is being ILP32 =>
- 32 bit vm; LP64 => 64 bit vm */
-#ifdef _LP64
- 64;
-#else
- 32;
-#endif
-
- int wanted = running; /* What data mode is being
- asked for? Current model is
- fine unless another model
- is asked for */
-
- char* new_runpath = NULL; /* desired new LD_LIBRARY_PATH string */
- char* newpath = NULL; /* path on new LD_LIBRARY_PATH */
- char* lastslash = NULL;
-
- char** newenvp = NULL; /* current environment */
-
- char** newargv = NULL;
- int newargc = 0;
-#ifdef __sun
- char* dmpath = NULL; /* data model specific LD_LIBRARY_PATH,
- Solaris only */
-#endif
-
- /*
- * Starting in 1.5, all unix platforms accept the -d32 and -d64
- * options. On platforms where only one data-model is supported
- * (e.g. ia-64 Linux), using the flag for the other data model is
- * an error and will terminate the program.
- */
-
- { /* open new scope to declare local variables */
- int i;
-
- newargv = (char **)JLI_MemAlloc((argc+1) * sizeof(*newargv));
- newargv[newargc++] = argv[0];
-
- /* scan for data model arguments and remove from argument list;
- last occurrence determines desired data model */
- for (i=1; i < argc; i++) {
-
- if (strcmp(argv[i], "-J-d64") == 0 || strcmp(argv[i], "-d64") == 0) {
- wanted = 64;
- continue;
- }
- if (strcmp(argv[i], "-J-d32") == 0 || strcmp(argv[i], "-d32") == 0) {
- wanted = 32;
- continue;
- }
- newargv[newargc++] = argv[i];
-
-#ifdef JAVA_ARGS
- if (argv[i][0] != '-')
- continue;
-#else
- if (strcmp(argv[i], "-classpath") == 0 || strcmp(argv[i], "-cp") == 0) {
- i++;
- if (i >= argc) break;
- newargv[newargc++] = argv[i];
- continue;
- }
- if (argv[i][0] != '-') { i++; break; }
-#endif
- }
-
- /* copy rest of args [i .. argc) */
- while (i < argc) {
- newargv[newargc++] = argv[i++];
- }
- newargv[newargc] = NULL;
-
- /*
- * newargv has all proper arguments here
- */
-
- argc = newargc;
- argv = newargv;
- }
-
- /* If the data model is not changing, it is an error if the
- jvmpath does not exist */
- if (wanted == running) {
- /* Find out where the JRE is that we will be using. */
- if (!GetJREPath(jrepath, so_jrepath, arch, JNI_FALSE) ) {
- fprintf(stderr, "Error: could not find Java 2 Runtime Environment.\n");
- exit(2);
- }
-
- /* Find the specified JVM type */
- if (ReadKnownVMs(jrepath, arch, JNI_FALSE) < 1) {
- fprintf(stderr, "Error: no known VMs. (check for corrupt jvm.cfg file)\n");
- exit(1);
- }
-
- jvmpath[0] = '\0';
- jvmtype = CheckJvmType(_argcp, _argvp, JNI_FALSE);
-
- if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, arch )) {
- fprintf(stderr, "Error: no `%s' JVM at `%s'.\n", jvmtype, jvmpath);
- exit(4);
- }
- } else { /* do the same speculatively or exit */
-#ifdef DUAL_MODE
- if (running != wanted) {
- /* Find out where the JRE is that we will be using. */
- if (!GetJREPath(jrepath, so_jrepath, ((wanted==64)?LIBARCH64NAME:LIBARCH32NAME), JNI_TRUE)) {
- goto EndDataModelSpeculate;
- }
-
- /*
- * Read in jvm.cfg for target data model and process vm
- * selection options.
- */
- if (ReadKnownVMs(jrepath, ((wanted==64)?LIBARCH64NAME:LIBARCH32NAME), JNI_TRUE) < 1) {
- goto EndDataModelSpeculate;
- }
- jvmpath[0] = '\0';
- jvmtype = CheckJvmType(_argcp, _argvp, JNI_TRUE);
- /* exec child can do error checking on the existence of the path */
- jvmpathExists = GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath,
- ((wanted==64)?LIBARCH64NAME:LIBARCH32NAME));
-
- }
- EndDataModelSpeculate: /* give up and let other code report error message */
- ;
-#else
- fprintf(stderr, "Running a %d-bit JVM is not supported on this platform.\n", wanted);
- exit(1);
-#endif
- }
-
- /*
- * We will set the LD_LIBRARY_PATH as follows:
- *
- * o $JVMPATH (directory portion only)
- * o $JRE/lib/$LIBARCHNAME
- * o $JRE/../lib/$LIBARCHNAME
- *
- * followed by the user's previous effective LD_LIBRARY_PATH, if
- * any.
- */
-
-#ifdef __sun
- /*
- * Starting in Solaris 7, ld.so.1 supports three LD_LIBRARY_PATH
- * variables:
- *
- * 1. LD_LIBRARY_PATH -- used for 32 and 64 bit searches if
- * data-model specific variables are not set.
- *
- * 2. LD_LIBRARY_PATH_64 -- overrides and replaces LD_LIBRARY_PATH
- * for 64-bit binaries.
- *
- * 3. LD_LIBRARY_PATH_32 -- overrides and replaces LD_LIBRARY_PATH
- * for 32-bit binaries.
- *
- * The vm uses LD_LIBRARY_PATH to set the java.library.path system
- * property. To shield the vm from the complication of multiple
- * LD_LIBRARY_PATH variables, if the appropriate data model
- * specific variable is set, we will act as if LD_LIBRARY_PATH had
- * the value of the data model specific variant and the data model
- * specific variant will be unset. Note that the variable for the
- * *wanted* data model must be used (if it is set), not simply the
- * current running data model.
- */
-
- switch(wanted) {
- case 0:
- if(running == 32) {
- dmpath = getenv("LD_LIBRARY_PATH_32");
- wanted = 32;
- }
- else {
- dmpath = getenv("LD_LIBRARY_PATH_64");
- wanted = 64;
- }
- break;
-
- case 32:
- dmpath = getenv("LD_LIBRARY_PATH_32");
- break;
-
- case 64:
- dmpath = getenv("LD_LIBRARY_PATH_64");
- break;
-
- default:
- fprintf(stderr, "Improper value at line %d.", __LINE__);
- exit(1); /* unknown value in wanted */
- break;
- }
-
- /*
- * If dmpath is NULL, the relevant data model specific variable is
- * not set and normal LD_LIBRARY_PATH should be used.
- */
- if( dmpath == NULL) {
- runpath = getenv("LD_LIBRARY_PATH");
- }
- else {
- runpath = dmpath;
- }
-#else
- /*
- * If not on Solaris, assume only a single LD_LIBRARY_PATH
- * variable.
- */
- runpath = getenv(LD_LIBRARY_PATH);
-#endif /* __sun */
-
-#if defined(__linux__)
- /*
- * On linux, if a binary is running as sgid or suid, glibc sets
- * LD_LIBRARY_PATH to the empty string for security purposes. (In
- * contrast, on Solaris the LD_LIBRARY_PATH variable for a
- * privileged binary does not lose its settings; but the dynamic
- * linker does apply more scrutiny to the path.) The launcher uses
- * the value of LD_LIBRARY_PATH to prevent an exec loop.
- * Therefore, if we are running sgid or suid, this function's
- * setting of LD_LIBRARY_PATH will be ineffective and we should
- * return from the function now. Getting the right libraries to
- * be found must be handled through other mechanisms.
- */
- if((getgid() != getegid()) || (getuid() != geteuid()) ) {
- return;
- }
-#elif defined(_ALLBSD_SOURCE)
- /*
- * On BSD, if a binary is running as sgid or suid, libc sets
- * LD_LIBRARY_PATH to the empty string for security purposes. (In
- * contrast, on Solaris the LD_LIBRARY_PATH variable for a
- * privileged binary does not lose its settings; but the dynamic
- * linker does apply more scrutiny to the path.) The launcher uses
- * the value of LD_LIBRARY_PATH to prevent an exec loop.
- * Therefore, if we are running sgid or suid, this function's
- * setting of LD_LIBRARY_PATH will be ineffective and we should
- * return from the function now. Getting the right libraries to
- * be found must be handled through other mechanisms.
- */
- if(issetugid()) {
- return;
- }
-#endif
-
- /* runpath contains current effective LD_LIBRARY_PATH setting */
-
- jvmpath = JLI_StringDup(jvmpath);
- new_runpath = JLI_MemAlloc( ((runpath!=NULL)?strlen(runpath):0) +
- 2*strlen(jrepath) + 2*strlen(arch) +
- strlen(jvmpath) + 52);
- newpath = new_runpath + strlen(LD_LIBRARY_PATH "=");
-
-
- /*
- * Create desired LD_LIBRARY_PATH value for target data model.
- */
- {
- /* remove the name of the .so from the JVM path */
- lastslash = strrchr(jvmpath, '/');
- if (lastslash)
- *lastslash = '\0';
-
-
- /* jvmpath, ((running != wanted)?((wanted==64)?"/"LIBARCH64NAME:"/.."):""), */
-
- sprintf(new_runpath, LD_LIBRARY_PATH "="
- "%s:"
- "%s/lib/%s:"
- "%s/../lib/%s",
- jvmpath,
-#ifdef DUAL_MODE
- jrepath, ((wanted==64)?LIBARCH64NAME:LIBARCH32NAME),
- jrepath, ((wanted==64)?LIBARCH64NAME:LIBARCH32NAME)
-#else
- jrepath, arch,
- jrepath, arch
-#endif
- );
-
-
- /*
- * Check to make sure that the prefix of the current path is the
- * desired environment variable setting.
- */
- if (runpath != NULL &&
- strncmp(newpath, runpath, strlen(newpath))==0 &&
- (runpath[strlen(newpath)] == 0 || runpath[strlen(newpath)] == ':') &&
- (running == wanted) /* data model does not have to be changed */
-#ifdef __sun
- && (dmpath == NULL) /* data model specific variables not set */
-#endif
- ) {
-
- return;
-
- }
- }
-
- /*
- * Place the desired environment setting onto the prefix of
- * LD_LIBRARY_PATH. Note that this prevents any possible infinite
- * loop of execv() because we test for the prefix, above.
- */
- if (runpath != 0) {
- strcat(new_runpath, ":");
- strcat(new_runpath, runpath);
- }
-
- if( putenv(new_runpath) != 0) {
- exit(1); /* problem allocating memory; LD_LIBRARY_PATH not set
- properly */
- }
-
- /*
- * Unix systems document that they look at LD_LIBRARY_PATH only
- * once at startup, so we have to re-exec the current executable
- * to get the changed environment variable to have an effect.
- */
-
-#ifdef __sun
- /*
- * If dmpath is not NULL, remove the data model specific string
- * in the environment for the exec'ed child.
- */
-
- if( dmpath != NULL)
- (void)UnsetEnv((wanted==32)?"LD_LIBRARY_PATH_32":"LD_LIBRARY_PATH_64");
-#endif
-
- newenvp = environ;
-
- {
- char *newexec = execname;
-#ifdef DUAL_MODE
- /*
- * If the data model is being changed, the path to the
- * executable must be updated accordingly; the executable name
- * and directory the executable resides in are separate. In the
- * case of 32 => 64, the new bits are assumed to reside in, e.g.
- * "olddir/LIBARCH64NAME/execname"; in the case of 64 => 32,
- * the bits are assumed to be in "olddir/../execname". For example,
- *
- * olddir/sparcv9/execname
- * olddir/amd64/execname
- *
- * for Solaris SPARC and Linux amd64, respectively.
- */
-
- if (running != wanted) {
- char *oldexec = strcpy(JLI_MemAlloc(strlen(execname) + 1), execname);
- char *olddir = oldexec;
- char *oldbase = strrchr(oldexec, '/');
-
-
- newexec = JLI_MemAlloc(strlen(execname) + 20);
- *oldbase++ = 0;
- sprintf(newexec, "%s/%s/%s", olddir,
- ((wanted==64) ? LIBARCH64NAME : ".."), oldbase);
- argv[0] = newexec;
- }
-#endif
-
- (void)fflush(stdout);
- (void)fflush(stderr);
- execve(newexec, argv, newenvp);
- perror("execve()");
-
- fprintf(stderr, "Error trying to exec %s.\n", newexec);
- fprintf(stderr, "Check if file exists and permissions are set correctly.\n");
-
-#ifdef DUAL_MODE
- if (running != wanted) {
- fprintf(stderr, "Failed to start a %d-bit JVM process from a %d-bit JVM.\n",
- wanted, running);
-# ifdef __sun
-
-# ifdef __sparc
- fprintf(stderr, "Verify all necessary J2SE components have been installed.\n" );
- fprintf(stderr,
- "(Solaris SPARC 64-bit components must be installed after 32-bit components.)\n" );
-# else
- fprintf(stderr, "Either 64-bit processes are not supported by this platform\n");
- fprintf(stderr, "or the 64-bit components have not been installed.\n");
-# endif
- }
-# endif
-#endif
-
- }
-
- exit(1);
- }
-
-#else /* ifndef GAMMA */
-
- /*
- * gamma launcher is simpler in that it doesn't handle VM flavors, data
- * model, LD_LIBRARY_PATH, etc. Assuming everything is set-up correctly
- * all we need to do here is to return correct path names. See also
- * GetJVMPath() and GetApplicationHome().
- */
-
- { char *arch = (char *) ARCH; /* like sparc or sparcv9 */
- char *p;
-
- if (!GetJREPath(jrepath, so_jrepath, arch, JNI_FALSE) ) {
- fprintf(stderr, "Error: could not find Java 2 Runtime Environment.\n");
- exit(2);
- }
-
- if (!GetJVMPath(jrepath, NULL, jvmpath, so_jvmpath, arch )) {
- fprintf(stderr, "Error: no JVM at `%s'.\n", jvmpath);
- exit(4);
- }
- }
-
-#endif /* ifndef GAMMA */
-}
-
-
-/*
- * On Solaris VM choosing is done by the launcher (java.c).
- */
-static jboolean
-GetJVMPath(const char *jrepath, const char *jvmtype,
- char *jvmpath, jint jvmpathsize, char * arch)
-{
- struct stat s;
-
-#ifndef GAMMA
- if (strchr(jvmtype, '/')) {
- sprintf(jvmpath, "%s/" JVM_DLL, jvmtype);
- } else {
- sprintf(jvmpath, "%s/lib/%s/%s/" JVM_DLL, jrepath, arch, jvmtype);
- }
-#else
- /*
- * For gamma launcher, JVM is either built-in or in the same directory.
- * Either way we return "/libjvm.so" where is the
- * directory where gamma launcher is located.
- */
-
- char *p;
-
- snprintf(jvmpath, jvmpathsize, "%s", GetExecname());
- p = strrchr(jvmpath, '/');
- if (p) {
- /* replace executable name with libjvm.so */
- snprintf(p + 1, jvmpathsize - (p + 1 - jvmpath), "%s", JVM_DLL);
- } else {
- /* this case shouldn't happen */
- snprintf(jvmpath, jvmpathsize, "%s", JVM_DLL);
- }
-#endif /* ifndef GAMMA */
-
- if (_launcher_debug)
- printf("Does `%s' exist ... ", jvmpath);
-
- if (stat(jvmpath, &s) == 0) {
- if (_launcher_debug)
- printf("yes.\n");
- return JNI_TRUE;
- } else {
- if (_launcher_debug)
- printf("no.\n");
- return JNI_FALSE;
- }
-}
-
-/*
- * Find path to JRE based on .exe's location or registry settings.
- */
-static jboolean
-GetJREPath(char *path, jint pathsize, char * arch, jboolean speculative)
-{
- char libjava[MAXPATHLEN];
-
- if (GetApplicationHome(path, pathsize)) {
-
- /* Is the JRE universal, i.e. no arch dir? */
- sprintf(libjava, "%s/jre/lib/" JAVA_DLL, path);
- if (access(libjava, F_OK) == 0) {
- strcat(path, "/jre");
- goto found;
- }
-
- /* Is JRE co-located with the application? */
- sprintf(libjava, "%s/lib/%s/" JAVA_DLL, path, arch);
- if (access(libjava, F_OK) == 0) {
- goto found;
- }
-
- /* Does the app ship a private JRE in /jre directory? */
- sprintf(libjava, "%s/jre/lib/%s/" JAVA_DLL, path, arch);
- if (access(libjava, F_OK) == 0) {
- strcat(path, "/jre");
- goto found;
- }
- }
-
- if (!speculative)
- fprintf(stderr, "Error: could not find " JAVA_DLL "\n");
- return JNI_FALSE;
-
- found:
- if (_launcher_debug)
- printf("JRE path is %s\n", path);
- return JNI_TRUE;
-}
-
-jboolean
-LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
-{
-#ifdef GAMMA
- /* JVM is directly linked with gamma launcher; no dlopen() */
- ifn->CreateJavaVM = JNI_CreateJavaVM;
- ifn->GetDefaultJavaVMInitArgs = JNI_GetDefaultJavaVMInitArgs;
- return JNI_TRUE;
-#else
- Dl_info dlinfo;
- void *libjvm;
-
- if (_launcher_debug) {
- printf("JVM path is %s\n", jvmpath);
- }
-
- libjvm = dlopen(jvmpath, RTLD_NOW + RTLD_GLOBAL);
- if (libjvm == NULL) {
-#if defined(__sparc) && !defined(_LP64) /* i.e. 32-bit sparc */
- FILE * fp;
- Elf32_Ehdr elf_head;
- int count;
- int location;
-
- fp = fopen(jvmpath, "r");
- if(fp == NULL)
- goto error;
-
- /* read in elf header */
- count = fread((void*)(&elf_head), sizeof(Elf32_Ehdr), 1, fp);
- fclose(fp);
- if(count < 1)
- goto error;
-
- /*
- * Check for running a server vm (compiled with -xarch=v8plus)
- * on a stock v8 processor. In this case, the machine type in
- * the elf header would not be included the architecture list
- * provided by the isalist command, which is turn is gotten from
- * sysinfo. This case cannot occur on 64-bit hardware and thus
- * does not have to be checked for in binaries with an LP64 data
- * model.
- */
- if(elf_head.e_machine == EM_SPARC32PLUS) {
- char buf[257]; /* recommended buffer size from sysinfo man
- page */
- long length;
- char* location;
-
- length = sysinfo(SI_ISALIST, buf, 257);
- if(length > 0) {
- location = strstr(buf, "sparcv8plus ");
- if(location == NULL) {
- fprintf(stderr, "SPARC V8 processor detected; Server compiler requires V9 or better.\n");
- fprintf(stderr, "Use Client compiler on V8 processors.\n");
- fprintf(stderr, "Could not create the Java virtual machine.\n");
- return JNI_FALSE;
- }
- }
- }
-#endif
- fprintf(stderr, "dl failure on line %d", __LINE__);
- goto error;
- }
-
- ifn->CreateJavaVM = (CreateJavaVM_t)
- dlsym(libjvm, "JNI_CreateJavaVM");
- if (ifn->CreateJavaVM == NULL)
- goto error;
-
- ifn->GetDefaultJavaVMInitArgs = (GetDefaultJavaVMInitArgs_t)
- dlsym(libjvm, "JNI_GetDefaultJavaVMInitArgs");
- if (ifn->GetDefaultJavaVMInitArgs == NULL)
- goto error;
-
- return JNI_TRUE;
-
-error:
- fprintf(stderr, "Error: failed %s, because %s\n", jvmpath, dlerror());
- return JNI_FALSE;
-#endif /* ifndef GAMMA */
-}
-
-/*
- * If app is "/foo/bin/javac", or "/foo/bin/sparcv9/javac" then put
- * "/foo" into buf.
- */
-jboolean
-GetApplicationHome(char *buf, jint bufsize)
-{
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
- char *execname = GetExecname();
- if (execname) {
- strncpy(buf, execname, bufsize-1);
- buf[bufsize-1] = '\0';
- } else {
- return JNI_FALSE;
- }
-#else
- Dl_info dlinfo;
-
- dladdr((void *)GetApplicationHome, &dlinfo);
- if (realpath(dlinfo.dli_fname, buf) == NULL) {
- fprintf(stderr, "Error: realpath(`%s') failed.\n", dlinfo.dli_fname);
- return JNI_FALSE;
- }
-#endif
-
-#ifdef GAMMA
- {
- /* gamma launcher uses JAVA_HOME environment variable to find JDK/JRE */
- char* java_home_var = getenv("JAVA_HOME");
- if (java_home_var == NULL) {
- printf("JAVA_HOME must point to a valid JDK/JRE to run gamma\n");
- return JNI_FALSE;
- }
- snprintf(buf, bufsize, "%s", java_home_var);
- }
-#else
- if (strrchr(buf, '/') == 0) {
- buf[0] = '\0';
- return JNI_FALSE;
- }
- *(strrchr(buf, '/')) = '\0'; /* executable file */
- if (strlen(buf) < 4 || strrchr(buf, '/') == 0) {
- buf[0] = '\0';
- return JNI_FALSE;
- }
- if (strcmp("/bin", buf + strlen(buf) - 4) != 0)
- *(strrchr(buf, '/')) = '\0'; /* sparcv9 or amd64 */
- if (strlen(buf) < 4 || strcmp("/bin", buf + strlen(buf) - 4) != 0) {
- buf[0] = '\0';
- return JNI_FALSE;
- }
- *(strrchr(buf, '/')) = '\0'; /* bin */
-#endif /* ifndef GAMMA */
-
- return JNI_TRUE;
-}
-
-
-/*
- * Return true if the named program exists
- */
-static int
-ProgramExists(char *name)
-{
- struct stat sb;
- if (stat(name, &sb) != 0) return 0;
- if (S_ISDIR(sb.st_mode)) return 0;
- return (sb.st_mode & S_IEXEC) != 0;
-}
-
-
-/*
- * Find a command in a directory, returning the path.
- */
-static char *
-Resolve(char *indir, char *cmd)
-{
- char name[PATH_MAX + 2], *real;
-
- if ((strlen(indir) + strlen(cmd) + 1) > PATH_MAX) return 0;
- sprintf(name, "%s%c%s", indir, FILE_SEPARATOR, cmd);
- if (!ProgramExists(name)) return 0;
- real = JLI_MemAlloc(PATH_MAX + 2);
- if (!realpath(name, real))
- strcpy(real, name);
- return real;
-}
-
-
-/*
- * Find a path for the executable
- */
-static char *
-FindExecName(char *program)
-{
- char cwdbuf[PATH_MAX+2];
- char *path;
- char *tmp_path;
- char *f;
- char *result = NULL;
-
- /* absolute path? */
- if (*program == FILE_SEPARATOR ||
- (FILE_SEPARATOR=='\\' && strrchr(program, ':')))
- return Resolve("", program+1);
-
- /* relative path? */
- if (strrchr(program, FILE_SEPARATOR) != 0) {
- char buf[PATH_MAX+2];
- return Resolve(getcwd(cwdbuf, sizeof(cwdbuf)), program);
- }
-
- /* from search path? */
- path = getenv("PATH");
- if (!path || !*path) path = ".";
- tmp_path = JLI_MemAlloc(strlen(path) + 2);
- strcpy(tmp_path, path);
-
- for (f=tmp_path; *f && result==0; ) {
- char *s = f;
- while (*f && (*f != PATH_SEPARATOR)) ++f;
- if (*f) *f++ = 0;
- if (*s == FILE_SEPARATOR)
- result = Resolve(s, program);
- else {
- /* relative path element */
- char dir[2*PATH_MAX];
- sprintf(dir, "%s%c%s", getcwd(cwdbuf, sizeof(cwdbuf)),
- FILE_SEPARATOR, s);
- result = Resolve(dir, program);
- }
- if (result != 0) break;
- }
-
- JLI_MemFree(tmp_path);
- return result;
-}
-
-
-/* Store the name of the executable once computed */
-static char *execname = NULL;
-
-/*
- * Compute the name of the executable
- *
- * In order to re-exec securely we need the absolute path of the
- * executable. On Solaris getexecname(3c) may not return an absolute
- * path so we use dladdr to get the filename of the executable and
- * then use realpath to derive an absolute path. From Solaris 9
- * onwards the filename returned in DL_info structure from dladdr is
- * an absolute pathname so technically realpath isn't required.
- * On Linux we read the executable name from /proc/self/exe.
- * As a fallback, and for platforms other than Solaris and Linux,
- * we use FindExecName to compute the executable name.
- */
-static char *
-SetExecname(char **argv)
-{
- char* exec_path = NULL;
-
- if (execname != NULL) /* Already determined */
- return (execname);
-
-#if defined(__sun)
- {
- Dl_info dlinfo;
- if (dladdr((void*)&SetExecname, &dlinfo)) {
- char *resolved = (char*)JLI_MemAlloc(PATH_MAX+1);
- if (resolved != NULL) {
- exec_path = realpath(dlinfo.dli_fname, resolved);
- if (exec_path == NULL) {
- JLI_MemFree(resolved);
- }
- }
- }
- }
-#elif defined(__linux__)
- {
- const char* self = "/proc/self/exe";
- char buf[PATH_MAX+1];
- int len = readlink(self, buf, PATH_MAX);
- if (len >= 0) {
- buf[len] = '\0'; /* readlink doesn't nul terminate */
- exec_path = JLI_StringDup(buf);
- }
- }
-#else /* !__sun && !__linux */
- {
- /* Not implemented */
- }
-#endif
-
- if (exec_path == NULL) {
- exec_path = FindExecName(argv[0]);
- }
- execname = exec_path;
- return exec_path;
-}
-
-/*
- * Return the name of the executable. Used in java_md.c to find the JRE area.
- */
-static char *
-GetExecname() {
- return execname;
-}
-
-void ReportErrorMessage(char * message, jboolean always) {
- if (always) {
- fprintf(stderr, "%s\n", message);
- }
-}
-
-void ReportErrorMessage2(char * format, char * string, jboolean always) {
- if (always) {
- fprintf(stderr, format, string);
- fprintf(stderr, "\n");
- }
-}
-
-void ReportExceptionDescription(JNIEnv * env) {
- (*env)->ExceptionDescribe(env);
-}
-
-/*
- * Return JNI_TRUE for an option string that has no effect but should
- * _not_ be passed on to the vm; return JNI_FALSE otherwise. On
- * Solaris SPARC, this screening needs to be done if:
- * 1) LD_LIBRARY_PATH does _not_ need to be reset and
- * 2) -d32 or -d64 is passed to a binary with a matching data model
- * (the exec in SetLibraryPath removes -d options and points the
- * exec to the proper binary). When this exec is not done, these options
- * would end up getting passed onto the vm.
- */
-jboolean RemovableMachineDependentOption(char * option) {
- /*
- * Unconditionally remove both -d32 and -d64 options since only
- * the last such options has an effect; e.g.
- * java -d32 -d64 -d32 -version
- * is equivalent to
- * java -d32 -version
- */
-
- if( (strcmp(option, "-d32") == 0 ) ||
- (strcmp(option, "-d64") == 0 ))
- return JNI_TRUE;
- else
- return JNI_FALSE;
-}
-
-void PrintMachineDependentOptions() {
- fprintf(stdout,
- " -d32 use a 32-bit data model if available\n"
- "\n"
- " -d64 use a 64-bit data model if available\n");
- return;
-}
-
-#ifndef GAMMA
-/*
- * The following methods (down to ServerClassMachine()) answer
- * the question about whether a machine is a "server-class"
- * machine. A server-class machine is loosely defined as one
- * with 2 or more processors and 2 gigabytes or more physical
- * memory. The definition of a processor is a physical package,
- * not a hyperthreaded chip masquerading as a multi-processor.
- * The definition of memory is also somewhat fuzzy, since x86
- * machines seem not to report all the memory in their DIMMs, we
- * think because of memory mapping of graphics cards, etc.
- *
- * This code is somewhat more confused with #ifdef's than we'd
- * like because this file is used by both Solaris and Linux
- * platforms, and so needs to be parameterized for SPARC and
- * i586 hardware. The other Linux platforms (amd64 and ia64)
- * don't even ask this question, because they only come with
- * server JVMs. */
-
-# define KB (1024UL)
-# define MB (1024UL * KB)
-# define GB (1024UL * MB)
-
-/* Compute physical memory by asking the OS */
-uint64_t
-physical_memory(void) {
- const uint64_t pages = (uint64_t) sysconf(_SC_PHYS_PAGES);
- const uint64_t page_size = (uint64_t) sysconf(_SC_PAGESIZE);
- const uint64_t result = pages * page_size;
-# define UINT64_FORMAT "%" PRIu64
-
- if (_launcher_debug) {
- printf("pages: " UINT64_FORMAT
- " page_size: " UINT64_FORMAT
- " physical memory: " UINT64_FORMAT " (%.3fGB)\n",
- pages, page_size, result, result / (double) GB);
- }
- return result;
-}
-
-#if defined(__sun) && defined(__sparc)
-
-/* Methods for solaris-sparc: these are easy. */
-
-/* Ask the OS how many processors there are. */
-unsigned long
-physical_processors(void) {
- const unsigned long sys_processors = sysconf(_SC_NPROCESSORS_CONF);
-
- if (_launcher_debug) {
- printf("sysconf(_SC_NPROCESSORS_CONF): %lu\n", sys_processors);
- }
- return sys_processors;
-}
-
-/* The solaris-sparc version of the "server-class" predicate. */
-jboolean
-solaris_sparc_ServerClassMachine(void) {
- jboolean result = JNI_FALSE;
- /* How big is a server class machine? */
- const unsigned long server_processors = 2UL;
- const uint64_t server_memory = 2UL * GB;
- const uint64_t actual_memory = physical_memory();
-
- /* Is this a server class machine? */
- if (actual_memory >= server_memory) {
- const unsigned long actual_processors = physical_processors();
- if (actual_processors >= server_processors) {
- result = JNI_TRUE;
- }
- }
- if (_launcher_debug) {
- printf("solaris_" LIBARCHNAME "_ServerClassMachine: %s\n",
- (result == JNI_TRUE ? "JNI_TRUE" : "JNI_FALSE"));
- }
- return result;
-}
-
-#endif /* __sun && __sparc */
-
-#if defined(__sun) && defined(i586)
-
-/*
- * A utility method for asking the CPU about itself.
- * There's a corresponding version of linux-i586
- * because the compilers are different.
- */
-void
-get_cpuid(uint32_t arg,
- uint32_t* eaxp,
- uint32_t* ebxp,
- uint32_t* ecxp,
- uint32_t* edxp) {
-#ifdef _LP64
- asm(
- /* rbx is a callee-saved register */
- " movq %rbx, %r11 \n"
- /* rdx and rcx are 3rd and 4th argument registers */
- " movq %rdx, %r10 \n"
- " movq %rcx, %r9 \n"
- " movl %edi, %eax \n"
- " cpuid \n"
- " movl %eax, (%rsi)\n"
- " movl %ebx, (%r10)\n"
- " movl %ecx, (%r9) \n"
- " movl %edx, (%r8) \n"
- /* Restore rbx */
- " movq %r11, %rbx");
-#else
- /* EBX is a callee-saved register */
- asm(" pushl %ebx");
- /* Need ESI for storing through arguments */
- asm(" pushl %esi");
- asm(" movl 8(%ebp), %eax \n"
- " cpuid \n"
- " movl 12(%ebp), %esi \n"
- " movl %eax, (%esi) \n"
- " movl 16(%ebp), %esi \n"
- " movl %ebx, (%esi) \n"
- " movl 20(%ebp), %esi \n"
- " movl %ecx, (%esi) \n"
- " movl 24(%ebp), %esi \n"
- " movl %edx, (%esi) ");
- /* Restore ESI and EBX */
- asm(" popl %esi");
- /* Restore EBX */
- asm(" popl %ebx");
-#endif
-}
-
-#endif /* __sun && i586 */
-
-#if (defined(__linux__) || defined(_ALLBSD_SOURCE)) && defined(i586)
-
-/*
- * A utility method for asking the CPU about itself.
- * There's a corresponding version of solaris-i586
- * because the compilers are different.
- */
-void
-get_cpuid(uint32_t arg,
- uint32_t* eaxp,
- uint32_t* ebxp,
- uint32_t* ecxp,
- uint32_t* edxp) {
-#ifdef _LP64
- __asm__ volatile (/* Instructions */
- " movl %4, %%eax \n"
- " cpuid \n"
- " movl %%eax, (%0)\n"
- " movl %%ebx, (%1)\n"
- " movl %%ecx, (%2)\n"
- " movl %%edx, (%3)\n"
- : /* Outputs */
- : /* Inputs */
- "r" (eaxp),
- "r" (ebxp),
- "r" (ecxp),
- "r" (edxp),
- "r" (arg)
- : /* Clobbers */
- "%rax", "%rbx", "%rcx", "%rdx", "memory"
- );
-#else
- uint32_t value_of_eax = 0;
- uint32_t value_of_ebx = 0;
- uint32_t value_of_ecx = 0;
- uint32_t value_of_edx = 0;
- __asm__ volatile (/* Instructions */
- /* ebx is callee-save, so push it */
- " pushl %%ebx \n"
- " movl %4, %%eax \n"
- " cpuid \n"
- " movl %%eax, %0 \n"
- " movl %%ebx, %1 \n"
- " movl %%ecx, %2 \n"
- " movl %%edx, %3 \n"
- /* restore ebx */
- " popl %%ebx \n"
-
- : /* Outputs */
- "=m" (value_of_eax),
- "=m" (value_of_ebx),
- "=m" (value_of_ecx),
- "=m" (value_of_edx)
- : /* Inputs */
- "m" (arg)
- : /* Clobbers */
- "%eax", "%ecx", "%edx"
- );
- *eaxp = value_of_eax;
- *ebxp = value_of_ebx;
- *ecxp = value_of_ecx;
- *edxp = value_of_edx;
-#endif
-}
-
-#endif /* __linux__ && i586 */
-
-#ifdef i586
-/*
- * Routines shared by solaris-i586 and linux-i586.
- */
-
-enum HyperThreadingSupport_enum {
- hts_supported = 1,
- hts_too_soon_to_tell = 0,
- hts_not_supported = -1,
- hts_not_pentium4 = -2,
- hts_not_intel = -3
-};
-typedef enum HyperThreadingSupport_enum HyperThreadingSupport;
-
-/* Determine if hyperthreading is supported */
-HyperThreadingSupport
-hyperthreading_support(void) {
- HyperThreadingSupport result = hts_too_soon_to_tell;
- /* Bits 11 through 8 is family processor id */
-# define FAMILY_ID_SHIFT 8
-# define FAMILY_ID_MASK 0xf
- /* Bits 23 through 20 is extended family processor id */
-# define EXT_FAMILY_ID_SHIFT 20
-# define EXT_FAMILY_ID_MASK 0xf
- /* Pentium 4 family processor id */
-# define PENTIUM4_FAMILY_ID 0xf
- /* Bit 28 indicates Hyper-Threading Technology support */
-# define HT_BIT_SHIFT 28
-# define HT_BIT_MASK 1
- uint32_t vendor_id[3] = { 0U, 0U, 0U };
- uint32_t value_of_eax = 0U;
- uint32_t value_of_edx = 0U;
- uint32_t dummy = 0U;
-
- /* Yes, this is supposed to be [0], [2], [1] */
- get_cpuid(0, &dummy, &vendor_id[0], &vendor_id[2], &vendor_id[1]);
- if (_launcher_debug) {
- printf("vendor: %c %c %c %c %c %c %c %c %c %c %c %c \n",
- ((vendor_id[0] >> 0) & 0xff),
- ((vendor_id[0] >> 8) & 0xff),
- ((vendor_id[0] >> 16) & 0xff),
- ((vendor_id[0] >> 24) & 0xff),
- ((vendor_id[1] >> 0) & 0xff),
- ((vendor_id[1] >> 8) & 0xff),
- ((vendor_id[1] >> 16) & 0xff),
- ((vendor_id[1] >> 24) & 0xff),
- ((vendor_id[2] >> 0) & 0xff),
- ((vendor_id[2] >> 8) & 0xff),
- ((vendor_id[2] >> 16) & 0xff),
- ((vendor_id[2] >> 24) & 0xff));
- }
- get_cpuid(1, &value_of_eax, &dummy, &dummy, &value_of_edx);
- if (_launcher_debug) {
- printf("value_of_eax: 0x%x value_of_edx: 0x%x\n",
- value_of_eax, value_of_edx);
- }
- if ((((value_of_eax >> FAMILY_ID_SHIFT) & FAMILY_ID_MASK) == PENTIUM4_FAMILY_ID) ||
- (((value_of_eax >> EXT_FAMILY_ID_SHIFT) & EXT_FAMILY_ID_MASK) != 0)) {
- if ((((vendor_id[0] >> 0) & 0xff) == 'G') &&
- (((vendor_id[0] >> 8) & 0xff) == 'e') &&
- (((vendor_id[0] >> 16) & 0xff) == 'n') &&
- (((vendor_id[0] >> 24) & 0xff) == 'u') &&
- (((vendor_id[1] >> 0) & 0xff) == 'i') &&
- (((vendor_id[1] >> 8) & 0xff) == 'n') &&
- (((vendor_id[1] >> 16) & 0xff) == 'e') &&
- (((vendor_id[1] >> 24) & 0xff) == 'I') &&
- (((vendor_id[2] >> 0) & 0xff) == 'n') &&
- (((vendor_id[2] >> 8) & 0xff) == 't') &&
- (((vendor_id[2] >> 16) & 0xff) == 'e') &&
- (((vendor_id[2] >> 24) & 0xff) == 'l')) {
- if (((value_of_edx >> HT_BIT_SHIFT) & HT_BIT_MASK) == HT_BIT_MASK) {
- if (_launcher_debug) {
- printf("Hyperthreading supported\n");
- }
- result = hts_supported;
- } else {
- if (_launcher_debug) {
- printf("Hyperthreading not supported\n");
- }
- result = hts_not_supported;
- }
- } else {
- if (_launcher_debug) {
- printf("Not GenuineIntel\n");
- }
- result = hts_not_intel;
- }
- } else {
- if (_launcher_debug) {
- printf("not Pentium 4 or extended\n");
- }
- result = hts_not_pentium4;
- }
- return result;
-}
-
-/* Determine how many logical processors there are per CPU */
-unsigned int
-logical_processors_per_package(void) {
- /*
- * After CPUID with EAX==1, register EBX bits 23 through 16
- * indicate the number of logical processors per package
- */
-# define NUM_LOGICAL_SHIFT 16
-# define NUM_LOGICAL_MASK 0xff
- unsigned int result = 1U;
- const HyperThreadingSupport hyperthreading = hyperthreading_support();
-
- if (hyperthreading == hts_supported) {
- uint32_t value_of_ebx = 0U;
- uint32_t dummy = 0U;
-
- get_cpuid(1, &dummy, &value_of_ebx, &dummy, &dummy);
- result = (value_of_ebx >> NUM_LOGICAL_SHIFT) & NUM_LOGICAL_MASK;
- if (_launcher_debug) {
- printf("logical processors per package: %u\n", result);
- }
- }
- return result;
-}
-
-/* Compute the number of physical processors, not logical processors */
-unsigned long
-physical_processors(void) {
- const long sys_processors = sysconf(_SC_NPROCESSORS_CONF);
- unsigned long result = sys_processors;
-
- if (_launcher_debug) {
- printf("sysconf(_SC_NPROCESSORS_CONF): %lu\n", sys_processors);
- }
- if (sys_processors > 1) {
- unsigned int logical_processors = logical_processors_per_package();
- if (logical_processors > 1) {
- result = (unsigned long) sys_processors / logical_processors;
- }
- }
- if (_launcher_debug) {
- printf("physical processors: %lu\n", result);
- }
- return result;
-}
-
-#endif /* i586 */
-
-#if defined(__sun) && defined(i586)
-
-/* The definition of a server-class machine for solaris-i586/amd64 */
-jboolean
-solaris_i586_ServerClassMachine(void) {
- jboolean result = JNI_FALSE;
- /* How big is a server class machine? */
- const unsigned long server_processors = 2UL;
- const uint64_t server_memory = 2UL * GB;
- /*
- * We seem not to get our full complement of memory.
- * We allow some part (1/8?) of the memory to be "missing",
- * based on the sizes of DIMMs, and maybe graphics cards.
- */
- const uint64_t missing_memory = 256UL * MB;
- const uint64_t actual_memory = physical_memory();
-
- /* Is this a server class machine? */
- if (actual_memory >= (server_memory - missing_memory)) {
- const unsigned long actual_processors = physical_processors();
- if (actual_processors >= server_processors) {
- result = JNI_TRUE;
- }
- }
- if (_launcher_debug) {
- printf("solaris_" LIBARCHNAME "_ServerClassMachine: %s\n",
- (result == JNI_TRUE ? "true" : "false"));
- }
- return result;
-}
-
-#endif /* __sun && i586 */
-
-#if defined(__linux__) && defined(i586)
-
-/* The definition of a server-class machine for linux-i586 */
-jboolean
-linux_i586_ServerClassMachine(void) {
- jboolean result = JNI_FALSE;
- /* How big is a server class machine? */
- const unsigned long server_processors = 2UL;
- const uint64_t server_memory = 2UL * GB;
- /*
- * We seem not to get our full complement of memory.
- * We allow some part (1/8?) of the memory to be "missing",
- * based on the sizes of DIMMs, and maybe graphics cards.
- */
- const uint64_t missing_memory = 256UL * MB;
- const uint64_t actual_memory = physical_memory();
-
- /* Is this a server class machine? */
- if (actual_memory >= (server_memory - missing_memory)) {
- const unsigned long actual_processors = physical_processors();
- if (actual_processors >= server_processors) {
- result = JNI_TRUE;
- }
- }
- if (_launcher_debug) {
- printf("linux_" LIBARCHNAME "_ServerClassMachine: %s\n",
- (result == JNI_TRUE ? "true" : "false"));
- }
- return result;
-}
-
-#endif /* __linux__ && i586 */
-
-#if defined(_ALLBSD_SOURCE) && defined(i586)
-
-/* The definition of a server-class machine for bsd-i586 */
-jboolean
-bsd_i586_ServerClassMachine(void) {
- jboolean result = JNI_FALSE;
- /* How big is a server class machine? */
- const unsigned long server_processors = 2UL;
- const uint64_t server_memory = 2UL * GB;
- /*
- * We seem not to get our full complement of memory.
- * We allow some part (1/8?) of the memory to be "missing",
- * based on the sizes of DIMMs, and maybe graphics cards.
- */
- const uint64_t missing_memory = 256UL * MB;
- const uint64_t actual_memory = physical_memory();
-
- /* Is this a server class machine? */
- if (actual_memory >= (server_memory - missing_memory)) {
- const unsigned long actual_processors = physical_processors();
- if (actual_processors >= server_processors) {
- result = JNI_TRUE;
- }
- }
- if (_launcher_debug) {
- printf("linux_" LIBARCHNAME "_ServerClassMachine: %s\n",
- (result == JNI_TRUE ? "true" : "false"));
- }
- return result;
-}
-
-#endif /* _ALLBSD_SOURCE && i586 */
-
-/* Dispatch to the platform-specific definition of "server-class" */
-jboolean
-ServerClassMachine(void) {
- jboolean result = JNI_FALSE;
-#if defined(NEVER_ACT_AS_SERVER_CLASS_MACHINE)
- result = JNI_FALSE;
-#elif defined(ALWAYS_ACT_AS_SERVER_CLASS_MACHINE)
- result = JNI_TRUE;
-#elif defined(__sun) && defined(__sparc)
- result = solaris_sparc_ServerClassMachine();
-#elif defined(__sun) && defined(i586)
- result = solaris_i586_ServerClassMachine();
-#elif defined(__linux__) && defined(i586)
- result = linux_i586_ServerClassMachine();
-#elif defined(_ALLBSD_SOURCE) && defined(i586)
- result = bsd_i586_ServerClassMachine();
-#else
- if (_launcher_debug) {
- printf("ServerClassMachine: returns default value of %s\n",
- (result == JNI_TRUE ? "true" : "false"));
- }
-#endif
- return result;
-}
-
-/*
- * Since using the file system as a registry is a bit risky, perform
- * additional sanity checks on the identified directory to validate
- * it as a valid jre/sdk.
- *
- * Return 0 if the tests fail; otherwise return non-zero (true).
- *
- * Note that checking for anything more than the existence of an
- * executable object at bin/java relative to the path being checked
- * will break the regression tests.
- */
-static int
-CheckSanity(char *path, char *dir)
-{
- char buffer[PATH_MAX];
-
- if (strlen(path) + strlen(dir) + 11 > PATH_MAX)
- return (0); /* Silently reject "impossibly" long paths */
-
- (void)strcat(strcat(strcat(strcpy(buffer, path), "/"), dir), "/bin/java");
- return ((access(buffer, X_OK) == 0) ? 1 : 0);
-}
-
-/*
- * Determine if there is an acceptable JRE in the directory dirname.
- * Upon locating the "best" one, return a fully qualified path to
- * it. "Best" is defined as the most advanced JRE meeting the
- * constraints contained in the manifest_info. If no JRE in this
- * directory meets the constraints, return NULL.
- *
- * Note that we don't check for errors in reading the directory
- * (which would be done by checking errno). This is because it
- * doesn't matter if we get an error reading the directory, or
- * we just don't find anything interesting in the directory. We
- * just return NULL in either case.
- *
- * The historical names of j2sdk and j2re were changed to jdk and
- * jre respecively as part of the 1.5 rebranding effort. Since the
- * former names are legacy on Linux, they must be recognized for
- * all time. Fortunately, this is a minor cost.
- */
-static char
-*ProcessDir(manifest_info *info, char *dirname)
-{
- DIR *dirp;
- struct dirent *dp;
- char *best = NULL;
- int offset;
- int best_offset = 0;
- char *ret_str = NULL;
- char buffer[PATH_MAX];
-
- if ((dirp = opendir(dirname)) == NULL)
- return (NULL);
-
- do {
- if ((dp = readdir(dirp)) != NULL) {
- offset = 0;
- if ((strncmp(dp->d_name, "jre", 3) == 0) ||
- (strncmp(dp->d_name, "jdk", 3) == 0))
- offset = 3;
- else if (strncmp(dp->d_name, "j2re", 4) == 0)
- offset = 4;
- else if (strncmp(dp->d_name, "j2sdk", 5) == 0)
- offset = 5;
- if (offset > 0) {
- if ((JLI_AcceptableRelease(dp->d_name + offset,
- info->jre_version)) && CheckSanity(dirname, dp->d_name))
- if ((best == NULL) || (JLI_ExactVersionId(
- dp->d_name + offset, best + best_offset) > 0)) {
- if (best != NULL)
- JLI_MemFree(best);
- best = JLI_StringDup(dp->d_name);
- best_offset = offset;
- }
- }
- }
- } while (dp != NULL);
- (void) closedir(dirp);
- if (best == NULL)
- return (NULL);
- else {
- ret_str = JLI_MemAlloc(strlen(dirname) + strlen(best) + 2);
- ret_str = strcat(strcat(strcpy(ret_str, dirname), "/"), best);
- JLI_MemFree(best);
- return (ret_str);
- }
-}
-
-/*
- * This is the global entry point. It examines the host for the optimal
- * JRE to be used by scanning a set of directories. The set of directories
- * is platform dependent and can be overridden by the environment
- * variable JAVA_VERSION_PATH.
- *
- * This routine itself simply determines the set of appropriate
- * directories before passing control onto ProcessDir().
- */
-char*
-LocateJRE(manifest_info* info)
-{
- char *path;
- char *home;
- char *target = NULL;
- char *dp;
- char *cp;
-
- /*
- * Start by getting JAVA_VERSION_PATH
- */
- if (info->jre_restrict_search)
- path = JLI_StringDup(system_dir);
- else if ((path = getenv("JAVA_VERSION_PATH")) != NULL)
- path = JLI_StringDup(path);
- else
- if ((home = getenv("HOME")) != NULL) {
- path = (char *)JLI_MemAlloc(strlen(home) + strlen(system_dir) +
- strlen(user_dir) + 2);
- path = strcat(strcat(strcat(strcpy(path, home),
- user_dir), ":"), system_dir);
- } else
- path = JLI_StringDup(system_dir);
-
- /*
- * Step through each directory on the path. Terminate the scan with
- * the first directory with an acceptable JRE.
- */
- cp = dp = path;
- while (dp != NULL) {
- cp = strchr(dp, (int)':');
- if (cp != NULL)
- *cp = (char)NULL;
- if ((target = ProcessDir(info, dp)) != NULL)
- break;
- dp = cp;
- if (dp != NULL)
- dp++;
- }
- JLI_MemFree(path);
- return (target);
-}
-
-/*
- * Given a path to a jre to execute, this routine checks if this process
- * is indeed that jre. If not, it exec's that jre.
- *
- * We want to actually check the paths rather than just the version string
- * built into the executable, so that given version specification (and
- * JAVA_VERSION_PATH) will yield the exact same Java environment, regardless
- * of the version of the arbitrary launcher we start with.
- */
-void
-ExecJRE(char *jre, char **argv)
-{
- char wanted[PATH_MAX];
- char *execname;
- char *progname;
-
- /*
- * Resolve the real path to the directory containing the selected JRE.
- */
- if (realpath(jre, wanted) == NULL) {
- fprintf(stderr, "Unable to resolve %s\n", jre);
- exit(1);
- }
-
- /*
- * Resolve the real path to the currently running launcher.
- */
- execname = SetExecname(argv);
- if (execname == NULL) {
- fprintf(stderr, "Unable to resolve current executable\n");
- exit(1);
- }
-
- /*
- * If the path to the selected JRE directory is a match to the initial
- * portion of the path to the currently executing JRE, we have a winner!
- * If so, just return.
- */
- if (strncmp(wanted, execname, strlen(wanted)) == 0)
- return; /* I am the droid you were looking for */
-
- /*
- * If this isn't the selected version, exec the selected version.
- */
-#ifdef JAVA_ARGS /* javac, jar and friends. */
- progname = "java";
-#else /* java, oldjava, javaw and friends */
-#ifdef PROGNAME
- progname = PROGNAME;
-#else
- progname = *argv;
- if ((s = strrchr(progname, FILE_SEPARATOR)) != 0) {
- progname = s + 1;
- }
-#endif /* PROGNAME */
-#endif /* JAVA_ARGS */
-
- /*
- * This should never happen (because of the selection code in SelectJRE),
- * but check for "impossibly" long path names just because buffer overruns
- * can be so deadly.
- */
- if (strlen(wanted) + strlen(progname) + 6 > PATH_MAX) {
- fprintf(stderr, "Path length exceeds maximum length (PATH_MAX)\n");
- exit(1);
- }
-
- /*
- * Construct the path and exec it.
- */
- (void)strcat(strcat(wanted, "/bin/"), progname);
- argv[0] = progname;
- if (_launcher_debug) {
- int i;
- printf("ReExec Command: %s (%s)\n", wanted, argv[0]);
- printf("ReExec Args:");
- for (i = 1; argv[i] != NULL; i++)
- printf(" %s", argv[i]);
- printf("\n");
- }
- (void)fflush(stdout);
- (void)fflush(stderr);
- execv(wanted, argv);
- perror("execv()");
- fprintf(stderr, "Exec of %s failed\n", wanted);
- exit(1);
-}
-#endif /* ifndef GAMMA */
-
-/*
- * "Borrowed" from Solaris 10 where the unsetenv() function is being added
- * to libc thanks to SUSv3 (Standard Unix Specification, version 3). As
- * such, in the fullness of time this will appear in libc on all relevant
- * Solaris/Linux platforms and maybe even the Windows platform. At that
- * time, this stub can be removed.
- *
- * This implementation removes the environment locking for multithreaded
- * applications. (We don't have access to these mutexes within libc and
- * the launcher isn't multithreaded.) Note that what remains is platform
- * independent, because it only relies on attributes that a POSIX environment
- * defines.
- *
- * Returns 0 on success, -1 on failure.
- *
- * Also removed was the setting of errno. The only value of errno set
- * was EINVAL ("Invalid Argument").
- */
-
-/*
- * s1(environ) is name=value
- * s2(name) is name(not the form of name=value).
- * if names match, return value of 1, else return 0
- */
-static int
-match_noeq(const char *s1, const char *s2)
-{
- while (*s1 == *s2++) {
- if (*s1++ == '=')
- return (1);
- }
- if (*s1 == '=' && s2[-1] == '\0')
- return (1);
- return (0);
-}
-
-/*
- * added for SUSv3 standard
- *
- * Delete entry from environ.
- * Do not free() memory! Other threads may be using it.
- * Keep it around forever.
- */
-static int
-borrowed_unsetenv(const char *name)
-{
- long idx; /* index into environ */
-
- if (name == NULL || *name == '\0' ||
- strchr(name, '=') != NULL) {
- return (-1);
- }
-
- for (idx = 0; environ[idx] != NULL; idx++) {
- if (match_noeq(environ[idx], name))
- break;
- }
- if (environ[idx] == NULL) {
- /* name not found but still a success */
- return (0);
- }
- /* squeeze up one entry */
- do {
- environ[idx] = environ[idx+1];
- } while (environ[++idx] != NULL);
-
- return (0);
-}
-/* --- End of "borrowed" code --- */
-
-/*
- * Wrapper for unsetenv() function.
- */
-int
-UnsetEnv(char *name)
-{
- return(borrowed_unsetenv(name));
-}
-
-/* --- Splash Screen shared library support --- */
-
-static const char* SPLASHSCREEN_SO = "libsplashscreen.so";
-
-static void* hSplashLib = NULL;
-
-void* SplashProcAddress(const char* name) {
- if (!hSplashLib) {
- hSplashLib = dlopen(SPLASHSCREEN_SO, RTLD_LAZY | RTLD_GLOBAL);
- }
- if (hSplashLib) {
- void* sym = dlsym(hSplashLib, name);
- return sym;
- } else {
- return NULL;
- }
-}
-
-void SplashFreeLibrary() {
- if (hSplashLib) {
- dlclose(hSplashLib);
- hSplashLib = NULL;
- }
-}
-
-/*
- * Block current thread and continue execution in a new thread
- */
-int
-ContinueInNewThread(int (JNICALL *continuation)(void *), jlong stack_size, void * args) {
- int rslt;
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
- pthread_t tid;
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- if (stack_size > 0) {
- pthread_attr_setstacksize(&attr, stack_size);
- }
-
- if (pthread_create(&tid, &attr, (void *(*)(void*))continuation, (void*)args) == 0) {
- void * tmp;
- pthread_join(tid, &tmp);
- rslt = (int)(intptr_t)tmp;
- } else {
- /*
- * Continue execution in current thread if for some reason (e.g. out of
- * memory/LWP) a new thread can't be created. This will likely fail
- * later in continuation as JNI_CreateJavaVM needs to create quite a
- * few new threads, anyway, just give it a try..
- */
- rslt = continuation(args);
- }
-
- pthread_attr_destroy(&attr);
-#else
- thread_t tid;
- long flags = 0;
- if (thr_create(NULL, stack_size, (void *(*)(void *))continuation, args, flags, &tid) == 0) {
- void * tmp;
- thr_join(tid, NULL, &tmp);
- rslt = (int)(intptr_t)tmp;
- } else {
- /* See above. Continue in current thread if thr_create() failed */
- rslt = continuation(args);
- }
-#endif
- return rslt;
-}
-
-/* Coarse estimation of number of digits assuming the worst case is a 64-bit pid. */
-#define MAX_PID_STR_SZ 20
-
-void SetJavaLauncherPlatformProps() {
- /* Linux only */
-#ifdef __linux__
- const char *substr = "-Dsun.java.launcher.pid=";
- char *pid_prop_str = (char *)JLI_MemAlloc(strlen(substr) + MAX_PID_STR_SZ + 1);
- sprintf(pid_prop_str, "%s%d", substr, getpid());
- AddOption(pid_prop_str, NULL);
-#endif
-}
diff --git a/hotspot/src/os/posix/launcher/java_md.h b/hotspot/src/os/posix/launcher/java_md.h
deleted file mode 100644
index 63c449a2926..00000000000
--- a/hotspot/src/os/posix/launcher/java_md.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef JAVA_MD_H
-#define JAVA_MD_H
-
-#include
-#include
-#include
-#ifndef GAMMA
-#include "manifest_info.h"
-#endif
-#include "jli_util.h"
-
-#define PATH_SEPARATOR ':'
-#define FILESEP "/"
-#define FILE_SEPARATOR '/'
-#define IS_FILE_SEPARATOR(c) ((c) == '/')
-#ifndef MAXNAMELEN
-#define MAXNAMELEN PATH_MAX
-#endif
-
-#ifdef JAVA_ARGS
-/*
- * ApplicationHome is prepended to each of these entries; the resulting
- * strings are concatenated (separated by PATH_SEPARATOR) and used as the
- * value of -cp option to the launcher.
- */
-#ifndef APP_CLASSPATH
-#define APP_CLASSPATH { "/lib/tools.jar", "/classes" }
-#endif
-#endif
-
-#ifdef HAVE_GETHRTIME
-/*
- * Support for doing cheap, accurate interval timing.
- */
-#include
-#define CounterGet() (gethrtime()/1000)
-#define Counter2Micros(counts) (counts)
-#else
-#define CounterGet() (0)
-#define Counter2Micros(counts) (1)
-#endif /* HAVE_GETHRTIME */
-
-#ifdef _LP64
-#define JLONG_FORMAT "%ld"
-#else
-#define JLONG_FORMAT "%lld"
-#endif
-
-/*
- * Function prototypes.
- */
-#ifndef GAMMA
-char *LocateJRE(manifest_info *info);
-void ExecJRE(char *jre, char **argv);
-#endif
-int UnsetEnv(char *name);
-
-#endif
diff --git a/hotspot/src/os/windows/launcher/java_md.c b/hotspot/src/os/windows/launcher/java_md.c
deleted file mode 100644
index 3e28755009c..00000000000
--- a/hotspot/src/os/windows/launcher/java_md.c
+++ /dev/null
@@ -1,1507 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include "java.h"
-#ifndef GAMMA
-#include "version_comp.h"
-#endif
-
-#define JVM_DLL "jvm.dll"
-#define JAVA_DLL "java.dll"
-#define CRT_DLL "msvcr71.dll"
-
-/*
- * Prototypes.
- */
-static jboolean GetPublicJREHome(char *path, jint pathsize);
-static jboolean GetJVMPath(const char *jrepath, const char *jvmtype,
- char *jvmpath, jint jvmpathsize);
-static jboolean GetJREPath(char *path, jint pathsize);
-static void EnsureJreInstallation(const char *jrepath);
-
-/* We supports warmup for UI stack that is performed in parallel
- * to VM initialization.
- * This helps to improve startup of UI application as warmup phase
- * might be long due to initialization of OS or hardware resources.
- * It is not CPU bound and therefore it does not interfere with VM init.
- * Obviously such warmup only has sense for UI apps and therefore it needs
- * to be explicitly requested by passing -Dsun.awt.warmup=true property
- * (this is always the case for plugin/javaws).
- *
- * Implementation launches new thread after VM starts and use it to perform
- * warmup code (platform dependent).
- * This thread is later reused as AWT toolkit thread as graphics toolkit
- * often assume that they are used from the same thread they were launched on.
- *
- * At the moment we only support warmup for D3D. It only possible on windows
- * and only if other flags do not prohibit this (e.g. OpenGL support requested).
- */
-#undef ENABLE_AWT_PRELOAD
-#ifndef JAVA_ARGS /* turn off AWT preloading for javac, jar, etc */
- #ifdef _X86_ /* for now disable AWT preloading for 64bit */
- #define ENABLE_AWT_PRELOAD
- #endif
-#endif
-
-#ifdef ENABLE_AWT_PRELOAD
-/* "AWT was preloaded" flag;
- * Turned on by AWTPreload().
- */
-int awtPreloaded = 0;
-
-/* Calls a function with the name specified.
- * The function must be int(*fn)(void).
- */
-int AWTPreload(const char *funcName);
-/* Stops AWT preloading. */
-void AWTPreloadStop();
-
-/* D3D preloading */
-/* -1: not initialized; 0: OFF, 1: ON */
-int awtPreloadD3D = -1;
-/* Command line parameter to swith D3D preloading on. */
-#define PARAM_PRELOAD_D3D "-Dsun.awt.warmup"
-/* D3D/OpenGL management parameters (may disable D3D preloading) */
-#define PARAM_NODDRAW "-Dsun.java2d.noddraw"
-#define PARAM_D3D "-Dsun.java2d.d3d"
-#define PARAM_OPENGL "-Dsun.java2d.opengl"
-/* funtion in awt.dll (src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp) */
-#define D3D_PRELOAD_FUNC "preloadD3D"
-
-
-/* Extracts value of a parameter with the specified name
- * from command line argument (returns pointer in the argument).
- * Returns NULL if the argument does not contains the parameter.
- * e.g.:
- * GetParamValue("theParam", "theParam=value") returns pointer to "value".
- */
-const char * GetParamValue(const char *paramName, const char *arg) {
- int nameLen = strlen(paramName);
- if (strncmp(paramName, arg, nameLen) == 0) {
- // arg[nameLen] is valid (may contain final NULL)
- if (arg[nameLen] == '=') {
- return arg + nameLen + 1;
- }
- }
- return NULL;
-}
-
-/* Checks if commandline argument contains property specified
- * and analyze it as boolean property (true/false).
- * Returns -1 if the argument does not contain the parameter;
- * Returns 1 if the argument contains the parameter and its value is "true";
- * Returns 0 if the argument contains the parameter and its value is "false".
- */
-int GetBoolParamValue(const char *paramName, const char *arg) {
- const char * paramValue = GetParamValue(paramName, arg);
- if (paramValue != NULL) {
- if (stricmp(paramValue, "true") == 0) {
- return 1;
- }
- if (stricmp(paramValue, "false") == 0) {
- return 0;
- }
- }
- return -1;
-}
-#endif /* ENABLE_AWT_PRELOAD */
-
-
-const char *
-GetArch()
-{
-
-#ifdef _M_AMD64
- return "amd64";
-#elif defined(_M_IA64)
- return "ia64";
-#else
- return "i386";
-#endif
-}
-
-/*
- *
- */
-void
-CreateExecutionEnvironment(int *_argc,
- char ***_argv,
- char jrepath[],
- jint so_jrepath,
- char jvmpath[],
- jint so_jvmpath,
- char **original_argv) {
-#ifndef GAMMA
- char * jvmtype;
-
- /* Find out where the JRE is that we will be using. */
- if (!GetJREPath(jrepath, so_jrepath)) {
- ReportErrorMessage("Error: could not find Java SE Runtime Environment.",
- JNI_TRUE);
- exit(2);
- }
-
- /* Do this before we read jvm.cfg */
- EnsureJreInstallation(jrepath);
-
- /* Find the specified JVM type */
- if (ReadKnownVMs(jrepath, (char*)GetArch(), JNI_FALSE) < 1) {
- ReportErrorMessage("Error: no known VMs. (check for corrupt jvm.cfg file)",
- JNI_TRUE);
- exit(1);
- }
- jvmtype = CheckJvmType(_argc, _argv, JNI_FALSE);
-
- jvmpath[0] = '\0';
- if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath)) {
- char * message=NULL;
- const char * format = "Error: no `%s' JVM at `%s'.";
- message = (char *)JLI_MemAlloc((strlen(format)+strlen(jvmtype)+
- strlen(jvmpath)) * sizeof(char));
- sprintf(message,format, jvmtype, jvmpath);
- ReportErrorMessage(message, JNI_TRUE);
- exit(4);
- }
- /* If we got here, jvmpath has been correctly initialized. */
-
-#else /* ifndef GAMMA */
-
- /*
- * gamma launcher is simpler in that it doesn't handle VM flavors, data
- * model, etc. Assuming everything is set-up correctly
- * all we need to do here is to return correct path names. See also
- * GetJVMPath() and GetApplicationHome().
- */
-
- {
- if (!GetJREPath(jrepath, so_jrepath) ) {
- ReportErrorMessage("Error: could not find Java SE Runtime Environment.",
- JNI_TRUE);
- exit(2);
- }
-
- if (!GetJVMPath(jrepath, NULL, jvmpath, so_jvmpath)) {
- char * message=NULL;
- const char * format = "Error: no JVM at `%s'.";
- message = (char *)JLI_MemAlloc((strlen(format)+
- strlen(jvmpath)) * sizeof(char));
- sprintf(message, format, jvmpath);
- ReportErrorMessage(message, JNI_TRUE);
- exit(4);
- }
- }
-
-#endif /* ifndef GAMMA */
-
-}
-
-
-static jboolean
-LoadMSVCRT()
-{
- // Only do this once
- static int loaded = 0;
- char crtpath[MAXPATHLEN];
-
- if (!loaded) {
- /*
- * The Microsoft C Runtime Library needs to be loaded first. A copy is
- * assumed to be present in the "JRE path" directory. If it is not found
- * there (or "JRE path" fails to resolve), skip the explicit load and let
- * nature take its course, which is likely to be a failure to execute.
- */
- if (GetJREPath(crtpath, MAXPATHLEN)) {
- (void)strcat(crtpath, "\\bin\\" CRT_DLL); /* Add crt dll */
- if (_launcher_debug) {
- printf("CRT path is %s\n", crtpath);
- }
- if (_access(crtpath, 0) == 0) {
- if (LoadLibrary(crtpath) == 0) {
- ReportErrorMessage2("Error loading: %s", crtpath, JNI_TRUE);
- return JNI_FALSE;
- }
- }
- }
- loaded = 1;
- }
- return JNI_TRUE;
-}
-
-/*
- * The preJVMStart is a function in the jkernel.dll, which
- * performs the final step of synthesizing back the decomposed
- * modules (partial install) to the full JRE. Any tool which
- * uses the JRE must peform this step to ensure the complete synthesis.
- * The EnsureJreInstallation function calls preJVMStart based on
- * the conditions outlined below, noting that the operation
- * will fail silently if any of conditions are not met.
- * NOTE: this call must be made before jvm.dll is loaded, or jvm.cfg
- * is read, since jvm.cfg will be modified by the preJVMStart.
- * 1. Are we on a supported platform.
- * 2. Find the location of the JRE or the Kernel JRE.
- * 3. check existence of JREHOME/lib/bundles
- * 4. check jkernel.dll and invoke the entry-point
- */
-typedef VOID (WINAPI *PREJVMSTART)();
-
-static void
-EnsureJreInstallation(const char* jrepath)
-{
- HINSTANCE handle;
- char tmpbuf[MAXPATHLEN];
- PREJVMSTART PreJVMStart;
- struct stat s;
-
- /* 32 bit windows only please */
- if (strcmp(GetArch(), "i386") != 0 ) {
- if (_launcher_debug) {
- printf("EnsureJreInstallation:unsupported platform\n");
- }
- return;
- }
- /* Does our bundle directory exist ? */
- strcpy(tmpbuf, jrepath);
- strcat(tmpbuf, "\\lib\\bundles");
- if (stat(tmpbuf, &s) != 0) {
- if (_launcher_debug) {
- printf("EnsureJreInstallation:<%s>:not found\n", tmpbuf);
- }
- return;
- }
- /* Does our jkernel dll exist ? */
- strcpy(tmpbuf, jrepath);
- strcat(tmpbuf, "\\bin\\jkernel.dll");
- if (stat(tmpbuf, &s) != 0) {
- if (_launcher_debug) {
- printf("EnsureJreInstallation:<%s>:not found\n", tmpbuf);
- }
- return;
- }
- /* The Microsoft C Runtime Library needs to be loaded first. */
- if (!LoadMSVCRT()) {
- if (_launcher_debug) {
- printf("EnsureJreInstallation:could not load C runtime DLL\n");
- }
- return;
- }
- /* Load the jkernel.dll */
- if ((handle = LoadLibrary(tmpbuf)) == 0) {
- if (_launcher_debug) {
- printf("EnsureJreInstallation:%s:load failed\n", tmpbuf);
- }
- return;
- }
- /* Get the function address */
- PreJVMStart = (PREJVMSTART)GetProcAddress(handle, "preJVMStart");
- if (PreJVMStart == NULL) {
- if (_launcher_debug) {
- printf("EnsureJreInstallation:preJVMStart:function lookup failed\n");
- }
- FreeLibrary(handle);
- return;
- }
- PreJVMStart();
- if (_launcher_debug) {
- printf("EnsureJreInstallation:preJVMStart:called\n");
- }
- FreeLibrary(handle);
- return;
-}
-
-/*
- * Find path to JRE based on .exe's location or registry settings.
- */
-jboolean
-GetJREPath(char *path, jint pathsize)
-{
- char javadll[MAXPATHLEN];
- struct stat s;
-
- if (GetApplicationHome(path, pathsize)) {
- /* Is JRE co-located with the application? */
- sprintf(javadll, "%s\\bin\\" JAVA_DLL, path);
- if (stat(javadll, &s) == 0) {
- goto found;
- }
-
- /* Does this app ship a private JRE in \jre directory? */
- sprintf(javadll, "%s\\jre\\bin\\" JAVA_DLL, path);
- if (stat(javadll, &s) == 0) {
- strcat(path, "\\jre");
- goto found;
- }
- }
-
-#ifndef GAMMA
- /* Look for a public JRE on this machine. */
- if (GetPublicJREHome(path, pathsize)) {
- goto found;
- }
-#endif
-
- fprintf(stderr, "Error: could not find " JAVA_DLL "\n");
- return JNI_FALSE;
-
- found:
- if (_launcher_debug)
- printf("JRE path is %s\n", path);
- return JNI_TRUE;
-}
-
-/*
- * Given a JRE location and a JVM type, construct what the name the
- * JVM shared library will be. Return true, if such a library
- * exists, false otherwise.
- */
-static jboolean
-GetJVMPath(const char *jrepath, const char *jvmtype,
- char *jvmpath, jint jvmpathsize)
-{
- struct stat s;
-
-#ifndef GAMMA
- if (strchr(jvmtype, '/') || strchr(jvmtype, '\\')) {
- sprintf(jvmpath, "%s\\" JVM_DLL, jvmtype);
- } else {
- sprintf(jvmpath, "%s\\bin\\%s\\" JVM_DLL, jrepath, jvmtype);
- }
-#else
- /*
- * For gamma launcher, JVM is either built-in or in the same directory.
- * Either way we return "/jvm.dll" where is the
- * directory where gamma launcher is located.
- */
-
- char *p;
- GetModuleFileName(0, jvmpath, jvmpathsize);
-
- p = strrchr(jvmpath, '\\');
- if (p) {
- /* replace executable name with libjvm.so */
- snprintf(p + 1, jvmpathsize - (p + 1 - jvmpath), "%s", JVM_DLL);
- } else {
- /* this case shouldn't happen */
- snprintf(jvmpath, jvmpathsize, "%s", JVM_DLL);
- }
-#endif /* ifndef GAMMA */
-
- if (stat(jvmpath, &s) == 0) {
- return JNI_TRUE;
- } else {
- return JNI_FALSE;
- }
-}
-
-/*
- * Load a jvm from "jvmpath" and initialize the invocation functions.
- */
-jboolean
-LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
-{
-#ifdef GAMMA
- /* JVM is directly linked with gamma launcher; no Loadlibrary() */
- ifn->CreateJavaVM = JNI_CreateJavaVM;
- ifn->GetDefaultJavaVMInitArgs = JNI_GetDefaultJavaVMInitArgs;
- return JNI_TRUE;
-#else
- HINSTANCE handle;
-
- if (_launcher_debug) {
- printf("JVM path is %s\n", jvmpath);
- }
-
- /* The Microsoft C Runtime Library needs to be loaded first. */
- LoadMSVCRT();
-
- /* Load the Java VM DLL */
- if ((handle = LoadLibrary(jvmpath)) == 0) {
- ReportErrorMessage2("Error loading: %s", (char *)jvmpath, JNI_TRUE);
- return JNI_FALSE;
- }
-
- /* Now get the function addresses */
- ifn->CreateJavaVM =
- (void *)GetProcAddress(handle, "JNI_CreateJavaVM");
- ifn->GetDefaultJavaVMInitArgs =
- (void *)GetProcAddress(handle, "JNI_GetDefaultJavaVMInitArgs");
- if (ifn->CreateJavaVM == 0 || ifn->GetDefaultJavaVMInitArgs == 0) {
- ReportErrorMessage2("Error: can't find JNI interfaces in: %s",
- (char *)jvmpath, JNI_TRUE);
- return JNI_FALSE;
- }
-
- return JNI_TRUE;
-#endif /* ifndef GAMMA */
-}
-
-/*
- * If app is "c:\foo\bin\javac", then put "c:\foo" into buf.
- */
-jboolean
-GetApplicationHome(char *buf, jint bufsize)
-{
-#ifndef GAMMA
- char *cp;
- GetModuleFileName(0, buf, bufsize);
- *strrchr(buf, '\\') = '\0'; /* remove .exe file name */
- if ((cp = strrchr(buf, '\\')) == 0) {
- /* This happens if the application is in a drive root, and
- * there is no bin directory. */
- buf[0] = '\0';
- return JNI_FALSE;
- }
- *cp = '\0'; /* remove the bin\ part */
- return JNI_TRUE;
-
-#else /* ifndef GAMMA */
-
- char env[MAXPATHLEN + 1];
-
- /* gamma launcher uses ALT_JAVA_HOME environment variable or jdkpath.txt file to find JDK/JRE */
-
- if (getenv("ALT_JAVA_HOME") != NULL) {
- snprintf(buf, bufsize, "%s", getenv("ALT_JAVA_HOME"));
- }
- else {
- char path[MAXPATHLEN + 1];
- char* p;
- int len;
- FILE* fp;
-
- // find the path to the currect executable
- len = GetModuleFileName(NULL, path, MAXPATHLEN + 1);
- if (len == 0 || len > MAXPATHLEN) {
- printf("Could not get directory of current executable.");
- return JNI_FALSE;
- }
- // remove last path component ("hotspot.exe")
- p = strrchr(path, '\\');
- if (p == NULL) {
- printf("Could not parse directory of current executable.\n");
- return JNI_FALSE;
- }
- *p = '\0';
-
- // open jdkpath.txt and read JAVA_HOME from it
- if (strlen(path) + strlen("\\jdkpath.txt") + 1 >= MAXPATHLEN) {
- printf("Path too long: %s\n", path);
- return JNI_FALSE;
- }
- strcat(path, "\\jdkpath.txt");
- fp = fopen(path, "r");
- if (fp == NULL) {
- printf("Could not open file %s to get path to JDK.\n", path);
- return JNI_FALSE;
- }
-
- if (fgets(buf, bufsize, fp) == NULL) {
- printf("Could not read from file %s to get path to JDK.\n", path);
- fclose(fp);
- return JNI_FALSE;
- }
- // trim the buffer
- p = buf + strlen(buf) - 1;
- while(isspace(*p)) {
- *p = '\0';
- p--;
- }
- fclose(fp);
- }
-
- _snprintf(env, MAXPATHLEN, "JAVA_HOME=%s", buf);
- _putenv(env);
-
- return JNI_TRUE;
-#endif /* ifndef GAMMA */
-}
-
-#ifdef JAVAW
-__declspec(dllimport) char **__initenv;
-
-int WINAPI
-WinMain(HINSTANCE inst, HINSTANCE previnst, LPSTR cmdline, int cmdshow)
-{
- int ret;
-
- __initenv = _environ;
- ret = main(__argc, __argv);
-
- return ret;
-}
-#endif
-
-#ifndef GAMMA
-
-/*
- * Helpers to look in the registry for a public JRE.
- */
- /* Same for 1.5.0, 1.5.1, 1.5.2 etc. */
-#define DOTRELEASE JDK_MAJOR_VERSION "." JDK_MINOR_VERSION
-#define JRE_KEY "Software\\JavaSoft\\Java Runtime Environment"
-
-static jboolean
-GetStringFromRegistry(HKEY key, const char *name, char *buf, jint bufsize)
-{
- DWORD type, size;
-
- if (RegQueryValueEx(key, name, 0, &type, 0, &size) == 0
- && type == REG_SZ
- && (size < (unsigned int)bufsize)) {
- if (RegQueryValueEx(key, name, 0, 0, buf, &size) == 0) {
- return JNI_TRUE;
- }
- }
- return JNI_FALSE;
-}
-
-static jboolean
-GetPublicJREHome(char *buf, jint bufsize)
-{
- HKEY key, subkey;
- char version[MAXPATHLEN];
-
- /*
- * Note: There is a very similar implementation of the following
- * registry reading code in the Windows java control panel (javacp.cpl).
- * If there are bugs here, a similar bug probably exists there. Hence,
- * changes here require inspection there.
- */
-
- /* Find the current version of the JRE */
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, JRE_KEY, 0, KEY_READ, &key) != 0) {
- fprintf(stderr, "Error opening registry key '" JRE_KEY "'\n");
- return JNI_FALSE;
- }
-
- if (!GetStringFromRegistry(key, "CurrentVersion",
- version, sizeof(version))) {
- fprintf(stderr, "Failed reading value of registry key:\n\t"
- JRE_KEY "\\CurrentVersion\n");
- RegCloseKey(key);
- return JNI_FALSE;
- }
-
- if (strcmp(version, DOTRELEASE) != 0) {
- fprintf(stderr, "Registry key '" JRE_KEY "\\CurrentVersion'\nhas "
- "value '%s', but '" DOTRELEASE "' is required.\n", version);
- RegCloseKey(key);
- return JNI_FALSE;
- }
-
- /* Find directory where the current version is installed. */
- if (RegOpenKeyEx(key, version, 0, KEY_READ, &subkey) != 0) {
- fprintf(stderr, "Error opening registry key '"
- JRE_KEY "\\%s'\n", version);
- RegCloseKey(key);
- return JNI_FALSE;
- }
-
- if (!GetStringFromRegistry(subkey, "JavaHome", buf, bufsize)) {
- fprintf(stderr, "Failed reading value of registry key:\n\t"
- JRE_KEY "\\%s\\JavaHome\n", version);
- RegCloseKey(key);
- RegCloseKey(subkey);
- return JNI_FALSE;
- }
-
- if (_launcher_debug) {
- char micro[MAXPATHLEN];
- if (!GetStringFromRegistry(subkey, "MicroVersion", micro,
- sizeof(micro))) {
- printf("Warning: Can't read MicroVersion\n");
- micro[0] = '\0';
- }
- printf("Version major.minor.micro = %s.%s\n", version, micro);
- }
-
- RegCloseKey(key);
- RegCloseKey(subkey);
- return JNI_TRUE;
-}
-
-#endif /* ifndef GAMMA */
-
-/*
- * Support for doing cheap, accurate interval timing.
- */
-static jboolean counterAvailable = JNI_FALSE;
-static jboolean counterInitialized = JNI_FALSE;
-static LARGE_INTEGER counterFrequency;
-
-jlong CounterGet()
-{
- LARGE_INTEGER count;
-
- if (!counterInitialized) {
- counterAvailable = QueryPerformanceFrequency(&counterFrequency);
- counterInitialized = JNI_TRUE;
- }
- if (!counterAvailable) {
- return 0;
- }
- QueryPerformanceCounter(&count);
- return (jlong)(count.QuadPart);
-}
-
-jlong Counter2Micros(jlong counts)
-{
- if (!counterAvailable || !counterInitialized) {
- return 0;
- }
- return (counts * 1000 * 1000)/counterFrequency.QuadPart;
-}
-
-void ReportErrorMessage(char * message, jboolean always) {
-#ifdef JAVAW
- if (message != NULL) {
- MessageBox(NULL, message, "Java Virtual Machine Launcher",
- (MB_OK|MB_ICONSTOP|MB_APPLMODAL));
- }
-#else
- if (always) {
- fprintf(stderr, "%s\n", message);
- }
-#endif
-}
-
-void ReportErrorMessage2(char * format, char * string, jboolean always) {
- /*
- * The format argument must be a printf format string with one %s
- * argument, which is passed the string argument.
- */
-#ifdef JAVAW
- size_t size;
- char * message;
- size = strlen(format) + strlen(string);
- message = (char*)JLI_MemAlloc(size*sizeof(char));
- sprintf(message, (const char *)format, string);
-
- if (message != NULL) {
- MessageBox(NULL, message, "Java Virtual Machine Launcher",
- (MB_OK|MB_ICONSTOP|MB_APPLMODAL));
- JLI_MemFree(message);
- }
-#else
- if (always) {
- fprintf(stderr, (const char *)format, string);
- fprintf(stderr, "\n");
- }
-#endif
-}
-
-/*
- * As ReportErrorMessage2 (above) except the system message (if any)
- * associated with this error is written to a second %s format specifier
- * in the format argument.
- */
-void ReportSysErrorMessage2(char * format, char * string, jboolean always) {
- int save_errno = errno;
- DWORD errval;
- int freeit = 0;
- char *errtext = NULL;
-
- if ((errval = GetLastError()) != 0) { /* Platform SDK / DOS Error */
- int n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|
- FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_ALLOCATE_BUFFER,
- NULL, errval, 0, (LPTSTR)&errtext, 0, NULL);
- if (errtext == NULL || n == 0) { /* Paranoia check */
- errtext = "";
- n = 0;
- } else {
- freeit = 1;
- if (n > 2) { /* Drop final CR, LF */
- if (errtext[n - 1] == '\n') n--;
- if (errtext[n - 1] == '\r') n--;
- errtext[n] = '\0';
- }
- }
- } else /* C runtime error that has no corresponding DOS error code */
- errtext = strerror(save_errno);
-
-#ifdef JAVAW
- {
- size_t size;
- char * message;
- size = strlen(format) + strlen(string) + strlen(errtext);
- message = (char*)JLI_MemAlloc(size*sizeof(char));
- sprintf(message, (const char *)format, string, errtext);
-
- if (message != NULL) {
- MessageBox(NULL, message, "Java Virtual Machine Launcher",
- (MB_OK|MB_ICONSTOP|MB_APPLMODAL));
- JLI_MemFree(message);
- }
- }
-#else
- if (always) {
- fprintf(stderr, (const char *)format, string, errtext);
- fprintf(stderr, "\n");
- }
-#endif
- if (freeit)
- (void)LocalFree((HLOCAL)errtext);
-}
-
-void ReportExceptionDescription(JNIEnv * env) {
-#ifdef JAVAW
- /*
- * This code should be replaced by code which opens a window with
- * the exception detail message.
- */
- (*env)->ExceptionDescribe(env);
-#else
- (*env)->ExceptionDescribe(env);
-#endif
-}
-
-
-/*
- * Return JNI_TRUE for an option string that has no effect but should
- * _not_ be passed on to the vm; return JNI_FALSE otherwise. On
- * windows, there are no options that should be screened in this
- * manner.
- */
-jboolean RemovableMachineDependentOption(char * option) {
-#ifdef ENABLE_AWT_PRELOAD
- if (awtPreloadD3D < 0) {
- /* Tests the command line parameter only if not set yet. */
- if (GetBoolParamValue(PARAM_PRELOAD_D3D, option) == 1) {
- awtPreloadD3D = 1;
- }
- }
- if (awtPreloadD3D != 0) {
- /* Don't test the command line parameters if already disabled. */
- if (GetBoolParamValue(PARAM_NODDRAW, option) == 1
- || GetBoolParamValue(PARAM_D3D, option) == 0
- || GetBoolParamValue(PARAM_OPENGL, option) == 1)
- {
- awtPreloadD3D = 0;
- }
- }
-#endif /* ENABLE_AWT_PRELOAD */
-
- return JNI_FALSE;
-}
-
-void PrintMachineDependentOptions() {
- return;
-}
-
-#ifndef GAMMA
-
-jboolean
-ServerClassMachine() {
- jboolean result = JNI_FALSE;
-#if defined(NEVER_ACT_AS_SERVER_CLASS_MACHINE)
- result = JNI_FALSE;
-#elif defined(ALWAYS_ACT_AS_SERVER_CLASS_MACHINE)
- result = JNI_TRUE;
-#endif
- return result;
-}
-
-/*
- * Determine if there is an acceptable JRE in the registry directory top_key.
- * Upon locating the "best" one, return a fully qualified path to it.
- * "Best" is defined as the most advanced JRE meeting the constraints
- * contained in the manifest_info. If no JRE in this directory meets the
- * constraints, return NULL.
- *
- * It doesn't matter if we get an error reading the registry, or we just
- * don't find anything interesting in the directory. We just return NULL
- * in either case.
- */
-static char *
-ProcessDir(manifest_info* info, HKEY top_key) {
- DWORD index = 0;
- HKEY ver_key;
- char name[MAXNAMELEN];
- int len;
- char *best = NULL;
-
- /*
- * Enumerate "/SOFTWARE/JavaSoft/Java Runtime Environment"
- * searching for the best available version.
- */
- while (RegEnumKey(top_key, index, name, MAXNAMELEN) == ERROR_SUCCESS) {
- index++;
- if (JLI_AcceptableRelease(name, info->jre_version))
- if ((best == NULL) || (JLI_ExactVersionId(name, best) > 0)) {
- if (best != NULL)
- JLI_MemFree(best);
- best = JLI_StringDup(name);
- }
- }
-
- /*
- * Extract "JavaHome" from the "best" registry directory and return
- * that path. If no appropriate version was located, or there is an
- * error in extracting the "JavaHome" string, return null.
- */
- if (best == NULL)
- return (NULL);
- else {
- if (RegOpenKeyEx(top_key, best, 0, KEY_READ, &ver_key)
- != ERROR_SUCCESS) {
- JLI_MemFree(best);
- if (ver_key != NULL)
- RegCloseKey(ver_key);
- return (NULL);
- }
- JLI_MemFree(best);
- len = MAXNAMELEN;
- if (RegQueryValueEx(ver_key, "JavaHome", NULL, NULL, (LPBYTE)name, &len)
- != ERROR_SUCCESS) {
- if (ver_key != NULL)
- RegCloseKey(ver_key);
- return (NULL);
- }
- if (ver_key != NULL)
- RegCloseKey(ver_key);
- return (JLI_StringDup(name));
- }
-}
-
-/*
- * This is the global entry point. It examines the host for the optimal
- * JRE to be used by scanning a set of registry entries. This set of entries
- * is hardwired on Windows as "Software\JavaSoft\Java Runtime Environment"
- * under the set of roots "{ HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }".
- *
- * This routine simply opens each of these registry directories before passing
- * control onto ProcessDir().
- */
-char *
-LocateJRE(manifest_info* info) {
- HKEY key = NULL;
- char *path;
- int key_index;
- HKEY root_keys[2] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE };
-
- for (key_index = 0; key_index <= 1; key_index++) {
- if (RegOpenKeyEx(root_keys[key_index], JRE_KEY, 0, KEY_READ, &key)
- == ERROR_SUCCESS)
- if ((path = ProcessDir(info, key)) != NULL) {
- if (key != NULL)
- RegCloseKey(key);
- return (path);
- }
- if (key != NULL)
- RegCloseKey(key);
- }
- return NULL;
-}
-
-
-/*
- * Local helper routine to isolate a single token (option or argument)
- * from the command line.
- *
- * This routine accepts a pointer to a character pointer. The first
- * token (as defined by MSDN command-line argument syntax) is isolated
- * from that string.
- *
- * Upon return, the input character pointer pointed to by the parameter s
- * is updated to point to the remainding, unscanned, portion of the string,
- * or to a null character if the entire string has been consummed.
- *
- * This function returns a pointer to a null-terminated string which
- * contains the isolated first token, or to the null character if no
- * token could be isolated.
- *
- * Note the side effect of modifying the input string s by the insertion
- * of a null character, making it two strings.
- *
- * See "Parsing C Command-Line Arguments" in the MSDN Library for the
- * parsing rule details. The rule summary from that specification is:
- *
- * * Arguments are delimited by white space, which is either a space or a tab.
- *
- * * A string surrounded by double quotation marks is interpreted as a single
- * argument, regardless of white space contained within. A quoted string can
- * be embedded in an argument. Note that the caret (^) is not recognized as
- * an escape character or delimiter.
- *
- * * A double quotation mark preceded by a backslash, \", is interpreted as a
- * literal double quotation mark (").
- *
- * * Backslashes are interpreted literally, unless they immediately precede a
- * double quotation mark.
- *
- * * If an even number of backslashes is followed by a double quotation mark,
- * then one backslash (\) is placed in the argv array for every pair of
- * backslashes (\\), and the double quotation mark (") is interpreted as a
- * string delimiter.
- *
- * * If an odd number of backslashes is followed by a double quotation mark,
- * then one backslash (\) is placed in the argv array for every pair of
- * backslashes (\\) and the double quotation mark is interpreted as an
- * escape sequence by the remaining backslash, causing a literal double
- * quotation mark (") to be placed in argv.
- */
-static char*
-nextarg(char** s) {
- char *p = *s;
- char *head;
- int slashes = 0;
- int inquote = 0;
-
- /*
- * Strip leading whitespace, which MSDN defines as only space or tab.
- * (Hence, no locale specific "isspace" here.)
- */
- while (*p != (char)0 && (*p == ' ' || *p == '\t'))
- p++;
- head = p; /* Save the start of the token to return */
-
- /*
- * Isolate a token from the command line.
- */
- while (*p != (char)0 && (inquote || !(*p == ' ' || *p == '\t'))) {
- if (*p == '\\' && *(p+1) == '"' && slashes % 2 == 0)
- p++;
- else if (*p == '"')
- inquote = !inquote;
- slashes = (*p++ == '\\') ? slashes + 1 : 0;
- }
-
- /*
- * If the token isolated isn't already terminated in a "char zero",
- * then replace the whitespace character with one and move to the
- * next character.
- */
- if (*p != (char)0)
- *p++ = (char)0;
-
- /*
- * Update the parameter to point to the head of the remaining string
- * reflecting the command line and return a pointer to the leading
- * token which was isolated from the command line.
- */
- *s = p;
- return (head);
-}
-
-/*
- * Local helper routine to return a string equivalent to the input string
- * s, but with quotes removed so the result is a string as would be found
- * in argv[]. The returned string should be freed by a call to JLI_MemFree().
- *
- * The rules for quoting (and escaped quotes) are:
- *
- * 1 A double quotation mark preceded by a backslash, \", is interpreted as a
- * literal double quotation mark (").
- *
- * 2 Backslashes are interpreted literally, unless they immediately precede a
- * double quotation mark.
- *
- * 3 If an even number of backslashes is followed by a double quotation mark,
- * then one backslash (\) is placed in the argv array for every pair of
- * backslashes (\\), and the double quotation mark (") is interpreted as a
- * string delimiter.
- *
- * 4 If an odd number of backslashes is followed by a double quotation mark,
- * then one backslash (\) is placed in the argv array for every pair of
- * backslashes (\\) and the double quotation mark is interpreted as an
- * escape sequence by the remaining backslash, causing a literal double
- * quotation mark (") to be placed in argv.
- */
-static char*
-unquote(const char *s) {
- const char *p = s; /* Pointer to the tail of the original string */
- char *un = (char*)JLI_MemAlloc(strlen(s) + 1); /* Ptr to unquoted string */
- char *pun = un; /* Pointer to the tail of the unquoted string */
-
- while (*p != '\0') {
- if (*p == '"') {
- p++;
- } else if (*p == '\\') {
- const char *q = p + strspn(p,"\\");
- if (*q == '"')
- do {
- *pun++ = '\\';
- p += 2;
- } while (*p == '\\' && p < q);
- else
- while (p < q)
- *pun++ = *p++;
- } else {
- *pun++ = *p++;
- }
- }
- *pun = '\0';
- return un;
-}
-
-/*
- * Given a path to a jre to execute, this routine checks if this process
- * is indeed that jre. If not, it exec's that jre.
- *
- * We want to actually check the paths rather than just the version string
- * built into the executable, so that given version specification will yield
- * the exact same Java environment, regardless of the version of the arbitrary
- * launcher we start with.
- */
-void
-ExecJRE(char *jre, char **argv) {
- int len;
- char *progname;
- char path[MAXPATHLEN + 1];
-
- /*
- * Determine the executable we are building (or in the rare case, running).
- */
-#ifdef JAVA_ARGS /* javac, jar and friends. */
- progname = "java";
-#else /* java, oldjava, javaw and friends */
-#ifdef PROGNAME
- progname = PROGNAME;
-#else
- {
- char *s;
- progname = *argv;
- if ((s = strrchr(progname, FILE_SEPARATOR)) != 0) {
- progname = s + 1;
- }
- }
-#endif /* PROGNAME */
-#endif /* JAVA_ARGS */
-
- /*
- * Resolve the real path to the currently running launcher.
- */
- len = GetModuleFileName(NULL, path, MAXPATHLEN + 1);
- if (len == 0 || len > MAXPATHLEN) {
- ReportSysErrorMessage2(
- "Unable to resolve path to current %s executable: %s",
- progname, JNI_TRUE);
- exit(1);
- }
-
- if (_launcher_debug) {
- printf("ExecJRE: old: %s\n", path);
- printf("ExecJRE: new: %s\n", jre);
- }
-
- /*
- * If the path to the selected JRE directory is a match to the initial
- * portion of the path to the currently executing JRE, we have a winner!
- * If so, just return. (strnicmp() is the Windows equiv. of strncasecmp().)
- */
- if (strnicmp(jre, path, strlen(jre)) == 0)
- return; /* I am the droid you were looking for */
-
- /*
- * If this isn't the selected version, exec the selected version.
- */
- (void)strcat(strcat(strcpy(path, jre), "\\bin\\"), progname);
- (void)strcat(path, ".exe");
-
- /*
- * Although Windows has an execv() entrypoint, it doesn't actually
- * overlay a process: it can only create a new process and terminate
- * the old process. Therefore, any processes waiting on the initial
- * process wake up and they shouldn't. Hence, a chain of pseudo-zombie
- * processes must be retained to maintain the proper wait semantics.
- * Fortunately the image size of the launcher isn't too large at this
- * time.
- *
- * If it weren't for this semantic flaw, the code below would be ...
- *
- * execv(path, argv);
- * ReportErrorMessage2("Exec of %s failed\n", path, JNI_TRUE);
- * exit(1);
- *
- * The incorrect exec semantics could be addressed by:
- *
- * exit((int)spawnv(_P_WAIT, path, argv));
- *
- * Unfortunately, a bug in Windows spawn/exec impementation prevents
- * this from completely working. All the Windows POSIX process creation
- * interfaces are implemented as wrappers around the native Windows
- * function CreateProcess(). CreateProcess() takes a single string
- * to specify command line options and arguments, so the POSIX routine
- * wrappers build a single string from the argv[] array and in the
- * process, any quoting information is lost.
- *
- * The solution to this to get the original command line, to process it
- * to remove the new multiple JRE options (if any) as was done for argv
- * in the common SelectVersion() routine and finally to pass it directly
- * to the native CreateProcess() Windows process control interface.
- */
- {
- char *cmdline;
- char *p;
- char *np;
- char *ocl;
- char *ccl;
- char *unquoted;
- DWORD exitCode;
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
-
- /*
- * The following code block gets and processes the original command
- * line, replacing the argv[0] equivalent in the command line with
- * the path to the new executable and removing the appropriate
- * Multiple JRE support options. Note that similar logic exists
- * in the platform independent SelectVersion routine, but is
- * replicated here due to the syntax of CreateProcess().
- *
- * The magic "+ 4" characters added to the command line length are
- * 2 possible quotes around the path (argv[0]), a space after the
- * path and a terminating null character.
- */
- ocl = GetCommandLine();
- np = ccl = JLI_StringDup(ocl);
- p = nextarg(&np); /* Discard argv[0] */
- cmdline = (char *)JLI_MemAlloc(strlen(path) + strlen(np) + 4);
- if (strchr(path, (int)' ') == NULL && strchr(path, (int)'\t') == NULL)
- cmdline = strcpy(cmdline, path);
- else
- cmdline = strcat(strcat(strcpy(cmdline, "\""), path), "\"");
-
- while (*np != (char)0) { /* While more command-line */
- p = nextarg(&np);
- if (*p != (char)0) { /* If a token was isolated */
- unquoted = unquote(p);
- if (*unquoted == '-') { /* Looks like an option */
- if (strcmp(unquoted, "-classpath") == 0 ||
- strcmp(unquoted, "-cp") == 0) { /* Unique cp syntax */
- cmdline = strcat(strcat(cmdline, " "), p);
- p = nextarg(&np);
- if (*p != (char)0) /* If a token was isolated */
- cmdline = strcat(strcat(cmdline, " "), p);
- } else if (strncmp(unquoted, "-version:", 9) != 0 &&
- strcmp(unquoted, "-jre-restrict-search") != 0 &&
- strcmp(unquoted, "-no-jre-restrict-search") != 0) {
- cmdline = strcat(strcat(cmdline, " "), p);
- }
- } else { /* End of options */
- cmdline = strcat(strcat(cmdline, " "), p);
- cmdline = strcat(strcat(cmdline, " "), np);
- JLI_MemFree((void *)unquoted);
- break;
- }
- JLI_MemFree((void *)unquoted);
- }
- }
- JLI_MemFree((void *)ccl);
-
- if (_launcher_debug) {
- np = ccl = JLI_StringDup(cmdline);
- p = nextarg(&np);
- printf("ReExec Command: %s (%s)\n", path, p);
- printf("ReExec Args: %s\n", np);
- JLI_MemFree((void *)ccl);
- }
- (void)fflush(stdout);
- (void)fflush(stderr);
-
- /*
- * The following code is modeled after a model presented in the
- * Microsoft Technical Article "Moving Unix Applications to
- * Windows NT" (March 6, 1994) and "Creating Processes" on MSDN
- * (Februrary 2005). It approximates UNIX spawn semantics with
- * the parent waiting for termination of the child.
- */
- memset(&si, 0, sizeof(si));
- si.cb =sizeof(STARTUPINFO);
- memset(&pi, 0, sizeof(pi));
-
- if (!CreateProcess((LPCTSTR)path, /* executable name */
- (LPTSTR)cmdline, /* command line */
- (LPSECURITY_ATTRIBUTES)NULL, /* process security attr. */
- (LPSECURITY_ATTRIBUTES)NULL, /* thread security attr. */
- (BOOL)TRUE, /* inherits system handles */
- (DWORD)0, /* creation flags */
- (LPVOID)NULL, /* environment block */
- (LPCTSTR)NULL, /* current directory */
- (LPSTARTUPINFO)&si, /* (in) startup information */
- (LPPROCESS_INFORMATION)&pi)) { /* (out) process information */
- ReportSysErrorMessage2("CreateProcess(%s, ...) failed: %s",
- path, JNI_TRUE);
- exit(1);
- }
-
- if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED) {
- if (GetExitCodeProcess(pi.hProcess, &exitCode) == FALSE)
- exitCode = 1;
- } else {
- ReportErrorMessage("WaitForSingleObject() failed.", JNI_TRUE);
- exitCode = 1;
- }
-
- CloseHandle(pi.hThread);
- CloseHandle(pi.hProcess);
-
- exit(exitCode);
- }
-
-}
-
-#endif /* ifndef GAMMA */
-
-
-/*
- * Wrapper for platform dependent unsetenv function.
- */
-int
-UnsetEnv(char *name)
-{
- int ret;
- char *buf = JLI_MemAlloc(strlen(name) + 2);
- buf = strcat(strcpy(buf, name), "=");
- ret = _putenv(buf);
- JLI_MemFree(buf);
- return (ret);
-}
-
-/* --- Splash Screen shared library support --- */
-
-static const char* SPLASHSCREEN_SO = "\\bin\\splashscreen.dll";
-
-static HMODULE hSplashLib = NULL;
-
-void* SplashProcAddress(const char* name) {
- char libraryPath[MAXPATHLEN]; /* some extra space for strcat'ing SPLASHSCREEN_SO */
-
- if (!GetJREPath(libraryPath, MAXPATHLEN)) {
- return NULL;
- }
- if (strlen(libraryPath)+strlen(SPLASHSCREEN_SO) >= MAXPATHLEN) {
- return NULL;
- }
- strcat(libraryPath, SPLASHSCREEN_SO);
-
- if (!hSplashLib) {
- hSplashLib = LoadLibrary(libraryPath);
- }
- if (hSplashLib) {
- return GetProcAddress(hSplashLib, name);
- } else {
- return NULL;
- }
-}
-
-void SplashFreeLibrary() {
- if (hSplashLib) {
- FreeLibrary(hSplashLib);
- hSplashLib = NULL;
- }
-}
-
-/*
- * Block current thread and continue execution in a new thread
- */
-int
-ContinueInNewThread(int (JNICALL *continuation)(void *), jlong stack_size, void * args) {
- int rslt = 0;
- unsigned thread_id;
-
-#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION
-#define STACK_SIZE_PARAM_IS_A_RESERVATION (0x10000)
-#endif
-
- /*
- * STACK_SIZE_PARAM_IS_A_RESERVATION is what we want, but it's not
- * supported on older version of Windows. Try first with the flag; and
- * if that fails try again without the flag. See MSDN document or HotSpot
- * source (os_win32.cpp) for details.
- */
- HANDLE thread_handle =
- (HANDLE)_beginthreadex(NULL,
- (unsigned)stack_size,
- continuation,
- args,
- STACK_SIZE_PARAM_IS_A_RESERVATION,
- &thread_id);
- if (thread_handle == NULL) {
- thread_handle =
- (HANDLE)_beginthreadex(NULL,
- (unsigned)stack_size,
- continuation,
- args,
- 0,
- &thread_id);
- }
-
- /* AWT preloading (AFTER main thread start) */
-#ifdef ENABLE_AWT_PRELOAD
- /* D3D preloading */
- if (awtPreloadD3D != 0) {
- char *envValue;
- /* D3D routines checks env.var J2D_D3D if no appropriate
- * command line params was specified
- */
- envValue = getenv("J2D_D3D");
- if (envValue != NULL && stricmp(envValue, "false") == 0) {
- awtPreloadD3D = 0;
- }
- /* Test that AWT preloading isn't disabled by J2D_D3D_PRELOAD env.var */
- envValue = getenv("J2D_D3D_PRELOAD");
- if (envValue != NULL && stricmp(envValue, "false") == 0) {
- awtPreloadD3D = 0;
- }
- if (awtPreloadD3D < 0) {
- /* If awtPreloadD3D is still undefined (-1), test
- * if it is turned on by J2D_D3D_PRELOAD env.var.
- * By default it's turned OFF.
- */
- awtPreloadD3D = 0;
- if (envValue != NULL && stricmp(envValue, "true") == 0) {
- awtPreloadD3D = 1;
- }
- }
- }
- if (awtPreloadD3D) {
- AWTPreload(D3D_PRELOAD_FUNC);
- }
-#endif /* ENABLE_AWT_PRELOAD */
-
- if (thread_handle) {
- WaitForSingleObject(thread_handle, INFINITE);
- GetExitCodeThread(thread_handle, &rslt);
- CloseHandle(thread_handle);
- } else {
- rslt = continuation(args);
- }
-
-#ifdef ENABLE_AWT_PRELOAD
- if (awtPreloaded) {
- AWTPreloadStop();
- }
-#endif /* ENABLE_AWT_PRELOAD */
-
- return rslt;
-}
-
-/* Linux only, empty on windows. */
-void SetJavaLauncherPlatformProps() {}
-
-
-//==============================
-// AWT preloading
-#ifdef ENABLE_AWT_PRELOAD
-
-typedef int FnPreloadStart(void);
-typedef void FnPreloadStop(void);
-static FnPreloadStop *fnPreloadStop = NULL;
-static HMODULE hPreloadAwt = NULL;
-
-/*
- * Starts AWT preloading
- */
-int AWTPreload(const char *funcName)
-{
- int result = -1;
-
- // load AWT library once (if several preload function should be called)
- if (hPreloadAwt == NULL) {
- // awt.dll is not loaded yet
- char libraryPath[MAXPATHLEN];
- int jrePathLen = 0;
- HMODULE hJava = NULL;
- HMODULE hVerify = NULL;
-
- while (1) {
- // awt.dll depends on jvm.dll & java.dll;
- // jvm.dll is already loaded, so we need only java.dll;
- // java.dll depends on MSVCRT lib & verify.dll.
- if (!GetJREPath(libraryPath, MAXPATHLEN)) {
- break;
- }
-
- // save path length
- jrePathLen = strlen(libraryPath);
-
- // load msvcrt 1st
- LoadMSVCRT();
-
- // load verify.dll
- strcat(libraryPath, "\\bin\\verify.dll");
- hVerify = LoadLibrary(libraryPath);
- if (hVerify == NULL) {
- break;
- }
-
- // restore jrePath
- libraryPath[jrePathLen] = 0;
- // load java.dll
- strcat(libraryPath, "\\bin\\" JAVA_DLL);
- hJava = LoadLibrary(libraryPath);
- if (hJava == NULL) {
- break;
- }
-
- // restore jrePath
- libraryPath[jrePathLen] = 0;
- // load awt.dll
- strcat(libraryPath, "\\bin\\awt.dll");
- hPreloadAwt = LoadLibrary(libraryPath);
- if (hPreloadAwt == NULL) {
- break;
- }
-
- // get "preloadStop" func ptr
- fnPreloadStop = (FnPreloadStop *)GetProcAddress(hPreloadAwt, "preloadStop");
-
- break;
- }
- }
-
- if (hPreloadAwt != NULL) {
- FnPreloadStart *fnInit = (FnPreloadStart *)GetProcAddress(hPreloadAwt, funcName);
- if (fnInit != NULL) {
- // don't forget to stop preloading
- awtPreloaded = 1;
-
- result = fnInit();
- }
- }
-
- return result;
-}
-
-/*
- * Terminates AWT preloading
- */
-void AWTPreloadStop() {
- if (fnPreloadStop != NULL) {
- fnPreloadStop();
- }
-}
-
-#endif /* ENABLE_AWT_PRELOAD */
diff --git a/hotspot/src/os/windows/launcher/java_md.h b/hotspot/src/os/windows/launcher/java_md.h
deleted file mode 100644
index 763e2457644..00000000000
--- a/hotspot/src/os/windows/launcher/java_md.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef JAVA_MD_H
-#define JAVA_MD_H
-
-#include
-#include
-#include
-#ifndef GAMMA
-#include "manifest_info.h"
-#endif
-#include "jli_util.h"
-
-#ifdef GAMMA
-#define stricmp _stricmp
-#define strnicmp _strnicmp
-#define snprintf _snprintf
-#define strdup _strdup
-#endif
-
-#define PATH_SEPARATOR ';'
-#define FILESEP "\\"
-#define FILE_SEPARATOR '\\'
-#define IS_FILE_SEPARATOR(c) ((c) == '\\' || (c) == '/')
-#define MAXPATHLEN MAX_PATH
-#define MAXNAMELEN MAX_PATH
-
-#ifdef JAVA_ARGS
-/*
- * ApplicationHome is prepended to each of these entries; the resulting
- * strings are concatenated (separated by PATH_SEPARATOR) and used as the
- * value of -cp option to the launcher.
- */
-#ifndef APP_CLASSPATH
-#define APP_CLASSPATH { "\\lib\\tools.jar", "\\classes" }
-#endif
-#endif
-
-/*
- * Support for doing cheap, accurate interval timing.
- */
-extern jlong CounterGet(void);
-extern jlong Counter2Micros(jlong counts);
-
-#ifdef JAVAW
-#define main _main
-extern int _main(int argc, char **argv);
-#endif
-
-#define JLONG_FORMAT "%I64d"
-
-/*
- * Function prototypes.
- */
-#ifndef GAMMA
-char *LocateJRE(manifest_info *info);
-void ExecJRE(char *jre, char **argv);
-#endif
-int UnsetEnv(char *name);
-
-#endif
diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
index dfcb64dd99b..5a05d416a98 100644
--- a/hotspot/src/os/windows/vm/os_windows.cpp
+++ b/hotspot/src/os/windows/vm/os_windows.cpp
@@ -3307,7 +3307,7 @@ void os::pd_start_thread(Thread* thread) {
assert(ret != SYS_THREAD_ERROR, "StartThread failed"); // should propagate back
}
-class HighResolutionInterval {
+class HighResolutionInterval : public CHeapObj {
// The default timer resolution seems to be 10 milliseconds.
// (Where is this written down?)
// If someone wants to sleep for only a fraction of the default,
diff --git a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java b/hotspot/src/share/tools/ProjectCreator/BuildConfig.java
index 953967fccd4..f9283886a87 100644
--- a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java
+++ b/hotspot/src/share/tools/ProjectCreator/BuildConfig.java
@@ -65,6 +65,7 @@ class BuildConfig {
String sourceBase = getFieldString(null, "SourceBase");
String buildSpace = getFieldString(null, "BuildSpace");
String outDir = buildBase;
+ String jdkTargetRoot = getFieldString(null, "JdkTargetRoot");
put("Id", flavourBuild);
put("OutputDir", outDir);
@@ -72,6 +73,7 @@ class BuildConfig {
put("BuildBase", buildBase);
put("BuildSpace", buildSpace);
put("OutputDll", outDir + Util.sep + outDll);
+ put("JdkTargetRoot", jdkTargetRoot);
context = new String [] {flavourBuild, flavour, build, null};
}
diff --git a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
index 137abdc30e9..8d094d30108 100644
--- a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
+++ b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
@@ -98,11 +98,6 @@ public class WinGammaPlatformVC10 extends WinGammaPlatformVC7 {
tagV(cfg.getV("LinkerFlags"));
endTag();
- startTag("PostBuildEvent");
- tagData("Message", BuildConfig.getFieldString(null, "PostbuildDescription"));
- tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PostbuildCommand").replace("\t", "\r\n")));
- endTag();
-
startTag("PreLinkEvent");
tagData("Message", BuildConfig.getFieldString(null, "PrelinkDescription"));
tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand").replace("\t", "\r\n")));
@@ -141,7 +136,9 @@ public class WinGammaPlatformVC10 extends WinGammaPlatformVC7 {
for (BuildConfig cfg : allConfigs) {
startTag(cfg, "PropertyGroup");
- tagData("LocalDebuggerCommand", "$(TargetDir)/hotspot.exe");
+ tagData("LocalDebuggerCommand", cfg.get("JdkTargetRoot") + "\\bin\\java.exe");
+ tagData("LocalDebuggerCommandArguments", "-XXaltjvm=$(TargetDir) -Dsun.java.launcher=gamma");
+ tagData("LocalDebuggerEnvironment", "JAVA_HOME=" + cfg.get("JdkTargetRoot"));
endTag();
}
diff --git a/hotspot/src/share/tools/hsdis/hsdis.c b/hotspot/src/share/tools/hsdis/hsdis.c
index 397793021c0..162e2aba3e7 100644
--- a/hotspot/src/share/tools/hsdis/hsdis.c
+++ b/hotspot/src/share/tools/hsdis/hsdis.c
@@ -27,6 +27,7 @@
HotSpot PrintAssembly option.
*/
+#include /* required by bfd.h */
#include
#include
#include
diff --git a/hotspot/src/share/tools/launcher/java.c b/hotspot/src/share/tools/launcher/java.c
deleted file mode 100644
index 63f11d77c86..00000000000
--- a/hotspot/src/share/tools/launcher/java.c
+++ /dev/null
@@ -1,2080 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-/*
- * Gamma (Hotspot internal engineering test) launcher based on 6.0u22 JDK,
- * search "GAMMA" for gamma specific changes.
- *
- * GAMMA: gamma launcher is much simpler than regular java launcher in that
- * JVM is either statically linked in or it is installed in the
- * same directory where the launcher exists, so we don't have to
- * worry about choosing the right JVM based on command line flag, jar
- * file and/or ergonomics. Intead of removing unused logic from source
- * they are commented out with #ifndef GAMMA, hopefully it'll be easier
- * to maintain this file in sync with regular JDK launcher.
- */
-
-/*
- * Shared source for 'java' command line tool.
- *
- * If JAVA_ARGS is defined, then acts as a launcher for applications. For
- * instance, the JDK command line tools such as javac and javadoc (see
- * makefiles for more details) are built with this program. Any arguments
- * prefixed with '-J' will be passed directly to the 'java' command.
- */
-
-#ifdef GAMMA
-# ifdef JAVA_ARGS
-# error Do NOT define JAVA_ARGS when building gamma launcher
-# endif
-# if !defined(LINK_INTO_AOUT) && !defined(LINK_INTO_LIBJVM)
-# error Either LINK_INTO_AOUT or LINK_INTO_LIBJVM must be defined
-# endif
-#endif
-
-/*
- * One job of the launcher is to remove command line options which the
- * vm does not understand and will not process. These options include
- * options which select which style of vm is run (e.g. -client and
- * -server) as well as options which select the data model to use.
- * Additionally, for tools which invoke an underlying vm "-J-foo"
- * options are turned into "-foo" options to the vm. This option
- * filtering is handled in a number of places in the launcher, some of
- * it in machine-dependent code. In this file, the function
- * CheckJVMType removes vm style options and TranslateApplicationArgs
- * removes "-J" prefixes. On unix platforms, the
- * CreateExecutionEnvironment function from the unix java_md.c file
- * processes and removes -d options. However, in case
- * CreateExecutionEnvironment does not need to exec because
- * LD_LIBRARY_PATH is set acceptably and the data model does not need
- * to be changed, ParseArguments will screen out the redundant -d
- * options and prevent them from being passed to the vm; this is done
- * by using the machine-dependent call
- * RemovableMachineDependentOption.
- */
-
-#include
-#include
-#include
-
-#include
-#include
-#include "java.h"
-#ifndef GAMMA
-#include "manifest_info.h"
-#include "version_comp.h"
-#include "splashscreen.h"
-#endif
-#include "wildcard.h"
-
-#ifndef FULL_VERSION
-#define FULL_VERSION JDK_MAJOR_VERSION "." JDK_MINOR_VERSION
-#endif
-
-/*
- * The following environment variable is used to influence the behavior
- * of the jre exec'd through the SelectVersion routine. The command line
- * options which specify the version are not passed to the exec'd version,
- * because that jre may be an older version which wouldn't recognize them.
- * This environment variable is known to this (and later) version and serves
- * to suppress the version selection code. This is not only for efficiency,
- * but also for correctness, since any command line options have been
- * removed which would cause any value found in the manifest to be used.
- * This would be incorrect because the command line options are defined
- * to take precedence.
- *
- * The value associated with this environment variable is the MainClass
- * name from within the executable jar file (if any). This is strictly a
- * performance enhancement to avoid re-reading the jar file manifest.
- *
- * A NOTE TO DEVELOPERS: For performance reasons it is important that
- * the program image remain relatively small until after SelectVersion
- * CreateExecutionEnvironment have finished their possibly recursive
- * processing. Watch everything, but resist all temptations to use Java
- * interfaces.
- */
-#define ENV_ENTRY "_JAVA_VERSION_SET"
-
-#ifndef GAMMA
-#define SPLASH_FILE_ENV_ENTRY "_JAVA_SPLASH_FILE"
-#define SPLASH_JAR_ENV_ENTRY "_JAVA_SPLASH_JAR"
-#endif
-
-static jboolean printVersion = JNI_FALSE; /* print and exit */
-static jboolean showVersion = JNI_FALSE; /* print but continue */
-static char *progname;
-jboolean _launcher_debug = JNI_FALSE;
-
-#ifndef GAMMA
-/*
- * Entries for splash screen environment variables.
- * putenv is performed in SelectVersion. We need
- * them in memory until UnsetEnv, so they are made static
- * global instead of auto local.
- */
-static char* splash_file_entry = NULL;
-static char* splash_jar_entry = NULL;
-#endif
-
-/*
- * List of VM options to be specified when the VM is created.
- */
-static JavaVMOption *options;
-static int numOptions, maxOptions;
-
-/*
- * Prototypes for functions internal to launcher.
- */
-static void SetClassPath(const char *s);
-static void SelectVersion(int argc, char **argv, char **main_class);
-static jboolean ParseArguments(int *pargc, char ***pargv, char **pjarfile,
- char **pclassname, int *pret, const char *jvmpath);
-static jboolean InitializeJVM(JavaVM **pvm, JNIEnv **penv,
- InvocationFunctions *ifn);
-static jstring NewPlatformString(JNIEnv *env, char *s);
-static jobjectArray NewPlatformStringArray(JNIEnv *env, char **strv, int strc);
-static jclass LoadClass(JNIEnv *env, char *name);
-static jstring GetMainClassName(JNIEnv *env, char *jarname);
-static void SetJavaCommandLineProp(char* classname, char* jarfile, int argc, char** argv);
-static void SetJavaLauncherProp(void);
-
-#ifdef JAVA_ARGS
-static void TranslateApplicationArgs(int *pargc, char ***pargv);
-static jboolean AddApplicationOptions(void);
-#endif
-
-static void PrintJavaVersion(JNIEnv *env);
-static void PrintUsage(void);
-static jint PrintXUsage(const char *jvmpath);
-
-static void SetPaths(int argc, char **argv);
-
-#ifndef GAMMA
-
-/* Maximum supported entries from jvm.cfg. */
-#define INIT_MAX_KNOWN_VMS 10
-/* Values for vmdesc.flag */
-#define VM_UNKNOWN -1
-#define VM_KNOWN 0
-#define VM_ALIASED_TO 1
-#define VM_WARN 2
-#define VM_ERROR 3
-#define VM_IF_SERVER_CLASS 4
-#define VM_IGNORE 5
-struct vmdesc {
- char *name;
- int flag;
- char *alias;
- char *server_class;
-};
-static struct vmdesc *knownVMs = NULL;
-static int knownVMsCount = 0;
-static int knownVMsLimit = 0;
-
-static void GrowKnownVMs();
-static int KnownVMIndex(const char* name);
-static void FreeKnownVMs();
-static void ShowSplashScreen();
-
-#endif /* ifndef GAMMA */
-
-jboolean ServerClassMachine();
-
-/* flag which if set suppresses error messages from the launcher */
-static int noExitErrorMessage = 0;
-
-/*
- * Running Java code in primordial thread caused many problems. We will
- * create a new thread to invoke JVM. See 6316197 for more information.
- */
-static jlong threadStackSize = 0; /* stack size of the new thread */
-
-int JNICALL JavaMain(void * args); /* entry point */
-
-struct JavaMainArgs {
- int argc;
- char ** argv;
- char * jarfile;
- char * classname;
- InvocationFunctions ifn;
-};
-
-/*
- * Entry point.
- */
-int
-main(int argc, char ** argv)
-{
- char *jarfile = 0;
- char *classname = 0;
- char *s = 0;
- char *main_class = NULL;
- int ret;
- InvocationFunctions ifn;
- jlong start, end;
- char jrepath[MAXPATHLEN], jvmpath[MAXPATHLEN];
- char ** original_argv = argv;
-
- if (getenv("_JAVA_LAUNCHER_DEBUG") != 0) {
- _launcher_debug = JNI_TRUE;
- printf("----_JAVA_LAUNCHER_DEBUG----\n");
- }
-
-#ifndef GAMMA
- /*
- * Make sure the specified version of the JRE is running.
- *
- * There are three things to note about the SelectVersion() routine:
- * 1) If the version running isn't correct, this routine doesn't
- * return (either the correct version has been exec'd or an error
- * was issued).
- * 2) Argc and Argv in this scope are *not* altered by this routine.
- * It is the responsibility of subsequent code to ignore the
- * arguments handled by this routine.
- * 3) As a side-effect, the variable "main_class" is guaranteed to
- * be set (if it should ever be set). This isn't exactly the
- * poster child for structured programming, but it is a small
- * price to pay for not processing a jar file operand twice.
- * (Note: This side effect has been disabled. See comment on
- * bugid 5030265 below.)
- */
- SelectVersion(argc, argv, &main_class);
-#endif /* ifndef GAMMA */
-
- /* copy original argv */
- {
- int i;
- original_argv = (char**)JLI_MemAlloc(sizeof(char*)*(argc+1));
- for(i = 0; i < argc+1; i++)
- original_argv[i] = argv[i];
- }
-
- CreateExecutionEnvironment(&argc, &argv,
- jrepath, sizeof(jrepath),
- jvmpath, sizeof(jvmpath),
- original_argv);
-
- printf("Using java runtime at: %s\n", jrepath);
-
- ifn.CreateJavaVM = 0;
- ifn.GetDefaultJavaVMInitArgs = 0;
-
- if (_launcher_debug)
- start = CounterGet();
- if (!LoadJavaVM(jvmpath, &ifn)) {
- exit(6);
- }
- if (_launcher_debug) {
- end = CounterGet();
- printf("%ld micro seconds to LoadJavaVM\n",
- (long)(jint)Counter2Micros(end-start));
- }
-
-#ifdef JAVA_ARGS /* javac, jar and friends. */
- progname = "java";
-#else /* java, oldjava, javaw and friends */
-#ifdef PROGNAME
- progname = PROGNAME;
-#else
- progname = *argv;
- if ((s = strrchr(progname, FILE_SEPARATOR)) != 0) {
- progname = s + 1;
- }
-#endif /* PROGNAME */
-#endif /* JAVA_ARGS */
- ++argv;
- --argc;
-
-#ifdef JAVA_ARGS
- /* Preprocess wrapper arguments */
- TranslateApplicationArgs(&argc, &argv);
- if (!AddApplicationOptions()) {
- exit(1);
- }
-#endif
-
- /* Set default CLASSPATH */
- if ((s = getenv("CLASSPATH")) == 0) {
- s = ".";
- }
-#ifndef JAVA_ARGS
- SetClassPath(s);
-#endif
-
- /*
- * Parse command line options; if the return value of
- * ParseArguments is false, the program should exit.
- */
- if (!ParseArguments(&argc, &argv, &jarfile, &classname, &ret, jvmpath)) {
- exit(ret);
- }
-
- /* Override class path if -jar flag was specified */
- if (jarfile != 0) {
- SetClassPath(jarfile);
- }
-
- /* set the -Dsun.java.command pseudo property */
- SetJavaCommandLineProp(classname, jarfile, argc, argv);
-
- /* Set the -Dsun.java.launcher pseudo property */
- SetJavaLauncherProp();
-
- /* set the -Dsun.java.launcher.* platform properties */
- SetJavaLauncherPlatformProps();
-
-#ifndef GAMMA
- /* Show the splash screen if needed */
- ShowSplashScreen();
-#endif
-
- /*
- * Done with all command line processing and potential re-execs so
- * clean up the environment.
- */
- (void)UnsetEnv(ENV_ENTRY);
-#ifndef GAMMA
- (void)UnsetEnv(SPLASH_FILE_ENV_ENTRY);
- (void)UnsetEnv(SPLASH_JAR_ENV_ENTRY);
-
- JLI_MemFree(splash_jar_entry);
- JLI_MemFree(splash_file_entry);
-#endif
-
- /*
- * If user doesn't specify stack size, check if VM has a preference.
- * Note that HotSpot no longer supports JNI_VERSION_1_1 but it will
- * return its default stack size through the init args structure.
- */
- if (threadStackSize == 0) {
- struct JDK1_1InitArgs args1_1;
- memset((void*)&args1_1, 0, sizeof(args1_1));
- args1_1.version = JNI_VERSION_1_1;
- ifn.GetDefaultJavaVMInitArgs(&args1_1); /* ignore return value */
- if (args1_1.javaStackSize > 0) {
- threadStackSize = args1_1.javaStackSize;
- }
- }
-
- { /* Create a new thread to create JVM and invoke main method */
- struct JavaMainArgs args;
-
- args.argc = argc;
- args.argv = argv;
- args.jarfile = jarfile;
- args.classname = classname;
- args.ifn = ifn;
-
- return ContinueInNewThread(JavaMain, threadStackSize, (void*)&args);
- }
-}
-
-int JNICALL
-JavaMain(void * _args)
-{
- struct JavaMainArgs *args = (struct JavaMainArgs *)_args;
- int argc = args->argc;
- char **argv = args->argv;
- char *jarfile = args->jarfile;
- char *classname = args->classname;
- InvocationFunctions ifn = args->ifn;
-
- JavaVM *vm = 0;
- JNIEnv *env = 0;
- jstring mainClassName;
- jclass mainClass;
- jmethodID mainID;
- jobjectArray mainArgs;
- int ret = 0;
- jlong start, end;
-
- /*
- * Error message to print or display; by default the message will
- * only be displayed in a window.
- */
- char * message = "Fatal exception occurred. Program will exit.";
- jboolean messageDest = JNI_FALSE;
-
- /* Initialize the virtual machine */
-
- if (_launcher_debug)
- start = CounterGet();
- if (!InitializeJVM(&vm, &env, &ifn)) {
- ReportErrorMessage("Could not create the Java virtual machine.",
- JNI_TRUE);
- exit(1);
- }
-
- if (printVersion || showVersion) {
- PrintJavaVersion(env);
- if ((*env)->ExceptionOccurred(env)) {
- ReportExceptionDescription(env);
- goto leave;
- }
- if (printVersion) {
- ret = 0;
- message = NULL;
- goto leave;
- }
- if (showVersion) {
- fprintf(stderr, "\n");
- }
- }
-
- /* If the user specified neither a class name nor a JAR file */
- if (jarfile == 0 && classname == 0) {
- PrintUsage();
- message = NULL;
- goto leave;
- }
-
-#ifndef GAMMA
- FreeKnownVMs(); /* after last possible PrintUsage() */
-#endif
-
- if (_launcher_debug) {
- end = CounterGet();
- printf("%ld micro seconds to InitializeJVM\n",
- (long)(jint)Counter2Micros(end-start));
- }
-
- /* At this stage, argc/argv have the applications' arguments */
- if (_launcher_debug) {
- int i = 0;
- printf("Main-Class is '%s'\n", classname ? classname : "");
- printf("Apps' argc is %d\n", argc);
- for (; i < argc; i++) {
- printf(" argv[%2d] = '%s'\n", i, argv[i]);
- }
- }
-
- ret = 1;
-
- /*
- * Get the application's main class.
- *
- * See bugid 5030265. The Main-Class name has already been parsed
- * from the manifest, but not parsed properly for UTF-8 support.
- * Hence the code here ignores the value previously extracted and
- * uses the pre-existing code to reextract the value. This is
- * possibly an end of release cycle expedient. However, it has
- * also been discovered that passing some character sets through
- * the environment has "strange" behavior on some variants of
- * Windows. Hence, maybe the manifest parsing code local to the
- * launcher should never be enhanced.
- *
- * Hence, future work should either:
- * 1) Correct the local parsing code and verify that the
- * Main-Class attribute gets properly passed through
- * all environments,
- * 2) Remove the vestages of maintaining main_class through
- * the environment (and remove these comments).
- */
- if (jarfile != 0) {
- mainClassName = GetMainClassName(env, jarfile);
- if ((*env)->ExceptionOccurred(env)) {
- ReportExceptionDescription(env);
- goto leave;
- }
- if (mainClassName == NULL) {
- const char * format = "Failed to load Main-Class manifest "
- "attribute from\n%s";
- message = (char*)JLI_MemAlloc((strlen(format) + strlen(jarfile)) *
- sizeof(char));
- sprintf(message, format, jarfile);
- messageDest = JNI_TRUE;
- goto leave;
- }
- classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0);
- if (classname == NULL) {
- ReportExceptionDescription(env);
- goto leave;
- }
- mainClass = LoadClass(env, classname);
- if(mainClass == NULL) { /* exception occured */
- const char * format = "Could not find the main class: %s. Program will exit.";
- ReportExceptionDescription(env);
- message = (char *)JLI_MemAlloc((strlen(format) +
- strlen(classname)) * sizeof(char) );
- messageDest = JNI_TRUE;
- sprintf(message, format, classname);
- goto leave;
- }
- (*env)->ReleaseStringUTFChars(env, mainClassName, classname);
- } else {
- mainClassName = NewPlatformString(env, classname);
- if (mainClassName == NULL) {
- const char * format = "Failed to load Main Class: %s";
- message = (char *)JLI_MemAlloc((strlen(format) + strlen(classname)) *
- sizeof(char) );
- sprintf(message, format, classname);
- messageDest = JNI_TRUE;
- goto leave;
- }
- classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0);
- if (classname == NULL) {
- ReportExceptionDescription(env);
- goto leave;
- }
- mainClass = LoadClass(env, classname);
- if(mainClass == NULL) { /* exception occured */
- const char * format = "Could not find the main class: %s. Program will exit.";
- ReportExceptionDescription(env);
- message = (char *)JLI_MemAlloc((strlen(format) +
- strlen(classname)) * sizeof(char) );
- messageDest = JNI_TRUE;
- sprintf(message, format, classname);
- goto leave;
- }
- (*env)->ReleaseStringUTFChars(env, mainClassName, classname);
- }
-
- /* Get the application's main method */
- mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
- "([Ljava/lang/String;)V");
- if (mainID == NULL) {
- if ((*env)->ExceptionOccurred(env)) {
- ReportExceptionDescription(env);
- } else {
- message = "No main method found in specified class.";
- messageDest = JNI_TRUE;
- }
- goto leave;
- }
-
- { /* Make sure the main method is public */
- jint mods;
- jmethodID mid;
- jobject obj = (*env)->ToReflectedMethod(env, mainClass,
- mainID, JNI_TRUE);
-
- if( obj == NULL) { /* exception occurred */
- ReportExceptionDescription(env);
- goto leave;
- }
-
- mid =
- (*env)->GetMethodID(env,
- (*env)->GetObjectClass(env, obj),
- "getModifiers", "()I");
- if ((*env)->ExceptionOccurred(env)) {
- ReportExceptionDescription(env);
- goto leave;
- }
-
- mods = (*env)->CallIntMethod(env, obj, mid);
- if ((mods & 1) == 0) { /* if (!Modifier.isPublic(mods)) ... */
- message = "Main method not public.";
- messageDest = JNI_TRUE;
- goto leave;
- }
- }
-
- /* Build argument array */
- mainArgs = NewPlatformStringArray(env, argv, argc);
- if (mainArgs == NULL) {
- ReportExceptionDescription(env);
- goto leave;
- }
-
- /* Invoke main method. */
- (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
-
- /*
- * The launcher's exit code (in the absence of calls to
- * System.exit) will be non-zero if main threw an exception.
- */
- ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
-
- /*
- * Detach the main thread so that it appears to have ended when
- * the application's main method exits. This will invoke the
- * uncaught exception handler machinery if main threw an
- * exception. An uncaught exception handler cannot change the
- * launcher's return code except by calling System.exit.
- */
- if ((*vm)->DetachCurrentThread(vm) != 0) {
- message = "Could not detach main thread.";
- messageDest = JNI_TRUE;
- ret = 1;
- goto leave;
- }
-
- message = NULL;
-
- leave:
- /*
- * Wait for all non-daemon threads to end, then destroy the VM.
- * This will actually create a trivial new Java waiter thread
- * named "DestroyJavaVM", but this will be seen as a different
- * thread from the one that executed main, even though they are
- * the same C thread. This allows mainThread.join() and
- * mainThread.isAlive() to work as expected.
- */
- (*vm)->DestroyJavaVM(vm);
-
- if(message != NULL && !noExitErrorMessage)
- ReportErrorMessage(message, messageDest);
- return ret;
-}
-
-#ifndef GAMMA
-/*
- * Checks the command line options to find which JVM type was
- * specified. If no command line option was given for the JVM type,
- * the default type is used. The environment variable
- * JDK_ALTERNATE_VM and the command line option -XXaltjvm= are also
- * checked as ways of specifying which JVM type to invoke.
- */
-char *
-CheckJvmType(int *pargc, char ***argv, jboolean speculative) {
- int i, argi;
- int argc;
- char **newArgv;
- int newArgvIdx = 0;
- int isVMType;
- int jvmidx = -1;
- char *jvmtype = getenv("JDK_ALTERNATE_VM");
-
- argc = *pargc;
-
- /* To make things simpler we always copy the argv array */
- newArgv = JLI_MemAlloc((argc + 1) * sizeof(char *));
-
- /* The program name is always present */
- newArgv[newArgvIdx++] = (*argv)[0];
-
- for (argi = 1; argi < argc; argi++) {
- char *arg = (*argv)[argi];
- isVMType = 0;
-
-#ifdef JAVA_ARGS
- if (arg[0] != '-') {
- newArgv[newArgvIdx++] = arg;
- continue;
- }
-#else
- if (strcmp(arg, "-classpath") == 0 ||
- strcmp(arg, "-cp") == 0) {
- newArgv[newArgvIdx++] = arg;
- argi++;
- if (argi < argc) {
- newArgv[newArgvIdx++] = (*argv)[argi];
- }
- continue;
- }
- if (arg[0] != '-') break;
-#endif
-
- /* Did the user pass an explicit VM type? */
- i = KnownVMIndex(arg);
- if (i >= 0) {
- jvmtype = knownVMs[jvmidx = i].name + 1; /* skip the - */
- isVMType = 1;
- *pargc = *pargc - 1;
- }
-
- /* Did the user specify an "alternate" VM? */
- else if (strncmp(arg, "-XXaltjvm=", 10) == 0 || strncmp(arg, "-J-XXaltjvm=", 12) == 0) {
- isVMType = 1;
- jvmtype = arg+((arg[1]=='X')? 10 : 12);
- jvmidx = -1;
- }
-
- if (!isVMType) {
- newArgv[newArgvIdx++] = arg;
- }
- }
-
- /*
- * Finish copying the arguments if we aborted the above loop.
- * NOTE that if we aborted via "break" then we did NOT copy the
- * last argument above, and in addition argi will be less than
- * argc.
- */
- while (argi < argc) {
- newArgv[newArgvIdx++] = (*argv)[argi];
- argi++;
- }
-
- /* argv is null-terminated */
- newArgv[newArgvIdx] = 0;
-
- /* Copy back argv */
- *argv = newArgv;
- *pargc = newArgvIdx;
-
- /* use the default VM type if not specified (no alias processing) */
- if (jvmtype == NULL) {
- char* result = knownVMs[0].name+1;
- /* Use a different VM type if we are on a server class machine? */
- if ((knownVMs[0].flag == VM_IF_SERVER_CLASS) &&
- (ServerClassMachine() == JNI_TRUE)) {
- result = knownVMs[0].server_class+1;
- }
- if (_launcher_debug) {
- printf("Default VM: %s\n", result);
- }
- return result;
- }
-
- /* if using an alternate VM, no alias processing */
- if (jvmidx < 0)
- return jvmtype;
-
- /* Resolve aliases first */
- {
- int loopCount = 0;
- while (knownVMs[jvmidx].flag == VM_ALIASED_TO) {
- int nextIdx = KnownVMIndex(knownVMs[jvmidx].alias);
-
- if (loopCount > knownVMsCount) {
- if (!speculative) {
- ReportErrorMessage("Error: Corrupt jvm.cfg file; cycle in alias list.",
- JNI_TRUE);
- exit(1);
- } else {
- return "ERROR";
- /* break; */
- }
- }
-
- if (nextIdx < 0) {
- if (!speculative) {
- ReportErrorMessage2("Error: Unable to resolve VM alias %s",
- knownVMs[jvmidx].alias, JNI_TRUE);
- exit(1);
- } else {
- return "ERROR";
- }
- }
- jvmidx = nextIdx;
- jvmtype = knownVMs[jvmidx].name+1;
- loopCount++;
- }
- }
-
- switch (knownVMs[jvmidx].flag) {
- case VM_WARN:
- if (!speculative) {
- fprintf(stderr, "Warning: %s VM not supported; %s VM will be used\n",
- jvmtype, knownVMs[0].name + 1);
- }
- /* fall through */
- case VM_IGNORE:
- jvmtype = knownVMs[jvmidx=0].name + 1;
- /* fall through */
- case VM_KNOWN:
- break;
- case VM_ERROR:
- if (!speculative) {
- ReportErrorMessage2("Error: %s VM not supported", jvmtype, JNI_TRUE);
- exit(1);
- } else {
- return "ERROR";
- }
- }
-
- return jvmtype;
-}
-#endif /* ifndef GAMMA */
-
-# define KB (1024UL)
-# define MB (1024UL * KB)
-# define GB (1024UL * MB)
-
-/* copied from HotSpot function "atomll()" */
-static int
-parse_stack_size(const char *s, jlong *result) {
- jlong n = 0;
- int args_read = sscanf(s, JLONG_FORMAT, &n);
- if (args_read != 1) {
- return 0;
- }
- while (*s != '\0' && *s >= '0' && *s <= '9') {
- s++;
- }
- // 4705540: illegal if more characters are found after the first non-digit
- if (strlen(s) > 1) {
- return 0;
- }
- switch (*s) {
- case 'T': case 't':
- *result = n * GB * KB;
- return 1;
- case 'G': case 'g':
- *result = n * GB;
- return 1;
- case 'M': case 'm':
- *result = n * MB;
- return 1;
- case 'K': case 'k':
- *result = n * KB;
- return 1;
- case '\0':
- *result = n;
- return 1;
- default:
- /* Create JVM with default stack and let VM handle malformed -Xss string*/
- return 0;
- }
-}
-
-/*
- * Adds a new VM option with the given given name and value.
- */
-void
-AddOption(char *str, void *info)
-{
- /*
- * Expand options array if needed to accommodate at least one more
- * VM option.
- */
- if (numOptions >= maxOptions) {
- if (options == 0) {
- maxOptions = 4;
- options = JLI_MemAlloc(maxOptions * sizeof(JavaVMOption));
- } else {
- JavaVMOption *tmp;
- maxOptions *= 2;
- tmp = JLI_MemAlloc(maxOptions * sizeof(JavaVMOption));
- memcpy(tmp, options, numOptions * sizeof(JavaVMOption));
- JLI_MemFree(options);
- options = tmp;
- }
- }
- options[numOptions].optionString = str;
- options[numOptions++].extraInfo = info;
-
- if (strncmp(str, "-Xss", 4) == 0) {
- jlong tmp;
- if (parse_stack_size(str + 4, &tmp)) {
- threadStackSize = tmp;
- }
- }
-}
-
-static void
-SetClassPath(const char *s)
-{
- char *def;
- s = JLI_WildcardExpandClasspath(s);
- def = JLI_MemAlloc(strlen(s) + 40);
- sprintf(def, "-Djava.class.path=%s", s);
- AddOption(def, NULL);
-}
-
-#ifndef GAMMA
-/*
- * The SelectVersion() routine ensures that an appropriate version of
- * the JRE is running. The specification for the appropriate version
- * is obtained from either the manifest of a jar file (preferred) or
- * from command line options.
- * The routine also parses splash screen command line options and
- * passes on their values in private environment variables.
- */
-static void
-SelectVersion(int argc, char **argv, char **main_class)
-{
- char *arg;
- char **new_argv;
- char **new_argp;
- char *operand;
- char *version = NULL;
- char *jre = NULL;
- int jarflag = 0;
- int headlessflag = 0;
- int restrict_search = -1; /* -1 implies not known */
- manifest_info info;
- char env_entry[MAXNAMELEN + 24] = ENV_ENTRY "=";
- char *splash_file_name = NULL;
- char *splash_jar_name = NULL;
- char *env_in;
- int res;
-
- /*
- * If the version has already been selected, set *main_class
- * with the value passed through the environment (if any) and
- * simply return.
- */
- if ((env_in = getenv(ENV_ENTRY)) != NULL) {
- if (*env_in != '\0')
- *main_class = JLI_StringDup(env_in);
- return;
- }
-
- /*
- * Scan through the arguments for options relevant to multiple JRE
- * support. For reference, the command line syntax is defined as:
- *
- * SYNOPSIS
- * java [options] class [argument...]
- *
- * java [options] -jar file.jar [argument...]
- *
- * As the scan is performed, make a copy of the argument list with
- * the version specification options (new to 1.5) removed, so that
- * a version less than 1.5 can be exec'd.
- *
- * Note that due to the syntax of the native Windows interface
- * CreateProcess(), processing similar to the following exists in
- * the Windows platform specific routine ExecJRE (in java_md.c).
- * Changes here should be reproduced there.
- */
- new_argv = JLI_MemAlloc((argc + 1) * sizeof(char*));
- new_argv[0] = argv[0];
- new_argp = &new_argv[1];
- argc--;
- argv++;
- while ((arg = *argv) != 0 && *arg == '-') {
- if (strncmp(arg, "-version:", 9) == 0) {
- version = arg + 9;
- } else if (strcmp(arg, "-jre-restrict-search") == 0) {
- restrict_search = 1;
- } else if (strcmp(arg, "-no-jre-restrict-search") == 0) {
- restrict_search = 0;
- } else {
- if (strcmp(arg, "-jar") == 0)
- jarflag = 1;
- /* deal with "unfortunate" classpath syntax */
- if ((strcmp(arg, "-classpath") == 0 || strcmp(arg, "-cp") == 0) &&
- (argc >= 2)) {
- *new_argp++ = arg;
- argc--;
- argv++;
- arg = *argv;
- }
-
- /*
- * Checking for headless toolkit option in the some way as AWT does:
- * "true" means true and any other value means false
- */
- if (strcmp(arg, "-Djava.awt.headless=true") == 0) {
- headlessflag = 1;
- } else if (strncmp(arg, "-Djava.awt.headless=", 20) == 0) {
- headlessflag = 0;
- } else if (strncmp(arg, "-splash:", 8) == 0) {
- splash_file_name = arg+8;
- }
- *new_argp++ = arg;
- }
- argc--;
- argv++;
- }
- if (argc <= 0) { /* No operand? Possibly legit with -[full]version */
- operand = NULL;
- } else {
- argc--;
- *new_argp++ = operand = *argv++;
- }
- while (argc-- > 0) /* Copy over [argument...] */
- *new_argp++ = *argv++;
- *new_argp = NULL;
-
- /*
- * If there is a jar file, read the manifest. If the jarfile can't be
- * read, the manifest can't be read from the jar file, or the manifest
- * is corrupt, issue the appropriate error messages and exit.
- *
- * Even if there isn't a jar file, construct a manifest_info structure
- * containing the command line information. It's a convenient way to carry
- * this data around.
- */
- if (jarflag && operand) {
- if ((res = JLI_ParseManifest(operand, &info)) != 0) {
- if (res == -1)
- ReportErrorMessage2("Unable to access jarfile %s",
- operand, JNI_TRUE);
- else
- ReportErrorMessage2("Invalid or corrupt jarfile %s",
- operand, JNI_TRUE);
- exit(1);
- }
-
- /*
- * Command line splash screen option should have precedence
- * over the manifest, so the manifest data is used only if
- * splash_file_name has not been initialized above during command
- * line parsing
- */
- if (!headlessflag && !splash_file_name && info.splashscreen_image_file_name) {
- splash_file_name = info.splashscreen_image_file_name;
- splash_jar_name = operand;
- }
- } else {
- info.manifest_version = NULL;
- info.main_class = NULL;
- info.jre_version = NULL;
- info.jre_restrict_search = 0;
- }
-
- /*
- * Passing on splash screen info in environment variables
- */
- if (splash_file_name && !headlessflag) {
- char* splash_file_entry = JLI_MemAlloc(strlen(SPLASH_FILE_ENV_ENTRY "=")+strlen(splash_file_name)+1);
- strcpy(splash_file_entry, SPLASH_FILE_ENV_ENTRY "=");
- strcat(splash_file_entry, splash_file_name);
- putenv(splash_file_entry);
- }
- if (splash_jar_name && !headlessflag) {
- char* splash_jar_entry = JLI_MemAlloc(strlen(SPLASH_JAR_ENV_ENTRY "=")+strlen(splash_jar_name)+1);
- strcpy(splash_jar_entry, SPLASH_JAR_ENV_ENTRY "=");
- strcat(splash_jar_entry, splash_jar_name);
- putenv(splash_jar_entry);
- }
-
- /*
- * The JRE-Version and JRE-Restrict-Search values (if any) from the
- * manifest are overwritten by any specified on the command line.
- */
- if (version != NULL)
- info.jre_version = version;
- if (restrict_search != -1)
- info.jre_restrict_search = restrict_search;
-
- /*
- * "Valid" returns (other than unrecoverable errors) follow. Set
- * main_class as a side-effect of this routine.
- */
- if (info.main_class != NULL)
- *main_class = JLI_StringDup(info.main_class);
-
- /*
- * If no version selection information is found either on the command
- * line or in the manifest, simply return.
- */
- if (info.jre_version == NULL) {
- JLI_FreeManifest();
- JLI_MemFree(new_argv);
- return;
- }
-
- /*
- * Check for correct syntax of the version specification (JSR 56).
- */
- if (!JLI_ValidVersionString(info.jre_version)) {
- ReportErrorMessage2("Syntax error in version specification \"%s\"",
- info.jre_version, JNI_TRUE);
- exit(1);
- }
-
- /*
- * Find the appropriate JVM on the system. Just to be as forgiving as
- * possible, if the standard algorithms don't locate an appropriate
- * jre, check to see if the one running will satisfy the requirements.
- * This can happen on systems which haven't been set-up for multiple
- * JRE support.
- */
- jre = LocateJRE(&info);
- if (_launcher_debug)
- printf("JRE-Version = %s, JRE-Restrict-Search = %s Selected = %s\n",
- (info.jre_version?info.jre_version:"null"),
- (info.jre_restrict_search?"true":"false"), (jre?jre:"null"));
- if (jre == NULL) {
- if (JLI_AcceptableRelease(FULL_VERSION, info.jre_version)) {
- JLI_FreeManifest();
- JLI_MemFree(new_argv);
- return;
- } else {
- ReportErrorMessage2(
- "Unable to locate JRE meeting specification \"%s\"",
- info.jre_version, JNI_TRUE);
- exit(1);
- }
- }
-
- /*
- * If I'm not the chosen one, exec the chosen one. Returning from
- * ExecJRE indicates that I am indeed the chosen one.
- *
- * The private environment variable _JAVA_VERSION_SET is used to
- * prevent the chosen one from re-reading the manifest file and
- * using the values found within to override the (potential) command
- * line flags stripped from argv (because the target may not
- * understand them). Passing the MainClass value is an optimization
- * to avoid locating, expanding and parsing the manifest extra
- * times.
- */
- if (info.main_class != NULL) {
- if (strlen(info.main_class) <= MAXNAMELEN) {
- (void)strcat(env_entry, info.main_class);
- } else {
- ReportErrorMessage("Error: main-class: attribute exceeds system limits\n", JNI_TRUE);
- exit(1);
- }
- }
- (void)putenv(env_entry);
- ExecJRE(jre, new_argv);
- JLI_FreeManifest();
- JLI_MemFree(new_argv);
- return;
-}
-#endif /* ifndef GAMMA */
-
-/*
- * Parses command line arguments. Returns JNI_FALSE if launcher
- * should exit without starting vm (e.g. certain version and usage
- * options); returns JNI_TRUE if vm needs to be started to process
- * given options. *pret (the launcher process return value) is set to
- * 0 for a normal exit.
- */
-static jboolean
-ParseArguments(int *pargc, char ***pargv, char **pjarfile,
- char **pclassname, int *pret, const char *jvmpath)
-{
- int argc = *pargc;
- char **argv = *pargv;
- jboolean jarflag = JNI_FALSE;
- char *arg;
-
- *pret = 1;
- while ((arg = *argv) != 0 && *arg == '-') {
- argv++; --argc;
- if (strcmp(arg, "-classpath") == 0 || strcmp(arg, "-cp") == 0) {
- if (argc < 1) {
- ReportErrorMessage2("%s requires class path specification",
- arg, JNI_TRUE);
- PrintUsage();
- return JNI_FALSE;
- }
- SetClassPath(*argv);
- argv++; --argc;
- } else if (strcmp(arg, "-jar") == 0) {
- jarflag = JNI_TRUE;
- } else if (strcmp(arg, "-help") == 0 ||
- strcmp(arg, "-h") == 0 ||
- strcmp(arg, "-?") == 0) {
- PrintUsage();
- *pret = 0;
- return JNI_FALSE;
- } else if (strcmp(arg, "-version") == 0) {
- printVersion = JNI_TRUE;
- return JNI_TRUE;
- } else if (strcmp(arg, "-showversion") == 0) {
- showVersion = JNI_TRUE;
- } else if (strcmp(arg, "-X") == 0) {
- *pret = PrintXUsage(jvmpath);
- return JNI_FALSE;
-/*
- * The following case provide backward compatibility with old-style
- * command line options.
- */
- } else if (strcmp(arg, "-fullversion") == 0) {
- fprintf(stderr, "%s full version \"%s\"\n", progname,
- FULL_VERSION);
- *pret = 0;
- return JNI_FALSE;
- } else if (strcmp(arg, "-verbosegc") == 0) {
- AddOption("-verbose:gc", NULL);
- } else if (strcmp(arg, "-t") == 0) {
- AddOption("-Xt", NULL);
- } else if (strcmp(arg, "-tm") == 0) {
- AddOption("-Xtm", NULL);
- } else if (strcmp(arg, "-debug") == 0) {
- AddOption("-Xdebug", NULL);
- } else if (strcmp(arg, "-noclassgc") == 0) {
- AddOption("-Xnoclassgc", NULL);
- } else if (strcmp(arg, "-Xfuture") == 0) {
- AddOption("-Xverify:all", NULL);
- } else if (strcmp(arg, "-verify") == 0) {
- AddOption("-Xverify:all", NULL);
- } else if (strcmp(arg, "-verifyremote") == 0) {
- AddOption("-Xverify:remote", NULL);
- } else if (strcmp(arg, "-noverify") == 0) {
- AddOption("-Xverify:none", NULL);
- } else if (strcmp(arg, "-XXsuppressExitMessage") == 0) {
- noExitErrorMessage = 1;
- } else if (strncmp(arg, "-prof", 5) == 0) {
- char *p = arg + 5;
- char *tmp = JLI_MemAlloc(strlen(arg) + 50);
- if (*p) {
- sprintf(tmp, "-Xrunhprof:cpu=old,file=%s", p + 1);
- } else {
- sprintf(tmp, "-Xrunhprof:cpu=old,file=java.prof");
- }
- AddOption(tmp, NULL);
- } else if (strncmp(arg, "-ss", 3) == 0 ||
- strncmp(arg, "-oss", 4) == 0 ||
- strncmp(arg, "-ms", 3) == 0 ||
- strncmp(arg, "-mx", 3) == 0) {
- char *tmp = JLI_MemAlloc(strlen(arg) + 6);
- sprintf(tmp, "-X%s", arg + 1); /* skip '-' */
- AddOption(tmp, NULL);
- } else if (strcmp(arg, "-checksource") == 0 ||
- strcmp(arg, "-cs") == 0 ||
- strcmp(arg, "-noasyncgc") == 0) {
- /* No longer supported */
- fprintf(stderr,
- "Warning: %s option is no longer supported.\n",
- arg);
- } else if (strncmp(arg, "-version:", 9) == 0 ||
- strcmp(arg, "-no-jre-restrict-search") == 0 ||
- strcmp(arg, "-jre-restrict-search") == 0 ||
- strncmp(arg, "-splash:", 8) == 0) {
- ; /* Ignore machine independent options already handled */
- } else if (RemovableMachineDependentOption(arg) ) {
- ; /* Do not pass option to vm. */
- }
- else {
- AddOption(arg, NULL);
- }
- }
-
- if (--argc >= 0) {
- if (jarflag) {
- *pjarfile = *argv++;
- *pclassname = 0;
- } else {
- *pjarfile = 0;
- *pclassname = *argv++;
- }
- *pargc = argc;
- *pargv = argv;
- }
-
- return JNI_TRUE;
-}
-
-/*
- * Initializes the Java Virtual Machine. Also frees options array when
- * finished.
- */
-static jboolean
-InitializeJVM(JavaVM **pvm, JNIEnv **penv, InvocationFunctions *ifn)
-{
- JavaVMInitArgs args;
- jint r;
-
- memset(&args, 0, sizeof(args));
- args.version = JNI_VERSION_1_2;
- args.nOptions = numOptions;
- args.options = options;
- args.ignoreUnrecognized = JNI_FALSE;
-
- if (_launcher_debug) {
- int i = 0;
- printf("JavaVM args:\n ");
- printf("version 0x%08lx, ", (long)args.version);
- printf("ignoreUnrecognized is %s, ",
- args.ignoreUnrecognized ? "JNI_TRUE" : "JNI_FALSE");
- printf("nOptions is %ld\n", (long)args.nOptions);
- for (i = 0; i < numOptions; i++)
- printf(" option[%2d] = '%s'\n",
- i, args.options[i].optionString);
- }
-
- r = ifn->CreateJavaVM(pvm, (void **)penv, &args);
- JLI_MemFree(options);
- return r == JNI_OK;
-}
-
-
-#define NULL_CHECK0(e) if ((e) == 0) return 0
-#define NULL_CHECK(e) if ((e) == 0) return
-
-static jstring platformEncoding = NULL;
-static jstring getPlatformEncoding(JNIEnv *env) {
- if (platformEncoding == NULL) {
- jstring propname = (*env)->NewStringUTF(env, "sun.jnu.encoding");
- if (propname) {
- jclass cls;
- jmethodID mid;
- NULL_CHECK0 (cls = (*env)->FindClass(env, "java/lang/System"));
- NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
- env, cls,
- "getProperty",
- "(Ljava/lang/String;)Ljava/lang/String;"));
- platformEncoding = (*env)->CallStaticObjectMethod (
- env, cls, mid, propname);
- }
- }
- return platformEncoding;
-}
-
-static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
- jclass cls;
- jmethodID mid;
- NULL_CHECK0 (cls = (*env)->FindClass(env, "java/nio/charset/Charset"));
- NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
- env, cls,
- "isSupported",
- "(Ljava/lang/String;)Z"));
- return (*env)->CallStaticBooleanMethod(env, cls, mid, enc);
-}
-
-/*
- * Returns a new Java string object for the specified platform string.
- */
-static jstring
-NewPlatformString(JNIEnv *env, char *s)
-{
- int len = (int)strlen(s);
- jclass cls;
- jmethodID mid;
- jbyteArray ary;
- jstring enc;
-
- if (s == NULL)
- return 0;
- enc = getPlatformEncoding(env);
-
- ary = (*env)->NewByteArray(env, len);
- if (ary != 0) {
- jstring str = 0;
- (*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s);
- if (!(*env)->ExceptionOccurred(env)) {
- if (isEncodingSupported(env, enc) == JNI_TRUE) {
- NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
- NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "",
- "([BLjava/lang/String;)V"));
- str = (*env)->NewObject(env, cls, mid, ary, enc);
- } else {
- /*If the encoding specified in sun.jnu.encoding is not
- endorsed by "Charset.isSupported" we have to fall back
- to use String(byte[]) explicitly here without specifying
- the encoding name, in which the StringCoding class will
- pickup the iso-8859-1 as the fallback converter for us.
- */
- NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
- NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "",
- "([B)V"));
- str = (*env)->NewObject(env, cls, mid, ary);
- }
- (*env)->DeleteLocalRef(env, ary);
- return str;
- }
- }
- return 0;
-}
-
-/*
- * Returns a new array of Java string objects for the specified
- * array of platform strings.
- */
-static jobjectArray
-NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
-{
- jarray cls;
- jarray ary;
- int i;
-
- NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
- NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
- for (i = 0; i < strc; i++) {
- jstring str = NewPlatformString(env, *strv++);
- NULL_CHECK0(str);
- (*env)->SetObjectArrayElement(env, ary, i, str);
- (*env)->DeleteLocalRef(env, str);
- }
- return ary;
-}
-
-/*
- * Loads a class, convert the '.' to '/'.
- */
-static jclass
-LoadClass(JNIEnv *env, char *name)
-{
- char *buf = JLI_MemAlloc(strlen(name) + 1);
- char *s = buf, *t = name, c;
- jclass cls;
- jlong start, end;
-
- if (_launcher_debug)
- start = CounterGet();
-
- do {
- c = *t++;
- *s++ = (c == '.') ? '/' : c;
- } while (c != '\0');
- cls = (*env)->FindClass(env, buf);
- JLI_MemFree(buf);
-
- if (_launcher_debug) {
- end = CounterGet();
- printf("%ld micro seconds to load main class\n",
- (long)(jint)Counter2Micros(end-start));
- printf("----_JAVA_LAUNCHER_DEBUG----\n");
- }
-
- return cls;
-}
-
-
-/*
- * Returns the main class name for the specified jar file.
- */
-static jstring
-GetMainClassName(JNIEnv *env, char *jarname)
-{
-#define MAIN_CLASS "Main-Class"
- jclass cls;
- jmethodID mid;
- jobject jar, man, attr;
- jstring str, result = 0;
-
- NULL_CHECK0(cls = (*env)->FindClass(env, "java/util/jar/JarFile"));
- NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "",
- "(Ljava/lang/String;)V"));
- NULL_CHECK0(str = NewPlatformString(env, jarname));
- NULL_CHECK0(jar = (*env)->NewObject(env, cls, mid, str));
- NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "getManifest",
- "()Ljava/util/jar/Manifest;"));
- man = (*env)->CallObjectMethod(env, jar, mid);
- if (man != 0) {
- NULL_CHECK0(mid = (*env)->GetMethodID(env,
- (*env)->GetObjectClass(env, man),
- "getMainAttributes",
- "()Ljava/util/jar/Attributes;"));
- attr = (*env)->CallObjectMethod(env, man, mid);
- if (attr != 0) {
- NULL_CHECK0(mid = (*env)->GetMethodID(env,
- (*env)->GetObjectClass(env, attr),
- "getValue",
- "(Ljava/lang/String;)Ljava/lang/String;"));
- NULL_CHECK0(str = NewPlatformString(env, MAIN_CLASS));
- result = (*env)->CallObjectMethod(env, attr, mid, str);
- }
- }
- return result;
-}
-
-#ifdef JAVA_ARGS
-static char *java_args[] = JAVA_ARGS;
-static char *app_classpath[] = APP_CLASSPATH;
-
-/*
- * For tools, convert command line args thus:
- * javac -cp foo:foo/"*" -J-ms32m ...
- * java -ms32m -cp JLI_WildcardExpandClasspath(foo:foo/"*") ...
- */
-static void
-TranslateApplicationArgs(int *pargc, char ***pargv)
-{
- const int NUM_ARGS = (sizeof(java_args) / sizeof(char *));
- int argc = *pargc;
- char **argv = *pargv;
- int nargc = argc + NUM_ARGS;
- char **nargv = JLI_MemAlloc((nargc + 1) * sizeof(char *));
- int i;
-
- *pargc = nargc;
- *pargv = nargv;
-
- /* Copy the VM arguments (i.e. prefixed with -J) */
- for (i = 0; i < NUM_ARGS; i++) {
- char *arg = java_args[i];
- if (arg[0] == '-' && arg[1] == 'J') {
- *nargv++ = arg + 2;
- }
- }
-
- for (i = 0; i < argc; i++) {
- char *arg = argv[i];
- if (arg[0] == '-' && arg[1] == 'J') {
- if (arg[2] == '\0') {
- ReportErrorMessage("Error: the -J option should not be "
- "followed by a space.", JNI_TRUE);
- exit(1);
- }
- *nargv++ = arg + 2;
- }
- }
-
- /* Copy the rest of the arguments */
- for (i = 0; i < NUM_ARGS; i++) {
- char *arg = java_args[i];
- if (arg[0] != '-' || arg[1] != 'J') {
- *nargv++ = arg;
- }
- }
- for (i = 0; i < argc; i++) {
- char *arg = argv[i];
- if (arg[0] == '-') {
- if (arg[1] == 'J')
- continue;
-#ifdef EXPAND_CLASSPATH_WILDCARDS
- if (arg[1] == 'c'
- && (strcmp(arg, "-cp") == 0 ||
- strcmp(arg, "-classpath") == 0)
- && i < argc - 1) {
- *nargv++ = arg;
- *nargv++ = (char *) JLI_WildcardExpandClasspath(argv[i+1]);
- i++;
- continue;
- }
-#endif
- }
- *nargv++ = arg;
- }
- *nargv = 0;
-}
-
-/*
- * For our tools, we try to add 3 VM options:
- * -Denv.class.path=
- * -Dapplication.home=
- * -Djava.class.path=
- * is the user's setting of CLASSPATH -- for instance the user
- * tells javac where to find binary classes through this environment
- * variable. Notice that users will be able to compile against our
- * tools classes (sun.tools.javac.Main) only if they explicitly add
- * tools.jar to CLASSPATH.
- * is the directory where the application is installed.
- * is the classpath to where our apps' classfiles are.
- */
-static jboolean
-AddApplicationOptions()
-{
- const int NUM_APP_CLASSPATH = (sizeof(app_classpath) / sizeof(char *));
- char *envcp, *appcp, *apphome;
- char home[MAXPATHLEN]; /* application home */
- char separator[] = { PATH_SEPARATOR, '\0' };
- int size, i;
- int strlenHome;
-
- {
- const char *s = getenv("CLASSPATH");
- if (s) {
- s = (char *) JLI_WildcardExpandClasspath(s);
- /* 40 for -Denv.class.path= */
- envcp = (char *)JLI_MemAlloc(strlen(s) + 40);
- sprintf(envcp, "-Denv.class.path=%s", s);
- AddOption(envcp, NULL);
- }
- }
-
- if (!GetApplicationHome(home, sizeof(home))) {
- ReportErrorMessage("Can't determine application home", JNI_TRUE);
- return JNI_FALSE;
- }
-
- /* 40 for '-Dapplication.home=' */
- apphome = (char *)JLI_MemAlloc(strlen(home) + 40);
- sprintf(apphome, "-Dapplication.home=%s", home);
- AddOption(apphome, NULL);
-
- /* How big is the application's classpath? */
- size = 40; /* 40: "-Djava.class.path=" */
- strlenHome = (int)strlen(home);
- for (i = 0; i < NUM_APP_CLASSPATH; i++) {
- size += strlenHome + (int)strlen(app_classpath[i]) + 1; /* 1: separator */
- }
- appcp = (char *)JLI_MemAlloc(size + 1);
- strcpy(appcp, "-Djava.class.path=");
- for (i = 0; i < NUM_APP_CLASSPATH; i++) {
- strcat(appcp, home); /* c:\program files\myapp */
- strcat(appcp, app_classpath[i]); /* \lib\myapp.jar */
- strcat(appcp, separator); /* ; */
- }
- appcp[strlen(appcp)-1] = '\0'; /* remove trailing path separator */
- AddOption(appcp, NULL);
- return JNI_TRUE;
-}
-#endif /* JAVA_ARGS */
-
-/*
- * inject the -Dsun.java.command pseudo property into the args structure
- * this pseudo property is used in the HotSpot VM to expose the
- * Java class name and arguments to the main method to the VM. The
- * HotSpot VM uses this pseudo property to store the Java class name
- * (or jar file name) and the arguments to the class's main method
- * to the instrumentation memory region. The sun.java.command pseudo
- * property is not exported by HotSpot to the Java layer.
- */
-void
-SetJavaCommandLineProp(char *classname, char *jarfile,
- int argc, char **argv)
-{
-
- int i = 0;
- size_t len = 0;
- char* javaCommand = NULL;
- char* dashDstr = "-Dsun.java.command=";
-
- if (classname == NULL && jarfile == NULL) {
- /* unexpected, one of these should be set. just return without
- * setting the property
- */
- return;
- }
-
- /* if the class name is not set, then use the jarfile name */
- if (classname == NULL) {
- classname = jarfile;
- }
-
- /* determine the amount of memory to allocate assuming
- * the individual components will be space separated
- */
- len = strlen(classname);
- for (i = 0; i < argc; i++) {
- len += strlen(argv[i]) + 1;
- }
-
- /* allocate the memory */
- javaCommand = (char*) JLI_MemAlloc(len + strlen(dashDstr) + 1);
-
- /* build the -D string */
- *javaCommand = '\0';
- strcat(javaCommand, dashDstr);
- strcat(javaCommand, classname);
-
- for (i = 0; i < argc; i++) {
- /* the components of the string are space separated. In
- * the case of embedded white space, the relationship of
- * the white space separated components to their true
- * positional arguments will be ambiguous. This issue may
- * be addressed in a future release.
- */
- strcat(javaCommand, " ");
- strcat(javaCommand, argv[i]);
- }
-
- AddOption(javaCommand, NULL);
-}
-
-/*
- * JVM would like to know if it's created by a standard Sun launcher, or by
- * user native application, the following property indicates the former.
- */
-void SetJavaLauncherProp() {
- AddOption("-Dsun.java.launcher=" LAUNCHER_TYPE, NULL);
-}
-
-/*
- * Prints the version information from the java.version and other properties.
- */
-static void
-PrintJavaVersion(JNIEnv *env)
-{
- jclass ver;
- jmethodID print;
-
- NULL_CHECK(ver = (*env)->FindClass(env, "sun/misc/Version"));
- NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, "print", "()V"));
-
- (*env)->CallStaticVoidMethod(env, ver, print);
-}
-
-/*
- * Prints default usage message.
- */
-static void
-PrintUsage(void)
-{
-#ifndef GAMMA
- int i;
-#endif
-
- fprintf(stdout,
- "Usage: %s [-options] class [args...]\n"
- " (to execute a class)\n"
- " or %s [-options] -jar jarfile [args...]\n"
- " (to execute a jar file)\n"
- "\n"
- "where options include:\n",
- progname,
- progname);
-
-#ifndef GAMMA
- PrintMachineDependentOptions();
-
- if ((knownVMs[0].flag == VM_KNOWN) ||
- (knownVMs[0].flag == VM_IF_SERVER_CLASS)) {
- fprintf(stdout, " %s\t to select the \"%s\" VM\n",
- knownVMs[0].name, knownVMs[0].name+1);
- }
- for (i=1; i\n"
-" -classpath \n"
-" A %c separated list of directories, JAR archives,\n"
-" and ZIP archives to search for class files.\n"
-" -D=\n"
-" set a system property\n"
-" -verbose[:class|gc|jni]\n"
-" enable verbose output\n"
-" -version print product version and exit\n"
-" -version:\n"
-" require the specified version to run\n"
-" -showversion print product version and continue\n"
-" -jre-restrict-search | -jre-no-restrict-search\n"
-" include/exclude user private JREs in the version search\n"
-" -? -help print this help message\n"
-" -X print help on non-standard options\n"
-" -ea[:...|:]\n"
-" -enableassertions[:...|:]\n"
-" enable assertions\n"
-" -da[:...|:]\n"
-" -disableassertions[:...|:]\n"
-" disable assertions\n"
-" -esa | -enablesystemassertions\n"
-" enable system assertions\n"
-" -dsa | -disablesystemassertions\n"
-" disable system assertions\n"
-" -agentlib:[=]\n"
-" load native agent library , e.g. -agentlib:hprof\n"
-" see also, -agentlib:jdwp=help and -agentlib:hprof=help\n"
-" -agentpath:[=]\n"
-" load native agent library by full pathname\n"
-" -javaagent:[=]\n"
-" load Java programming language agent, see java.lang.instrument\n"
-" -splash:\n"
-" show splash screen with specified image\n"
-
- ,PATH_SEPARATOR);
-}
-
-/*
- * Print usage message for -X options.
- */
-static jint
-PrintXUsage(const char *jvmpath)
-{
- /*
- A 32 bit cushion to prevent buffer overrun, noting that
- fopen(3C) may fail if the buffer exceeds MAXPATHLEN.
- */
- char path[MAXPATHLEN+32];
- char buf[128];
- size_t n;
- FILE *fp;
- static const char Xusage_txt[] = "/Xusage.txt";
-
- strcpy(path, jvmpath);
- /* Note the FILE_SEPARATOR is platform dependent */
- strcpy(strrchr(path, FILE_SEPARATOR), Xusage_txt);
- fp = fopen(path, "r");
- if (fp == 0) {
- fprintf(stderr, "Can't open %s\n", path);
- return 1;
- }
- while ((n = fread(buf, 1, sizeof(buf), fp)) != 0) {
- fwrite(buf, 1, n, stdout);
- }
- fclose(fp);
- return 0;
-}
-
-#ifndef GAMMA
-/*
- * Read the jvm.cfg file and fill the knownJVMs[] array.
- *
- * The functionality of the jvm.cfg file is subject to change without
- * notice and the mechanism will be removed in the future.
- *
- * The lexical structure of the jvm.cfg file is as follows:
- *
- * jvmcfg := { vmLine }
- * vmLine := knownLine
- * | aliasLine
- * | warnLine
- * | ignoreLine
- * | errorLine
- * | predicateLine
- * | commentLine
- * knownLine := flag "KNOWN" EOL
- * warnLine := flag "WARN" EOL
- * ignoreLine := flag "IGNORE" EOL
- * errorLine := flag "ERROR" EOL
- * aliasLine := flag "ALIASED_TO" flag EOL
- * predicateLine := flag "IF_SERVER_CLASS" flag EOL
- * commentLine := "#" text EOL
- * flag := "-" identifier
- *
- * The semantics are that when someone specifies a flag on the command line:
- * - if the flag appears on a knownLine, then the identifier is used as
- * the name of the directory holding the JVM library (the name of the JVM).
- * - if the flag appears as the first flag on an aliasLine, the identifier
- * of the second flag is used as the name of the JVM.
- * - if the flag appears on a warnLine, the identifier is used as the
- * name of the JVM, but a warning is generated.
- * - if the flag appears on an ignoreLine, the identifier is recognized as the
- * name of a JVM, but the identifier is ignored and the default vm used
- * - if the flag appears on an errorLine, an error is generated.
- * - if the flag appears as the first flag on a predicateLine, and
- * the machine on which you are running passes the predicate indicated,
- * then the identifier of the second flag is used as the name of the JVM,
- * otherwise the identifier of the first flag is used as the name of the JVM.
- * If no flag is given on the command line, the first vmLine of the jvm.cfg
- * file determines the name of the JVM.
- * PredicateLines are only interpreted on first vmLine of a jvm.cfg file,
- * since they only make sense if someone hasn't specified the name of the
- * JVM on the command line.
- *
- * The intent of the jvm.cfg file is to allow several JVM libraries to
- * be installed in different subdirectories of a single JRE installation,
- * for space-savings and convenience in testing.
- * The intent is explicitly not to provide a full aliasing or predicate
- * mechanism.
- */
-jint
-ReadKnownVMs(const char *jrepath, char * arch, jboolean speculative)
-{
- FILE *jvmCfg;
- char jvmCfgName[MAXPATHLEN+20];
- char line[MAXPATHLEN+20];
- int cnt = 0;
- int lineno = 0;
- jlong start, end;
- int vmType;
- char *tmpPtr;
- char *altVMName = NULL;
- char *serverClassVMName = NULL;
- static char *whiteSpace = " \t";
- if (_launcher_debug) {
- start = CounterGet();
- }
-
- strcpy(jvmCfgName, jrepath);
- strcat(jvmCfgName, FILESEP "lib" FILESEP);
- strcat(jvmCfgName, arch);
- strcat(jvmCfgName, FILESEP "jvm.cfg");
-
- jvmCfg = fopen(jvmCfgName, "r");
- if (jvmCfg == NULL) {
- if (!speculative) {
- ReportErrorMessage2("Error: could not open `%s'", jvmCfgName,
- JNI_TRUE);
- exit(1);
- } else {
- return -1;
- }
- }
- while (fgets(line, sizeof(line), jvmCfg) != NULL) {
- vmType = VM_UNKNOWN;
- lineno++;
- if (line[0] == '#')
- continue;
- if (line[0] != '-') {
- fprintf(stderr, "Warning: no leading - on line %d of `%s'\n",
- lineno, jvmCfgName);
- }
- if (cnt >= knownVMsLimit) {
- GrowKnownVMs(cnt);
- }
- line[strlen(line)-1] = '\0'; /* remove trailing newline */
- tmpPtr = line + strcspn(line, whiteSpace);
- if (*tmpPtr == 0) {
- fprintf(stderr, "Warning: missing VM type on line %d of `%s'\n",
- lineno, jvmCfgName);
- } else {
- /* Null-terminate this string for JLI_StringDup below */
- *tmpPtr++ = 0;
- tmpPtr += strspn(tmpPtr, whiteSpace);
- if (*tmpPtr == 0) {
- fprintf(stderr, "Warning: missing VM type on line %d of `%s'\n",
- lineno, jvmCfgName);
- } else {
- if (!strncmp(tmpPtr, "KNOWN", strlen("KNOWN"))) {
- vmType = VM_KNOWN;
- } else if (!strncmp(tmpPtr, "ALIASED_TO", strlen("ALIASED_TO"))) {
- tmpPtr += strcspn(tmpPtr, whiteSpace);
- if (*tmpPtr != 0) {
- tmpPtr += strspn(tmpPtr, whiteSpace);
- }
- if (*tmpPtr == 0) {
- fprintf(stderr, "Warning: missing VM alias on line %d of `%s'\n",
- lineno, jvmCfgName);
- } else {
- /* Null terminate altVMName */
- altVMName = tmpPtr;
- tmpPtr += strcspn(tmpPtr, whiteSpace);
- *tmpPtr = 0;
- vmType = VM_ALIASED_TO;
- }
- } else if (!strncmp(tmpPtr, "WARN", strlen("WARN"))) {
- vmType = VM_WARN;
- } else if (!strncmp(tmpPtr, "IGNORE", strlen("IGNORE"))) {
- vmType = VM_IGNORE;
- } else if (!strncmp(tmpPtr, "ERROR", strlen("ERROR"))) {
- vmType = VM_ERROR;
- } else if (!strncmp(tmpPtr,
- "IF_SERVER_CLASS",
- strlen("IF_SERVER_CLASS"))) {
- tmpPtr += strcspn(tmpPtr, whiteSpace);
- if (*tmpPtr != 0) {
- tmpPtr += strspn(tmpPtr, whiteSpace);
- }
- if (*tmpPtr == 0) {
- fprintf(stderr, "Warning: missing server class VM on line %d of `%s'\n",
- lineno, jvmCfgName);
- } else {
- /* Null terminate server class VM name */
- serverClassVMName = tmpPtr;
- tmpPtr += strcspn(tmpPtr, whiteSpace);
- *tmpPtr = 0;
- vmType = VM_IF_SERVER_CLASS;
- }
- } else {
- fprintf(stderr, "Warning: unknown VM type on line %d of `%s'\n",
- lineno, &jvmCfgName[0]);
- vmType = VM_KNOWN;
- }
- }
- }
-
- if (_launcher_debug)
- printf("jvm.cfg[%d] = ->%s<-\n", cnt, line);
- if (vmType != VM_UNKNOWN) {
- knownVMs[cnt].name = JLI_StringDup(line);
- knownVMs[cnt].flag = vmType;
- switch (vmType) {
- default:
- break;
- case VM_ALIASED_TO:
- knownVMs[cnt].alias = JLI_StringDup(altVMName);
- if (_launcher_debug) {
- printf(" name: %s vmType: %s alias: %s\n",
- knownVMs[cnt].name, "VM_ALIASED_TO", knownVMs[cnt].alias);
- }
- break;
- case VM_IF_SERVER_CLASS:
- knownVMs[cnt].server_class = JLI_StringDup(serverClassVMName);
- if (_launcher_debug) {
- printf(" name: %s vmType: %s server_class: %s\n",
- knownVMs[cnt].name, "VM_IF_SERVER_CLASS", knownVMs[cnt].server_class);
- }
- break;
- }
- cnt++;
- }
- }
- fclose(jvmCfg);
- knownVMsCount = cnt;
-
- if (_launcher_debug) {
- end = CounterGet();
- printf("%ld micro seconds to parse jvm.cfg\n",
- (long)(jint)Counter2Micros(end-start));
- }
-
- return cnt;
-}
-
-
-static void
-GrowKnownVMs(int minimum)
-{
- struct vmdesc* newKnownVMs;
- int newMax;
-
- newMax = (knownVMsLimit == 0 ? INIT_MAX_KNOWN_VMS : (2 * knownVMsLimit));
- if (newMax <= minimum) {
- newMax = minimum;
- }
- newKnownVMs = (struct vmdesc*) JLI_MemAlloc(newMax * sizeof(struct vmdesc));
- if (knownVMs != NULL) {
- memcpy(newKnownVMs, knownVMs, knownVMsLimit * sizeof(struct vmdesc));
- }
- JLI_MemFree(knownVMs);
- knownVMs = newKnownVMs;
- knownVMsLimit = newMax;
-}
-
-
-/* Returns index of VM or -1 if not found */
-static int
-KnownVMIndex(const char* name)
-{
- int i;
- if (strncmp(name, "-J", 2) == 0) name += 2;
- for (i = 0; i < knownVMsCount; i++) {
- if (!strcmp(name, knownVMs[i].name)) {
- return i;
- }
- }
- return -1;
-}
-
-static void
-FreeKnownVMs()
-{
- int i;
- for (i = 0; i < knownVMsCount; i++) {
- JLI_MemFree(knownVMs[i].name);
- knownVMs[i].name = NULL;
- }
- JLI_MemFree(knownVMs);
-}
-
-
-/*
- * Displays the splash screen according to the jar file name
- * and image file names stored in environment variables
- */
-static void
-ShowSplashScreen()
-{
- const char *jar_name = getenv(SPLASH_JAR_ENV_ENTRY);
- const char *file_name = getenv(SPLASH_FILE_ENV_ENTRY);
- int data_size;
- void *image_data;
- if (jar_name) {
- image_data = JLI_JarUnpackFile(jar_name, file_name, &data_size);
- if (image_data) {
- DoSplashInit();
- DoSplashLoadMemory(image_data, data_size);
- JLI_MemFree(image_data);
- }
- } else if (file_name) {
- DoSplashInit();
- DoSplashLoadFile(file_name);
- } else {
- return;
- }
- DoSplashSetFileJarName(file_name, jar_name);
-}
-
-#endif /* ifndef GAMMA */
diff --git a/hotspot/src/share/tools/launcher/java.h b/hotspot/src/share/tools/launcher/java.h
deleted file mode 100644
index 1dd79618c84..00000000000
--- a/hotspot/src/share/tools/launcher/java.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-
-#ifndef _JAVA_H_
-#define _JAVA_H_
-
-/*
- * Get system specific defines.
- */
-#include "jni.h"
-#include "java_md.h"
-#include "jli_util.h"
-
-/*
- * Pointers to the needed JNI invocation API, initialized by LoadJavaVM.
- */
-typedef jint (JNICALL *CreateJavaVM_t)(JavaVM **pvm, void **env, void *args);
-typedef jint (JNICALL *GetDefaultJavaVMInitArgs_t)(void *args);
-
-typedef struct {
- CreateJavaVM_t CreateJavaVM;
- GetDefaultJavaVMInitArgs_t GetDefaultJavaVMInitArgs;
-} InvocationFunctions;
-
-/*
- * Prototypes for launcher functions in the system specific java_md.c.
- */
-
-jboolean
-LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn);
-
-void
-GetXUsagePath(char *buf, jint bufsize);
-
-jboolean
-GetApplicationHome(char *buf, jint bufsize);
-
-const char *
-GetArch();
-
-void CreateExecutionEnvironment(int *_argc,
- char ***_argv,
- char jrepath[],
- jint so_jrepath,
- char jvmpath[],
- jint so_jvmpath,
- char **original_argv);
-
-/*
- * Report an error message to stderr or a window as appropriate. The
- * flag always is set to JNI_TRUE if message is to be reported to both
- * strerr and windows and set to JNI_FALSE if the message should only
- * be sent to a window.
- */
-void ReportErrorMessage(char * message, jboolean always);
-void ReportErrorMessage2(char * format, char * string, jboolean always);
-
-/*
- * Report an exception which terminates the vm to stderr or a window
- * as appropriate.
- */
-void ReportExceptionDescription(JNIEnv * env);
-
-jboolean RemovableMachineDependentOption(char * option);
-void PrintMachineDependentOptions();
-
-/*
- * Block current thread and continue execution in new thread
- */
-int ContinueInNewThread(int (JNICALL *continuation)(void *),
- jlong stack_size, void * args);
-
-/* sun.java.launcher.* platform properties. */
-void SetJavaLauncherPlatformProps(void);
-
-/*
- * Functions defined in java.c and used in java_md.c.
- */
-jint ReadKnownVMs(const char *jrepath, char * arch, jboolean speculative);
-char *CheckJvmType(int *argc, char ***argv, jboolean speculative);
-void AddOption(char *str, void *info);
-
-/*
- * Make launcher spit debug output.
- */
-extern jboolean _launcher_debug;
-
-#endif /* _JAVA_H_ */
diff --git a/hotspot/src/share/tools/launcher/jli_util.c b/hotspot/src/share/tools/launcher/jli_util.c
deleted file mode 100644
index 36b164e3d37..00000000000
--- a/hotspot/src/share/tools/launcher/jli_util.c
+++ /dev/null
@@ -1,89 +0,0 @@
-
-/*
- * Copyright (c) 1999, 2010, 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
-#include
-#include "jli_util.h"
-
-#ifdef GAMMA
-#ifdef TARGET_OS_FAMILY_windows
-#define strdup _strdup
-#endif
-#endif
-
-/*
- * Returns a pointer to a block of at least 'size' bytes of memory.
- * Prints error message and exits if the memory could not be allocated.
- */
-void *
-JLI_MemAlloc(size_t size)
-{
- void *p = malloc(size);
- if (p == 0) {
- perror("malloc");
- exit(1);
- }
- return p;
-}
-
-/*
- * Equivalent to realloc(size).
- * Prints error message and exits if the memory could not be reallocated.
- */
-void *
-JLI_MemRealloc(void *ptr, size_t size)
-{
- void *p = realloc(ptr, size);
- if (p == 0) {
- perror("realloc");
- exit(1);
- }
- return p;
-}
-
-/*
- * Wrapper over strdup(3C) which prints an error message and exits if memory
- * could not be allocated.
- */
-char *
-JLI_StringDup(const char *s1)
-{
- char *s = strdup(s1);
- if (s == NULL) {
- perror("strdup");
- exit(1);
- }
- return s;
-}
-
-/*
- * Very equivalent to free(ptr).
- * Here to maintain pairing with the above routines.
- */
-void
-JLI_MemFree(void *ptr)
-{
- free(ptr);
-}
diff --git a/hotspot/src/share/tools/launcher/wildcard.c b/hotspot/src/share/tools/launcher/wildcard.c
deleted file mode 100644
index 8b3cbcd69c4..00000000000
--- a/hotspot/src/share/tools/launcher/wildcard.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, 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.
- *
- */
-
-/*
- * Class-Path Wildcards
- *
- * The syntax for wildcards is a single asterisk. The class path
- * foo/"*", e.g., loads all jar files in the directory named foo.
- * (This requires careful quotation when used in shell scripts.)
- *
- * Only files whose names end in .jar or .JAR are matched.
- * Files whose names end in .zip, or which have a particular
- * magic number, regardless of filename extension, are not
- * matched.
- *
- * Files are considered regardless of whether or not they are
- * "hidden" in the UNIX sense, i.e., have names beginning with '.'.
- *
- * A wildcard only matches jar files, not class files in the same
- * directory. If you want to load both class files and jar files from
- * a single directory foo then you can say foo:foo/"*", or foo/"*":foo
- * if you want the jar files to take precedence.
- *
- * Subdirectories are not searched recursively, i.e., foo/"*" only
- * looks for jar files in foo, not in foo/bar, foo/baz, etc.
- *
- * Expansion of wildcards is done early, prior to the invocation of a
- * program's main method, rather than late, during the class-loading
- * process itself. Each element of the input class path containing a
- * wildcard is replaced by the (possibly empty) sequence of elements
- * generated by enumerating the jar files in the named directory. If
- * the directory foo contains a.jar, b.jar, and c.jar,
- * e.g., then the class path foo/"*" is expanded into
- * foo/a.jar:foo/b.jar:foo/c.jar, and that string would be the value
- * of the system property java.class.path.
- *
- * The order in which the jar files in a directory are enumerated in
- * the expanded class path is not specified and may vary from platform
- * to platform and even from moment to moment on the same machine. A
- * well-constructed application should not depend upon any particular
- * order. If a specific order is required then the jar files can be
- * enumerated explicitly in the class path.
- *
- * The CLASSPATH environment variable is not treated any differently
- * from the -classpath (equiv. -cp) command-line option,
- * i.e. wildcards are honored in all these cases.
- *
- * Class-path wildcards are not honored in the Class-Path jar-manifest
- * header.
- *
- * Class-path wildcards are honored not only by the Java launcher but
- * also by most other command-line tools that accept class paths, and
- * in particular by javac and javadoc.
- *
- * Class-path wildcards are not honored in any other kind of path, and
- * especially not in the bootstrap class path, which is a mere
- * artifact of our implementation and not something that developers
- * should use.
- *
- * Classpath wildcards are only expanded in the Java launcher code,
- * supporting the use of wildcards on the command line and in the
- * CLASSPATH environment variable. We do not support the use of
- * wildcards by applications that embed the JVM.
- */
-
-#include
-#include
-#include
-#include
-#include
-#include "java.h" /* Strictly for PATH_SEPARATOR/FILE_SEPARATOR */
-#include "jli_util.h"
-
-#ifdef _WIN32
-#include
-#else /* Unix */
-#include
-#include
-#endif /* Unix */
-
-static int
-exists(const char* filename)
-{
-#ifdef _WIN32
- return _access(filename, 0) == 0;
-#else
- return access(filename, F_OK) == 0;
-#endif
-}
-
-#define NEW_(TYPE) ((TYPE) JLI_MemAlloc(sizeof(struct TYPE##_)))
-
-/*
- * Wildcard directory iteration.
- * WildcardIterator_for(wildcard) returns an iterator.
- * Each call to that iterator's next() method returns the basename
- * of an entry in the wildcard's directory. The basename's memory
- * belongs to the iterator. The caller is responsible for prepending
- * the directory name and file separator, if necessary.
- * When done with the iterator, call the close method to clean up.
- */
-typedef struct WildcardIterator_* WildcardIterator;
-
-#ifdef _WIN32
-struct WildcardIterator_
-{
- HANDLE handle;
- char *firstFile; /* Stupid FindFirstFile...FindNextFile */
-};
-
-static WildcardIterator
-WildcardIterator_for(const char *wildcard)
-{
- WIN32_FIND_DATA find_data;
- WildcardIterator it = NEW_(WildcardIterator);
- HANDLE handle = FindFirstFile(wildcard, &find_data);
- if (handle == INVALID_HANDLE_VALUE)
- return NULL;
- it->handle = handle;
- it->firstFile = find_data.cFileName;
- return it;
-}
-
-static char *
-WildcardIterator_next(WildcardIterator it)
-{
- WIN32_FIND_DATA find_data;
- if (it->firstFile != NULL) {
- char *firstFile = it->firstFile;
- it->firstFile = NULL;
- return firstFile;
- }
- return FindNextFile(it->handle, &find_data)
- ? find_data.cFileName : NULL;
-}
-
-static void
-WildcardIterator_close(WildcardIterator it)
-{
- if (it) {
- FindClose(it->handle);
- JLI_MemFree(it->firstFile);
- JLI_MemFree(it);
- }
-}
-
-#else /* Unix */
-struct WildcardIterator_
-{
- DIR *dir;
-};
-
-static WildcardIterator
-WildcardIterator_for(const char *wildcard)
-{
- DIR *dir;
- int wildlen = strlen(wildcard);
- if (wildlen < 2) {
- dir = opendir(".");
- } else {
- char *dirname = JLI_StringDup(wildcard);
- dirname[wildlen - 1] = '\0';
- dir = opendir(dirname);
- JLI_MemFree(dirname);
- }
- if (dir == NULL)
- return NULL;
- else {
- WildcardIterator it = NEW_(WildcardIterator);
- it->dir = dir;
- return it;
- }
-}
-
-static char *
-WildcardIterator_next(WildcardIterator it)
-{
- struct dirent* dirp = readdir(it->dir);
- return dirp ? dirp->d_name : NULL;
-}
-
-static void
-WildcardIterator_close(WildcardIterator it)
-{
- if (it) {
- closedir(it->dir);
- JLI_MemFree(it);
- }
-}
-#endif /* Unix */
-
-static int
-equal(const char *s1, const char *s2)
-{
- return strcmp(s1, s2) == 0;
-}
-
-/*
- * FileList ADT - a dynamic list of C filenames
- */
-struct FileList_
-{
- char **files;
- int size;
- int capacity;
-};
-typedef struct FileList_ *FileList;
-
-static FileList
-FileList_new(int capacity)
-{
- FileList fl = NEW_(FileList);
- fl->capacity = capacity;
- fl->files = (char **) JLI_MemAlloc(capacity * sizeof(fl->files[0]));
- fl->size = 0;
- return fl;
-}
-
-#ifdef DEBUG_WILDCARD
-static void
-FileList_print(FileList fl)
-{
- int i;
- putchar('[');
- for (i = 0; i < fl->size; i++) {
- if (i > 0) printf(", ");
- printf("\"%s\"",fl->files[i]);
- }
- putchar(']');
-}
-#endif
-
-static void
-FileList_free(FileList fl)
-{
- if (fl) {
- if (fl->files) {
- int i;
- for (i = 0; i < fl->size; i++)
- JLI_MemFree(fl->files[i]);
- JLI_MemFree(fl->files);
- }
- JLI_MemFree(fl);
- }
-}
-
-static void
-FileList_ensureCapacity(FileList fl, int capacity)
-{
- if (fl->capacity < capacity) {
- while (fl->capacity < capacity)
- fl->capacity *= 2;
- fl->files = JLI_MemRealloc(fl->files,
- fl->capacity * sizeof(fl->files[0]));
- }
-}
-
-static void
-FileList_add(FileList fl, char *file)
-{
- FileList_ensureCapacity(fl, fl->size+1);
- fl->files[fl->size++] = file;
-}
-
-static void
-FileList_addSubstring(FileList fl, const char *beg, int len)
-{
- char *filename = (char *) JLI_MemAlloc(len+1);
- memcpy(filename, beg, len);
- filename[len] = '\0';
- FileList_ensureCapacity(fl, fl->size+1);
- fl->files[fl->size++] = filename;
-}
-
-static char *
-FileList_join(FileList fl, char sep)
-{
- int i;
- int size;
- char *path;
- char *p;
- for (i = 0, size = 1; i < fl->size; i++)
- size += strlen(fl->files[i]) + 1;
-
- path = JLI_MemAlloc(size);
-
- for (i = 0, p = path; i < fl->size; i++) {
- int len = strlen(fl->files[i]);
- if (i > 0) *p++ = sep;
- memcpy(p, fl->files[i], len);
- p += len;
- }
- *p = '\0';
-
- return path;
-}
-
-static FileList
-FileList_split(const char *path, char sep)
-{
- const char *p, *q;
- int len = strlen(path);
- int count;
- FileList fl;
- for (count = 1, p = path; p < path + len; p++)
- count += (*p == sep);
- fl = FileList_new(count);
- for (p = path;;) {
- for (q = p; q <= path + len; q++) {
- if (*q == sep || *q == '\0') {
- FileList_addSubstring(fl, p, q - p);
- if (*q == '\0')
- return fl;
- p = q + 1;
- }
- }
- }
-}
-
-static int
-isJarFileName(const char *filename)
-{
- int len = strlen(filename);
- return (len >= 4) &&
- (filename[len - 4] == '.') &&
- (equal(filename + len - 3, "jar") ||
- equal(filename + len - 3, "JAR")) &&
- /* Paranoia: Maybe filename is "DIR:foo.jar" */
- (strchr(filename, PATH_SEPARATOR) == NULL);
-}
-
-static char *
-wildcardConcat(const char *wildcard, const char *basename)
-{
- int wildlen = strlen(wildcard);
- int baselen = strlen(basename);
- char *filename = (char *) JLI_MemAlloc(wildlen + baselen);
- /* Replace the trailing '*' with basename */
- memcpy(filename, wildcard, wildlen-1);
- memcpy(filename+wildlen-1, basename, baselen+1);
- return filename;
-}
-
-static FileList
-wildcardFileList(const char *wildcard)
-{
- const char *basename;
- FileList fl = FileList_new(16);
- WildcardIterator it = WildcardIterator_for(wildcard);
- if (it == NULL) {
- FileList_free(fl);
- return NULL;
- }
- while ((basename = WildcardIterator_next(it)) != NULL)
- if (isJarFileName(basename))
- FileList_add(fl, wildcardConcat(wildcard, basename));
- WildcardIterator_close(it);
- return fl;
-}
-
-static int
-isWildcard(const char *filename)
-{
- int len = strlen(filename);
- return (len > 0) &&
- (filename[len - 1] == '*') &&
- (len == 1 || IS_FILE_SEPARATOR(filename[len - 2])) &&
- (! exists(filename));
-}
-
-static void
-FileList_expandWildcards(FileList fl)
-{
- int i, j;
- for (i = 0; i < fl->size; i++) {
- if (isWildcard(fl->files[i])) {
- FileList expanded = wildcardFileList(fl->files[i]);
- if (expanded != NULL && expanded->size > 0) {
- JLI_MemFree(fl->files[i]);
- FileList_ensureCapacity(fl, fl->size + expanded->size);
- for (j = fl->size - 1; j >= i+1; j--)
- fl->files[j+expanded->size-1] = fl->files[j];
- for (j = 0; j < expanded->size; j++)
- fl->files[i+j] = expanded->files[j];
- i += expanded->size - 1;
- fl->size += expanded->size - 1;
- /* fl expropriates expanded's elements. */
- expanded->size = 0;
- }
- FileList_free(expanded);
- }
- }
-}
-
-const char *
-JLI_WildcardExpandClasspath(const char *classpath)
-{
- char *expanded;
- FileList fl;
-
- if (strchr(classpath, '*') == NULL)
- return classpath;
- fl = FileList_split(classpath, PATH_SEPARATOR);
- FileList_expandWildcards(fl);
- expanded = FileList_join(fl, PATH_SEPARATOR);
- FileList_free(fl);
- if (getenv("_JAVA_LAUNCHER_DEBUG") != 0)
- printf("Expanded wildcards:\n"
- " before: \"%s\"\n"
- " after : \"%s\"\n",
- classpath, expanded);
- return expanded;
-}
-
-#ifdef DEBUG_WILDCARD
-static void
-wildcardExpandArgv(const char ***argv)
-{
- int i;
- for (i = 0; (*argv)[i]; i++) {
- if (equal((*argv)[i], "-cp") ||
- equal((*argv)[i], "-classpath")) {
- i++;
- (*argv)[i] = wildcardExpandClasspath((*argv)[i]);
- }
- }
-}
-
-static void
-debugPrintArgv(char *argv[])
-{
- int i;
- putchar('[');
- for (i = 0; argv[i]; i++) {
- if (i > 0) printf(", ");
- printf("\"%s\"", argv[i]);
- }
- printf("]\n");
-}
-
-int
-main(int argc, char *argv[])
-{
- argv[0] = "java";
- wildcardExpandArgv((const char***)&argv);
- debugPrintArgv(argv);
- /* execvp("java", argv); */
- return 0;
-}
-#endif /* DEBUG_WILDCARD */
-
-/* Cute little perl prototype implementation....
-
-my $sep = ($^O =~ /^(Windows|cygwin)/) ? ";" : ":";
-
-sub expand($) {
- opendir DIR, $_[0] or return $_[0];
- join $sep, map {"$_[0]/$_"} grep {/\.(jar|JAR)$/} readdir DIR;
-}
-
-sub munge($) {
- join $sep,
- map {(! -r $_ and s/[\/\\]+\*$//) ? expand $_ : $_} split $sep, $_[0];
-}
-
-for (my $i = 0; $i < @ARGV - 1; $i++) {
- $ARGV[$i+1] = munge $ARGV[$i+1] if $ARGV[$i] =~ /^-c(p|lasspath)$/;
-}
-
-$ENV{CLASSPATH} = munge $ENV{CLASSPATH} if exists $ENV{CLASSPATH};
-@ARGV = ("java", @ARGV);
-print "@ARGV\n";
-exec @ARGV;
-
-*/
diff --git a/hotspot/src/share/vm/c1/c1_Compiler.cpp b/hotspot/src/share/vm/c1/c1_Compiler.cpp
index 2820506182a..ecace4dad07 100644
--- a/hotspot/src/share/vm/c1/c1_Compiler.cpp
+++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp
@@ -77,30 +77,42 @@ void Compiler::initialize() {
}
-BufferBlob* Compiler::build_buffer_blob() {
+BufferBlob* Compiler::get_buffer_blob(ciEnv* env) {
+ // Allocate buffer blob once at startup since allocation for each
+ // compilation seems to be too expensive (at least on Intel win32).
+ BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob();
+ if (buffer_blob != NULL) {
+ return buffer_blob;
+ }
+
// setup CodeBuffer. Preallocate a BufferBlob of size
// NMethodSizeLimit plus some extra space for constants.
int code_buffer_size = Compilation::desired_max_code_buffer_size() +
Compilation::desired_max_constant_size();
- BufferBlob* blob = BufferBlob::create("Compiler1 temporary CodeBuffer",
- code_buffer_size);
- guarantee(blob != NULL, "must create initial code buffer");
- return blob;
+
+ buffer_blob = BufferBlob::create("Compiler1 temporary CodeBuffer",
+ code_buffer_size);
+ if (buffer_blob == NULL) {
+ CompileBroker::handle_full_code_cache();
+ env->record_failure("CodeCache is full");
+ } else {
+ CompilerThread::current()->set_buffer_blob(buffer_blob);
+ }
+
+ return buffer_blob;
}
void Compiler::compile_method(ciEnv* env, ciMethod* method, int entry_bci) {
- // Allocate buffer blob once at startup since allocation for each
- // compilation seems to be too expensive (at least on Intel win32).
- BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob();
+ BufferBlob* buffer_blob = Compiler::get_buffer_blob(env);
if (buffer_blob == NULL) {
- buffer_blob = build_buffer_blob();
- CompilerThread::current()->set_buffer_blob(buffer_blob);
+ return;
}
if (!is_initialized()) {
initialize();
}
+
// invoke compilation
{
// We are nested here because we need for the destructor
diff --git a/hotspot/src/share/vm/c1/c1_Compiler.hpp b/hotspot/src/share/vm/c1/c1_Compiler.hpp
index 9702a15ee4b..6e209d0034f 100644
--- a/hotspot/src/share/vm/c1/c1_Compiler.hpp
+++ b/hotspot/src/share/vm/c1/c1_Compiler.hpp
@@ -46,7 +46,7 @@ class Compiler: public AbstractCompiler {
virtual bool is_c1() { return true; };
- BufferBlob* build_buffer_blob();
+ BufferBlob* get_buffer_blob(ciEnv* env);
// Missing feature tests
virtual bool supports_native() { return true; }
diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp
index e274076d06b..53d1f5326a8 100644
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1261,7 +1261,7 @@ JRT_LEAF(int, Runtime1::arraycopy(oopDesc* src, int src_pos, oopDesc* dst, int d
if (length == 0) return ac_ok;
if (src->is_typeArray()) {
- Klass* const klass_oop = src->klass();
+ Klass* klass_oop = src->klass();
if (klass_oop != dst->klass()) return ac_failed;
TypeArrayKlass* klass = TypeArrayKlass::cast(klass_oop);
const int l2es = klass->log2_element_size();
diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp
index d74e3693ae1..d74e484c66e 100644
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp
@@ -211,12 +211,41 @@ bool ciInstanceKlass::is_java_lang_Object() const {
// ------------------------------------------------------------------
// ciInstanceKlass::uses_default_loader
-bool ciInstanceKlass::uses_default_loader() {
+bool ciInstanceKlass::uses_default_loader() const {
// Note: We do not need to resolve the handle or enter the VM
// in order to test null-ness.
return _loader == NULL;
}
+// ------------------------------------------------------------------
+
+/**
+ * Return basic type of boxed value for box klass or T_OBJECT if not.
+ */
+BasicType ciInstanceKlass::box_klass_type() const {
+ if (uses_default_loader() && is_loaded()) {
+ return SystemDictionary::box_klass_type(get_Klass());
+ } else {
+ return T_OBJECT;
+ }
+}
+
+/**
+ * Is this boxing klass?
+ */
+bool ciInstanceKlass::is_box_klass() const {
+ return is_java_primitive(box_klass_type());
+}
+
+/**
+ * Is this boxed value offset?
+ */
+bool ciInstanceKlass::is_boxed_value_offset(int offset) const {
+ BasicType bt = box_klass_type();
+ return is_java_primitive(bt) &&
+ (offset == java_lang_boxing_object::value_offset_in_bytes(bt));
+}
+
// ------------------------------------------------------------------
// ciInstanceKlass::is_in_package
//
diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp
index f7aeba2df3b..0b244a2972c 100644
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp
@@ -217,10 +217,14 @@ public:
ciInstanceKlass* implementor();
// Is the defining class loader of this class the default loader?
- bool uses_default_loader();
+ bool uses_default_loader() const;
bool is_java_lang_Object() const;
+ BasicType box_klass_type() const;
+ bool is_box_klass() const;
+ bool is_boxed_value_offset(int offset) const;
+
// Is this klass in the given package?
bool is_in_package(const char* packagename) {
return is_in_package(packagename, (int) strlen(packagename));
diff --git a/hotspot/src/share/vm/ci/ciMethod.cpp b/hotspot/src/share/vm/ci/ciMethod.cpp
index 780f4ad868f..d0363250ee6 100644
--- a/hotspot/src/share/vm/ci/ciMethod.cpp
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp
@@ -1179,6 +1179,44 @@ bool ciMethod::has_jsrs () const { FETCH_FLAG_FROM_VM(has_jsrs);
bool ciMethod::is_accessor () const { FETCH_FLAG_FROM_VM(is_accessor); }
bool ciMethod::is_initializer () const { FETCH_FLAG_FROM_VM(is_initializer); }
+bool ciMethod::is_boxing_method() const {
+ if (holder()->is_box_klass()) {
+ switch (intrinsic_id()) {
+ case vmIntrinsics::_Boolean_valueOf:
+ case vmIntrinsics::_Byte_valueOf:
+ case vmIntrinsics::_Character_valueOf:
+ case vmIntrinsics::_Short_valueOf:
+ case vmIntrinsics::_Integer_valueOf:
+ case vmIntrinsics::_Long_valueOf:
+ case vmIntrinsics::_Float_valueOf:
+ case vmIntrinsics::_Double_valueOf:
+ return true;
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
+bool ciMethod::is_unboxing_method() const {
+ if (holder()->is_box_klass()) {
+ switch (intrinsic_id()) {
+ case vmIntrinsics::_booleanValue:
+ case vmIntrinsics::_byteValue:
+ case vmIntrinsics::_charValue:
+ case vmIntrinsics::_shortValue:
+ case vmIntrinsics::_intValue:
+ case vmIntrinsics::_longValue:
+ case vmIntrinsics::_floatValue:
+ case vmIntrinsics::_doubleValue:
+ return true;
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
BCEscapeAnalyzer *ciMethod::get_bcea() {
#ifdef COMPILER2
if (_bcea == NULL) {
diff --git a/hotspot/src/share/vm/ci/ciMethod.hpp b/hotspot/src/share/vm/ci/ciMethod.hpp
index 46ea500b551..8305547c56f 100644
--- a/hotspot/src/share/vm/ci/ciMethod.hpp
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp
@@ -298,6 +298,8 @@ class ciMethod : public ciMetadata {
bool is_initializer () const;
bool can_be_statically_bound() const { return _can_be_statically_bound; }
void dump_replay_data(outputStream* st);
+ bool is_boxing_method() const;
+ bool is_unboxing_method() const;
// Print the bytecodes of this method.
void print_codes_on(outputStream* st);
diff --git a/hotspot/src/share/vm/ci/ciReplay.cpp b/hotspot/src/share/vm/ci/ciReplay.cpp
index a314f35f821..71813b8f338 100644
--- a/hotspot/src/share/vm/ci/ciReplay.cpp
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp
@@ -492,7 +492,9 @@ class CompileReplay : public StackObj {
}
Klass* k = parse_klass(CHECK);
rec->oops_offsets[i] = offset;
- rec->oops_handles[i] = (jobject)(new KlassHandle(THREAD, k));
+ KlassHandle *kh = NEW_C_HEAP_OBJ(KlassHandle, mtCompiler);
+ ::new ((void*)kh) KlassHandle(THREAD, k);
+ rec->oops_handles[i] = (jobject)kh;
}
}
diff --git a/hotspot/src/share/vm/classfile/altHashing.cpp b/hotspot/src/share/vm/classfile/altHashing.cpp
index df2c53e5501..8dfc3153ca4 100644
--- a/hotspot/src/share/vm/classfile/altHashing.cpp
+++ b/hotspot/src/share/vm/classfile/altHashing.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -242,8 +242,8 @@ static const juint MURMUR3_32_X86_CHECK_VALUE = 0xB0F57EE3;
void AltHashing::testMurmur3_32_ByteArray() {
// printf("testMurmur3_32_ByteArray\n");
- jbyte* vector = new jbyte[256];
- jbyte* hashes = new jbyte[4 * 256];
+ jbyte vector[256];
+ jbyte hashes[4 * 256];
for (int i = 0; i < 256; i++) {
vector[i] = (jbyte) i;
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index c93d72de623..6b2ddd140c6 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -1719,15 +1719,28 @@ void ClassFileParser::parse_annotations(u1* buffer, int limit,
coll->set_annotation(id);
if (id == AnnotationCollector::_sun_misc_Contended) {
+ // @Contended can optionally specify the contention group.
+ //
+ // Contended group defines the equivalence class over the fields:
+ // the fields within the same contended group are not treated distinct.
+ // The only exception is default group, which does not incur the
+ // equivalence. Naturally, contention group for classes is meaningless.
+ //
+ // While the contention group is specified as String, annotation
+ // values are already interned, and we might as well use the constant
+ // pool index as the group tag.
+ //
+ u2 group_index = 0; // default contended group
if (count == 1
&& s_size == (index - index0) // match size
&& s_tag_val == *(abase + tag_off)
&& member == vmSymbols::value_name()) {
- u2 group_index = Bytes::get_Java_u2(abase + s_con_off);
- coll->set_contended_group(group_index);
- } else {
- coll->set_contended_group(0); // default contended group
+ group_index = Bytes::get_Java_u2(abase + s_con_off);
+ if (_cp->symbol_at(group_index)->utf8_length() == 0) {
+ group_index = 0; // default contended group
+ }
}
+ coll->set_contended_group(group_index);
}
}
}
@@ -3028,7 +3041,7 @@ AnnotationArray* ClassFileParser::assemble_annotations(u1* runtime_visible_annot
}
-#ifndef PRODUCT
+#ifdef ASSERT
static void parseAndPrintGenericSignatures(
instanceKlassHandle this_klass, TRAPS) {
assert(ParseAllGenericSignatures == true, "Shouldn't call otherwise");
@@ -3053,7 +3066,7 @@ static void parseAndPrintGenericSignatures(
}
}
}
-#endif // ndef PRODUCT
+#endif // def ASSERT
instanceKlassHandle ClassFileParser::parse_super_class(int super_class_index,
@@ -3108,15 +3121,8 @@ void ClassFileParser::layout_fields(Handle class_loader,
FieldLayoutInfo* info,
TRAPS) {
- // get the padding width from the option
- // TODO: Ask VM about specific CPU we are running on
- int pad_size = ContendedPaddingWidth;
-
// Field size and offset computation
int nonstatic_field_size = _super_klass() == NULL ? 0 : _super_klass()->nonstatic_field_size();
-#ifndef PRODUCT
- int orig_nonstatic_field_size = 0;
-#endif
int next_static_oop_offset;
int next_static_double_offset;
int next_static_word_offset;
@@ -3127,13 +3133,14 @@ void ClassFileParser::layout_fields(Handle class_loader,
int next_nonstatic_word_offset;
int next_nonstatic_short_offset;
int next_nonstatic_byte_offset;
- int next_nonstatic_type_offset;
int first_nonstatic_oop_offset;
- int first_nonstatic_field_offset;
int next_nonstatic_field_offset;
int next_nonstatic_padded_offset;
// Count the contended fields by type.
+ //
+ // We ignore static fields, because @Contended is not supported for them.
+ // The layout code below will also ignore the static fields.
int nonstatic_contended_count = 0;
FieldAllocationCount fac_contended;
for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) {
@@ -3165,16 +3172,17 @@ void ClassFileParser::layout_fields(Handle class_loader,
next_static_byte_offset = next_static_short_offset +
((fac->count[STATIC_SHORT]) * BytesPerShort);
- first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() +
- nonstatic_field_size * heapOopSize;
+ int nonstatic_fields_start = instanceOopDesc::base_offset_in_bytes() +
+ nonstatic_field_size * heapOopSize;
- // class is contended, pad before all the fields
+ next_nonstatic_field_offset = nonstatic_fields_start;
+
+ // Class is contended, pad before all the fields
if (parsed_annotations->is_contended()) {
- first_nonstatic_field_offset += pad_size;
+ next_nonstatic_field_offset += ContendedPaddingWidth;
}
- next_nonstatic_field_offset = first_nonstatic_field_offset;
-
+ // Compute the non-contended fields count
unsigned int nonstatic_double_count = fac->count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE];
unsigned int nonstatic_word_count = fac->count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD];
unsigned int nonstatic_short_count = fac->count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT];
@@ -3201,25 +3209,6 @@ void ClassFileParser::layout_fields(Handle class_loader,
first_nonstatic_oop_offset = 0; // will be set for first oop field
-#ifndef PRODUCT
- if( PrintCompactFieldsSavings ) {
- next_nonstatic_double_offset = next_nonstatic_field_offset +
- (nonstatic_oop_count * heapOopSize);
- if ( nonstatic_double_count > 0 ) {
- next_nonstatic_double_offset = align_size_up(next_nonstatic_double_offset, BytesPerLong);
- }
- next_nonstatic_word_offset = next_nonstatic_double_offset +
- (nonstatic_double_count * BytesPerLong);
- next_nonstatic_short_offset = next_nonstatic_word_offset +
- (nonstatic_word_count * BytesPerInt);
- next_nonstatic_byte_offset = next_nonstatic_short_offset +
- (nonstatic_short_count * BytesPerShort);
- next_nonstatic_type_offset = align_size_up((next_nonstatic_byte_offset +
- nonstatic_byte_count ), heapOopSize );
- orig_nonstatic_field_size = nonstatic_field_size +
- ((next_nonstatic_type_offset - first_nonstatic_field_offset)/heapOopSize);
- }
-#endif
bool compact_fields = CompactFields;
int allocation_style = FieldsAllocationStyle;
if( allocation_style < 0 || allocation_style > 2 ) { // Out of range?
@@ -3251,6 +3240,7 @@ void ClassFileParser::layout_fields(Handle class_loader,
compact_fields = false; // Don't compact fields
}
+ // Rearrange fields for a given allocation style
if( allocation_style == 0 ) {
// Fields order: oops, longs/doubles, ints, shorts/chars, bytes, padded fields
next_nonstatic_oop_offset = next_nonstatic_field_offset;
@@ -3291,6 +3281,8 @@ void ClassFileParser::layout_fields(Handle class_loader,
int nonstatic_short_space_offset;
int nonstatic_byte_space_offset;
+ // Try to squeeze some of the fields into the gaps due to
+ // long/double alignment.
if( nonstatic_double_count > 0 ) {
int offset = next_nonstatic_double_offset;
next_nonstatic_double_offset = align_size_up(offset, BytesPerLong);
@@ -3464,7 +3456,7 @@ void ClassFileParser::layout_fields(Handle class_loader,
// if there is at least one contended field, we need to have pre-padding for them
if (nonstatic_contended_count > 0) {
- next_nonstatic_padded_offset += pad_size;
+ next_nonstatic_padded_offset += ContendedPaddingWidth;
}
// collect all contended groups
@@ -3543,7 +3535,7 @@ void ClassFileParser::layout_fields(Handle class_loader,
// the fields within the same contended group are not inter-padded.
// The only exception is default group, which does not incur the
// equivalence, and so requires intra-padding.
- next_nonstatic_padded_offset += pad_size;
+ next_nonstatic_padded_offset += ContendedPaddingWidth;
}
fs.set_offset(real_offset);
@@ -3555,7 +3547,7 @@ void ClassFileParser::layout_fields(Handle class_loader,
// subclass fields and/or adjacent object.
// If this was the default group, the padding is already in place.
if (current_group != 0) {
- next_nonstatic_padded_offset += pad_size;
+ next_nonstatic_padded_offset += ContendedPaddingWidth;
}
}
@@ -3569,22 +3561,22 @@ void ClassFileParser::layout_fields(Handle class_loader,
// This helps to alleviate memory contention effects for subclass fields
// and/or adjacent object.
if (parsed_annotations->is_contended()) {
- notaligned_offset += pad_size;
+ notaligned_offset += ContendedPaddingWidth;
}
- int next_static_type_offset = align_size_up(next_static_byte_offset, wordSize);
- int static_field_size = (next_static_type_offset -
- InstanceMirrorKlass::offset_of_static_fields()) / wordSize;
+ int nonstatic_fields_end = align_size_up(notaligned_offset, heapOopSize);
+ int instance_end = align_size_up(notaligned_offset, wordSize);
+ int static_fields_end = align_size_up(next_static_byte_offset, wordSize);
- next_nonstatic_type_offset = align_size_up(notaligned_offset, heapOopSize );
- nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset
- - first_nonstatic_field_offset)/heapOopSize);
+ int static_field_size = (static_fields_end -
+ InstanceMirrorKlass::offset_of_static_fields()) / wordSize;
+ nonstatic_field_size = nonstatic_field_size +
+ (nonstatic_fields_end - nonstatic_fields_start) / heapOopSize;
- next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize );
- int instance_size = align_object_size(next_nonstatic_type_offset / wordSize);
+ int instance_size = align_object_size(instance_end / wordSize);
assert(instance_size == align_object_size(align_size_up(
- (instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize + ((parsed_annotations->is_contended()) ? pad_size : 0)),
+ (instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize),
wordSize) / wordSize), "consistent layout helper value");
// Number of non-static oop map blocks allocated at end of klass.
@@ -3593,29 +3585,14 @@ void ClassFileParser::layout_fields(Handle class_loader,
first_nonstatic_oop_offset);
#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,
- orig_nonstatic_field_size*heapOopSize,
- _class_name);
- } else if( nonstatic_field_size > orig_nonstatic_field_size ) {
- tty->print("[Wasted %d over %d bytes in %s]\n",
- (nonstatic_field_size - orig_nonstatic_field_size)*heapOopSize,
- orig_nonstatic_field_size*heapOopSize,
- _class_name);
- }
- }
-
if (PrintFieldLayout) {
print_field_layout(_class_name,
_fields,
_cp,
instance_size,
- first_nonstatic_field_offset,
- next_nonstatic_field_offset,
- next_static_type_offset);
+ nonstatic_fields_start,
+ nonstatic_fields_end,
+ static_fields_end);
}
#endif
diff --git a/hotspot/src/share/vm/classfile/dictionary.cpp b/hotspot/src/share/vm/classfile/dictionary.cpp
index 92d9fb438fe..b79cda74f0c 100644
--- a/hotspot/src/share/vm/classfile/dictionary.cpp
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp
@@ -253,22 +253,6 @@ void Dictionary::classes_do(void f(Klass*, TRAPS), TRAPS) {
}
}
-
-// All classes, and their class loaders
-// (added for helpers that use HandleMarks and ResourceMarks)
-// Don't iterate over placeholders
-void Dictionary::classes_do(void f(Klass*, ClassLoaderData*, TRAPS), TRAPS) {
- for (int index = 0; index < table_size(); index++) {
- for (DictionaryEntry* probe = bucket(index);
- probe != NULL;
- probe = probe->next()) {
- Klass* k = probe->klass();
- f(k, probe->loader_data(), CHECK);
- }
- }
-}
-
-
// All classes, and their class loaders
// Don't iterate over placeholders
void Dictionary::classes_do(void f(Klass*, ClassLoaderData*)) {
diff --git a/hotspot/src/share/vm/classfile/dictionary.hpp b/hotspot/src/share/vm/classfile/dictionary.hpp
index 8820b251700..53629a015fd 100644
--- a/hotspot/src/share/vm/classfile/dictionary.hpp
+++ b/hotspot/src/share/vm/classfile/dictionary.hpp
@@ -90,7 +90,6 @@ public:
void classes_do(void f(Klass*));
void classes_do(void f(Klass*, TRAPS), TRAPS);
void classes_do(void f(Klass*, ClassLoaderData*));
- void classes_do(void f(Klass*, ClassLoaderData*, TRAPS), TRAPS);
void methods_do(void f(Method*));
diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp
index b36432a3c10..5fbd184a421 100644
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp
@@ -35,7 +35,6 @@
#include "oops/oop.inline2.hpp"
#include "runtime/mutexLocker.hpp"
#include "utilities/hashtable.inline.hpp"
-#include "utilities/numberSeq.hpp"
// --------------------------------------------------------------------------
@@ -451,21 +450,7 @@ void SymbolTable::verify() {
}
void SymbolTable::dump(outputStream* st) {
- NumberSeq summary;
- for (int i = 0; i < the_table()->table_size(); ++i) {
- int count = 0;
- for (HashtableEntry* e = the_table()->bucket(i);
- e != NULL; e = e->next()) {
- count++;
- }
- summary.add((double)count);
- }
- st->print_cr("SymbolTable statistics:");
- st->print_cr("Number of buckets : %7d", summary.num());
- st->print_cr("Average bucket size : %7.0f", summary.avg());
- st->print_cr("Variance of bucket size : %7.0f", summary.variance());
- st->print_cr("Std. dev. of bucket size: %7.0f", summary.sd());
- st->print_cr("Maximum bucket size : %7.0f", summary.maximum());
+ the_table()->dump_table(st, "SymbolTable");
}
@@ -814,21 +799,7 @@ void StringTable::verify() {
}
void StringTable::dump(outputStream* st) {
- NumberSeq summary;
- for (int i = 0; i < the_table()->table_size(); ++i) {
- HashtableEntry* p = the_table()->bucket(i);
- int count = 0;
- for ( ; p != NULL; p = p->next()) {
- count++;
- }
- summary.add((double)count);
- }
- st->print_cr("StringTable statistics:");
- st->print_cr("Number of buckets : %7d", summary.num());
- st->print_cr("Average bucket size : %7.0f", summary.avg());
- st->print_cr("Variance of bucket size : %7.0f", summary.variance());
- st->print_cr("Std. dev. of bucket size: %7.0f", summary.sd());
- st->print_cr("Maximum bucket size : %7.0f", summary.maximum());
+ the_table()->dump_table(st, "StringTable");
}
diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp
index 3aa1b77c92a..682309035f3 100644
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp
@@ -1747,13 +1747,6 @@ void SystemDictionary::classes_do(void f(Klass*, ClassLoaderData*)) {
dictionary()->classes_do(f);
}
-// All classes, and their class loaders
-// (added for helpers that use HandleMarks and ResourceMarks)
-// Don't iterate over placeholders
-void SystemDictionary::classes_do(void f(Klass*, ClassLoaderData*, TRAPS), TRAPS) {
- dictionary()->classes_do(f, CHECK);
-}
-
void SystemDictionary::placeholders_do(void f(Symbol*)) {
placeholders()->entries_do(f);
}
diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp
index f1ac0b4e684..98e8f433e14 100644
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp
@@ -313,10 +313,7 @@ public:
static void classes_do(void f(Klass*, TRAPS), TRAPS);
// All classes, and their class loaders
static void classes_do(void f(Klass*, ClassLoaderData*));
- // All classes, and their class loaders
- // (added for helpers that use HandleMarks and ResourceMarks)
- static void classes_do(void f(Klass*, ClassLoaderData*, TRAPS), TRAPS);
- // All entries in the placeholder table and their class loaders
+
static void placeholders_do(void f(Symbol*));
// Iterate over all methods in all klasses in dictionary
diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp
index fda30acd158..015b8093d21 100644
--- a/hotspot/src/share/vm/classfile/verifier.cpp
+++ b/hotspot/src/share/vm/classfile/verifier.cpp
@@ -362,7 +362,7 @@ void TypeOrigin::print_on(outputStream* str) const {
}
#endif
-void ErrorContext::details(outputStream* ss, Method* method) const {
+void ErrorContext::details(outputStream* ss, const Method* method) const {
if (is_valid()) {
ss->print_cr("");
ss->print_cr("Exception Details:");
@@ -435,7 +435,7 @@ void ErrorContext::reason_details(outputStream* ss) const {
ss->print_cr("");
}
-void ErrorContext::location_details(outputStream* ss, Method* method) const {
+void ErrorContext::location_details(outputStream* ss, const Method* method) const {
if (_bci != -1 && method != NULL) {
streamIndentor si(ss);
const char* bytecode_name = "";
@@ -470,7 +470,7 @@ void ErrorContext::frame_details(outputStream* ss) const {
}
}
-void ErrorContext::bytecode_details(outputStream* ss, Method* method) const {
+void ErrorContext::bytecode_details(outputStream* ss, const Method* method) const {
if (method != NULL) {
streamIndentor si(ss);
ss->indent().print_cr("Bytecode:");
@@ -479,7 +479,7 @@ void ErrorContext::bytecode_details(outputStream* ss, Method* method) const {
}
}
-void ErrorContext::handler_details(outputStream* ss, Method* method) const {
+void ErrorContext::handler_details(outputStream* ss, const Method* method) const {
if (method != NULL) {
streamIndentor si(ss);
ExceptionTable table(method);
@@ -494,7 +494,7 @@ void ErrorContext::handler_details(outputStream* ss, Method* method) const {
}
}
-void ErrorContext::stackmap_details(outputStream* ss, Method* method) const {
+void ErrorContext::stackmap_details(outputStream* ss, const Method* method) const {
if (method != NULL && method->has_stackmap_table()) {
streamIndentor si(ss);
ss->indent().print_cr("Stackmap Table:");
diff --git a/hotspot/src/share/vm/classfile/verifier.hpp b/hotspot/src/share/vm/classfile/verifier.hpp
index bdab7a7e2f5..bfab2c83085 100644
--- a/hotspot/src/share/vm/classfile/verifier.hpp
+++ b/hotspot/src/share/vm/classfile/verifier.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -224,7 +224,7 @@ class ErrorContext VALUE_OBJ_CLASS_SPEC {
_expected.reset_frame();
}
- void details(outputStream* ss, Method* method) const;
+ void details(outputStream* ss, const Method* method) const;
#ifdef ASSERT
void print_on(outputStream* str) const {
@@ -237,12 +237,12 @@ class ErrorContext VALUE_OBJ_CLASS_SPEC {
#endif
private:
- void location_details(outputStream* ss, Method* method) const;
+ void location_details(outputStream* ss, const Method* method) const;
void reason_details(outputStream* ss) const;
void frame_details(outputStream* ss) const;
- void bytecode_details(outputStream* ss, Method* method) const;
- void handler_details(outputStream* ss, Method* method) const;
- void stackmap_details(outputStream* ss, Method* method) const;
+ void bytecode_details(outputStream* ss, const Method* method) const;
+ void handler_details(outputStream* ss, const Method* method) const;
+ void stackmap_details(outputStream* ss, const Method* method) const;
};
// A new instance of this class is created for each class being verified
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.cpp b/hotspot/src/share/vm/classfile/vmSymbols.cpp
index 92939ea2487..cc38c6d2cd6 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.cpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp
@@ -49,7 +49,7 @@ extern "C" {
}
}
-#ifndef PRODUCT
+#ifdef ASSERT
#define VM_SYMBOL_ENUM_NAME_BODY(name, string) #name "\0"
static const char* vm_symbol_enum_names =
VM_SYMBOLS_DO(VM_SYMBOL_ENUM_NAME_BODY, VM_ALIAS_IGNORE)
@@ -64,7 +64,7 @@ static const char* vm_symbol_enum_name(vmSymbols::SID sid) {
}
return string;
}
-#endif //PRODUCT
+#endif //ASSERT
// Put all the VM symbol strings in one place.
// Makes for a more compact libjvm.
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp
index 428b2940f61..9fd9aff5e22 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp
@@ -68,7 +68,7 @@
template(java_lang_Float, "java/lang/Float") \
template(java_lang_Double, "java/lang/Double") \
template(java_lang_Byte, "java/lang/Byte") \
- template(java_lang_Byte_Cache, "java/lang/Byte$ByteCache") \
+ template(java_lang_Byte_ByteCache, "java/lang/Byte$ByteCache") \
template(java_lang_Short, "java/lang/Short") \
template(java_lang_Short_ShortCache, "java/lang/Short$ShortCache") \
template(java_lang_Integer, "java/lang/Integer") \
diff --git a/hotspot/src/share/vm/code/codeCache.cpp b/hotspot/src/share/vm/code/codeCache.cpp
index f7be307b254..44d65e23345 100644
--- a/hotspot/src/share/vm/code/codeCache.cpp
+++ b/hotspot/src/share/vm/code/codeCache.cpp
@@ -622,6 +622,15 @@ address CodeCache::last_address() {
return (address)_heap->high();
}
+/**
+ * Returns the reverse free ratio. E.g., if 25% (1/4) of the code cache
+ * is free, reverse_free_ratio() returns 4.
+ */
+double CodeCache::reverse_free_ratio() {
+ double unallocated_capacity = (double)(CodeCache::unallocated_capacity() - CodeCacheMinimumFreeSpace);
+ double max_capacity = (double)CodeCache::max_capacity();
+ return max_capacity / unallocated_capacity;
+}
void icache_init();
diff --git a/hotspot/src/share/vm/code/codeCache.hpp b/hotspot/src/share/vm/code/codeCache.hpp
index 38799019b8f..3dde92702e3 100644
--- a/hotspot/src/share/vm/code/codeCache.hpp
+++ b/hotspot/src/share/vm/code/codeCache.hpp
@@ -163,6 +163,7 @@ class CodeCache : AllStatic {
static size_t max_capacity() { return _heap->max_capacity(); }
static size_t unallocated_capacity() { return _heap->unallocated_capacity(); }
static bool needs_flushing() { return unallocated_capacity() < CodeCacheFlushingMinimumFreeSpace; }
+ static double reverse_free_ratio();
static bool needs_cache_clean() { return _needs_cache_clean; }
static void set_needs_cache_clean(bool v) { _needs_cache_clean = v; }
diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp
index 60bc88b7734..597a7ac548e 100644
--- a/hotspot/src/share/vm/code/nmethod.cpp
+++ b/hotspot/src/share/vm/code/nmethod.cpp
@@ -1794,6 +1794,19 @@ void nmethod::metadata_do(void f(Metadata*)) {
Metadata* md = r->metadata_value();
f(md);
}
+ } else if (iter.type() == relocInfo::virtual_call_type) {
+ // Check compiledIC holders associated with this nmethod
+ CompiledIC *ic = CompiledIC_at(iter.reloc());
+ if (ic->is_icholder_call()) {
+ CompiledICHolder* cichk = ic->cached_icholder();
+ f(cichk->holder_method());
+ f(cichk->holder_klass());
+ } else {
+ Metadata* ic_oop = ic->cached_metadata();
+ if (ic_oop != NULL) {
+ f(ic_oop);
+ }
+ }
}
}
}
@@ -1804,6 +1817,7 @@ void nmethod::metadata_do(void f(Metadata*)) {
Metadata* md = *p;
f(md);
}
+
// Call function Method*, not embedded in these other places.
if (_method != NULL) f(_method);
}
diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp
index 086bff881cd..ad097d96a9b 100644
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp
@@ -1854,8 +1854,10 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
tty->print("%7d ", (int) tty->time_stamp().milliseconds()); // print timestamp
tty->print("%4d ", compile_id); // print compilation number
tty->print("%s ", (is_osr ? "%" : " "));
- int code_size = (task->code() == NULL) ? 0 : task->code()->total_size();
- tty->print_cr("size: %d time: %d inlined: %d bytes", code_size, (int)time.milliseconds(), task->num_inlined_bytecodes());
+ if (task->code() != NULL) {
+ tty->print("size: %d(%d) ", task->code()->total_size(), task->code()->insts_size());
+ }
+ tty->print_cr("time: %d inlined: %d bytes", (int)time.milliseconds(), task->num_inlined_bytecodes());
}
if (PrintCodeCacheOnCompilation)
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp
index 01e0e8745a1..cfba2376ea8 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp
@@ -50,14 +50,6 @@ AdaptiveFreeList::AdaptiveFreeList() : FreeList(), _hint(0) {
init_statistics();
}
-template
-AdaptiveFreeList::AdaptiveFreeList(Chunk* fc) : FreeList(fc), _hint(0) {
- init_statistics();
-#ifndef PRODUCT
- _allocation_stats.set_returned_bytes(size() * HeapWordSize);
-#endif
-}
-
template
void AdaptiveFreeList::initialize() {
FreeList::initialize();
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp
index 8b56bb11d76..7215119aef5 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp
@@ -55,7 +55,6 @@ class AdaptiveFreeList : public FreeList {
public:
AdaptiveFreeList();
- AdaptiveFreeList(Chunk* fc);
using FreeList::assert_proper_lock_protection;
#ifdef ASSERT
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp
index e57d405e5d0..c2aafb7bc20 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,7 @@ ConcurrentMarkSweepPolicy::ConcurrentMarkSweepPolicy() {
}
void ConcurrentMarkSweepPolicy::initialize_generations() {
- _generations = new GenerationSpecPtr[number_of_generations()];
+ _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC, 0, AllocFailStrategy::RETURN_NULL);
if (_generations == NULL)
vm_exit_during_initialization("Unable to allocate gen spec");
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
index cb8b73743e1..d91f907a2c0 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
@@ -153,8 +153,6 @@ CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs,
_indexedFreeListParLocks[i] = new Mutex(Mutex::leaf - 1, // == ExpandHeap_lock - 1
"a freelist par lock",
true);
- if (_indexedFreeListParLocks[i] == NULL)
- vm_exit_during_initialization("Could not allocate a par lock");
DEBUG_ONLY(
_indexedFreeList[i].set_protecting_lock(_indexedFreeListParLocks[i]);
)
@@ -285,6 +283,7 @@ void CompactibleFreeListSpace::reset(MemRegion mr) {
_bt.verify_not_unallocated((HeapWord*)fc, fc->size());
_indexedFreeList[mr.word_size()].return_chunk_at_head(fc);
}
+ coalBirth(mr.word_size());
}
_promoInfo.reset();
_smallLinearAllocBlock._ptr = NULL;
@@ -1762,7 +1761,7 @@ CompactibleFreeListSpace::addChunkToFreeListsAtEndRecordingStats(
}
ec->set_size(size);
debug_only(ec->mangleFreed(size));
- if (size < SmallForDictionary) {
+ if (size < SmallForDictionary && ParallelGCThreads != 0) {
lock = _indexedFreeListParLocks[size];
}
MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag);
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
index 0f92b3602de..2cc054e9123 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
@@ -692,8 +692,7 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
_cmsGen ->init_initiating_occupancy(CMSInitiatingOccupancyFraction, CMSTriggerRatio);
// Clip CMSBootstrapOccupancy between 0 and 100.
- _bootstrap_occupancy = ((double)MIN2((uintx)100, MAX2((uintx)0, CMSBootstrapOccupancy)))
- /(double)100;
+ _bootstrap_occupancy = ((double)CMSBootstrapOccupancy)/(double)100;
_full_gcs_since_conc_gc = 0;
@@ -3382,7 +3381,6 @@ bool ConcurrentMarkSweepGeneration::grow_by(size_t bytes) {
assert_locked_or_safepoint(Heap_lock);
bool result = _virtual_space.expand_by(bytes);
if (result) {
- HeapWord* old_end = _cmsSpace->end();
size_t new_word_size =
heap_word_size(_virtual_space.committed_size());
MemRegion mr(_cmsSpace->bottom(), new_word_size);
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
index e930b586370..8d627c75792 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
@@ -485,10 +485,6 @@ class CMSIsAliveClosure: public BoolObjectClosure {
assert(!span.is_empty(), "Empty span could spell trouble");
}
- void do_object(oop obj) {
- assert(false, "not to be invoked");
- }
-
bool do_object_b(oop obj);
};
@@ -1536,9 +1532,6 @@ class ScanMarkedObjectsAgainClosure: public UpwardsObjectClosure {
_bit_map(bit_map),
_par_scan_closure(cl) { }
- void do_object(oop obj) {
- guarantee(false, "Call do_object_b(oop, MemRegion) instead");
- }
bool do_object_b(oop obj) {
guarantee(false, "Call do_object_b(oop, MemRegion) form instead");
return false;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
index 39e5a2792b5..137f76c0974 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
@@ -4515,7 +4515,8 @@ G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name)
_total_used_bytes(0), _total_capacity_bytes(0),
_total_prev_live_bytes(0), _total_next_live_bytes(0),
_hum_used_bytes(0), _hum_capacity_bytes(0),
- _hum_prev_live_bytes(0), _hum_next_live_bytes(0) {
+ _hum_prev_live_bytes(0), _hum_next_live_bytes(0),
+ _total_remset_bytes(0) {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
MemRegion g1_committed = g1h->g1_committed();
MemRegion g1_reserved = g1h->g1_reserved();
@@ -4533,23 +4534,25 @@ G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name)
HeapRegion::GrainBytes);
_out->print_cr(G1PPRL_LINE_PREFIX);
_out->print_cr(G1PPRL_LINE_PREFIX
- G1PPRL_TYPE_H_FORMAT
- G1PPRL_ADDR_BASE_H_FORMAT
- G1PPRL_BYTE_H_FORMAT
- G1PPRL_BYTE_H_FORMAT
- G1PPRL_BYTE_H_FORMAT
- G1PPRL_DOUBLE_H_FORMAT,
- "type", "address-range",
- "used", "prev-live", "next-live", "gc-eff");
+ G1PPRL_TYPE_H_FORMAT
+ G1PPRL_ADDR_BASE_H_FORMAT
+ G1PPRL_BYTE_H_FORMAT
+ G1PPRL_BYTE_H_FORMAT
+ G1PPRL_BYTE_H_FORMAT
+ G1PPRL_DOUBLE_H_FORMAT
+ G1PPRL_BYTE_H_FORMAT,
+ "type", "address-range",
+ "used", "prev-live", "next-live", "gc-eff", "remset");
_out->print_cr(G1PPRL_LINE_PREFIX
- G1PPRL_TYPE_H_FORMAT
- G1PPRL_ADDR_BASE_H_FORMAT
- G1PPRL_BYTE_H_FORMAT
- G1PPRL_BYTE_H_FORMAT
- G1PPRL_BYTE_H_FORMAT
- G1PPRL_DOUBLE_H_FORMAT,
- "", "",
- "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)");
+ G1PPRL_TYPE_H_FORMAT
+ G1PPRL_ADDR_BASE_H_FORMAT
+ G1PPRL_BYTE_H_FORMAT
+ G1PPRL_BYTE_H_FORMAT
+ G1PPRL_BYTE_H_FORMAT
+ G1PPRL_DOUBLE_H_FORMAT
+ G1PPRL_BYTE_H_FORMAT,
+ "", "",
+ "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)", "(bytes)");
}
// It takes as a parameter a reference to one of the _hum_* fields, it
@@ -4591,6 +4594,7 @@ bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) {
size_t prev_live_bytes = r->live_bytes();
size_t next_live_bytes = r->next_live_bytes();
double gc_eff = r->gc_efficiency();
+ size_t remset_bytes = r->rem_set()->mem_size();
if (r->used() == 0) {
type = "FREE";
} else if (r->is_survivor()) {
@@ -4624,6 +4628,7 @@ bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) {
_total_capacity_bytes += capacity_bytes;
_total_prev_live_bytes += prev_live_bytes;
_total_next_live_bytes += next_live_bytes;
+ _total_remset_bytes += remset_bytes;
// Print a line for this particular region.
_out->print_cr(G1PPRL_LINE_PREFIX
@@ -4632,14 +4637,17 @@ bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) {
G1PPRL_BYTE_FORMAT
G1PPRL_BYTE_FORMAT
G1PPRL_BYTE_FORMAT
- G1PPRL_DOUBLE_FORMAT,
+ G1PPRL_DOUBLE_FORMAT
+ G1PPRL_BYTE_FORMAT,
type, bottom, end,
- used_bytes, prev_live_bytes, next_live_bytes, gc_eff);
+ used_bytes, prev_live_bytes, next_live_bytes, gc_eff , remset_bytes);
return false;
}
G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() {
+ // add static memory usages to remembered set sizes
+ _total_remset_bytes += HeapRegionRemSet::fl_mem_size() + HeapRegionRemSet::static_mem_size();
// Print the footer of the output.
_out->print_cr(G1PPRL_LINE_PREFIX);
_out->print_cr(G1PPRL_LINE_PREFIX
@@ -4647,13 +4655,15 @@ G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() {
G1PPRL_SUM_MB_FORMAT("capacity")
G1PPRL_SUM_MB_PERC_FORMAT("used")
G1PPRL_SUM_MB_PERC_FORMAT("prev-live")
- G1PPRL_SUM_MB_PERC_FORMAT("next-live"),
+ G1PPRL_SUM_MB_PERC_FORMAT("next-live")
+ G1PPRL_SUM_MB_FORMAT("remset"),
bytes_to_mb(_total_capacity_bytes),
bytes_to_mb(_total_used_bytes),
perc(_total_used_bytes, _total_capacity_bytes),
bytes_to_mb(_total_prev_live_bytes),
perc(_total_prev_live_bytes, _total_capacity_bytes),
bytes_to_mb(_total_next_live_bytes),
- perc(_total_next_live_bytes, _total_capacity_bytes));
+ perc(_total_next_live_bytes, _total_capacity_bytes),
+ bytes_to_mb(_total_remset_bytes));
_out->cr();
}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
index 211a728e23e..0e576488d4b 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
@@ -44,9 +44,6 @@ class G1CMIsAliveClosure: public BoolObjectClosure {
public:
G1CMIsAliveClosure(G1CollectedHeap* g1) : _g1(g1) { }
- void do_object(oop obj) {
- ShouldNotCallThis();
- }
bool do_object_b(oop obj);
};
@@ -1257,6 +1254,9 @@ private:
size_t _hum_prev_live_bytes;
size_t _hum_next_live_bytes;
+ // Accumulator for the remembered set size
+ size_t _total_remset_bytes;
+
static double perc(size_t val, size_t total) {
if (total == 0) {
return 0.0;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp
index a055d4f285b..00ea5b54850 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp
@@ -101,20 +101,23 @@ void G1CardCounts::resize(size_t heap_capacity) {
ReservedSpace::allocation_align_size_up(_committed_size),
err_msg("Unaligned? committed_size: " SIZE_FORMAT, _committed_size));
- // Verify that the committed space for the card counts
- // matches our committed max card num.
+ // Verify that the committed space for the card counts matches our
+ // committed max card num. Note for some allocation alignments, the
+ // amount of space actually committed for the counts table will be able
+ // to span more cards than the number spanned by the maximum heap.
size_t prev_committed_size = _committed_size;
- size_t prev_committed_card_num = prev_committed_size / sizeof(jbyte);
+ size_t prev_committed_card_num = committed_to_card_num(prev_committed_size);
+
assert(prev_committed_card_num == _committed_max_card_num,
err_msg("Card mismatch: "
"prev: " SIZE_FORMAT ", "
- "committed: "SIZE_FORMAT,
- prev_committed_card_num, _committed_max_card_num));
+ "committed: "SIZE_FORMAT", "
+ "reserved: "SIZE_FORMAT,
+ prev_committed_card_num, _committed_max_card_num, _reserved_max_card_num));
size_t new_size = (heap_capacity >> CardTableModRefBS::card_shift) * sizeof(jbyte);
size_t new_committed_size = ReservedSpace::allocation_align_size_up(new_size);
- size_t new_committed_card_num =
- MIN2(_reserved_max_card_num, new_committed_size / sizeof(jbyte));
+ size_t new_committed_card_num = committed_to_card_num(new_committed_size);
if (_committed_max_card_num < new_committed_card_num) {
// we need to expand the backing store for the card counts
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp
index cef297bd234..fd516c0b90e 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp
@@ -94,6 +94,14 @@ class G1CardCounts: public CHeapObj {
return (jbyte*) (_ct_bot + card_num);
}
+ // Helper routine.
+ // Returns the number of cards that can be counted by the given committed
+ // table size, with a maximum of the number of cards spanned by the max
+ // capacity of the heap.
+ size_t committed_to_card_num(size_t committed_size) {
+ return MIN2(_reserved_max_card_num, committed_size / sizeof(jbyte));
+ }
+
// Clear the counts table for the given (exclusive) index range.
void clear_range(size_t from_card_num, size_t to_card_num);
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
index 49cde427238..c95cf0a0452 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
@@ -1549,7 +1549,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc,
}
if (G1Log::finer()) {
- g1_policy()->print_detailed_heap_transition();
+ g1_policy()->print_detailed_heap_transition(true /* full */);
}
print_heap_after_gc();
@@ -5090,7 +5090,6 @@ class G1AlwaysAliveClosure: public BoolObjectClosure {
G1CollectedHeap* _g1;
public:
G1AlwaysAliveClosure(G1CollectedHeap* g1) : _g1(g1) {}
- void do_object(oop p) { assert(false, "Do not call."); }
bool do_object_b(oop p) {
if (p != NULL) {
return true;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
index 32f5a46b471..1b817a9da2d 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
@@ -165,7 +165,6 @@ class G1STWIsAliveClosure: public BoolObjectClosure {
G1CollectedHeap* _g1;
public:
G1STWIsAliveClosure(G1CollectedHeap* g1) : _g1(g1) {}
- void do_object(oop p) { assert(false, "Do not call."); }
bool do_object_b(oop p);
};
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
index a21290c835b..741c6b7130a 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
@@ -124,9 +124,12 @@ G1CollectorPolicy::G1CollectorPolicy() :
_last_young_gc(false),
_last_gc_was_young(false),
- _eden_bytes_before_gc(0),
- _survivor_bytes_before_gc(0),
- _capacity_before_gc(0),
+ _eden_used_bytes_before_gc(0),
+ _survivor_used_bytes_before_gc(0),
+ _heap_used_bytes_before_gc(0),
+ _metaspace_used_bytes_before_gc(0),
+ _eden_capacity_bytes_before_gc(0),
+ _heap_capacity_bytes_before_gc(0),
_eden_cset_region_length(0),
_survivor_cset_region_length(0),
@@ -746,7 +749,7 @@ G1CollectorPolicy::verify_young_ages(HeapRegion* head,
void G1CollectorPolicy::record_full_collection_start() {
_full_collection_start_sec = os::elapsedTime();
- record_heap_size_info_at_start();
+ record_heap_size_info_at_start(true /* full */);
// Release the future to-space so that it is available for compaction into.
_g1->set_full_collection();
}
@@ -803,7 +806,7 @@ void G1CollectorPolicy::record_collection_pause_start(double start_time_sec) {
_trace_gen0_time_data.record_start_collection(s_w_t_ms);
_stop_world_start = 0.0;
- record_heap_size_info_at_start();
+ record_heap_size_info_at_start(false /* full */);
phase_times()->record_cur_collection_start_sec(start_time_sec);
_pending_cards = _g1->pending_card_num();
@@ -938,14 +941,6 @@ void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms) {
_mmu_tracker->add_pause(end_time_sec - pause_time_ms/1000.0,
end_time_sec, false);
- size_t freed_bytes =
- _cur_collection_pause_used_at_start_bytes - cur_used_bytes;
- size_t surviving_bytes = _collection_set_bytes_used_before - freed_bytes;
-
- double survival_fraction =
- (double)surviving_bytes/
- (double)_collection_set_bytes_used_before;
-
if (update_stats) {
_trace_gen0_time_data.record_end_collection(pause_time_ms, phase_times());
// this is where we update the allocation rate of the application
@@ -998,6 +993,7 @@ void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms) {
}
}
}
+
bool new_in_marking_window = _in_marking_window;
bool new_in_marking_window_im = false;
if (during_initial_mark_pause()) {
@@ -1083,8 +1079,10 @@ void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms) {
}
_rs_length_diff_seq->add((double) rs_length_diff);
- size_t copied_bytes = surviving_bytes;
+ size_t freed_bytes = _heap_used_bytes_before_gc - cur_used_bytes;
+ size_t copied_bytes = _collection_set_bytes_used_before - freed_bytes;
double cost_per_byte_ms = 0.0;
+
if (copied_bytes > 0) {
cost_per_byte_ms = phase_times()->average_last_obj_copy_time() / (double) copied_bytes;
if (_in_marking_window) {
@@ -1148,51 +1146,61 @@ void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms) {
byte_size_in_proper_unit((double)(bytes)), \
proper_unit_for_byte_size((bytes))
-void G1CollectorPolicy::record_heap_size_info_at_start() {
+void G1CollectorPolicy::record_heap_size_info_at_start(bool full) {
YoungList* young_list = _g1->young_list();
- _eden_bytes_before_gc = young_list->eden_used_bytes();
- _survivor_bytes_before_gc = young_list->survivor_used_bytes();
- _capacity_before_gc = _g1->capacity();
-
- _cur_collection_pause_used_at_start_bytes = _g1->used();
+ _eden_used_bytes_before_gc = young_list->eden_used_bytes();
+ _survivor_used_bytes_before_gc = young_list->survivor_used_bytes();
+ _heap_capacity_bytes_before_gc = _g1->capacity();
+ _heap_used_bytes_before_gc = _g1->used();
_cur_collection_pause_used_regions_at_start = _g1->used_regions();
- size_t eden_capacity_before_gc =
- (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_bytes_before_gc;
+ _eden_capacity_bytes_before_gc =
+ (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_used_bytes_before_gc;
- _prev_eden_capacity = eden_capacity_before_gc;
+ if (full) {
+ _metaspace_used_bytes_before_gc = MetaspaceAux::allocated_used_bytes();
+ }
}
void G1CollectorPolicy::print_heap_transition() {
_g1->print_size_transition(gclog_or_tty,
- _cur_collection_pause_used_at_start_bytes, _g1->used(), _g1->capacity());
+ _heap_used_bytes_before_gc,
+ _g1->used(),
+ _g1->capacity());
}
-void G1CollectorPolicy::print_detailed_heap_transition() {
- YoungList* young_list = _g1->young_list();
- size_t eden_bytes = young_list->eden_used_bytes();
- size_t survivor_bytes = young_list->survivor_used_bytes();
- size_t used_before_gc = _cur_collection_pause_used_at_start_bytes;
- size_t used = _g1->used();
- size_t capacity = _g1->capacity();
- size_t eden_capacity =
- (_young_list_target_length * HeapRegion::GrainBytes) - survivor_bytes;
+void G1CollectorPolicy::print_detailed_heap_transition(bool full) {
+ YoungList* young_list = _g1->young_list();
- gclog_or_tty->print_cr(
- " [Eden: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT") "
- "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
- "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"
- EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]",
- EXT_SIZE_PARAMS(_eden_bytes_before_gc),
- EXT_SIZE_PARAMS(_prev_eden_capacity),
- EXT_SIZE_PARAMS(eden_bytes),
- EXT_SIZE_PARAMS(eden_capacity),
- EXT_SIZE_PARAMS(_survivor_bytes_before_gc),
- EXT_SIZE_PARAMS(survivor_bytes),
- EXT_SIZE_PARAMS(used_before_gc),
- EXT_SIZE_PARAMS(_capacity_before_gc),
- EXT_SIZE_PARAMS(used),
- EXT_SIZE_PARAMS(capacity));
+ size_t eden_used_bytes_after_gc = young_list->eden_used_bytes();
+ size_t survivor_used_bytes_after_gc = young_list->survivor_used_bytes();
+ size_t heap_used_bytes_after_gc = _g1->used();
+
+ size_t heap_capacity_bytes_after_gc = _g1->capacity();
+ size_t eden_capacity_bytes_after_gc =
+ (_young_list_target_length * HeapRegion::GrainBytes) - survivor_used_bytes_after_gc;
+
+ gclog_or_tty->print(
+ " [Eden: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT") "
+ "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
+ "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"
+ EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]",
+ EXT_SIZE_PARAMS(_eden_used_bytes_before_gc),
+ EXT_SIZE_PARAMS(_eden_capacity_bytes_before_gc),
+ EXT_SIZE_PARAMS(eden_used_bytes_after_gc),
+ EXT_SIZE_PARAMS(eden_capacity_bytes_after_gc),
+ EXT_SIZE_PARAMS(_survivor_used_bytes_before_gc),
+ EXT_SIZE_PARAMS(survivor_used_bytes_after_gc),
+ EXT_SIZE_PARAMS(_heap_used_bytes_before_gc),
+ EXT_SIZE_PARAMS(_heap_capacity_bytes_before_gc),
+ EXT_SIZE_PARAMS(heap_used_bytes_after_gc),
+ EXT_SIZE_PARAMS(heap_capacity_bytes_after_gc));
+
+ if (full) {
+ MetaspaceAux::print_metaspace_change(_metaspace_used_bytes_before_gc);
+ }
+
+ gclog_or_tty->cr();
}
void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
index 08867850394..90106c00a34 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
@@ -175,7 +175,6 @@ private:
CollectionSetChooser* _collectionSetChooser;
double _full_collection_start_sec;
- size_t _cur_collection_pause_used_at_start_bytes;
uint _cur_collection_pause_used_regions_at_start;
// These exclude marking times.
@@ -194,7 +193,6 @@ private:
uint _young_list_target_length;
uint _young_list_fixed_length;
- size_t _prev_eden_capacity; // used for logging
// The max number of regions we can extend the eden by while the GC
// locker is active. This should be >= _young_list_target_length;
@@ -693,11 +691,11 @@ public:
// Records the information about the heap size for reporting in
// print_detailed_heap_transition
- void record_heap_size_info_at_start();
+ void record_heap_size_info_at_start(bool full);
// Print heap sizing transition (with less and more detail).
void print_heap_transition();
- void print_detailed_heap_transition();
+ void print_detailed_heap_transition(bool full = false);
void record_stop_world_start();
void record_concurrent_pause();
@@ -861,9 +859,16 @@ private:
uint _max_survivor_regions;
// For reporting purposes.
- size_t _eden_bytes_before_gc;
- size_t _survivor_bytes_before_gc;
- size_t _capacity_before_gc;
+ // The value of _heap_bytes_before_gc is also used to calculate
+ // the cost of copying.
+
+ size_t _eden_used_bytes_before_gc; // Eden occupancy before GC
+ size_t _survivor_used_bytes_before_gc; // Survivor occupancy before GC
+ size_t _heap_used_bytes_before_gc; // Heap occupancy before GC
+ size_t _metaspace_used_bytes_before_gc; // Metaspace occupancy before GC
+
+ size_t _eden_capacity_bytes_before_gc; // Eden capacity before GC
+ size_t _heap_capacity_bytes_before_gc; // Heap capacity before GC
// The amount of survivor regions after a collection.
uint _recorded_survivor_regions;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
index 1e005a26ecd..635babcbb30 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -242,11 +242,13 @@ public:
PerRegionTable* cur = _free_list;
size_t res = 0;
while (cur != NULL) {
- res += sizeof(PerRegionTable);
+ res += cur->mem_size();
cur = cur->next();
}
return res;
}
+
+ static void test_fl_mem_size();
};
PerRegionTable* PerRegionTable::_free_list = NULL;
@@ -282,7 +284,8 @@ OtherRegionsTable::OtherRegionsTable(HeapRegion* hr) :
_fine_eviction_stride = _max_fine_entries / _fine_eviction_sample_size;
}
- _fine_grain_regions = new PerRegionTablePtr[_max_fine_entries];
+ _fine_grain_regions = NEW_C_HEAP_ARRAY3(PerRegionTablePtr, _max_fine_entries,
+ mtGC, 0, AllocFailStrategy::RETURN_NULL);
if (_fine_grain_regions == NULL) {
vm_exit_out_of_memory(sizeof(void*)*_max_fine_entries, OOM_MALLOC_ERROR,
@@ -706,10 +709,11 @@ size_t OtherRegionsTable::mem_size() const {
// Cast away const in this case.
MutexLockerEx x((Mutex*)&_m, Mutex::_no_safepoint_check_flag);
size_t sum = 0;
- PerRegionTable * cur = _first_all_fine_prts;
- while (cur != NULL) {
- sum += cur->mem_size();
- cur = cur->next();
+ // all PRTs are of the same size so it is sufficient to query only one of them.
+ if (_first_all_fine_prts != NULL) {
+ assert(_last_all_fine_prts != NULL &&
+ _first_all_fine_prts->mem_size() == _last_all_fine_prts->mem_size(), "check that mem_size() is constant");
+ sum += _first_all_fine_prts->mem_size() * _n_fine_entries;
}
sum += (sizeof(PerRegionTable*) * _max_fine_entries);
sum += (_coarse_map.size_in_words() * HeapWordSize);
@@ -1147,6 +1151,19 @@ HeapRegionRemSet::finish_cleanup_task(HRRSCleanupTask* hrrs_cleanup_task) {
}
#ifndef PRODUCT
+void PerRegionTable::test_fl_mem_size() {
+ PerRegionTable* dummy = alloc(NULL);
+ free(dummy);
+ guarantee(dummy->mem_size() == fl_mem_size(), "fl_mem_size() does not return the correct element size");
+ // try to reset the state
+ _free_list = NULL;
+ delete dummy;
+}
+
+void HeapRegionRemSet::test_prt() {
+ PerRegionTable::test_fl_mem_size();
+}
+
void HeapRegionRemSet::test() {
os::sleep(Thread::current(), (jlong)5000, false);
G1CollectedHeap* g1h = G1CollectedHeap::heap();
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp
index 2e165074e10..1b9e5f46aa5 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp
@@ -338,6 +338,7 @@ public:
// Run unit tests.
#ifndef PRODUCT
+ static void test_prt();
static void test();
#endif
};
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
index 3d4cbedd827..0db70cdd7d8 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,6 @@
#include "precompiled.hpp"
#include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
-#include "gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp"
#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/os.hpp"
@@ -55,18 +54,18 @@ ParMarkBitMap::initialize(MemRegion covered_region)
const size_t raw_bytes = words * sizeof(idx_t);
const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10);
const size_t granularity = os::vm_allocation_granularity();
- const size_t bytes = align_size_up(raw_bytes, MAX2(page_sz, granularity));
+ _reserved_byte_size = align_size_up(raw_bytes, MAX2(page_sz, granularity));
const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
MAX2(page_sz, granularity);
- ReservedSpace rs(bytes, rs_align, rs_align > 0);
+ ReservedSpace rs(_reserved_byte_size, rs_align, rs_align > 0);
os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz,
rs.base(), rs.size());
MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
_virtual_space = new PSVirtualSpace(rs, page_sz);
- if (_virtual_space != NULL && _virtual_space->expand_by(bytes)) {
+ if (_virtual_space != NULL && _virtual_space->expand_by(_reserved_byte_size)) {
_region_start = covered_region.start();
_region_size = covered_region.word_size();
idx_t* map = (idx_t*)_virtual_space->reserved_low_addr();
@@ -108,31 +107,6 @@ ParMarkBitMap::mark_obj(HeapWord* addr, size_t size)
return false;
}
-size_t
-ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, HeapWord* end_addr) const
-{
- assert(beg_addr <= end_addr, "bad range");
-
- idx_t live_bits = 0;
-
- // The bitmap routines require the right boundary to be word-aligned.
- const idx_t end_bit = addr_to_bit(end_addr);
- const idx_t range_end = BitMap::word_align_up(end_bit);
-
- idx_t beg_bit = find_obj_beg(addr_to_bit(beg_addr), range_end);
- while (beg_bit < end_bit) {
- idx_t tmp_end = find_obj_end(beg_bit, range_end);
- if (tmp_end < end_bit) {
- live_bits += tmp_end - beg_bit + 1;
- beg_bit = find_obj_beg(tmp_end + 1, range_end);
- } else {
- live_bits += end_bit - beg_bit; // No + 1 here; end_bit is not counted.
- return bits_to_words(live_bits);
- }
- }
- return bits_to_words(live_bits);
-}
-
size_t ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, oop end_obj) const
{
assert(beg_addr <= (HeapWord*)end_obj, "bad range");
@@ -244,13 +218,6 @@ ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
return complete;
}
-#ifndef PRODUCT
-void ParMarkBitMap::reset_counters()
-{
- _cas_tries = _cas_retries = _cas_by_another = 0;
-}
-#endif // #ifndef PRODUCT
-
#ifdef ASSERT
void ParMarkBitMap::verify_clear() const
{
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp
index fdc0febfa21..32f7eed82cb 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,11 +26,11 @@
#define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PARMARKBITMAP_HPP
#include "memory/memRegion.hpp"
-#include "gc_implementation/parallelScavenge/psVirtualspace.hpp"
-#include "utilities/bitMap.inline.hpp"
+#include "oops/oop.hpp"
+#include "utilities/bitMap.hpp"
-class oopDesc;
class ParMarkBitMapClosure;
+class PSVirtualSpace;
class ParMarkBitMap: public CHeapObj
{
@@ -41,13 +41,11 @@ public:
enum IterationStatus { incomplete, complete, full, would_overflow };
inline ParMarkBitMap();
- inline ParMarkBitMap(MemRegion covered_region);
bool initialize(MemRegion covered_region);
// Atomically mark an object as live.
bool mark_obj(HeapWord* addr, size_t size);
inline bool mark_obj(oop obj, int size);
- inline bool mark_obj(oop obj);
// Return whether the specified begin or end bit is set.
inline bool is_obj_beg(idx_t bit) const;
@@ -77,11 +75,6 @@ public:
// Return the size in words of the object (a search is done for the end bit).
inline size_t obj_size(idx_t beg_bit) const;
inline size_t obj_size(HeapWord* addr) const;
- inline size_t obj_size(oop obj) const;
-
- // Synonyms for the above.
- size_t obj_size_in_words(oop obj) const { return obj_size((HeapWord*)obj); }
- size_t obj_size_in_words(HeapWord* addr) const { return obj_size(addr); }
// Apply live_closure to each live object that lies completely within the
// range [live_range_beg, live_range_end). This is used to iterate over the
@@ -124,15 +117,12 @@ public:
HeapWord* range_end,
HeapWord* dead_range_end) const;
- // Return the number of live words in the range [beg_addr, end_addr) due to
+ // Return the number of live words in the range [beg_addr, end_obj) due to
// objects that start in the range. If a live object extends onto the range,
// the caller must detect and account for any live words due to that object.
// If a live object extends beyond the end of the range, only the words within
- // the range are included in the result.
- size_t live_words_in_range(HeapWord* beg_addr, HeapWord* end_addr) const;
-
- // Same as the above, except the end of the range must be a live object, which
- // is the case when updating pointers. This allows a branch to be removed
+ // the range are included in the result. The end of the range must be a live object,
+ // which is the case when updating pointers. This allows a branch to be removed
// from inside the loop.
size_t live_words_in_range(HeapWord* beg_addr, oop end_obj) const;
@@ -141,6 +131,8 @@ public:
inline size_t region_size() const;
inline size_t size() const;
+ size_t reserved_byte_size() const { return _reserved_byte_size; }
+
// Convert a heap address to/from a bit index.
inline idx_t addr_to_bit(HeapWord* addr) const;
inline HeapWord* bit_to_addr(idx_t bit) const;
@@ -156,22 +148,11 @@ public:
// Clear a range of bits or the entire bitmap (both begin and end bits are
// cleared).
inline void clear_range(idx_t beg, idx_t end);
- inline void clear() { clear_range(0, size()); }
// Return the number of bits required to represent the specified number of
// HeapWords, or the specified region.
static inline idx_t bits_required(size_t words);
static inline idx_t bits_required(MemRegion covered_region);
- static inline idx_t words_required(MemRegion covered_region);
-
-#ifndef PRODUCT
- // CAS statistics.
- size_t cas_tries() { return _cas_tries; }
- size_t cas_retries() { return _cas_retries; }
- size_t cas_by_another() { return _cas_by_another; }
-
- void reset_counters();
-#endif // #ifndef PRODUCT
void print_on_error(outputStream* st) const {
st->print_cr("Marking Bits: (ParMarkBitMap*) " PTR_FORMAT, this);
@@ -197,28 +178,12 @@ private:
BitMap _beg_bits;
BitMap _end_bits;
PSVirtualSpace* _virtual_space;
-
-#ifndef PRODUCT
- size_t _cas_tries;
- size_t _cas_retries;
- size_t _cas_by_another;
-#endif // #ifndef PRODUCT
+ size_t _reserved_byte_size;
};
inline ParMarkBitMap::ParMarkBitMap():
- _beg_bits(),
- _end_bits()
-{
- _region_start = 0;
- _virtual_space = 0;
-}
-
-inline ParMarkBitMap::ParMarkBitMap(MemRegion covered_region):
- _beg_bits(),
- _end_bits()
-{
- initialize(covered_region);
-}
+ _beg_bits(), _end_bits(), _region_start(NULL), _region_size(0), _virtual_space(NULL), _reserved_byte_size(0)
+{ }
inline void ParMarkBitMap::clear_range(idx_t beg, idx_t end)
{
@@ -240,12 +205,6 @@ ParMarkBitMap::bits_required(MemRegion covered_region)
return bits_required(covered_region.word_size());
}
-inline ParMarkBitMap::idx_t
-ParMarkBitMap::words_required(MemRegion covered_region)
-{
- return bits_required(covered_region) / BitsPerWord;
-}
-
inline HeapWord*
ParMarkBitMap::region_start() const
{
@@ -350,11 +309,6 @@ inline size_t ParMarkBitMap::obj_size(HeapWord* addr) const
return obj_size(addr_to_bit(addr));
}
-inline size_t ParMarkBitMap::obj_size(oop obj) const
-{
- return obj_size((HeapWord*)obj);
-}
-
inline ParMarkBitMap::IterationStatus
ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
HeapWord* range_beg,
@@ -435,8 +389,10 @@ inline void ParMarkBitMap::verify_bit(idx_t bit) const {
inline void ParMarkBitMap::verify_addr(HeapWord* addr) const {
// Allow one past the last valid address; useful for loop bounds.
- assert(addr >= region_start(), "addr too small");
- assert(addr <= region_start() + region_size(), "addr too big");
+ assert(addr >= region_start(),
+ err_msg("addr too small, addr: " PTR_FORMAT " region start: " PTR_FORMAT, addr, region_start()));
+ assert(addr <= region_end(),
+ err_msg("addr too big, addr: " PTR_FORMAT " region end: " PTR_FORMAT, addr, region_end()));
}
#endif // #ifdef ASSERT
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
index 3834722fa73..ed91fe2588e 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -213,7 +213,7 @@ void StealMarkingTask::do_it(GCTaskManager* manager, uint which) {
int random_seed = 17;
do {
while (ParCompactionManager::steal_objarray(which, &random_seed, task)) {
- ObjArrayKlass* const k = (ObjArrayKlass*)task.obj()->klass();
+ ObjArrayKlass* k = (ObjArrayKlass*)task.obj()->klass();
k->oop_follow_contents(cm, task.obj(), task.index());
cm->follow_marking_stacks();
}
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp
index 3b24ed8866a..8b3ee26548d 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -201,15 +201,232 @@ void PSAdaptiveSizePolicy::compute_generation_free_space(
size_t cur_eden,
size_t max_old_gen_size,
size_t max_eden_size,
- bool is_full_gc,
- GCCause::Cause gc_cause,
- CollectorPolicy* collector_policy) {
+ bool is_full_gc) {
+ compute_eden_space_size(young_live,
+ eden_live,
+ cur_eden,
+ max_eden_size,
+ is_full_gc);
+
+ compute_old_gen_free_space(old_live,
+ cur_eden,
+ max_old_gen_size,
+ is_full_gc);
+}
+
+void PSAdaptiveSizePolicy::compute_eden_space_size(
+ size_t young_live,
+ size_t eden_live,
+ size_t cur_eden,
+ size_t max_eden_size,
+ bool is_full_gc) {
// Update statistics
// Time statistics are updated as we go, update footprint stats here
_avg_base_footprint->sample(BaseFootPrintEstimate);
avg_young_live()->sample(young_live);
avg_eden_live()->sample(eden_live);
+
+ // This code used to return if the policy was not ready , i.e.,
+ // policy_is_ready() returning false. The intent was that
+ // decisions below needed major collection times and so could
+ // not be made before two major collections. A consequence was
+ // adjustments to the young generation were not done until after
+ // two major collections even if the minor collections times
+ // exceeded the requested goals. Now let the young generation
+ // adjust for the minor collection times. Major collection times
+ // will be zero for the first collection and will naturally be
+ // ignored. Tenured generation adjustments are only made at the
+ // full collections so until the second major collection has
+ // been reached, no tenured generation adjustments will be made.
+
+ // Until we know better, desired promotion size uses the last calculation
+ size_t desired_promo_size = _promo_size;
+
+ // Start eden at the current value. The desired value that is stored
+ // in _eden_size is not bounded by constraints of the heap and can
+ // run away.
+ //
+ // As expected setting desired_eden_size to the current
+ // value of desired_eden_size as a starting point
+ // caused desired_eden_size to grow way too large and caused
+ // an overflow down stream. It may have improved performance in
+ // some case but is dangerous.
+ size_t desired_eden_size = cur_eden;
+
+ // Cache some values. There's a bit of work getting these, so
+ // we might save a little time.
+ const double major_cost = major_gc_cost();
+ const double minor_cost = minor_gc_cost();
+
+ // This method sets the desired eden size. That plus the
+ // desired survivor space sizes sets the desired young generation
+ // size. This methods does not know what the desired survivor
+ // size is but expects that other policy will attempt to make
+ // the survivor sizes compatible with the live data in the
+ // young generation. This limit is an estimate of the space left
+ // in the young generation after the survivor spaces have been
+ // subtracted out.
+ size_t eden_limit = max_eden_size;
+
+ const double gc_cost_limit = GCTimeLimit/100.0;
+
+ // Which way should we go?
+ // if pause requirement is not met
+ // adjust size of any generation with average paus exceeding
+ // the pause limit. Adjust one pause at a time (the larger)
+ // and only make adjustments for the major pause at full collections.
+ // else if throughput requirement not met
+ // adjust the size of the generation with larger gc time. Only
+ // adjust one generation at a time.
+ // else
+ // adjust down the total heap size. Adjust down the larger of the
+ // generations.
+
+ // Add some checks for a threshold for a change. For example,
+ // a change less than the necessary alignment is probably not worth
+ // attempting.
+
+
+ if ((_avg_minor_pause->padded_average() > gc_pause_goal_sec()) ||
+ (_avg_major_pause->padded_average() > gc_pause_goal_sec())) {
+ //
+ // Check pauses
+ //
+ // Make changes only to affect one of the pauses (the larger)
+ // at a time.
+ adjust_eden_for_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
+
+ } else if (_avg_minor_pause->padded_average() > gc_minor_pause_goal_sec()) {
+ // Adjust only for the minor pause time goal
+ adjust_eden_for_minor_pause_time(is_full_gc, &desired_eden_size);
+
+ } else if(adjusted_mutator_cost() < _throughput_goal) {
+ // This branch used to require that (mutator_cost() > 0.0 in 1.4.2.
+ // This sometimes resulted in skipping to the minimize footprint
+ // code. Change this to try and reduce GC time if mutator time is
+ // negative for whatever reason. Or for future consideration,
+ // bail out of the code if mutator time is negative.
+ //
+ // Throughput
+ //
+ assert(major_cost >= 0.0, "major cost is < 0.0");
+ assert(minor_cost >= 0.0, "minor cost is < 0.0");
+ // Try to reduce the GC times.
+ adjust_eden_for_throughput(is_full_gc, &desired_eden_size);
+
+ } else {
+
+ // Be conservative about reducing the footprint.
+ // Do a minimum number of major collections first.
+ // Have reasonable averages for major and minor collections costs.
+ if (UseAdaptiveSizePolicyFootprintGoal &&
+ young_gen_policy_is_ready() &&
+ avg_major_gc_cost()->average() >= 0.0 &&
+ avg_minor_gc_cost()->average() >= 0.0) {
+ size_t desired_sum = desired_eden_size + desired_promo_size;
+ desired_eden_size = adjust_eden_for_footprint(desired_eden_size, desired_sum);
+ }
+ }
+
+ // Note we make the same tests as in the code block below; the code
+ // seems a little easier to read with the printing in another block.
+ if (PrintAdaptiveSizePolicy) {
+ if (desired_eden_size > eden_limit) {
+ gclog_or_tty->print_cr(
+ "PSAdaptiveSizePolicy::compute_eden_space_size limits:"
+ " desired_eden_size: " SIZE_FORMAT
+ " old_eden_size: " SIZE_FORMAT
+ " eden_limit: " SIZE_FORMAT
+ " cur_eden: " SIZE_FORMAT
+ " max_eden_size: " SIZE_FORMAT
+ " avg_young_live: " SIZE_FORMAT,
+ desired_eden_size, _eden_size, eden_limit, cur_eden,
+ max_eden_size, (size_t)avg_young_live()->average());
+ }
+ if (gc_cost() > gc_cost_limit) {
+ gclog_or_tty->print_cr(
+ "PSAdaptiveSizePolicy::compute_eden_space_size: gc time limit"
+ " gc_cost: %f "
+ " GCTimeLimit: %d",
+ gc_cost(), GCTimeLimit);
+ }
+ }
+
+ // Align everything and make a final limit check
+ const size_t alignment = _intra_generation_alignment;
+ desired_eden_size = align_size_up(desired_eden_size, alignment);
+ desired_eden_size = MAX2(desired_eden_size, alignment);
+
+ eden_limit = align_size_down(eden_limit, alignment);
+
+ // And one last limit check, now that we've aligned things.
+ if (desired_eden_size > eden_limit) {
+ // If the policy says to get a larger eden but
+ // is hitting the limit, don't decrease eden.
+ // This can lead to a general drifting down of the
+ // eden size. Let the tenuring calculation push more
+ // into the old gen.
+ desired_eden_size = MAX2(eden_limit, cur_eden);
+ }
+
+ if (PrintAdaptiveSizePolicy) {
+ // Timing stats
+ gclog_or_tty->print(
+ "PSAdaptiveSizePolicy::compute_eden_space_size: costs"
+ " minor_time: %f"
+ " major_cost: %f"
+ " mutator_cost: %f"
+ " throughput_goal: %f",
+ minor_gc_cost(), major_gc_cost(), mutator_cost(),
+ _throughput_goal);
+
+ // We give more details if Verbose is set
+ if (Verbose) {
+ gclog_or_tty->print( " minor_pause: %f"
+ " major_pause: %f"
+ " minor_interval: %f"
+ " major_interval: %f"
+ " pause_goal: %f",
+ _avg_minor_pause->padded_average(),
+ _avg_major_pause->padded_average(),
+ _avg_minor_interval->average(),
+ _avg_major_interval->average(),
+ gc_pause_goal_sec());
+ }
+
+ // Footprint stats
+ gclog_or_tty->print( " live_space: " SIZE_FORMAT
+ " free_space: " SIZE_FORMAT,
+ live_space(), free_space());
+ // More detail
+ if (Verbose) {
+ gclog_or_tty->print( " base_footprint: " SIZE_FORMAT
+ " avg_young_live: " SIZE_FORMAT
+ " avg_old_live: " SIZE_FORMAT,
+ (size_t)_avg_base_footprint->average(),
+ (size_t)avg_young_live()->average(),
+ (size_t)avg_old_live()->average());
+ }
+
+ // And finally, our old and new sizes.
+ gclog_or_tty->print(" old_eden_size: " SIZE_FORMAT
+ " desired_eden_size: " SIZE_FORMAT,
+ _eden_size, desired_eden_size);
+ gclog_or_tty->cr();
+ }
+
+ set_eden_size(desired_eden_size);
+}
+
+void PSAdaptiveSizePolicy::compute_old_gen_free_space(
+ size_t old_live,
+ size_t cur_eden,
+ size_t max_old_gen_size,
+ bool is_full_gc) {
+
+ // Update statistics
+ // Time statistics are updated as we go, update footprint stats here
if (is_full_gc) {
// old_live is only accurate after a full gc
avg_old_live()->sample(old_live);
@@ -242,32 +459,14 @@ void PSAdaptiveSizePolicy::compute_generation_free_space(
// some case but is dangerous.
size_t desired_eden_size = cur_eden;
-#ifdef ASSERT
- size_t original_promo_size = desired_promo_size;
- size_t original_eden_size = desired_eden_size;
-#endif
-
// Cache some values. There's a bit of work getting these, so
// we might save a little time.
const double major_cost = major_gc_cost();
const double minor_cost = minor_gc_cost();
- // Used for diagnostics
- clear_generation_free_space_flags();
-
// Limits on our growth
size_t promo_limit = (size_t)(max_old_gen_size - avg_old_live()->average());
- // This method sets the desired eden size. That plus the
- // desired survivor space sizes sets the desired young generation
- // size. This methods does not know what the desired survivor
- // size is but expects that other policy will attempt to make
- // the survivor sizes compatible with the live data in the
- // young generation. This limit is an estimate of the space left
- // in the young generation after the survivor spaces have been
- // subtracted out.
- size_t eden_limit = max_eden_size;
-
// But don't force a promo size below the current promo size. Otherwise,
// the promo size will shrink for no good reason.
promo_limit = MAX2(promo_limit, _promo_size);
@@ -290,7 +489,6 @@ void PSAdaptiveSizePolicy::compute_generation_free_space(
// a change less than the necessary alignment is probably not worth
// attempting.
-
if ((_avg_minor_pause->padded_average() > gc_pause_goal_sec()) ||
(_avg_major_pause->padded_average() > gc_pause_goal_sec())) {
//
@@ -298,12 +496,13 @@ void PSAdaptiveSizePolicy::compute_generation_free_space(
//
// Make changes only to affect one of the pauses (the larger)
// at a time.
- adjust_for_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
-
+ if (is_full_gc) {
+ set_decide_at_full_gc(decide_at_full_gc_true);
+ adjust_promo_for_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
+ }
} else if (_avg_minor_pause->padded_average() > gc_minor_pause_goal_sec()) {
// Adjust only for the minor pause time goal
- adjust_for_minor_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
-
+ adjust_promo_for_minor_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
} else if(adjusted_mutator_cost() < _throughput_goal) {
// This branch used to require that (mutator_cost() > 0.0 in 1.4.2.
// This sometimes resulted in skipping to the minimize footprint
@@ -316,8 +515,10 @@ void PSAdaptiveSizePolicy::compute_generation_free_space(
assert(major_cost >= 0.0, "major cost is < 0.0");
assert(minor_cost >= 0.0, "minor cost is < 0.0");
// Try to reduce the GC times.
- adjust_for_throughput(is_full_gc, &desired_promo_size, &desired_eden_size);
-
+ if (is_full_gc) {
+ set_decide_at_full_gc(decide_at_full_gc_true);
+ adjust_promo_for_throughput(is_full_gc, &desired_promo_size);
+ }
} else {
// Be conservative about reducing the footprint.
@@ -327,13 +528,10 @@ void PSAdaptiveSizePolicy::compute_generation_free_space(
young_gen_policy_is_ready() &&
avg_major_gc_cost()->average() >= 0.0 &&
avg_minor_gc_cost()->average() >= 0.0) {
- size_t desired_sum = desired_eden_size + desired_promo_size;
- desired_eden_size = adjust_eden_for_footprint(desired_eden_size,
- desired_sum);
if (is_full_gc) {
set_decide_at_full_gc(decide_at_full_gc_true);
- desired_promo_size = adjust_promo_for_footprint(desired_promo_size,
- desired_sum);
+ size_t desired_sum = desired_eden_size + desired_promo_size;
+ desired_promo_size = adjust_promo_for_footprint(desired_promo_size, desired_sum);
}
}
}
@@ -345,7 +543,7 @@ void PSAdaptiveSizePolicy::compute_generation_free_space(
// "free_in_old_gen" was the original value for used for promo_limit
size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average());
gclog_or_tty->print_cr(
- "PSAdaptiveSizePolicy::compute_generation_free_space limits:"
+ "PSAdaptiveSizePolicy::compute_old_gen_free_space limits:"
" desired_promo_size: " SIZE_FORMAT
" promo_limit: " SIZE_FORMAT
" free_in_old_gen: " SIZE_FORMAT
@@ -354,21 +552,9 @@ void PSAdaptiveSizePolicy::compute_generation_free_space(
desired_promo_size, promo_limit, free_in_old_gen,
max_old_gen_size, (size_t) avg_old_live()->average());
}
- if (desired_eden_size > eden_limit) {
- gclog_or_tty->print_cr(
- "AdaptiveSizePolicy::compute_generation_free_space limits:"
- " desired_eden_size: " SIZE_FORMAT
- " old_eden_size: " SIZE_FORMAT
- " eden_limit: " SIZE_FORMAT
- " cur_eden: " SIZE_FORMAT
- " max_eden_size: " SIZE_FORMAT
- " avg_young_live: " SIZE_FORMAT,
- desired_eden_size, _eden_size, eden_limit, cur_eden,
- max_eden_size, (size_t)avg_young_live()->average());
- }
if (gc_cost() > gc_cost_limit) {
gclog_or_tty->print_cr(
- "AdaptiveSizePolicy::compute_generation_free_space: gc time limit"
+ "PSAdaptiveSizePolicy::compute_old_gen_free_space: gc time limit"
" gc_cost: %f "
" GCTimeLimit: %d",
gc_cost(), GCTimeLimit);
@@ -377,46 +563,18 @@ void PSAdaptiveSizePolicy::compute_generation_free_space(
// Align everything and make a final limit check
const size_t alignment = _intra_generation_alignment;
- desired_eden_size = align_size_up(desired_eden_size, alignment);
- desired_eden_size = MAX2(desired_eden_size, alignment);
desired_promo_size = align_size_up(desired_promo_size, alignment);
desired_promo_size = MAX2(desired_promo_size, alignment);
- eden_limit = align_size_down(eden_limit, alignment);
promo_limit = align_size_down(promo_limit, alignment);
- // Is too much time being spent in GC?
- // Is the heap trying to grow beyond it's limits?
-
- const size_t free_in_old_gen =
- (size_t)(max_old_gen_size - avg_old_live()->average());
- if (desired_promo_size > free_in_old_gen && desired_eden_size > eden_limit) {
- check_gc_overhead_limit(young_live,
- eden_live,
- max_old_gen_size,
- max_eden_size,
- is_full_gc,
- gc_cause,
- collector_policy);
- }
-
-
// And one last limit check, now that we've aligned things.
- if (desired_eden_size > eden_limit) {
- // If the policy says to get a larger eden but
- // is hitting the limit, don't decrease eden.
- // This can lead to a general drifting down of the
- // eden size. Let the tenuring calculation push more
- // into the old gen.
- desired_eden_size = MAX2(eden_limit, cur_eden);
- }
desired_promo_size = MIN2(desired_promo_size, promo_limit);
-
if (PrintAdaptiveSizePolicy) {
// Timing stats
gclog_or_tty->print(
- "PSAdaptiveSizePolicy::compute_generation_free_space: costs"
+ "PSAdaptiveSizePolicy::compute_old_gen_free_space: costs"
" minor_time: %f"
" major_cost: %f"
" mutator_cost: %f"
@@ -454,19 +612,13 @@ void PSAdaptiveSizePolicy::compute_generation_free_space(
// And finally, our old and new sizes.
gclog_or_tty->print(" old_promo_size: " SIZE_FORMAT
- " old_eden_size: " SIZE_FORMAT
- " desired_promo_size: " SIZE_FORMAT
- " desired_eden_size: " SIZE_FORMAT,
- _promo_size, _eden_size,
- desired_promo_size, desired_eden_size);
+ " desired_promo_size: " SIZE_FORMAT,
+ _promo_size, desired_promo_size);
gclog_or_tty->cr();
}
- decay_supplemental_growth(is_full_gc);
-
set_promo_size(desired_promo_size);
- set_eden_size(desired_eden_size);
-};
+}
void PSAdaptiveSizePolicy::decay_supplemental_growth(bool is_full_gc) {
// Decay the supplemental increment? Decay the supplement growth
@@ -490,9 +642,39 @@ void PSAdaptiveSizePolicy::decay_supplemental_growth(bool is_full_gc) {
}
}
-void PSAdaptiveSizePolicy::adjust_for_minor_pause_time(bool is_full_gc,
+void PSAdaptiveSizePolicy::adjust_promo_for_minor_pause_time(bool is_full_gc,
size_t* desired_promo_size_ptr, size_t* desired_eden_size_ptr) {
+ if (PSAdjustTenuredGenForMinorPause) {
+ if (is_full_gc) {
+ set_decide_at_full_gc(decide_at_full_gc_true);
+ }
+ // If the desired eden size is as small as it will get,
+ // try to adjust the old gen size.
+ if (*desired_eden_size_ptr <= _intra_generation_alignment) {
+ // Vary the old gen size to reduce the young gen pause. This
+ // may not be a good idea. This is just a test.
+ if (minor_pause_old_estimator()->decrement_will_decrease()) {
+ set_change_old_gen_for_min_pauses(decrease_old_gen_for_min_pauses_true);
+ *desired_promo_size_ptr =
+ _promo_size - promo_decrement_aligned_down(*desired_promo_size_ptr);
+ } else {
+ set_change_old_gen_for_min_pauses(increase_old_gen_for_min_pauses_true);
+ size_t promo_heap_delta =
+ promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
+ if ((*desired_promo_size_ptr + promo_heap_delta) >
+ *desired_promo_size_ptr) {
+ *desired_promo_size_ptr =
+ _promo_size + promo_heap_delta;
+ }
+ }
+ }
+ }
+}
+
+void PSAdaptiveSizePolicy::adjust_eden_for_minor_pause_time(bool is_full_gc,
+ size_t* desired_eden_size_ptr) {
+
// Adjust the young generation size to reduce pause time of
// of collections.
//
@@ -512,49 +694,19 @@ void PSAdaptiveSizePolicy::adjust_for_minor_pause_time(bool is_full_gc,
set_change_young_gen_for_min_pauses(
increase_young_gen_for_min_pauses_true);
}
- if (PSAdjustTenuredGenForMinorPause) {
- // If the desired eden size is as small as it will get,
- // try to adjust the old gen size.
- if (*desired_eden_size_ptr <= _intra_generation_alignment) {
- // Vary the old gen size to reduce the young gen pause. This
- // may not be a good idea. This is just a test.
- if (minor_pause_old_estimator()->decrement_will_decrease()) {
- set_change_old_gen_for_min_pauses(
- decrease_old_gen_for_min_pauses_true);
- *desired_promo_size_ptr =
- _promo_size - promo_decrement_aligned_down(*desired_promo_size_ptr);
- } else {
- set_change_old_gen_for_min_pauses(
- increase_old_gen_for_min_pauses_true);
- size_t promo_heap_delta =
- promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
- if ((*desired_promo_size_ptr + promo_heap_delta) >
- *desired_promo_size_ptr) {
- *desired_promo_size_ptr =
- _promo_size + promo_heap_delta;
- }
- }
- }
- }
}
-void PSAdaptiveSizePolicy::adjust_for_pause_time(bool is_full_gc,
+void PSAdaptiveSizePolicy::adjust_promo_for_pause_time(bool is_full_gc,
size_t* desired_promo_size_ptr,
size_t* desired_eden_size_ptr) {
size_t promo_heap_delta = 0;
- size_t eden_heap_delta = 0;
- // Add some checks for a threshhold for a change. For example,
+ // Add some checks for a threshold for a change. For example,
// a change less than the required alignment is probably not worth
// attempting.
- if (is_full_gc) {
- set_decide_at_full_gc(decide_at_full_gc_true);
- }
if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) {
- adjust_for_minor_pause_time(is_full_gc,
- desired_promo_size_ptr,
- desired_eden_size_ptr);
+ adjust_promo_for_minor_pause_time(is_full_gc, desired_promo_size_ptr, desired_eden_size_ptr);
// major pause adjustments
} else if (is_full_gc) {
// Adjust for the major pause time only at full gc's because the
@@ -573,6 +725,33 @@ void PSAdaptiveSizePolicy::adjust_for_pause_time(bool is_full_gc,
// promo_increment_aligned_up(*desired_promo_size_ptr);
set_change_old_gen_for_maj_pauses(increase_old_gen_for_maj_pauses_true);
}
+ }
+
+ if (PrintAdaptiveSizePolicy && Verbose) {
+ gclog_or_tty->print_cr(
+ "PSAdaptiveSizePolicy::compute_old_gen_free_space "
+ "adjusting gen sizes for major pause (avg %f goal %f). "
+ "desired_promo_size " SIZE_FORMAT " promo delta " SIZE_FORMAT,
+ _avg_major_pause->average(), gc_pause_goal_sec(),
+ *desired_promo_size_ptr, promo_heap_delta);
+ }
+}
+
+void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(bool is_full_gc,
+ size_t* desired_promo_size_ptr,
+ size_t* desired_eden_size_ptr) {
+
+ size_t eden_heap_delta = 0;
+ // Add some checks for a threshold for a change. For example,
+ // a change less than the required alignment is probably not worth
+ // attempting.
+ if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) {
+ adjust_eden_for_minor_pause_time(is_full_gc,
+ desired_eden_size_ptr);
+ // major pause adjustments
+ } else if (is_full_gc) {
+ // Adjust for the major pause time only at full gc's because the
+ // affects of a change can only be seen at full gc's.
if (PSAdjustYoungGenForMajorPause) {
// If the promo size is at the minimum (i.e., the old gen
// size will not actually decrease), consider changing the
@@ -607,43 +786,35 @@ void PSAdaptiveSizePolicy::adjust_for_pause_time(bool is_full_gc,
if (PrintAdaptiveSizePolicy && Verbose) {
gclog_or_tty->print_cr(
- "AdaptiveSizePolicy::compute_generation_free_space "
+ "PSAdaptiveSizePolicy::compute_eden_space_size "
"adjusting gen sizes for major pause (avg %f goal %f). "
- "desired_promo_size " SIZE_FORMAT "desired_eden_size "
- SIZE_FORMAT
- " promo delta " SIZE_FORMAT " eden delta " SIZE_FORMAT,
+ "desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
_avg_major_pause->average(), gc_pause_goal_sec(),
- *desired_promo_size_ptr, *desired_eden_size_ptr,
- promo_heap_delta, eden_heap_delta);
+ *desired_eden_size_ptr, eden_heap_delta);
}
}
-void PSAdaptiveSizePolicy::adjust_for_throughput(bool is_full_gc,
- size_t* desired_promo_size_ptr,
- size_t* desired_eden_size_ptr) {
+void PSAdaptiveSizePolicy::adjust_promo_for_throughput(bool is_full_gc,
+ size_t* desired_promo_size_ptr) {
- // Add some checks for a threshhold for a change. For example,
+ // Add some checks for a threshold for a change. For example,
// a change less than the required alignment is probably not worth
// attempting.
- if (is_full_gc) {
- set_decide_at_full_gc(decide_at_full_gc_true);
- }
if ((gc_cost() + mutator_cost()) == 0.0) {
return;
}
if (PrintAdaptiveSizePolicy && Verbose) {
- gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_for_throughput("
- "is_full: %d, promo: " SIZE_FORMAT ", cur_eden: " SIZE_FORMAT "): ",
- is_full_gc, *desired_promo_size_ptr, *desired_eden_size_ptr);
+ gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_promo_for_throughput("
+ "is_full: %d, promo: " SIZE_FORMAT "): ",
+ is_full_gc, *desired_promo_size_ptr);
gclog_or_tty->print_cr("mutator_cost %f major_gc_cost %f "
"minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost());
}
// Tenured generation
if (is_full_gc) {
-
// Calculate the change to use for the tenured gen.
size_t scaled_promo_heap_delta = 0;
// Can the increment to the generation be scaled?
@@ -720,6 +891,26 @@ void PSAdaptiveSizePolicy::adjust_for_throughput(bool is_full_gc,
*desired_promo_size_ptr, scaled_promo_heap_delta);
}
}
+}
+
+void PSAdaptiveSizePolicy::adjust_eden_for_throughput(bool is_full_gc,
+ size_t* desired_eden_size_ptr) {
+
+ // Add some checks for a threshold for a change. For example,
+ // a change less than the required alignment is probably not worth
+ // attempting.
+
+ if ((gc_cost() + mutator_cost()) == 0.0) {
+ return;
+ }
+
+ if (PrintAdaptiveSizePolicy && Verbose) {
+ gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_eden_for_throughput("
+ "is_full: %d, cur_eden: " SIZE_FORMAT "): ",
+ is_full_gc, *desired_eden_size_ptr);
+ gclog_or_tty->print_cr("mutator_cost %f major_gc_cost %f "
+ "minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost());
+ }
// Young generation
size_t scaled_eden_heap_delta = 0;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp
index 030cb9da167..683c6a991fe 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -136,18 +136,24 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
double gc_minor_pause_goal_sec() const { return _gc_minor_pause_goal_sec; }
// Change the young generation size to achieve a minor GC pause time goal
- void adjust_for_minor_pause_time(bool is_full_gc,
+ void adjust_promo_for_minor_pause_time(bool is_full_gc,
size_t* desired_promo_size_ptr,
size_t* desired_eden_size_ptr);
+ void adjust_eden_for_minor_pause_time(bool is_full_gc,
+ size_t* desired_eden_size_ptr);
// Change the generation sizes to achieve a GC pause time goal
// Returned sizes are not necessarily aligned.
- void adjust_for_pause_time(bool is_full_gc,
+ void adjust_promo_for_pause_time(bool is_full_gc,
+ size_t* desired_promo_size_ptr,
+ size_t* desired_eden_size_ptr);
+ void adjust_eden_for_pause_time(bool is_full_gc,
size_t* desired_promo_size_ptr,
size_t* desired_eden_size_ptr);
// Change the generation sizes to achieve an application throughput goal
// Returned sizes are not necessarily aligned.
- void adjust_for_throughput(bool is_full_gc,
- size_t* desired_promo_size_ptr,
+ void adjust_promo_for_throughput(bool is_full_gc,
+ size_t* desired_promo_size_ptr);
+ void adjust_eden_for_throughput(bool is_full_gc,
size_t* desired_eden_size_ptr);
// Change the generation sizes to achieve minimum footprint
// Returned sizes are not aligned.
@@ -168,9 +174,6 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
size_t promo_decrement_aligned_down(size_t cur_promo);
size_t promo_increment_with_supplement_aligned_up(size_t cur_promo);
- // Decay the supplemental growth additive.
- void decay_supplemental_growth(bool is_full_gc);
-
// Returns a change that has been scaled down. Result
// is not aligned. (If useful, move to some shared
// location.)
@@ -336,7 +339,7 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
// perform a Full GC?
bool should_full_GC(size_t live_in_old_gen);
- // Calculates optimial free space sizes for both the old and young
+ // Calculates optimal (free) space sizes for both the young and old
// generations. Stores results in _eden_size and _promo_size.
// Takes current used space in all generations as input, as well
// as an indication if a full gc has just been performed, for use
@@ -347,9 +350,18 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
size_t cur_eden, // current eden in bytes
size_t max_old_gen_size,
size_t max_eden_size,
- bool is_full_gc,
- GCCause::Cause gc_cause,
- CollectorPolicy* collector_policy);
+ bool is_full_gc);
+
+ void compute_eden_space_size(size_t young_live,
+ size_t eden_live,
+ size_t cur_eden, // current eden in bytes
+ size_t max_eden_size,
+ bool is_full_gc);
+
+ void compute_old_gen_free_space(size_t old_live,
+ size_t cur_eden, // current eden in bytes
+ size_t max_old_gen_size,
+ bool is_full_gc);
// Calculates new survivor space size; returns a new tenuring threshold
// value. Stores new survivor size in _survivor_size.
@@ -390,6 +402,9 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
// Printing support
virtual bool print_adaptive_size_policy_on(outputStream* st) const;
+
+ // Decay the supplemental growth additive.
+ void decay_supplemental_growth(bool is_full_gc);
};
#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSADAPTIVESIZEPOLICY_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
index 62c578f33fd..415d6294795 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -187,11 +187,8 @@ void ParCompactionManager::follow_marking_stacks() {
// Process ObjArrays one at a time to avoid marking stack bloat.
ObjArrayTask task;
- if (_objarray_stack.pop_overflow(task)) {
- ObjArrayKlass* const k = (ObjArrayKlass*)task.obj()->klass();
- k->oop_follow_contents(this, task.obj(), task.index());
- } else if (_objarray_stack.pop_local(task)) {
- ObjArrayKlass* const k = (ObjArrayKlass*)task.obj()->klass();
+ if (_objarray_stack.pop_overflow(task) || _objarray_stack.pop_local(task)) {
+ ObjArrayKlass* k = (ObjArrayKlass*)task.obj()->klass();
k->oop_follow_contents(this, task.obj(), task.index());
}
} while (!marking_stacks_empty());
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
index adbaee43fc3..e9b8280d921 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -92,8 +92,8 @@ void PSMarkSweep::invoke(bool maximum_heap_compaction) {
const bool clear_all_soft_refs =
heap->collector_policy()->should_clear_all_soft_refs();
- int count = (maximum_heap_compaction)?1:MarkSweepAlwaysCompactCount;
- IntFlagSetting flag_setting(MarkSweepAlwaysCompactCount, count);
+ uint count = maximum_heap_compaction ? 1 : MarkSweepAlwaysCompactCount;
+ UIntFlagSetting flag_setting(MarkSweepAlwaysCompactCount, count);
PSMarkSweep::invoke_no_policy(clear_all_soft_refs || maximum_heap_compaction);
}
@@ -277,18 +277,36 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
young_gen->from_space()->capacity_in_bytes() +
young_gen->to_space()->capacity_in_bytes(),
"Sizes of space in young gen are out-of-bounds");
+
+ size_t young_live = young_gen->used_in_bytes();
+ size_t eden_live = young_gen->eden_space()->used_in_bytes();
+ size_t old_live = old_gen->used_in_bytes();
+ size_t cur_eden = young_gen->eden_space()->capacity_in_bytes();
+ size_t max_old_gen_size = old_gen->max_gen_size();
size_t max_eden_size = young_gen->max_size() -
young_gen->from_space()->capacity_in_bytes() -
young_gen->to_space()->capacity_in_bytes();
- size_policy->compute_generation_free_space(young_gen->used_in_bytes(),
- young_gen->eden_space()->used_in_bytes(),
- old_gen->used_in_bytes(),
- young_gen->eden_space()->capacity_in_bytes(),
- old_gen->max_gen_size(),
- max_eden_size,
- true /* full gc*/,
- gc_cause,
- heap->collector_policy());
+
+ // Used for diagnostics
+ size_policy->clear_generation_free_space_flags();
+
+ size_policy->compute_generation_free_space(young_live,
+ eden_live,
+ old_live,
+ cur_eden,
+ max_old_gen_size,
+ max_eden_size,
+ true /* full gc*/);
+
+ size_policy->check_gc_overhead_limit(young_live,
+ eden_live,
+ max_old_gen_size,
+ max_eden_size,
+ true /* full gc*/,
+ gc_cause,
+ heap->collector_policy());
+
+ size_policy->decay_supplemental_growth(true /* full gc*/);
heap->resize_old_gen(size_policy->calculated_old_free_size_in_bytes());
@@ -562,7 +580,6 @@ void PSMarkSweep::mark_sweep_phase2() {
// This should be moved to the shared markSweep code!
class PSAlwaysTrueClosure: public BoolObjectClosure {
public:
- void do_object(oop p) { ShouldNotReachHere(); }
bool do_object_b(oop p) { return true; }
};
static PSAlwaysTrueClosure always_true;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp
index 9844d1afdf8..820696af085 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp
@@ -88,8 +88,7 @@ void PSMarkSweepDecorator::precompact() {
* by the MarkSweepAlwaysCompactCount parameter. This is a significant
* performance improvement!
*/
- bool skip_dead = (MarkSweepAlwaysCompactCount < 1)
- || ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
+ bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
size_t allowed_deadspace = 0;
if (skip_dead) {
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
index b03107a97cd..d01bdc8b13b 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -356,6 +356,7 @@ ParallelCompactData::ParallelCompactData()
_region_start = 0;
_region_vspace = 0;
+ _reserved_byte_size = 0;
_region_data = 0;
_region_count = 0;
}
@@ -382,11 +383,11 @@ ParallelCompactData::create_vspace(size_t count, size_t element_size)
const size_t raw_bytes = count * element_size;
const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10);
const size_t granularity = os::vm_allocation_granularity();
- const size_t bytes = align_size_up(raw_bytes, MAX2(page_sz, granularity));
+ _reserved_byte_size = align_size_up(raw_bytes, MAX2(page_sz, granularity));
const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
MAX2(page_sz, granularity);
- ReservedSpace rs(bytes, rs_align, rs_align > 0);
+ ReservedSpace rs(_reserved_byte_size, rs_align, rs_align > 0);
os::trace_page_sizes("par compact", raw_bytes, raw_bytes, page_sz, rs.base(),
rs.size());
@@ -394,7 +395,7 @@ ParallelCompactData::create_vspace(size_t count, size_t element_size)
PSVirtualSpace* vspace = new PSVirtualSpace(rs, page_sz);
if (vspace != 0) {
- if (vspace->expand_by(bytes)) {
+ if (vspace->expand_by(_reserved_byte_size)) {
return vspace;
}
delete vspace;
@@ -781,7 +782,6 @@ ParallelCompactData PSParallelCompact::_summary_data;
PSParallelCompact::IsAliveClosure PSParallelCompact::_is_alive_closure;
-void PSParallelCompact::IsAliveClosure::do_object(oop p) { ShouldNotReachHere(); }
bool PSParallelCompact::IsAliveClosure::do_object_b(oop p) { return mark_bitmap()->is_marked(p); }
void PSParallelCompact::KeepAliveClosure::do_oop(oop* p) { PSParallelCompact::KeepAliveClosure::do_oop_work(p); }
@@ -841,14 +841,18 @@ bool PSParallelCompact::initialize() {
initialize_dead_wood_limiter();
if (!_mark_bitmap.initialize(mr)) {
- vm_shutdown_during_initialization("Unable to allocate bit map for "
- "parallel garbage collection for the requested heap size.");
+ vm_shutdown_during_initialization(
+ err_msg("Unable to allocate " SIZE_FORMAT "KB bitmaps for parallel "
+ "garbage collection for the requested " SIZE_FORMAT "KB heap.",
+ _mark_bitmap.reserved_byte_size()/K, mr.byte_size()/K));
return false;
}
if (!_summary_data.initialize(mr)) {
- vm_shutdown_during_initialization("Unable to allocate tables for "
- "parallel garbage collection for the requested heap size.");
+ vm_shutdown_during_initialization(
+ err_msg("Unable to allocate " SIZE_FORMAT "KB card tables for parallel "
+ "garbage collection for the requested " SIZE_FORMAT "KB heap.",
+ _summary_data.reserved_byte_size()/K, mr.byte_size()/K));
return false;
}
@@ -948,7 +952,6 @@ void PSParallelCompact::pre_compact(PreGCValues* pre_gc_values)
pre_gc_values->fill(heap);
- NOT_PRODUCT(_mark_bitmap.reset_counters());
DEBUG_ONLY(add_obj_count = add_obj_size = 0;)
DEBUG_ONLY(mark_bitmap_count = mark_bitmap_size = 0;)
@@ -2042,15 +2045,6 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
marking_start.update();
marking_phase(vmthread_cm, maximum_heap_compaction);
-#ifndef PRODUCT
- if (TraceParallelOldGCMarkingPhase) {
- gclog_or_tty->print_cr("marking_phase: cas_tries %d cas_retries %d "
- "cas_by_another %d",
- mark_bitmap()->cas_tries(), mark_bitmap()->cas_retries(),
- mark_bitmap()->cas_by_another());
- }
-#endif // #ifndef PRODUCT
-
bool max_on_system_gc = UseMaximumCompactionOnSystemGC
&& gc_cause == GCCause::_java_lang_system_gc;
summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc);
@@ -2094,19 +2088,36 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
young_gen->from_space()->capacity_in_bytes() +
young_gen->to_space()->capacity_in_bytes(),
"Sizes of space in young gen are out-of-bounds");
+
+ size_t young_live = young_gen->used_in_bytes();
+ size_t eden_live = young_gen->eden_space()->used_in_bytes();
+ size_t old_live = old_gen->used_in_bytes();
+ size_t cur_eden = young_gen->eden_space()->capacity_in_bytes();
+ size_t max_old_gen_size = old_gen->max_gen_size();
size_t max_eden_size = young_gen->max_size() -
young_gen->from_space()->capacity_in_bytes() -
young_gen->to_space()->capacity_in_bytes();
- size_policy->compute_generation_free_space(
- young_gen->used_in_bytes(),
- young_gen->eden_space()->used_in_bytes(),
- old_gen->used_in_bytes(),
- young_gen->eden_space()->capacity_in_bytes(),
- old_gen->max_gen_size(),
- max_eden_size,
- true /* full gc*/,
- gc_cause,
- heap->collector_policy());
+
+ // Used for diagnostics
+ size_policy->clear_generation_free_space_flags();
+
+ size_policy->compute_generation_free_space(young_live,
+ eden_live,
+ old_live,
+ cur_eden,
+ max_old_gen_size,
+ max_eden_size,
+ true /* full gc*/);
+
+ size_policy->check_gc_overhead_limit(young_live,
+ eden_live,
+ max_old_gen_size,
+ max_eden_size,
+ true /* full gc*/,
+ gc_cause,
+ heap->collector_policy());
+
+ size_policy->decay_supplemental_growth(true /* full gc*/);
heap->resize_old_gen(
size_policy->calculated_old_free_size_in_bytes());
@@ -2406,7 +2417,6 @@ void PSParallelCompact::adjust_class_loader(ParCompactionManager* cm,
// This should be moved to the shared markSweep code!
class PSAlwaysTrueClosure: public BoolObjectClosure {
public:
- void do_object(oop p) { ShouldNotReachHere(); }
bool do_object_b(oop p) { return true; }
};
static PSAlwaysTrueClosure always_true;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
index 6ced655c21a..79cd3f8933b 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -347,6 +347,7 @@ public:
bool initialize(MemRegion covered_region);
size_t region_count() const { return _region_count; }
+ size_t reserved_byte_size() const { return _reserved_byte_size; }
// Convert region indices to/from RegionData pointers.
inline RegionData* region(size_t region_idx) const;
@@ -420,6 +421,7 @@ private:
#endif // #ifdef ASSERT
PSVirtualSpace* _region_vspace;
+ size_t _reserved_byte_size;
RegionData* _region_data;
size_t _region_count;
};
@@ -784,7 +786,6 @@ class PSParallelCompact : AllStatic {
//
class IsAliveClosure: public BoolObjectClosure {
public:
- virtual void do_object(oop p);
virtual bool do_object_b(oop p);
};
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
index 4bc7870b98a..2a718e4bf6d 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
@@ -70,9 +70,6 @@ bool PSScavenge::_promotion_failed = false;
// Define before use
class PSIsAliveClosure: public BoolObjectClosure {
public:
- void do_object(oop p) {
- assert(false, "Do not call.");
- }
bool do_object_b(oop p) {
return (!PSScavenge::is_obj_in_young((HeapWord*) p)) || p->is_forwarded();
}
@@ -552,19 +549,33 @@ bool PSScavenge::invoke_no_policy() {
young_gen->from_space()->capacity_in_bytes() +
young_gen->to_space()->capacity_in_bytes(),
"Sizes of space in young gen are out-of-bounds");
+
+ size_t young_live = young_gen->used_in_bytes();
+ size_t eden_live = young_gen->eden_space()->used_in_bytes();
+ size_t cur_eden = young_gen->eden_space()->capacity_in_bytes();
+ size_t max_old_gen_size = old_gen->max_gen_size();
size_t max_eden_size = young_gen->max_size() -
young_gen->from_space()->capacity_in_bytes() -
young_gen->to_space()->capacity_in_bytes();
- size_policy->compute_generation_free_space(young_gen->used_in_bytes(),
- young_gen->eden_space()->used_in_bytes(),
- old_gen->used_in_bytes(),
- young_gen->eden_space()->capacity_in_bytes(),
- old_gen->max_gen_size(),
- max_eden_size,
- false /* full gc*/,
- gc_cause,
- heap->collector_policy());
+ // Used for diagnostics
+ size_policy->clear_generation_free_space_flags();
+
+ size_policy->compute_eden_space_size(young_live,
+ eden_live,
+ cur_eden,
+ max_eden_size,
+ false /* not full gc*/);
+
+ size_policy->check_gc_overhead_limit(young_live,
+ eden_live,
+ max_old_gen_size,
+ max_eden_size,
+ false /* not full gc*/,
+ gc_cause,
+ heap->collector_policy());
+
+ size_policy->decay_supplemental_growth(false /* not full gc*/);
}
// Resize the young generation at every collection
// even if new sizes have not been calculated. This is
diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
index 5e52aa1eb84..1a977bbcefa 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
#include "oops/objArrayKlass.inline.hpp"
#include "oops/oop.inline.hpp"
-unsigned int MarkSweep::_total_invocations = 0;
+uint MarkSweep::_total_invocations = 0;
Stack MarkSweep::_marking_stack;
Stack MarkSweep::_objarray_stack;
@@ -95,7 +95,7 @@ void MarkSweep::follow_stack() {
// Process ObjArrays one at a time to avoid marking stack bloat.
if (!_objarray_stack.is_empty()) {
ObjArrayTask task = _objarray_stack.pop();
- ObjArrayKlass* const k = (ObjArrayKlass*)task.obj()->klass();
+ ObjArrayKlass* k = (ObjArrayKlass*)task.obj()->klass();
k->oop_follow_contents(task.obj(), task.index());
}
} while (!_marking_stack.is_empty() || !_objarray_stack.is_empty());
@@ -166,7 +166,6 @@ void MarkSweep::restore_marks() {
MarkSweep::IsAliveClosure MarkSweep::is_alive;
-void MarkSweep::IsAliveClosure::do_object(oop p) { ShouldNotReachHere(); }
bool MarkSweep::IsAliveClosure::do_object_b(oop p) { return p->is_gc_marked(); }
MarkSweep::KeepAliveClosure MarkSweep::keep_alive;
diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
index ec724afa5ec..ab5e6ef322c 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
@@ -88,7 +88,6 @@ class MarkSweep : AllStatic {
// Used for java/lang/ref handling
class IsAliveClosure: public BoolObjectClosure {
public:
- virtual void do_object(oop p);
virtual bool do_object_b(oop p);
};
@@ -113,7 +112,7 @@ class MarkSweep : AllStatic {
//
protected:
// Total invocations of a MarkSweep collection
- static unsigned int _total_invocations;
+ static uint _total_invocations;
// Traversal stacks used during phase1
static Stack _marking_stack;
@@ -147,7 +146,7 @@ class MarkSweep : AllStatic {
static AdjustKlassClosure adjust_klass_closure;
// Accessors
- static unsigned int total_invocations() { return _total_invocations; }
+ static uint total_invocations() { return _total_invocations; }
// Reference Processing
static ReferenceProcessor* const ref_processor() { return _ref_processor; }
diff --git a/hotspot/src/share/vm/memory/allocation.cpp b/hotspot/src/share/vm/memory/allocation.cpp
index 1c1bf7ab468..a6721c9e76f 100644
--- a/hotspot/src/share/vm/memory/allocation.cpp
+++ b/hotspot/src/share/vm/memory/allocation.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -49,10 +49,15 @@
# include "os_bsd.inline.hpp"
#endif
-void* StackObj::operator new(size_t size) { ShouldNotCallThis(); return 0; };
-void StackObj::operator delete(void* p) { ShouldNotCallThis(); };
-void* _ValueObj::operator new(size_t size) { ShouldNotCallThis(); return 0; };
-void _ValueObj::operator delete(void* p) { ShouldNotCallThis(); };
+void* StackObj::operator new(size_t size) { ShouldNotCallThis(); return 0; }
+void StackObj::operator delete(void* p) { ShouldNotCallThis(); }
+void* StackObj::operator new [](size_t size) { ShouldNotCallThis(); return 0; }
+void StackObj::operator delete [](void* p) { ShouldNotCallThis(); }
+
+void* _ValueObj::operator new(size_t size) { ShouldNotCallThis(); return 0; }
+void _ValueObj::operator delete(void* p) { ShouldNotCallThis(); }
+void* _ValueObj::operator new [](size_t size) { ShouldNotCallThis(); return 0; }
+void _ValueObj::operator delete [](void* p) { ShouldNotCallThis(); }
void* MetaspaceObj::operator new(size_t size, ClassLoaderData* loader_data,
size_t word_size, bool read_only, TRAPS) {
@@ -81,7 +86,6 @@ void MetaspaceObj::print_address_on(outputStream* st) const {
st->print(" {"INTPTR_FORMAT"}", this);
}
-
void* ResourceObj::operator new(size_t size, allocation_type type, MEMFLAGS flags) {
address res;
switch (type) {
@@ -99,6 +103,10 @@ void* ResourceObj::operator new(size_t size, allocation_type type, MEMFLAGS flag
return res;
}
+void* ResourceObj::operator new [](size_t size, allocation_type type, MEMFLAGS flags) {
+ return (address) operator new(size, type, flags);
+}
+
void* ResourceObj::operator new(size_t size, const std::nothrow_t& nothrow_constant,
allocation_type type, MEMFLAGS flags) {
//should only call this with std::nothrow, use other operator new() otherwise
@@ -118,6 +126,10 @@ void* ResourceObj::operator new(size_t size, const std::nothrow_t& nothrow_cons
return res;
}
+void* ResourceObj::operator new [](size_t size, const std::nothrow_t& nothrow_constant,
+ allocation_type type, MEMFLAGS flags) {
+ return (address)operator new(size, nothrow_constant, type, flags);
+}
void ResourceObj::operator delete(void* p) {
assert(((ResourceObj *)p)->allocated_on_C_heap(),
@@ -126,6 +138,10 @@ void ResourceObj::operator delete(void* p) {
FreeHeap(p);
}
+void ResourceObj::operator delete [](void* p) {
+ operator delete(p);
+}
+
#ifdef ASSERT
void ResourceObj::set_allocation_type(address res, allocation_type type) {
// Set allocation type in the resource object
@@ -215,8 +231,6 @@ void trace_heap_free(void* p) {
tty->print_cr("Heap free " INTPTR_FORMAT, p);
}
-bool warn_new_operator = false; // see vm_main
-
//--------------------------------------------------------------------------------------
// ChunkPool implementation
@@ -360,7 +374,7 @@ class ChunkPoolCleaner : public PeriodicTask {
void* Chunk::operator new(size_t requested_size, size_t length) {
// requested_size is equal to sizeof(Chunk) but in order for the arena
// allocations to come out aligned as expected the size must be aligned
- // to expected arean alignment.
+ // to expected arena alignment.
// expect requested_size but if sizeof(Chunk) doesn't match isn't proper size we must align it.
assert(ARENA_ALIGN(requested_size) == aligned_overhead_size(), "Bad alignment");
size_t bytes = ARENA_ALIGN(requested_size) + length;
@@ -669,19 +683,40 @@ void* Arena::internal_malloc_4(size_t x) {
// a memory leak. Use CHeapObj as the base class of such objects to make it explicit
// that they're allocated on the C heap.
// Commented out in product version to avoid conflicts with third-party C++ native code.
-// %% note this is causing a problem on solaris debug build. the global
-// new is being called from jdk source and causing data corruption.
-// src/share/native/sun/awt/font/fontmanager/textcache/hsMemory.cpp::hsSoftNew
-// define CATCH_OPERATOR_NEW_USAGE if you want to use this.
-#ifdef CATCH_OPERATOR_NEW_USAGE
+// On certain platforms, such as Mac OS X (Darwin), in debug version, new is being called
+// from jdk source and causing data corruption. Such as
+// Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair
+// define ALLOW_OPERATOR_NEW_USAGE for platform on which global operator new allowed.
+//
+#ifndef ALLOW_OPERATOR_NEW_USAGE
void* operator new(size_t size){
- static bool warned = false;
- if (!warned && warn_new_operator)
- warning("should not call global (default) operator new");
- warned = true;
- return (void *) AllocateHeap(size, "global operator new");
+ assert(false, "Should not call global operator new");
+ return 0;
}
-#endif
+
+void* operator new [](size_t size){
+ assert(false, "Should not call global operator new[]");
+ return 0;
+}
+
+void* operator new(size_t size, const std::nothrow_t& nothrow_constant){
+ assert(false, "Should not call global operator new");
+ return 0;
+}
+
+void* operator new [](size_t size, std::nothrow_t& nothrow_constant){
+ assert(false, "Should not call global operator new[]");
+ return 0;
+}
+
+void operator delete(void* p) {
+ assert(false, "Should not call global delete");
+}
+
+void operator delete [](void* p) {
+ assert(false, "Should not call global delete []");
+}
+#endif // ALLOW_OPERATOR_NEW_USAGE
void AllocatedObj::print() const { print_on(tty); }
void AllocatedObj::print_value() const { print_value_on(tty); }
diff --git a/hotspot/src/share/vm/memory/allocation.hpp b/hotspot/src/share/vm/memory/allocation.hpp
index b65b2979c2f..2955943b3f6 100644
--- a/hotspot/src/share/vm/memory/allocation.hpp
+++ b/hotspot/src/share/vm/memory/allocation.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -86,12 +86,23 @@ typedef AllocFailStrategy::AllocFailEnum AllocFailType;
// subclasses.
//
// The following macros and function should be used to allocate memory
-// directly in the resource area or in the C-heap:
+// directly in the resource area or in the C-heap, The _OBJ variants
+// of the NEW/FREE_C_HEAP macros are used for alloc/dealloc simple
+// objects which are not inherited from CHeapObj, note constructor and
+// destructor are not called. The preferable way to allocate objects
+// is using the new operator.
//
-// NEW_RESOURCE_ARRAY(type,size)
+// WARNING: The array variant must only be used for a homogenous array
+// where all objects are of the exact type specified. If subtypes are
+// stored in the array then must pay attention to calling destructors
+// at needed.
+//
+// NEW_RESOURCE_ARRAY(type, size)
// NEW_RESOURCE_OBJ(type)
-// NEW_C_HEAP_ARRAY(type,size)
-// NEW_C_HEAP_OBJ(type)
+// NEW_C_HEAP_ARRAY(type, size)
+// NEW_C_HEAP_OBJ(type, memflags)
+// FREE_C_HEAP_ARRAY(type, old, memflags)
+// FREE_C_HEAP_OBJ(objname, type, memflags)
// char* AllocateHeap(size_t size, const char* name);
// void FreeHeap(void* p);
//
@@ -195,8 +206,11 @@ template class CHeapObj ALLOCATION_SUPER_CLASS_SPEC {
_NOINLINE_ void* operator new(size_t size, address caller_pc = 0);
_NOINLINE_ void* operator new (size_t size, const std::nothrow_t& nothrow_constant,
address caller_pc = 0);
-
+ _NOINLINE_ void* operator new [](size_t size, address caller_pc = 0);
+ _NOINLINE_ void* operator new [](size_t size, const std::nothrow_t& nothrow_constant,
+ address caller_pc = 0);
void operator delete(void* p);
+ void operator delete [] (void* p);
};
// Base class for objects allocated on the stack only.
@@ -206,6 +220,8 @@ class StackObj ALLOCATION_SUPER_CLASS_SPEC {
private:
void* operator new(size_t size);
void operator delete(void* p);
+ void* operator new [](size_t size);
+ void operator delete [](void* p);
};
// Base class for objects used as value objects.
@@ -229,7 +245,9 @@ class StackObj ALLOCATION_SUPER_CLASS_SPEC {
class _ValueObj {
private:
void* operator new(size_t size);
- void operator delete(void* p);
+ void operator delete(void* p);
+ void* operator new [](size_t size);
+ void operator delete [](void* p);
};
@@ -510,13 +528,24 @@ class ResourceObj ALLOCATION_SUPER_CLASS_SPEC {
public:
void* operator new(size_t size, allocation_type type, MEMFLAGS flags);
+ void* operator new [](size_t size, allocation_type type, MEMFLAGS flags);
void* operator new(size_t size, const std::nothrow_t& nothrow_constant,
allocation_type type, MEMFLAGS flags);
+ void* operator new [](size_t size, const std::nothrow_t& nothrow_constant,
+ allocation_type type, MEMFLAGS flags);
+
void* operator new(size_t size, Arena *arena) {
address res = (address)arena->Amalloc(size);
DEBUG_ONLY(set_allocation_type(res, ARENA);)
return res;
}
+
+ void* operator new [](size_t size, Arena *arena) {
+ address res = (address)arena->Amalloc(size);
+ DEBUG_ONLY(set_allocation_type(res, ARENA);)
+ return res;
+ }
+
void* operator new(size_t size) {
address res = (address)resource_allocate_bytes(size);
DEBUG_ONLY(set_allocation_type(res, RESOURCE_AREA);)
@@ -529,7 +558,20 @@ class ResourceObj ALLOCATION_SUPER_CLASS_SPEC {
return res;
}
+ void* operator new [](size_t size) {
+ address res = (address)resource_allocate_bytes(size);
+ DEBUG_ONLY(set_allocation_type(res, RESOURCE_AREA);)
+ return res;
+ }
+
+ void* operator new [](size_t size, const std::nothrow_t& nothrow_constant) {
+ address res = (address)resource_allocate_bytes(size, AllocFailStrategy::RETURN_NULL);
+ DEBUG_ONLY(if (res != NULL) set_allocation_type(res, RESOURCE_AREA);)
+ return res;
+ }
+
void operator delete(void* p);
+ void operator delete [](void* p);
};
// One of the following macros must be used when allocating an array
@@ -563,24 +605,25 @@ class ResourceObj ALLOCATION_SUPER_CLASS_SPEC {
#define REALLOC_C_HEAP_ARRAY(type, old, size, memflags)\
(type*) (ReallocateHeap((char*)old, (size) * sizeof(type), memflags))
-#define FREE_C_HEAP_ARRAY(type,old,memflags) \
+#define FREE_C_HEAP_ARRAY(type, old, memflags) \
FreeHeap((char*)(old), memflags)
-#define NEW_C_HEAP_OBJ(type, memflags)\
- NEW_C_HEAP_ARRAY(type, 1, memflags)
-
-
#define NEW_C_HEAP_ARRAY2(type, size, memflags, pc)\
(type*) (AllocateHeap((size) * sizeof(type), memflags, pc))
#define REALLOC_C_HEAP_ARRAY2(type, old, size, memflags, pc)\
(type*) (ReallocateHeap((char*)old, (size) * sizeof(type), memflags, pc))
-#define NEW_C_HEAP_OBJ2(type, memflags, pc)\
- NEW_C_HEAP_ARRAY2(type, 1, memflags, pc)
+#define NEW_C_HEAP_ARRAY3(type, size, memflags, pc, allocfail) \
+ (type*) AllocateHeap(size * sizeof(type), memflags, pc, allocfail)
+// allocate type in heap without calling ctor
+#define NEW_C_HEAP_OBJ(type, memflags)\
+ NEW_C_HEAP_ARRAY(type, 1, memflags)
-extern bool warn_new_operator;
+// deallocate obj of type in heap without calling dtor
+#define FREE_C_HEAP_OBJ(objname, memflags)\
+ FreeHeap((char*)objname, memflags);
// for statistics
#ifndef PRODUCT
diff --git a/hotspot/src/share/vm/memory/allocation.inline.hpp b/hotspot/src/share/vm/memory/allocation.inline.hpp
index d55695bdc64..138dd660a9c 100644
--- a/hotspot/src/share/vm/memory/allocation.inline.hpp
+++ b/hotspot/src/share/vm/memory/allocation.inline.hpp
@@ -86,30 +86,39 @@ inline void FreeHeap(void* p, MEMFLAGS memflags = mtInternal) {
template void* CHeapObj::operator new(size_t size,
address caller_pc){
-#ifdef ASSERT
void* p = (void*)AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
+#ifdef ASSERT
if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
- return p;
-#else
- return (void *) AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
#endif
+ return p;
}
template void* CHeapObj::operator new (size_t size,
const std::nothrow_t& nothrow_constant, address caller_pc) {
-#ifdef ASSERT
void* p = (void*)AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC),
AllocFailStrategy::RETURN_NULL);
+#ifdef ASSERT
if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
- return p;
-#else
- return (void *) AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC),
- AllocFailStrategy::RETURN_NULL);
#endif
+ return p;
+}
+
+template void* CHeapObj::operator new [](size_t size,
+ address caller_pc){
+ return CHeapObj::operator new(size, caller_pc);
+}
+
+template void* CHeapObj::operator new [](size_t size,
+ const std::nothrow_t& nothrow_constant, address caller_pc) {
+ return CHeapObj::operator new(size, nothrow_constant, caller_pc);
}
template void CHeapObj::operator delete(void* p){
- FreeHeap(p, F);
+ FreeHeap(p, F);
+}
+
+template void CHeapObj::operator delete [](void* p){
+ FreeHeap(p, F);
}
template
diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
index cbe3654cc65..7cc68debfe5 100644
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -80,15 +80,11 @@ CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap,
_covered = new MemRegion[max_covered_regions];
_committed = new MemRegion[max_covered_regions];
- if (_covered == NULL || _committed == NULL)
+ if (_covered == NULL || _committed == NULL) {
vm_exit_during_initialization("couldn't alloc card table covered region set.");
- int i;
- for (i = 0; i < max_covered_regions; i++) {
- _covered[i].set_word_size(0);
- _committed[i].set_word_size(0);
}
- _cur_covered_regions = 0;
+ _cur_covered_regions = 0;
const size_t rs_align = _page_size == (size_t) os::vm_page_size() ? 0 :
MAX2(_page_size, (size_t) os::vm_allocation_granularity());
ReservedSpace heap_rs(_byte_map_size, rs_align, false);
@@ -134,7 +130,7 @@ CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap,
|| _lowest_non_clean_base_chunk_index == NULL
|| _last_LNC_resizing_collection == NULL)
vm_exit_during_initialization("couldn't allocate an LNC array.");
- for (i = 0; i < max_covered_regions; i++) {
+ for (int i = 0; i < max_covered_regions; i++) {
_lowest_non_clean[i] = NULL;
_lowest_non_clean_chunk_size[i] = 0;
_last_LNC_resizing_collection[i] = -1;
@@ -153,6 +149,33 @@ CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap,
}
}
+CardTableModRefBS::~CardTableModRefBS() {
+ if (_covered) {
+ delete[] _covered;
+ _covered = NULL;
+ }
+ if (_committed) {
+ delete[] _committed;
+ _committed = NULL;
+ }
+ if (_lowest_non_clean) {
+ FREE_C_HEAP_ARRAY(CardArr, _lowest_non_clean, mtGC);
+ _lowest_non_clean = NULL;
+ }
+ if (_lowest_non_clean_chunk_size) {
+ FREE_C_HEAP_ARRAY(size_t, _lowest_non_clean_chunk_size, mtGC);
+ _lowest_non_clean_chunk_size = NULL;
+ }
+ if (_lowest_non_clean_base_chunk_index) {
+ FREE_C_HEAP_ARRAY(uintptr_t, _lowest_non_clean_base_chunk_index, mtGC);
+ _lowest_non_clean_base_chunk_index = NULL;
+ }
+ if (_last_LNC_resizing_collection) {
+ FREE_C_HEAP_ARRAY(int, _last_LNC_resizing_collection, mtGC);
+ _last_LNC_resizing_collection = NULL;
+ }
+}
+
int CardTableModRefBS::find_covering_region_by_base(HeapWord* base) {
int i;
for (i = 0; i < _cur_covered_regions; i++) {
diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp
index 69af2daa8e1..6b5de2a4460 100644
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -280,6 +280,7 @@ public:
}
CardTableModRefBS(MemRegion whole_heap, int max_covered_regions);
+ ~CardTableModRefBS();
// *** Barrier set functions.
diff --git a/hotspot/src/share/vm/memory/cardTableRS.cpp b/hotspot/src/share/vm/memory/cardTableRS.cpp
index bd1cd9dd2cd..7c21869945b 100644
--- a/hotspot/src/share/vm/memory/cardTableRS.cpp
+++ b/hotspot/src/share/vm/memory/cardTableRS.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,9 +54,10 @@ CardTableRS::CardTableRS(MemRegion whole_heap,
_ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions);
#endif
set_bs(_ct_bs);
- _last_cur_val_in_gen = new jbyte[GenCollectedHeap::max_gens + 1];
+ _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, GenCollectedHeap::max_gens + 1,
+ mtGC, 0, AllocFailStrategy::RETURN_NULL);
if (_last_cur_val_in_gen == NULL) {
- vm_exit_during_initialization("Could not last_cur_val_in_gen array.");
+ vm_exit_during_initialization("Could not create last_cur_val_in_gen array.");
}
for (int i = 0; i < GenCollectedHeap::max_gens + 1; i++) {
_last_cur_val_in_gen[i] = clean_card_val();
@@ -64,6 +65,16 @@ CardTableRS::CardTableRS(MemRegion whole_heap,
_ct_bs->set_CTRS(this);
}
+CardTableRS::~CardTableRS() {
+ if (_ct_bs) {
+ delete _ct_bs;
+ _ct_bs = NULL;
+ }
+ if (_last_cur_val_in_gen) {
+ FREE_C_HEAP_ARRAY(jbyte, _last_cur_val_in_gen, mtInternal);
+ }
+}
+
void CardTableRS::resize_covered_region(MemRegion new_region) {
_ct_bs->resize_covered_region(new_region);
}
diff --git a/hotspot/src/share/vm/memory/cardTableRS.hpp b/hotspot/src/share/vm/memory/cardTableRS.hpp
index 7ac9e4162bd..234b3972db5 100644
--- a/hotspot/src/share/vm/memory/cardTableRS.hpp
+++ b/hotspot/src/share/vm/memory/cardTableRS.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -102,6 +102,7 @@ class CardTableRS: public GenRemSet {
public:
CardTableRS(MemRegion whole_heap, int max_covered_regions);
+ ~CardTableRS();
// *** GenRemSet functions.
GenRemSet::Name rs_kind() { return GenRemSet::CardTable; }
diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp
index c8543d943fe..cba14a01459 100644
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp
@@ -264,6 +264,27 @@ void TwoGenerationCollectorPolicy::initialize_flags() {
// need to do this again
MaxHeapSize = align_size_up(MaxHeapSize, max_alignment());
+ // adjust max heap size if necessary
+ if (NewSize + OldSize > MaxHeapSize) {
+ if (FLAG_IS_CMDLINE(MaxHeapSize)) {
+ // somebody set a maximum heap size with the intention that we should not
+ // exceed it. Adjust New/OldSize as necessary.
+ uintx calculated_size = NewSize + OldSize;
+ double shrink_factor = (double) MaxHeapSize / calculated_size;
+ // align
+ NewSize = align_size_down((uintx) (NewSize * shrink_factor), min_alignment());
+ // OldSize is already aligned because above we aligned MaxHeapSize to
+ // max_alignment(), and we just made sure that NewSize is aligned to
+ // min_alignment(). In initialize_flags() we verified that max_alignment()
+ // is a multiple of min_alignment().
+ OldSize = MaxHeapSize - NewSize;
+ } else {
+ MaxHeapSize = NewSize + OldSize;
+ }
+ }
+ // need to do this again
+ MaxHeapSize = align_size_up(MaxHeapSize, max_alignment());
+
always_do_update_barrier = UseConcMarkSweepGC;
// Check validity of heap flags
@@ -731,7 +752,7 @@ HeapWord* GenCollectorPolicy::satisfy_failed_allocation(size_t size,
// free memory should be here, especially if they are expensive. If this
// attempt fails, an OOM exception will be thrown.
{
- IntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
+ UIntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
gch->do_collection(true /* full */,
true /* clear_all_soft_refs */,
@@ -856,7 +877,7 @@ MarkSweepPolicy::MarkSweepPolicy() {
}
void MarkSweepPolicy::initialize_generations() {
- _generations = new GenerationSpecPtr[number_of_generations()];
+ _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC, 0, AllocFailStrategy::RETURN_NULL);
if (_generations == NULL)
vm_exit_during_initialization("Unable to allocate gen spec");
diff --git a/hotspot/src/share/vm/memory/defNewGeneration.cpp b/hotspot/src/share/vm/memory/defNewGeneration.cpp
index 689ce7b8bbf..39bbd14c49b 100644
--- a/hotspot/src/share/vm/memory/defNewGeneration.cpp
+++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp
@@ -50,9 +50,6 @@
DefNewGeneration::IsAliveClosure::IsAliveClosure(Generation* g) : _g(g) {
assert(g->level() == 0, "Optimized for youngest gen.");
}
-void DefNewGeneration::IsAliveClosure::do_object(oop p) {
- assert(false, "Do not call.");
-}
bool DefNewGeneration::IsAliveClosure::do_object_b(oop p) {
return (HeapWord*)p >= _g->reserved().end() || p->is_forwarded();
}
diff --git a/hotspot/src/share/vm/memory/defNewGeneration.hpp b/hotspot/src/share/vm/memory/defNewGeneration.hpp
index 38ea742b38a..ee2871820f2 100644
--- a/hotspot/src/share/vm/memory/defNewGeneration.hpp
+++ b/hotspot/src/share/vm/memory/defNewGeneration.hpp
@@ -150,7 +150,6 @@ protected:
Generation* _g;
public:
IsAliveClosure(Generation* g);
- void do_object(oop p);
bool do_object_b(oop p);
};
diff --git a/hotspot/src/share/vm/memory/freeList.cpp b/hotspot/src/share/vm/memory/freeList.cpp
index 05e4ef0a290..385451caf81 100644
--- a/hotspot/src/share/vm/memory/freeList.cpp
+++ b/hotspot/src/share/vm/memory/freeList.cpp
@@ -54,17 +54,6 @@ FreeList::FreeList() :
_count = 0;
}
-template
-FreeList::FreeList(Chunk* fc) :
- _head(fc), _tail(fc)
-#ifdef ASSERT
- , _protecting_lock(NULL)
-#endif
-{
- _size = fc->size();
- _count = 1;
-}
-
template
void FreeList::link_head(Chunk* v) {
assert_proper_lock_protection();
diff --git a/hotspot/src/share/vm/memory/freeList.hpp b/hotspot/src/share/vm/memory/freeList.hpp
index 37438cc3888..e69c8a32f0e 100644
--- a/hotspot/src/share/vm/memory/freeList.hpp
+++ b/hotspot/src/share/vm/memory/freeList.hpp
@@ -80,8 +80,6 @@ class FreeList VALUE_OBJ_CLASS_SPEC {
// Constructor
// Construct a list without any entries.
FreeList();
- // Construct a list with "fc" as the first (and lone) entry in the list.
- FreeList(Chunk_t* fc);
// Do initialization
void initialize();
@@ -177,9 +175,6 @@ class FreeList VALUE_OBJ_CLASS_SPEC {
// found. Return NULL if "fc" is not found.
bool verify_chunk_in_free_list(Chunk_t* fc) const;
- // Stats verification
-// void verify_stats() const { ShouldNotReachHere(); };
-
// Printing support
static void print_labels_on(outputStream* st, const char* c);
void print_on(outputStream* st, const char* c = NULL) const;
diff --git a/hotspot/src/share/vm/memory/heapInspection.cpp b/hotspot/src/share/vm/memory/heapInspection.cpp
index a51ea1d1561..d9310495458 100644
--- a/hotspot/src/share/vm/memory/heapInspection.cpp
+++ b/hotspot/src/share/vm/memory/heapInspection.cpp
@@ -154,12 +154,12 @@ KlassInfoTable::~KlassInfoTable() {
}
}
-uint KlassInfoTable::hash(Klass* p) {
+uint KlassInfoTable::hash(const Klass* p) {
assert(p->is_metadata(), "all klasses are metadata");
return (uint)(((uintptr_t)p - (uintptr_t)_ref) >> 2);
}
-KlassInfoEntry* KlassInfoTable::lookup(Klass* const k) {
+KlassInfoEntry* KlassInfoTable::lookup(Klass* k) {
uint idx = hash(k) % _size;
assert(_buckets != NULL, "Allocation failure should have been caught");
KlassInfoEntry* e = _buckets[idx].lookup(k);
diff --git a/hotspot/src/share/vm/memory/heapInspection.hpp b/hotspot/src/share/vm/memory/heapInspection.hpp
index a5de4551efa..ccf39bad5d1 100644
--- a/hotspot/src/share/vm/memory/heapInspection.hpp
+++ b/hotspot/src/share/vm/memory/heapInspection.hpp
@@ -189,15 +189,15 @@ class KlassInfoEntry: public CHeapObj {
KlassInfoEntry(Klass* k, KlassInfoEntry* next) :
_klass(k), _instance_count(0), _instance_words(0), _next(next), _index(-1)
{}
- KlassInfoEntry* next() { return _next; }
- bool is_equal(Klass* k) { return k == _klass; }
- Klass* klass() { return _klass; }
- long count() { return _instance_count; }
+ KlassInfoEntry* next() const { return _next; }
+ bool is_equal(const Klass* k) { return k == _klass; }
+ Klass* klass() const { return _klass; }
+ long count() const { return _instance_count; }
void set_count(long ct) { _instance_count = ct; }
- size_t words() { return _instance_words; }
+ size_t words() const { return _instance_words; }
void set_words(size_t wds) { _instance_words = wds; }
void set_index(long index) { _index = index; }
- long index() { return _index; }
+ long index() const { return _index; }
int compare(KlassInfoEntry* e1, KlassInfoEntry* e2);
void print_on(outputStream* st) const;
const char* name() const;
@@ -215,7 +215,7 @@ class KlassInfoBucket: public CHeapObj {
KlassInfoEntry* list() { return _list; }
void set_list(KlassInfoEntry* l) { _list = l; }
public:
- KlassInfoEntry* lookup(Klass* const k);
+ KlassInfoEntry* lookup(Klass* k);
void initialize() { _list = NULL; }
void empty();
void iterate(KlassInfoClosure* cic);
@@ -231,8 +231,8 @@ class KlassInfoTable: public StackObj {
HeapWord* _ref;
KlassInfoBucket* _buckets;
- uint hash(Klass* p);
- KlassInfoEntry* lookup(Klass* const k); // allocates if not found!
+ uint hash(const Klass* p);
+ KlassInfoEntry* lookup(Klass* k); // allocates if not found!
class AllClassesFinder : public KlassClosure {
KlassInfoTable *_table;
diff --git a/hotspot/src/share/vm/memory/iterator.hpp b/hotspot/src/share/vm/memory/iterator.hpp
index 736efdd618c..e590a3e9be2 100644
--- a/hotspot/src/share/vm/memory/iterator.hpp
+++ b/hotspot/src/share/vm/memory/iterator.hpp
@@ -158,7 +158,7 @@ class ObjectClosure : public Closure {
};
-class BoolObjectClosure : public ObjectClosure {
+class BoolObjectClosure : public Closure {
public:
virtual bool do_object_b(oop obj) = 0;
};
diff --git a/hotspot/src/share/vm/memory/memRegion.cpp b/hotspot/src/share/vm/memory/memRegion.cpp
index 70483f9adcb..baabdb8781c 100644
--- a/hotspot/src/share/vm/memory/memRegion.cpp
+++ b/hotspot/src/share/vm/memory/memRegion.cpp
@@ -23,6 +23,8 @@
*/
#include "precompiled.hpp"
+#include "memory/allocation.hpp"
+#include "memory/allocation.inline.hpp"
#include "memory/memRegion.hpp"
#include "runtime/globals.hpp"
@@ -99,3 +101,19 @@ MemRegion MemRegion::minus(const MemRegion mr2) const {
ShouldNotReachHere();
return MemRegion();
}
+
+void* MemRegion::operator new(size_t size) {
+ return (address)AllocateHeap(size, mtGC, 0, AllocFailStrategy::RETURN_NULL);
+}
+
+void* MemRegion::operator new [](size_t size) {
+ return (address)AllocateHeap(size, mtGC, 0, AllocFailStrategy::RETURN_NULL);
+}
+void MemRegion::operator delete(void* p) {
+ FreeHeap(p, mtGC);
+}
+
+void MemRegion::operator delete [](void* p) {
+ FreeHeap(p, mtGC);
+}
+
diff --git a/hotspot/src/share/vm/memory/memRegion.hpp b/hotspot/src/share/vm/memory/memRegion.hpp
index 66f90f3bc38..600d27533e8 100644
--- a/hotspot/src/share/vm/memory/memRegion.hpp
+++ b/hotspot/src/share/vm/memory/memRegion.hpp
@@ -34,7 +34,9 @@
// Note that MemRegions are passed by value, not by reference.
// The intent is that they remain very small and contain no
-// objects.
+// objects. _ValueObj should never be allocated in heap but we do
+// create MemRegions (in CardTableModRefBS) in heap so operator
+// new and operator new [] added for this special case.
class MetaWord;
@@ -92,6 +94,10 @@ public:
size_t word_size() const { return _word_size; }
bool is_empty() const { return word_size() == 0; }
+ void* operator new(size_t size);
+ void* operator new [](size_t size);
+ void operator delete(void* p);
+ void operator delete [](void* p);
};
// For iteration over MemRegion's.
diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp
index 68189bf3ea1..4be4658cad9 100644
--- a/hotspot/src/share/vm/memory/metaspace.cpp
+++ b/hotspot/src/share/vm/memory/metaspace.cpp
@@ -562,6 +562,9 @@ class SpaceManager : public CHeapObj {
// protects allocations and contains.
Mutex* const _lock;
+ // Type of metadata allocated.
+ Metaspace::MetadataType _mdtype;
+
// Chunk related size
size_t _medium_chunk_bunch;
@@ -606,6 +609,7 @@ class SpaceManager : public CHeapObj {
return (BlockFreelist*) &_block_freelists;
}
+ Metaspace::MetadataType mdtype() { return _mdtype; }
VirtualSpaceList* vs_list() const { return _vs_list; }
Metachunk* current_chunk() const { return _current_chunk; }
@@ -626,7 +630,8 @@ class SpaceManager : public CHeapObj {
void initialize();
public:
- SpaceManager(Mutex* lock,
+ SpaceManager(Metaspace::MetadataType mdtype,
+ Mutex* lock,
VirtualSpaceList* vs_list);
~SpaceManager();
@@ -2032,9 +2037,11 @@ void SpaceManager::print_on(outputStream* st) const {
}
}
-SpaceManager::SpaceManager(Mutex* lock,
+SpaceManager::SpaceManager(Metaspace::MetadataType mdtype,
+ Mutex* lock,
VirtualSpaceList* vs_list) :
_vs_list(vs_list),
+ _mdtype(mdtype),
_allocated_blocks_words(0),
_allocated_chunks_words(0),
_allocated_chunks_count(0),
@@ -2050,27 +2057,27 @@ void SpaceManager::inc_size_metrics(size_t words) {
_allocated_chunks_words = _allocated_chunks_words + words;
_allocated_chunks_count++;
// Global total of capacity in allocated Metachunks
- MetaspaceAux::inc_capacity(words);
+ MetaspaceAux::inc_capacity(mdtype(), words);
// Global total of allocated Metablocks.
// used_words_slow() includes the overhead in each
// Metachunk so include it in the used when the
// Metachunk is first added (so only added once per
// Metachunk).
- MetaspaceAux::inc_used(Metachunk::overhead());
+ MetaspaceAux::inc_used(mdtype(), Metachunk::overhead());
}
void SpaceManager::inc_used_metrics(size_t words) {
// Add to the per SpaceManager total
Atomic::add_ptr(words, &_allocated_blocks_words);
// Add to the global total
- MetaspaceAux::inc_used(words);
+ MetaspaceAux::inc_used(mdtype(), words);
}
void SpaceManager::dec_total_from_size_metrics() {
- MetaspaceAux::dec_capacity(allocated_chunks_words());
- MetaspaceAux::dec_used(allocated_blocks_words());
+ MetaspaceAux::dec_capacity(mdtype(), allocated_chunks_words());
+ MetaspaceAux::dec_used(mdtype(), allocated_blocks_words());
// Also deduct the overhead per Metachunk
- MetaspaceAux::dec_used(allocated_chunks_count() * Metachunk::overhead());
+ MetaspaceAux::dec_used(mdtype(), allocated_chunks_count() * Metachunk::overhead());
}
void SpaceManager::initialize() {
@@ -2470,8 +2477,8 @@ void SpaceManager::mangle_freed_chunks() {
// MetaspaceAux
-size_t MetaspaceAux::_allocated_capacity_words = 0;
-size_t MetaspaceAux::_allocated_used_words = 0;
+size_t MetaspaceAux::_allocated_capacity_words[] = {0, 0};
+size_t MetaspaceAux::_allocated_used_words[] = {0, 0};
size_t MetaspaceAux::free_bytes() {
size_t result = 0;
@@ -2484,40 +2491,40 @@ size_t MetaspaceAux::free_bytes() {
return result;
}
-void MetaspaceAux::dec_capacity(size_t words) {
+void MetaspaceAux::dec_capacity(Metaspace::MetadataType mdtype, size_t words) {
assert_lock_strong(SpaceManager::expand_lock());
- assert(words <= _allocated_capacity_words,
+ assert(words <= allocated_capacity_words(mdtype),
err_msg("About to decrement below 0: words " SIZE_FORMAT
- " is greater than _allocated_capacity_words " SIZE_FORMAT,
- words, _allocated_capacity_words));
- _allocated_capacity_words = _allocated_capacity_words - words;
+ " is greater than _allocated_capacity_words[%u] " SIZE_FORMAT,
+ words, mdtype, allocated_capacity_words(mdtype)));
+ _allocated_capacity_words[mdtype] -= words;
}
-void MetaspaceAux::inc_capacity(size_t words) {
+void MetaspaceAux::inc_capacity(Metaspace::MetadataType mdtype, size_t words) {
assert_lock_strong(SpaceManager::expand_lock());
// Needs to be atomic
- _allocated_capacity_words = _allocated_capacity_words + words;
+ _allocated_capacity_words[mdtype] += words;
}
-void MetaspaceAux::dec_used(size_t words) {
- assert(words <= _allocated_used_words,
+void MetaspaceAux::dec_used(Metaspace::MetadataType mdtype, size_t words) {
+ assert(words <= allocated_used_words(mdtype),
err_msg("About to decrement below 0: words " SIZE_FORMAT
- " is greater than _allocated_used_words " SIZE_FORMAT,
- words, _allocated_used_words));
+ " is greater than _allocated_used_words[%u] " SIZE_FORMAT,
+ words, mdtype, allocated_used_words(mdtype)));
// For CMS deallocation of the Metaspaces occurs during the
// sweep which is a concurrent phase. Protection by the expand_lock()
// is not enough since allocation is on a per Metaspace basis
// and protected by the Metaspace lock.
jlong minus_words = (jlong) - (jlong) words;
- Atomic::add_ptr(minus_words, &_allocated_used_words);
+ Atomic::add_ptr(minus_words, &_allocated_used_words[mdtype]);
}
-void MetaspaceAux::inc_used(size_t words) {
+void MetaspaceAux::inc_used(Metaspace::MetadataType mdtype, size_t words) {
// _allocated_used_words tracks allocations for
// each piece of metadata. Those allocations are
// generally done concurrently by different application
// threads so must be done atomically.
- Atomic::add_ptr(words, &_allocated_used_words);
+ Atomic::add_ptr(words, &_allocated_used_words[mdtype]);
}
size_t MetaspaceAux::used_bytes_slow(Metaspace::MetadataType mdtype) {
@@ -2619,21 +2626,19 @@ void MetaspaceAux::print_on(outputStream* out) {
SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
" reserved " SIZE_FORMAT "K",
allocated_capacity_bytes()/K, allocated_used_bytes()/K, reserved_in_bytes()/K);
-#if 0
-// The calls to capacity_bytes_slow() and used_bytes_slow() cause
-// lock ordering assertion failures with some collectors. Do
-// not include this code until the lock ordering is fixed.
- if (PrintGCDetails && Verbose) {
- out->print_cr(" data space "
- SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
- " reserved " SIZE_FORMAT "K",
- capacity_bytes_slow(nct)/K, used_bytes_slow(nct)/K, reserved_in_bytes(nct)/K);
- out->print_cr(" class space "
- SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
- " reserved " SIZE_FORMAT "K",
- capacity_bytes_slow(ct)/K, used_bytes_slow(ct)/K, reserved_in_bytes(ct)/K);
- }
-#endif
+
+ out->print_cr(" data space "
+ SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
+ " reserved " SIZE_FORMAT "K",
+ allocated_capacity_bytes(nct)/K,
+ allocated_used_bytes(nct)/K,
+ reserved_in_bytes(nct)/K);
+ out->print_cr(" class space "
+ SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
+ " reserved " SIZE_FORMAT "K",
+ allocated_capacity_bytes(ct)/K,
+ allocated_used_bytes(ct)/K,
+ reserved_in_bytes(ct)/K);
}
// Print information for class space and data space separately.
@@ -2717,24 +2722,42 @@ void MetaspaceAux::verify_free_chunks() {
void MetaspaceAux::verify_capacity() {
#ifdef ASSERT
size_t running_sum_capacity_bytes = allocated_capacity_bytes();
- // For purposes of the running sum of used, verify against capacity
+ // For purposes of the running sum of capacity, verify against capacity
size_t capacity_in_use_bytes = capacity_bytes_slow();
assert(running_sum_capacity_bytes == capacity_in_use_bytes,
err_msg("allocated_capacity_words() * BytesPerWord " SIZE_FORMAT
" capacity_bytes_slow()" SIZE_FORMAT,
running_sum_capacity_bytes, capacity_in_use_bytes));
+ for (Metaspace::MetadataType i = Metaspace::ClassType;
+ i < Metaspace:: MetadataTypeCount;
+ i = (Metaspace::MetadataType)(i + 1)) {
+ size_t capacity_in_use_bytes = capacity_bytes_slow(i);
+ assert(allocated_capacity_bytes(i) == capacity_in_use_bytes,
+ err_msg("allocated_capacity_bytes(%u) " SIZE_FORMAT
+ " capacity_bytes_slow(%u)" SIZE_FORMAT,
+ i, allocated_capacity_bytes(i), i, capacity_in_use_bytes));
+ }
#endif
}
void MetaspaceAux::verify_used() {
#ifdef ASSERT
size_t running_sum_used_bytes = allocated_used_bytes();
- // For purposes of the running sum of used, verify against capacity
+ // For purposes of the running sum of used, verify against used
size_t used_in_use_bytes = used_bytes_slow();
assert(allocated_used_bytes() == used_in_use_bytes,
err_msg("allocated_used_bytes() " SIZE_FORMAT
- " used_bytes_slow()()" SIZE_FORMAT,
+ " used_bytes_slow()" SIZE_FORMAT,
allocated_used_bytes(), used_in_use_bytes));
+ for (Metaspace::MetadataType i = Metaspace::ClassType;
+ i < Metaspace:: MetadataTypeCount;
+ i = (Metaspace::MetadataType)(i + 1)) {
+ size_t used_in_use_bytes = used_bytes_slow(i);
+ assert(allocated_used_bytes(i) == used_in_use_bytes,
+ err_msg("allocated_used_bytes(%u) " SIZE_FORMAT
+ " used_bytes_slow(%u)" SIZE_FORMAT,
+ i, allocated_used_bytes(i), i, used_in_use_bytes));
+ }
#endif
}
@@ -2835,7 +2858,7 @@ void Metaspace::initialize(Mutex* lock,
assert(space_list() != NULL,
"Metadata VirtualSpaceList has not been initialized");
- _vsm = new SpaceManager(lock, space_list());
+ _vsm = new SpaceManager(Metaspace::NonClassType, lock, space_list());
if (_vsm == NULL) {
return;
}
@@ -2849,7 +2872,7 @@ void Metaspace::initialize(Mutex* lock,
"Class VirtualSpaceList has not been initialized");
// Allocate SpaceManager for classes.
- _class_vsm = new SpaceManager(lock, class_space_list());
+ _class_vsm = new SpaceManager(Metaspace::ClassType, lock, class_space_list());
if (_class_vsm == NULL) {
return;
}
diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp
index 1108c79feab..7d8e0d9410e 100644
--- a/hotspot/src/share/vm/memory/metaspace.hpp
+++ b/hotspot/src/share/vm/memory/metaspace.hpp
@@ -86,7 +86,10 @@ class Metaspace : public CHeapObj {
friend class MetaspaceAux;
public:
- enum MetadataType {ClassType, NonClassType};
+ enum MetadataType {ClassType = 0,
+ NonClassType = ClassType + 1,
+ MetadataTypeCount = ClassType + 2
+ };
enum MetaspaceType {
StandardMetaspaceType,
BootMetaspaceType,
@@ -184,20 +187,22 @@ class MetaspaceAux : AllStatic {
public:
// Running sum of space in all Metachunks that has been
// allocated to a Metaspace. This is used instead of
- // iterating over all the classloaders
- static size_t _allocated_capacity_words;
+ // iterating over all the classloaders. One for each
+ // type of Metadata
+ static size_t _allocated_capacity_words[Metaspace:: MetadataTypeCount];
// Running sum of space in all Metachunks that have
- // are being used for metadata.
- static size_t _allocated_used_words;
+ // are being used for metadata. One for each
+ // type of Metadata.
+ static size_t _allocated_used_words[Metaspace:: MetadataTypeCount];
public:
// Decrement and increment _allocated_capacity_words
- static void dec_capacity(size_t words);
- static void inc_capacity(size_t words);
+ static void dec_capacity(Metaspace::MetadataType type, size_t words);
+ static void inc_capacity(Metaspace::MetadataType type, size_t words);
// Decrement and increment _allocated_used_words
- static void dec_used(size_t words);
- static void inc_used(size_t words);
+ static void dec_used(Metaspace::MetadataType type, size_t words);
+ static void inc_used(Metaspace::MetadataType type, size_t words);
// Total of space allocated to metadata in all Metaspaces.
// This sums the space used in each Metachunk by
@@ -211,18 +216,32 @@ class MetaspaceAux : AllStatic {
static size_t free_chunks_total();
static size_t free_chunks_total_in_bytes();
+ static size_t allocated_capacity_words(Metaspace::MetadataType mdtype) {
+ return _allocated_capacity_words[mdtype];
+ }
static size_t allocated_capacity_words() {
- return _allocated_capacity_words;
+ return _allocated_capacity_words[Metaspace::ClassType] +
+ _allocated_capacity_words[Metaspace::NonClassType];
+ }
+ static size_t allocated_capacity_bytes(Metaspace::MetadataType mdtype) {
+ return allocated_capacity_words(mdtype) * BytesPerWord;
}
static size_t allocated_capacity_bytes() {
- return _allocated_capacity_words * BytesPerWord;
+ return allocated_capacity_words() * BytesPerWord;
}
+ static size_t allocated_used_words(Metaspace::MetadataType mdtype) {
+ return _allocated_used_words[mdtype];
+ }
static size_t allocated_used_words() {
- return _allocated_used_words;
+ return _allocated_used_words[Metaspace::ClassType] +
+ _allocated_used_words[Metaspace::NonClassType];
+ }
+ static size_t allocated_used_bytes(Metaspace::MetadataType mdtype) {
+ return allocated_used_words(mdtype) * BytesPerWord;
}
static size_t allocated_used_bytes() {
- return _allocated_used_words * BytesPerWord;
+ return allocated_used_words() * BytesPerWord;
}
static size_t free_bytes();
diff --git a/hotspot/src/share/vm/memory/referenceProcessor.cpp b/hotspot/src/share/vm/memory/referenceProcessor.cpp
index 765e5085cfa..20ae92ac0f9 100644
--- a/hotspot/src/share/vm/memory/referenceProcessor.cpp
+++ b/hotspot/src/share/vm/memory/referenceProcessor.cpp
@@ -252,7 +252,6 @@ uint ReferenceProcessor::count_jni_refs() {
class AlwaysAliveClosure: public BoolObjectClosure {
public:
virtual bool do_object_b(oop obj) { return true; }
- virtual void do_object(oop obj) { assert(false, "Don't call"); }
};
class CountHandleClosure: public OopClosure {
diff --git a/hotspot/src/share/vm/memory/sharedHeap.cpp b/hotspot/src/share/vm/memory/sharedHeap.cpp
index cd577d4b57e..edc1a670a11 100644
--- a/hotspot/src/share/vm/memory/sharedHeap.cpp
+++ b/hotspot/src/share/vm/memory/sharedHeap.cpp
@@ -212,7 +212,6 @@ void SharedHeap::process_strong_roots(bool activate_scope,
class AlwaysTrueClosure: public BoolObjectClosure {
public:
- void do_object(oop p) { ShouldNotReachHere(); }
bool do_object_b(oop p) { return true; }
};
static AlwaysTrueClosure always_true;
diff --git a/hotspot/src/share/vm/memory/space.hpp b/hotspot/src/share/vm/memory/space.hpp
index a434b0a337a..eb1e209a850 100644
--- a/hotspot/src/share/vm/memory/space.hpp
+++ b/hotspot/src/share/vm/memory/space.hpp
@@ -537,9 +537,8 @@ protected:
* Occasionally, we want to ensure a full compaction, which is determined \
* by the MarkSweepAlwaysCompactCount parameter. \
*/ \
- int invocations = MarkSweep::total_invocations(); \
- bool skip_dead = (MarkSweepAlwaysCompactCount < 1) \
- ||((invocations % MarkSweepAlwaysCompactCount) != 0); \
+ uint invocations = MarkSweep::total_invocations(); \
+ bool skip_dead = ((invocations % MarkSweepAlwaysCompactCount) != 0); \
\
size_t allowed_deadspace = 0; \
if (skip_dead) { \
diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp
index a0849df9914..77fc4b846c8 100644
--- a/hotspot/src/share/vm/memory/universe.cpp
+++ b/hotspot/src/share/vm/memory/universe.cpp
@@ -1425,25 +1425,25 @@ ActiveMethodOopsCache::~ActiveMethodOopsCache() {
}
-void ActiveMethodOopsCache::add_previous_version(Method* const method) {
+void ActiveMethodOopsCache::add_previous_version(Method* method) {
assert(Thread::current()->is_VM_thread(),
"only VMThread can add previous versions");
// Only append the previous method if it is executing on the stack.
if (method->on_stack()) {
- if (_prev_methods == NULL) {
- // This is the first previous version so make some space.
- // Start with 2 elements under the assumption that the class
- // won't be redefined much.
+ if (_prev_methods == NULL) {
+ // This is the first previous version so make some space.
+ // Start with 2 elements under the assumption that the class
+ // won't be redefined much.
_prev_methods = new (ResourceObj::C_HEAP, mtClass) GrowableArray(2, true);
- }
+ }
- // RC_TRACE macro has an embedded ResourceMark
- RC_TRACE(0x00000100,
- ("add: %s(%s): adding prev version ref for cached method @%d",
- method->name()->as_C_string(), method->signature()->as_C_string(),
- _prev_methods->length()));
+ // RC_TRACE macro has an embedded ResourceMark
+ RC_TRACE(0x00000100,
+ ("add: %s(%s): adding prev version ref for cached method @%d",
+ method->name()->as_C_string(), method->signature()->as_C_string(),
+ _prev_methods->length()));
_prev_methods->append(method);
}
@@ -1464,16 +1464,17 @@ void ActiveMethodOopsCache::add_previous_version(Method* const method) {
MetadataFactory::free_metadata(method->method_holder()->class_loader_data(), method);
} else {
// RC_TRACE macro has an embedded ResourceMark
- RC_TRACE(0x00000400, ("add: %s(%s): previous cached method @%d is alive",
- method->name()->as_C_string(), method->signature()->as_C_string(), i));
+ RC_TRACE(0x00000400,
+ ("add: %s(%s): previous cached method @%d is alive",
+ method->name()->as_C_string(), method->signature()->as_C_string(), i));
}
}
} // end add_previous_version()
-bool ActiveMethodOopsCache::is_same_method(Method* const method) const {
+bool ActiveMethodOopsCache::is_same_method(const Method* method) const {
InstanceKlass* ik = InstanceKlass::cast(klass());
- Method* check_method = ik->method_with_idnum(method_idnum());
+ const Method* check_method = ik->method_with_idnum(method_idnum());
assert(check_method != NULL, "sanity check");
if (check_method == method) {
// done with the easy case
diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp
index 48d32f71ed6..6daf75d2c7f 100644
--- a/hotspot/src/share/vm/memory/universe.hpp
+++ b/hotspot/src/share/vm/memory/universe.hpp
@@ -90,8 +90,8 @@ class ActiveMethodOopsCache : public CommonMethodOopCache {
ActiveMethodOopsCache() { _prev_methods = NULL; }
~ActiveMethodOopsCache();
- void add_previous_version(Method* const method);
- bool is_same_method(Method* const method) const;
+ void add_previous_version(Method* method);
+ bool is_same_method(const Method* method) const;
};
diff --git a/hotspot/src/share/vm/oops/constantPool.hpp b/hotspot/src/share/vm/oops/constantPool.hpp
index 58cad7a6771..eca2dcd9c56 100644
--- a/hotspot/src/share/vm/oops/constantPool.hpp
+++ b/hotspot/src/share/vm/oops/constantPool.hpp
@@ -354,7 +354,7 @@ class ConstantPool : public Metadata {
Symbol* klass_name_at(int which); // Returns the name, w/o resolving.
- Klass* resolved_klass_at(int which) { // Used by Compiler
+ Klass* resolved_klass_at(int which) const { // Used by Compiler
guarantee(tag_at(which).is_klass(), "Corrupted constant pool");
// Must do an acquire here in case another thread resolved the klass
// behind our back, lest we later load stale values thru the oop.
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index ecb0dcbac93..06827e68148 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -2724,7 +2724,7 @@ void InstanceKlass::remove_osr_nmethod(nmethod* n) {
OsrList_lock->unlock();
}
-nmethod* InstanceKlass::lookup_osr_nmethod(Method* const m, int bci, int comp_level, bool match_level) const {
+nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_level, bool match_level) const {
// This is a short non-blocking critical region, so the no safepoint check is ok.
OsrList_lock->lock_without_safepoint_check();
nmethod* osr = osr_nmethods_head();
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
index 55b8ff48c4c..8ee9adc01f1 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
@@ -739,7 +739,7 @@ class InstanceKlass: public Klass {
void set_osr_nmethods_head(nmethod* h) { _osr_nmethods_head = h; };
void add_osr_nmethod(nmethod* n);
void remove_osr_nmethod(nmethod* n);
- nmethod* lookup_osr_nmethod(Method* const m, int bci, int level, bool match_level) const;
+ nmethod* lookup_osr_nmethod(const Method* m, int bci, int level, bool match_level) const;
// Breakpoint support (see methods on Method* for details)
BreakpointInfo* breakpoints() const { return _breakpoints; };
diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp
index 06c644c3478..52dd2645979 100644
--- a/hotspot/src/share/vm/oops/klass.cpp
+++ b/hotspot/src/share/vm/oops/klass.cpp
@@ -50,7 +50,7 @@ void Klass::set_name(Symbol* n) {
if (_name != NULL) _name->increment_refcount();
}
-bool Klass::is_subclass_of(Klass* k) const {
+bool Klass::is_subclass_of(const Klass* k) const {
// Run up the super chain and check
if (this == k) return true;
diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp
index d2a41914653..acd402c79ad 100644
--- a/hotspot/src/share/vm/oops/klass.hpp
+++ b/hotspot/src/share/vm/oops/klass.hpp
@@ -393,9 +393,10 @@ class Klass : public Metadata {
// vtables
virtual klassVtable* vtable() const { return NULL; }
+ virtual int vtable_length() const { return 0; }
// subclass check
- bool is_subclass_of(Klass* k) const;
+ bool is_subclass_of(const Klass* k) const;
// subtype check: true if is_subclass_of, or if k is interface and receiver implements it
bool is_subtype_of(Klass* k) const {
juint off = k->super_check_offset();
diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp
index 74364c3bd6a..62b81ea4e93 100644
--- a/hotspot/src/share/vm/oops/method.cpp
+++ b/hotspot/src/share/vm/oops/method.cpp
@@ -832,7 +832,9 @@ void Method::link_method(methodHandle h_method, TRAPS) {
assert(entry != NULL, "interpreter entry must be non-null");
// Sets both _i2i_entry and _from_interpreted_entry
set_interpreter_entry(entry);
- if (is_native() && !is_method_handle_intrinsic()) {
+
+ // Don't overwrite already registered native entries.
+ if (is_native() && !has_native_function()) {
set_native_function(
SharedRuntime::native_method_throw_unsatisfied_link_error_entry(),
!native_bind_event_is_interesting);
@@ -1581,7 +1583,7 @@ int Method::backedge_count() {
}
int Method::highest_comp_level() const {
- MethodData* mdo = method_data();
+ const MethodData* mdo = method_data();
if (mdo != NULL) {
return mdo->highest_comp_level();
} else {
@@ -1590,7 +1592,7 @@ int Method::highest_comp_level() const {
}
int Method::highest_osr_comp_level() const {
- MethodData* mdo = method_data();
+ const MethodData* mdo = method_data();
if (mdo != NULL) {
return mdo->highest_osr_comp_level();
} else {
diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp
index 7e2696a40a4..54c2647b790 100644
--- a/hotspot/src/share/vm/oops/method.hpp
+++ b/hotspot/src/share/vm/oops/method.hpp
@@ -986,7 +986,7 @@ class ExceptionTable : public StackObj {
u2 _length;
public:
- ExceptionTable(Method* m) {
+ ExceptionTable(const Method* m) {
if (m->has_exception_handler()) {
_table = m->exception_table_start();
_length = m->exception_table_length();
diff --git a/hotspot/src/share/vm/oops/methodData.hpp b/hotspot/src/share/vm/oops/methodData.hpp
index b9fc63e306b..765b91c142c 100644
--- a/hotspot/src/share/vm/oops/methodData.hpp
+++ b/hotspot/src/share/vm/oops/methodData.hpp
@@ -1338,9 +1338,9 @@ public:
void set_would_profile(bool p) { _would_profile = p; }
bool would_profile() const { return _would_profile; }
- int highest_comp_level() { return _highest_comp_level; }
+ int highest_comp_level() const { return _highest_comp_level; }
void set_highest_comp_level(int level) { _highest_comp_level = level; }
- int highest_osr_comp_level() { return _highest_osr_comp_level; }
+ int highest_osr_comp_level() const { return _highest_osr_comp_level; }
void set_highest_osr_comp_level(int level) { _highest_osr_comp_level = level; }
int num_loops() const { return _num_loops; }
diff --git a/hotspot/src/share/vm/opto/bytecodeInfo.cpp b/hotspot/src/share/vm/opto/bytecodeInfo.cpp
index 6d8f1b3da91..9d2a36be28e 100644
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp
@@ -85,16 +85,35 @@ InlineTree::InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvm
assert(!UseOldInlining, "do not use for old stuff");
}
+/**
+ * Return true when EA is ON and a java constructor is called or
+ * a super constructor is called from an inlined java constructor.
+ * Also return true for boxing methods.
+ */
static bool is_init_with_ea(ciMethod* callee_method,
ciMethod* caller_method, Compile* C) {
- // True when EA is ON and a java constructor is called or
- // a super constructor is called from an inlined java constructor.
- return C->do_escape_analysis() && EliminateAllocations &&
- ( callee_method->is_initializer() ||
- (caller_method->is_initializer() &&
- caller_method != C->method() &&
- caller_method->holder()->is_subclass_of(callee_method->holder()))
- );
+ if (!C->do_escape_analysis() || !EliminateAllocations) {
+ return false; // EA is off
+ }
+ if (callee_method->is_initializer()) {
+ return true; // constuctor
+ }
+ if (caller_method->is_initializer() &&
+ caller_method != C->method() &&
+ caller_method->holder()->is_subclass_of(callee_method->holder())) {
+ return true; // super constructor is called from inlined constructor
+ }
+ if (C->eliminate_boxing() && callee_method->is_boxing_method()) {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Force inlining unboxing accessor.
+ */
+static bool is_unboxing_method(ciMethod* callee_method, Compile* C) {
+ return C->eliminate_boxing() && callee_method->is_unboxing_method();
}
// positive filter: should callee be inlined?
@@ -144,6 +163,7 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method,
// bump the max size if the call is frequent
if ((freq >= InlineFrequencyRatio) ||
(call_site_count >= InlineFrequencyCount) ||
+ is_unboxing_method(callee_method, C) ||
is_init_with_ea(callee_method, caller_method, C)) {
max_inline_size = C->freq_inline_size();
@@ -237,8 +257,25 @@ bool InlineTree::should_not_inline(ciMethod *callee_method,
return false;
}
+ if (callee_method->should_not_inline()) {
+ set_msg("disallowed by CompilerOracle");
+ return true;
+ }
+
+#ifndef PRODUCT
+ if (ciReplay::should_not_inline(callee_method)) {
+ set_msg("disallowed by ciReplay");
+ return true;
+ }
+#endif
+
// Now perform checks which are heuristic
+ if (is_unboxing_method(callee_method, C)) {
+ // Inline unboxing methods.
+ return false;
+ }
+
if (!callee_method->force_inline()) {
if (callee_method->has_compiled_code() &&
callee_method->instructions_size() > InlineSmallCode) {
@@ -260,18 +297,6 @@ bool InlineTree::should_not_inline(ciMethod *callee_method,
}
}
- if (callee_method->should_not_inline()) {
- set_msg("disallowed by CompilerOracle");
- return true;
- }
-
-#ifndef PRODUCT
- if (ciReplay::should_not_inline(callee_method)) {
- set_msg("disallowed by ciReplay");
- return true;
- }
-#endif
-
if (UseStringCache) {
// Do not inline StringCache::profile() method used only at the beginning.
if (callee_method->name() == ciSymbol::profile_name() &&
@@ -296,9 +321,8 @@ bool InlineTree::should_not_inline(ciMethod *callee_method,
}
if (is_init_with_ea(callee_method, caller_method, C)) {
-
// Escape Analysis: inline all executed constructors
-
+ return false;
} else if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold,
CompileThreshold >> 1))) {
set_msg("executed < MinInliningThreshold times");
diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp
index f01101cd4bb..49ed1e8bcf0 100644
--- a/hotspot/src/share/vm/opto/c2_globals.hpp
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp
@@ -442,12 +442,15 @@
notproduct(bool, PrintEliminateLocks, false, \
"Print out when locks are eliminated") \
\
- diagnostic(bool, EliminateAutoBox, false, \
- "Private flag to control optimizations for autobox elimination") \
+ product(bool, EliminateAutoBox, true, \
+ "Control optimizations for autobox elimination") \
\
product(intx, AutoBoxCacheMax, 128, \
"Sets max value cached by the java.lang.Integer autobox cache") \
\
+ experimental(bool, AggressiveUnboxing, false, \
+ "Control optimizations for aggressive boxing elimination") \
+ \
product(bool, DoEscapeAnalysis, true, \
"Perform escape analysis") \
\
diff --git a/hotspot/src/share/vm/opto/c2compiler.cpp b/hotspot/src/share/vm/opto/c2compiler.cpp
index 713e3f1d1a1..85f30a5ac1e 100644
--- a/hotspot/src/share/vm/opto/c2compiler.cpp
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp
@@ -125,9 +125,10 @@ void C2Compiler::compile_method(ciEnv* env,
bool subsume_loads = SubsumeLoads;
bool do_escape_analysis = DoEscapeAnalysis &&
!env->jvmti_can_access_local_variables();
+ bool eliminate_boxing = EliminateAutoBox;
while (!env->failing()) {
// Attempt to compile while subsuming loads into machine instructions.
- Compile C(env, this, target, entry_bci, subsume_loads, do_escape_analysis);
+ Compile C(env, this, target, entry_bci, subsume_loads, do_escape_analysis, eliminate_boxing);
// Check result and retry if appropriate.
@@ -142,6 +143,12 @@ void C2Compiler::compile_method(ciEnv* env,
do_escape_analysis = false;
continue; // retry
}
+ if (C.has_boxed_value()) {
+ // Recompile without boxing elimination regardless failure reason.
+ assert(eliminate_boxing, "must make progress");
+ eliminate_boxing = false;
+ continue; // retry
+ }
// Pass any other failure reason up to the ciEnv.
// Note that serious, irreversible failures are already logged
// on the ciEnv via env->record_method_not_compilable().
diff --git a/hotspot/src/share/vm/opto/callGenerator.cpp b/hotspot/src/share/vm/opto/callGenerator.cpp
index 8cac8ee769b..470a36e5c9f 100644
--- a/hotspot/src/share/vm/opto/callGenerator.cpp
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp
@@ -134,7 +134,7 @@ JVMState* DirectCallGenerator::generate(JVMState* jvms) {
kit.C->log()->elem("direct_call bci='%d'", jvms->bci());
}
- CallStaticJavaNode *call = new (kit.C) CallStaticJavaNode(tf(), target, method(), kit.bci());
+ CallStaticJavaNode *call = new (kit.C) CallStaticJavaNode(kit.C, tf(), target, method(), kit.bci());
_call_node = call; // Save the call node in case we need it later
if (!is_static) {
// Make an explicit receiver null_check as part of this call.
@@ -304,29 +304,34 @@ class LateInlineCallGenerator : public DirectCallGenerator {
void LateInlineCallGenerator::do_late_inline() {
// Can't inline it
- if (call_node() == NULL || call_node()->outcnt() == 0 ||
- call_node()->in(0) == NULL || call_node()->in(0)->is_top()) {
+ CallStaticJavaNode* call = call_node();
+ if (call == NULL || call->outcnt() == 0 ||
+ call->in(0) == NULL || call->in(0)->is_top()) {
return;
}
- const TypeTuple *r = call_node()->tf()->domain();
+ const TypeTuple *r = call->tf()->domain();
for (int i1 = 0; i1 < method()->arg_size(); i1++) {
- if (call_node()->in(TypeFunc::Parms + i1)->is_top() && r->field_at(TypeFunc::Parms + i1) != Type::HALF) {
+ if (call->in(TypeFunc::Parms + i1)->is_top() && r->field_at(TypeFunc::Parms + i1) != Type::HALF) {
assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing");
return;
}
}
- if (call_node()->in(TypeFunc::Memory)->is_top()) {
+ if (call->in(TypeFunc::Memory)->is_top()) {
assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing");
return;
}
- CallStaticJavaNode* call = call_node();
+ Compile* C = Compile::current();
+ // Remove inlined methods from Compiler's lists.
+ if (call->is_macro()) {
+ C->remove_macro_node(call);
+ }
// Make a clone of the JVMState that appropriate to use for driving a parse
- Compile* C = Compile::current();
- JVMState* jvms = call->jvms()->clone_shallow(C);
+ JVMState* old_jvms = call->jvms();
+ JVMState* jvms = old_jvms->clone_shallow(C);
uint size = call->req();
SafePointNode* map = new (C) SafePointNode(size, jvms);
for (uint i1 = 0; i1 < size; i1++) {
@@ -340,16 +345,23 @@ void LateInlineCallGenerator::do_late_inline() {
map->set_req(TypeFunc::Memory, mem);
}
- // Make enough space for the expression stack and transfer the incoming arguments
- int nargs = method()->arg_size();
+ uint nargs = method()->arg_size();
+ // blow away old call arguments
+ Node* top = C->top();
+ for (uint i1 = 0; i1 < nargs; i1++) {
+ map->set_req(TypeFunc::Parms + i1, top);
+ }
jvms->set_map(map);
+
+ // Make enough space in the expression stack to transfer
+ // the incoming arguments and return value.
map->ensure_stack(jvms, jvms->method()->max_stack());
- if (nargs > 0) {
- for (int i1 = 0; i1 < nargs; i1++) {
- map->set_req(i1 + jvms->argoff(), call->in(TypeFunc::Parms + i1));
- }
+ for (uint i1 = 0; i1 < nargs; i1++) {
+ map->set_argument(jvms, i1, call->in(TypeFunc::Parms + i1));
}
+ // This check is done here because for_method_handle_inline() method
+ // needs jvms for inlined state.
if (!do_late_inline_check(jvms)) {
map->disconnect_inputs(NULL, C);
return;
@@ -480,6 +492,26 @@ CallGenerator* CallGenerator::for_string_late_inline(ciMethod* method, CallGener
return new LateInlineStringCallGenerator(method, inline_cg);
}
+class LateInlineBoxingCallGenerator : public LateInlineCallGenerator {
+
+ public:
+ LateInlineBoxingCallGenerator(ciMethod* method, CallGenerator* inline_cg) :
+ LateInlineCallGenerator(method, inline_cg) {}
+
+ virtual JVMState* generate(JVMState* jvms) {
+ Compile *C = Compile::current();
+ C->print_inlining_skip(this);
+
+ C->add_boxing_late_inline(this);
+
+ JVMState* new_jvms = DirectCallGenerator::generate(jvms);
+ return new_jvms;
+ }
+};
+
+CallGenerator* CallGenerator::for_boxing_late_inline(ciMethod* method, CallGenerator* inline_cg) {
+ return new LateInlineBoxingCallGenerator(method, inline_cg);
+}
//---------------------------WarmCallGenerator--------------------------------
// Internal class which handles initial deferral of inlining decisions.
diff --git a/hotspot/src/share/vm/opto/callGenerator.hpp b/hotspot/src/share/vm/opto/callGenerator.hpp
index 7051dbe5c2e..8cdc4e827cd 100644
--- a/hotspot/src/share/vm/opto/callGenerator.hpp
+++ b/hotspot/src/share/vm/opto/callGenerator.hpp
@@ -125,6 +125,7 @@ class CallGenerator : public ResourceObj {
static CallGenerator* for_late_inline(ciMethod* m, CallGenerator* inline_cg);
static CallGenerator* for_mh_late_inline(ciMethod* caller, ciMethod* callee, bool input_not_const);
static CallGenerator* for_string_late_inline(ciMethod* m, CallGenerator* inline_cg);
+ static CallGenerator* for_boxing_late_inline(ciMethod* m, CallGenerator* inline_cg);
// How to make a call but defer the decision whether to inline or not.
static CallGenerator* for_warm_call(WarmCallInfo* ci,
diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp
index c90b76d4adb..cce6c5f29b4 100644
--- a/hotspot/src/share/vm/opto/callnode.cpp
+++ b/hotspot/src/share/vm/opto/callnode.cpp
@@ -523,7 +523,9 @@ void JVMState::dump_spec(outputStream *st) const {
void JVMState::dump_on(outputStream* st) const {
- if (_map && !((uintptr_t)_map & 1)) {
+ bool print_map = _map && !((uintptr_t)_map & 1) &&
+ ((caller() == NULL) || (caller()->map() != _map));
+ if (print_map) {
if (_map->len() > _map->req()) { // _map->has_exceptions()
Node* ex = _map->in(_map->req()); // _map->next_exception()
// skip the first one; it's already being printed
@@ -532,7 +534,10 @@ void JVMState::dump_on(outputStream* st) const {
ex->dump(1);
}
}
- _map->dump(2);
+ _map->dump(Verbose ? 2 : 1);
+ }
+ if (caller() != NULL) {
+ caller()->dump_on(st);
}
st->print("JVMS depth=%d loc=%d stk=%d arg=%d mon=%d scalar=%d end=%d mondepth=%d sp=%d bci=%d reexecute=%s method=",
depth(), locoff(), stkoff(), argoff(), monoff(), scloff(), endoff(), monitor_depth(), sp(), bci(), should_reexecute()?"true":"false");
@@ -546,9 +551,6 @@ void JVMState::dump_on(outputStream* st) const {
_method->print_codes_on(bci(), bci()+1, st);
}
}
- if (caller() != NULL) {
- caller()->dump_on(st);
- }
}
// Extra way to dump a jvms from the debugger,
@@ -584,6 +586,15 @@ JVMState* JVMState::clone_deep(Compile* C) const {
return n;
}
+/**
+ * Reset map for all callers
+ */
+void JVMState::set_map_deep(SafePointNode* map) {
+ for (JVMState* p = this; p->_caller != NULL; p = p->_caller) {
+ p->set_map(map);
+ }
+}
+
//=============================================================================
uint CallNode::cmp( const Node &n ) const
{ return _tf == ((CallNode&)n)._tf && _jvms == ((CallNode&)n)._jvms; }
@@ -663,17 +674,49 @@ uint CallNode::match_edge(uint idx) const {
// Determine whether the call could modify the field of the specified
// instance at the specified offset.
//
-bool CallNode::may_modify(const TypePtr *addr_t, PhaseTransform *phase) {
- const TypeOopPtr *adrInst_t = addr_t->isa_oopptr();
-
- // If not an OopPtr or not an instance type, assume the worst.
- // Note: currently this method is called only for instance types.
- if (adrInst_t == NULL || !adrInst_t->is_known_instance()) {
- return true;
+bool CallNode::may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase) {
+ assert((t_oop != NULL), "sanity");
+ if (t_oop->is_known_instance()) {
+ // The instance_id is set only for scalar-replaceable allocations which
+ // are not passed as arguments according to Escape Analysis.
+ return false;
}
- // The instance_id is set only for scalar-replaceable allocations which
- // are not passed as arguments according to Escape Analysis.
- return false;
+ if (t_oop->is_ptr_to_boxed_value()) {
+ ciKlass* boxing_klass = t_oop->klass();
+ if (is_CallStaticJava() && as_CallStaticJava()->is_boxing_method()) {
+ // Skip unrelated boxing methods.
+ Node* proj = proj_out(TypeFunc::Parms);
+ if ((proj == NULL) || (phase->type(proj)->is_instptr()->klass() != boxing_klass)) {
+ return false;
+ }
+ }
+ if (is_CallJava() && as_CallJava()->method() != NULL) {
+ ciMethod* meth = as_CallJava()->method();
+ if (meth->is_accessor()) {
+ return false;
+ }
+ // May modify (by reflection) if an boxing object is passed
+ // as argument or returned.
+ if (returns_pointer() && (proj_out(TypeFunc::Parms) != NULL)) {
+ Node* proj = proj_out(TypeFunc::Parms);
+ const TypeInstPtr* inst_t = phase->type(proj)->isa_instptr();
+ if ((inst_t != NULL) && (!inst_t->klass_is_exact() ||
+ (inst_t->klass() == boxing_klass))) {
+ return true;
+ }
+ }
+ const TypeTuple* d = tf()->domain();
+ for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
+ const TypeInstPtr* inst_t = d->field_at(i)->isa_instptr();
+ if ((inst_t != NULL) && (!inst_t->klass_is_exact() ||
+ (inst_t->klass() == boxing_klass))) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+ return true;
}
// Does this call have a direct reference to n other than debug information?
@@ -1020,6 +1063,7 @@ void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) {
int scloff = jvms->scloff();
int endoff = jvms->endoff();
assert(endoff == (int)req(), "no other states or debug info after me");
+ assert(jvms->scl_size() == 0, "parsed code should not have scalar objects");
Node* top = Compile::current()->top();
for (uint i = 0; i < grow_by; i++) {
ins_req(monoff, top);
@@ -1035,6 +1079,7 @@ void SafePointNode::push_monitor(const FastLockNode *lock) {
const int MonitorEdges = 2;
assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges");
assert(req() == jvms()->endoff(), "correct sizing");
+ assert((jvms()->scl_size() == 0), "parsed code should not have scalar objects");
int nextmon = jvms()->scloff();
if (GenerateSynchronizationCode) {
add_req(lock->box_node());
@@ -1050,6 +1095,7 @@ void SafePointNode::push_monitor(const FastLockNode *lock) {
void SafePointNode::pop_monitor() {
// Delete last monitor from debug info
+ assert((jvms()->scl_size() == 0), "parsed code should not have scalar objects");
debug_only(int num_before_pop = jvms()->nof_monitors());
const int MonitorEdges = (1<scloff();
@@ -1154,6 +1200,7 @@ AllocateNode::AllocateNode(Compile* C, const TypeFunc *atype,
init_class_id(Class_Allocate);
init_flags(Flag_is_macro);
_is_scalar_replaceable = false;
+ _is_non_escaping = false;
Node *topnode = C->top();
init_req( TypeFunc::Control , ctrl );
@@ -1169,8 +1216,6 @@ AllocateNode::AllocateNode(Compile* C, const TypeFunc *atype,
}
//=============================================================================
-uint AllocateArrayNode::size_of() const { return sizeof(*this); }
-
Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) {
if (remove_dead_region(phase, can_reshape)) return this;
// Don't bother trying to transform a dead node
@@ -1235,6 +1280,8 @@ Node *AllocateArrayNode::make_ideal_length(const TypeOopPtr* oop_type, PhaseTran
// - the narrow_length is 0
// - the narrow_length is not wider than length
assert(narrow_length_type == TypeInt::ZERO ||
+ length_type->is_con() && narrow_length_type->is_con() &&
+ (narrow_length_type->_hi <= length_type->_lo) ||
(narrow_length_type->_hi <= length_type->_hi &&
narrow_length_type->_lo >= length_type->_lo),
"narrow type must be narrower than length type");
diff --git a/hotspot/src/share/vm/opto/callnode.hpp b/hotspot/src/share/vm/opto/callnode.hpp
index 0aa35c214e5..ebcca023315 100644
--- a/hotspot/src/share/vm/opto/callnode.hpp
+++ b/hotspot/src/share/vm/opto/callnode.hpp
@@ -49,6 +49,7 @@ class CallLeafNode;
class CallLeafNoFPNode;
class AllocateNode;
class AllocateArrayNode;
+class BoxLockNode;
class LockNode;
class UnlockNode;
class JVMState;
@@ -235,7 +236,6 @@ public:
int loc_size() const { return stkoff() - locoff(); }
int stk_size() const { return monoff() - stkoff(); }
- int arg_size() const { return monoff() - argoff(); }
int mon_size() const { return scloff() - monoff(); }
int scl_size() const { return endoff() - scloff(); }
@@ -298,6 +298,7 @@ public:
// Miscellaneous utility functions
JVMState* clone_deep(Compile* C) const; // recursively clones caller chain
JVMState* clone_shallow(Compile* C) const; // retains uncloned caller
+ void set_map_deep(SafePointNode *map);// reset map for all callers
#ifndef PRODUCT
void format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const;
@@ -439,7 +440,7 @@ public:
static bool needs_polling_address_input();
#ifndef PRODUCT
- virtual void dump_spec(outputStream *st) const;
+ virtual void dump_spec(outputStream *st) const;
#endif
};
@@ -554,10 +555,10 @@ public:
virtual bool guaranteed_safepoint() { return true; }
// For macro nodes, the JVMState gets modified during expansion, so when cloning
// the node the JVMState must be cloned.
- virtual void clone_jvms() { } // default is not to clone
+ virtual void clone_jvms(Compile* C) { } // default is not to clone
// Returns true if the call may modify n
- virtual bool may_modify(const TypePtr *addr_t, PhaseTransform *phase);
+ virtual bool may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase);
// Does this node have a use of n other than in debug information?
bool has_non_debug_use(Node *n);
// Returns the unique CheckCastPP of a call
@@ -630,9 +631,15 @@ class CallStaticJavaNode : public CallJavaNode {
virtual uint cmp( const Node &n ) const;
virtual uint size_of() const; // Size is bigger
public:
- CallStaticJavaNode(const TypeFunc* tf, address addr, ciMethod* method, int bci)
+ CallStaticJavaNode(Compile* C, const TypeFunc* tf, address addr, ciMethod* method, int bci)
: CallJavaNode(tf, addr, method, bci), _name(NULL) {
init_class_id(Class_CallStaticJava);
+ if (C->eliminate_boxing() && (method != NULL) && method->is_boxing_method()) {
+ init_flags(Flag_is_macro);
+ C->add_macro_node(this);
+ }
+ _is_scalar_replaceable = false;
+ _is_non_escaping = false;
}
CallStaticJavaNode(const TypeFunc* tf, address addr, const char* name, int bci,
const TypePtr* adr_type)
@@ -640,13 +647,31 @@ public:
init_class_id(Class_CallStaticJava);
// This node calls a runtime stub, which often has narrow memory effects.
_adr_type = adr_type;
+ _is_scalar_replaceable = false;
+ _is_non_escaping = false;
}
- const char *_name; // Runtime wrapper name
+ const char *_name; // Runtime wrapper name
+
+ // Result of Escape Analysis
+ bool _is_scalar_replaceable;
+ bool _is_non_escaping;
// If this is an uncommon trap, return the request code, else zero.
int uncommon_trap_request() const;
static int extract_uncommon_trap_request(const Node* call);
+ bool is_boxing_method() const {
+ return is_macro() && (method() != NULL) && method()->is_boxing_method();
+ }
+ // Later inlining modifies the JVMState, so we need to clone it
+ // when the call node is cloned (because it is macro node).
+ virtual void clone_jvms(Compile* C) {
+ if ((jvms() != NULL) && is_boxing_method()) {
+ set_jvms(jvms()->clone_deep(C));
+ jvms()->set_map_deep(this);
+ }
+ }
+
virtual int Opcode() const;
#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const;
@@ -748,12 +773,12 @@ public:
ParmLimit
};
- static const TypeFunc* alloc_type() {
+ static const TypeFunc* alloc_type(const Type* t) {
const Type** fields = TypeTuple::fields(ParmLimit - TypeFunc::Parms);
fields[AllocSize] = TypeInt::POS;
fields[KlassNode] = TypeInstPtr::NOTNULL;
fields[InitialTest] = TypeInt::BOOL;
- fields[ALength] = TypeInt::INT; // length (can be a bad length)
+ fields[ALength] = t; // length (can be a bad length)
const TypeTuple *domain = TypeTuple::make(ParmLimit, fields);
@@ -766,21 +791,26 @@ public:
return TypeFunc::make(domain, range);
}
- bool _is_scalar_replaceable; // Result of Escape Analysis
+ // Result of Escape Analysis
+ bool _is_scalar_replaceable;
+ bool _is_non_escaping;
virtual uint size_of() const; // Size is bigger
AllocateNode(Compile* C, const TypeFunc *atype, Node *ctrl, Node *mem, Node *abio,
Node *size, Node *klass_node, Node *initial_test);
// Expansion modifies the JVMState, so we need to clone it
- virtual void clone_jvms() {
- set_jvms(jvms()->clone_deep(Compile::current()));
+ virtual void clone_jvms(Compile* C) {
+ if (jvms() != NULL) {
+ set_jvms(jvms()->clone_deep(C));
+ jvms()->set_map_deep(this);
+ }
}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegP; }
virtual bool guaranteed_safepoint() { return false; }
// allocations do not modify their arguments
- virtual bool may_modify(const TypePtr *addr_t, PhaseTransform *phase) { return false;}
+ virtual bool may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase) { return false;}
// Pattern-match a possible usage of AllocateNode.
// Return null if no allocation is recognized.
@@ -815,10 +845,6 @@ public:
// are defined in graphKit.cpp, which sets up the bidirectional relation.)
InitializeNode* initialization();
- // Return the corresponding storestore barrier (or null if none).
- // Walks out edges to find it...
- MemBarStoreStoreNode* storestore();
-
// Convenience for initialization->maybe_set_complete(phase)
bool maybe_set_complete(PhaseGVN* phase);
};
@@ -840,7 +866,6 @@ public:
set_req(AllocateNode::ALength, count_val);
}
virtual int Opcode() const;
- virtual uint size_of() const; // Size is bigger
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
// Dig the length operand out of a array allocation site.
@@ -918,7 +943,7 @@ public:
void set_nested() { _kind = Nested; set_eliminated_lock_counter(); }
// locking does not modify its arguments
- virtual bool may_modify(const TypePtr *addr_t, PhaseTransform *phase){ return false;}
+ virtual bool may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase){ return false;}
#ifndef PRODUCT
void create_lock_counter(JVMState* s);
@@ -965,8 +990,11 @@ public:
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
// Expansion modifies the JVMState, so we need to clone it
- virtual void clone_jvms() {
- set_jvms(jvms()->clone_deep(Compile::current()));
+ virtual void clone_jvms(Compile* C) {
+ if (jvms() != NULL) {
+ set_jvms(jvms()->clone_deep(C));
+ jvms()->set_map_deep(this);
+ }
}
bool is_nested_lock_region(); // Is this Lock nested?
diff --git a/hotspot/src/share/vm/opto/cfgnode.cpp b/hotspot/src/share/vm/opto/cfgnode.cpp
index 68fcc9cbb8e..4185ada5d1c 100644
--- a/hotspot/src/share/vm/opto/cfgnode.cpp
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp
@@ -806,7 +806,7 @@ PhiNode* PhiNode::split_out_instance(const TypePtr* at, PhaseIterGVN *igvn) cons
Node *in = ophi->in(i);
if (in == NULL || igvn->type(in) == Type::TOP)
continue;
- Node *opt = MemNode::optimize_simple_memory_chain(in, at, igvn);
+ Node *opt = MemNode::optimize_simple_memory_chain(in, t_oop, NULL, igvn);
PhiNode *optphi = opt->is_Phi() ? opt->as_Phi() : NULL;
if (optphi != NULL && optphi->adr_type() == TypePtr::BOTTOM) {
opt = node_map[optphi->_idx];
@@ -1921,7 +1921,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
const TypePtr* at = adr_type();
for( uint i=1; iprint_cr("** Bailout: Recompile without escape analysis **");
tty->print_cr("*********************************************************");
}
+ if (_eliminate_boxing != EliminateAutoBox && PrintOpto) {
+ // Recompiling without boxing elimination
+ tty->print_cr("*********************************************************");
+ tty->print_cr("** Bailout: Recompile without boxing elimination **");
+ tty->print_cr("*********************************************************");
+ }
if (env()->break_at_compile()) {
// Open the debugger when compiling this method.
tty->print("### Breaking when compiling: ");
@@ -601,7 +608,8 @@ debug_only( int Compile::_debug_idx = 100000; )
// the continuation bci for on stack replacement.
-Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr_bci, bool subsume_loads, bool do_escape_analysis )
+Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr_bci,
+ bool subsume_loads, bool do_escape_analysis, bool eliminate_boxing )
: Phase(Compiler),
_env(ci_env),
_log(ci_env->log()),
@@ -617,6 +625,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
_warm_calls(NULL),
_subsume_loads(subsume_loads),
_do_escape_analysis(do_escape_analysis),
+ _eliminate_boxing(eliminate_boxing),
_failure_reason(NULL),
_code_buffer("Compile::Fill_buffer"),
_orig_pc_slot(0),
@@ -638,6 +647,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
_congraph(NULL),
_late_inlines(comp_arena(), 2, 0, NULL),
_string_late_inlines(comp_arena(), 2, 0, NULL),
+ _boxing_late_inlines(comp_arena(), 2, 0, NULL),
_late_inlines_pos(0),
_number_of_mh_late_inlines(0),
_inlining_progress(false),
@@ -906,6 +916,7 @@ Compile::Compile( ciEnv* ci_env,
_orig_pc_slot_offset_in_bytes(0),
_subsume_loads(true),
_do_escape_analysis(false),
+ _eliminate_boxing(false),
_failure_reason(NULL),
_code_buffer("Compile::Fill_buffer"),
_has_method_handle_invokes(false),
@@ -1016,6 +1027,7 @@ void Compile::Init(int aliaslevel) {
set_has_split_ifs(false);
set_has_loops(has_method() && method()->has_loops()); // first approximation
set_has_stringbuilder(false);
+ set_has_boxed_value(false);
_trap_can_recompile = false; // no traps emitted yet
_major_progress = true; // start out assuming good things will happen
set_has_unsafe_access(false);
@@ -1807,6 +1819,38 @@ void Compile::inline_string_calls(bool parse_time) {
_string_late_inlines.trunc_to(0);
}
+// Late inlining of boxing methods
+void Compile::inline_boxing_calls(PhaseIterGVN& igvn) {
+ if (_boxing_late_inlines.length() > 0) {
+ assert(has_boxed_value(), "inconsistent");
+
+ PhaseGVN* gvn = initial_gvn();
+ set_inlining_incrementally(true);
+
+ assert( igvn._worklist.size() == 0, "should be done with igvn" );
+ for_igvn()->clear();
+ gvn->replace_with(&igvn);
+
+ while (_boxing_late_inlines.length() > 0) {
+ CallGenerator* cg = _boxing_late_inlines.pop();
+ cg->do_late_inline();
+ if (failing()) return;
+ }
+ _boxing_late_inlines.trunc_to(0);
+
+ {
+ ResourceMark rm;
+ PhaseRemoveUseless pru(gvn, for_igvn());
+ }
+
+ igvn = PhaseIterGVN(gvn);
+ igvn.optimize();
+
+ set_inlining_progress(false);
+ set_inlining_incrementally(false);
+ }
+}
+
void Compile::inline_incrementally_one(PhaseIterGVN& igvn) {
assert(IncrementalInline, "incremental inlining should be on");
PhaseGVN* gvn = initial_gvn();
@@ -1831,7 +1875,7 @@ void Compile::inline_incrementally_one(PhaseIterGVN& igvn) {
{
ResourceMark rm;
- PhaseRemoveUseless pru(C->initial_gvn(), C->for_igvn());
+ PhaseRemoveUseless pru(gvn, for_igvn());
}
igvn = PhaseIterGVN(gvn);
@@ -1929,12 +1973,25 @@ void Compile::Optimize() {
if (failing()) return;
- inline_incrementally(igvn);
+ {
+ NOT_PRODUCT( TracePhase t2("incrementalInline", &_t_incrInline, TimeCompiler); )
+ inline_incrementally(igvn);
+ }
print_method("Incremental Inline", 2);
if (failing()) return;
+ if (eliminate_boxing()) {
+ NOT_PRODUCT( TracePhase t2("incrementalInline", &_t_incrInline, TimeCompiler); )
+ // Inline valueOf() methods now.
+ inline_boxing_calls(igvn);
+
+ print_method("Incremental Boxing Inline", 2);
+
+ if (failing()) return;
+ }
+
// No more new expensive nodes will be added to the list from here
// so keep only the actual candidates for optimizations.
cleanup_expensive_nodes(igvn);
@@ -2896,6 +2953,7 @@ void Compile::final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc) {
}
break;
case Op_MemBarStoreStore:
+ case Op_MemBarRelease:
// Break the link with AllocateNode: it is no longer useful and
// confuses register allocation.
if (n->req() > MemBarNode::Precedent) {
diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp
index d951fbf5f94..e0f1cd23d16 100644
--- a/hotspot/src/share/vm/opto/compile.hpp
+++ b/hotspot/src/share/vm/opto/compile.hpp
@@ -262,6 +262,7 @@ class Compile : public Phase {
const bool _save_argument_registers; // save/restore arg regs for trampolines
const bool _subsume_loads; // Load can be matched as part of a larger op.
const bool _do_escape_analysis; // Do escape analysis.
+ const bool _eliminate_boxing; // Do boxing elimination.
ciMethod* _method; // The method being compiled.
int _entry_bci; // entry bci for osr methods.
const TypeFunc* _tf; // My kind of signature
@@ -287,6 +288,7 @@ class Compile : public Phase {
bool _has_split_ifs; // True if the method _may_ have some split-if
bool _has_unsafe_access; // True if the method _may_ produce faults in unsafe loads or stores.
bool _has_stringbuilder; // True StringBuffers or StringBuilders are allocated
+ bool _has_boxed_value; // True if a boxed object is allocated
int _max_vector_size; // Maximum size of generated vectors
uint _trap_hist[trapHistLength]; // Cumulative traps
bool _trap_can_recompile; // Have we emitted a recompiling trap?
@@ -375,6 +377,8 @@ class Compile : public Phase {
// main parsing has finished.
GrowableArray _string_late_inlines; // same but for string operations
+ GrowableArray _boxing_late_inlines; // same but for boxing operations
+
int _late_inlines_pos; // Where in the queue should the next late inlining candidate go (emulate depth first inlining)
uint _number_of_mh_late_inlines; // number of method handle late inlining still pending
@@ -486,8 +490,12 @@ class Compile : public Phase {
// instructions that subsume a load may result in an unschedulable
// instruction sequence.
bool subsume_loads() const { return _subsume_loads; }
- // Do escape analysis.
+ /** Do escape analysis. */
bool do_escape_analysis() const { return _do_escape_analysis; }
+ /** Do boxing elimination. */
+ bool eliminate_boxing() const { return _eliminate_boxing; }
+ /** Do aggressive boxing elimination. */
+ bool aggressive_unboxing() const { return _eliminate_boxing && AggressiveUnboxing; }
bool save_argument_registers() const { return _save_argument_registers; }
@@ -527,6 +535,8 @@ class Compile : public Phase {
void set_has_unsafe_access(bool z) { _has_unsafe_access = z; }
bool has_stringbuilder() const { return _has_stringbuilder; }
void set_has_stringbuilder(bool z) { _has_stringbuilder = z; }
+ bool has_boxed_value() const { return _has_boxed_value; }
+ void set_has_boxed_value(bool z) { _has_boxed_value = z; }
int max_vector_size() const { return _max_vector_size; }
void set_max_vector_size(int s) { _max_vector_size = s; }
void set_trap_count(uint r, uint c) { assert(r < trapHistLength, "oob"); _trap_hist[r] = c; }
@@ -579,12 +589,12 @@ class Compile : public Phase {
#endif
}
- int macro_count() { return _macro_nodes->length(); }
- int predicate_count() { return _predicate_opaqs->length();}
- int expensive_count() { return _expensive_nodes->length(); }
- Node* macro_node(int idx) { return _macro_nodes->at(idx); }
- Node* predicate_opaque1_node(int idx) { return _predicate_opaqs->at(idx);}
- Node* expensive_node(int idx) { return _expensive_nodes->at(idx); }
+ int macro_count() const { return _macro_nodes->length(); }
+ int predicate_count() const { return _predicate_opaqs->length();}
+ int expensive_count() const { return _expensive_nodes->length(); }
+ Node* macro_node(int idx) const { return _macro_nodes->at(idx); }
+ Node* predicate_opaque1_node(int idx) const { return _predicate_opaqs->at(idx);}
+ Node* expensive_node(int idx) const { return _expensive_nodes->at(idx); }
ConnectionGraph* congraph() { return _congraph;}
void set_congraph(ConnectionGraph* congraph) { _congraph = congraph;}
void add_macro_node(Node * n) {
@@ -766,7 +776,12 @@ class Compile : public Phase {
// Decide how to build a call.
// The profile factor is a discount to apply to this site's interp. profile.
CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_does_dispatch, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true, bool delayed_forbidden = false);
- bool should_delay_inlining(ciMethod* call_method, JVMState* jvms);
+ bool should_delay_inlining(ciMethod* call_method, JVMState* jvms) {
+ return should_delay_string_inlining(call_method, jvms) ||
+ should_delay_boxing_inlining(call_method, jvms);
+ }
+ bool should_delay_string_inlining(ciMethod* call_method, JVMState* jvms);
+ bool should_delay_boxing_inlining(ciMethod* call_method, JVMState* jvms);
// Helper functions to identify inlining potential at call-site
ciMethod* optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass,
@@ -822,6 +837,10 @@ class Compile : public Phase {
_string_late_inlines.push(cg);
}
+ void add_boxing_late_inline(CallGenerator* cg) {
+ _boxing_late_inlines.push(cg);
+ }
+
void remove_useless_late_inlines(GrowableArray* inlines, Unique_Node_List &useful);
void dump_inlining();
@@ -841,6 +860,7 @@ class Compile : public Phase {
void inline_incrementally_one(PhaseIterGVN& igvn);
void inline_incrementally(PhaseIterGVN& igvn);
void inline_string_calls(bool parse_time);
+ void inline_boxing_calls(PhaseIterGVN& igvn);
// Matching, CFG layout, allocation, code generation
PhaseCFG* cfg() { return _cfg; }
@@ -913,7 +933,8 @@ class Compile : public Phase {
// replacement, entry_bci indicates the bytecode for which to compile a
// continuation.
Compile(ciEnv* ci_env, C2Compiler* compiler, ciMethod* target,
- int entry_bci, bool subsume_loads, bool do_escape_analysis);
+ int entry_bci, bool subsume_loads, bool do_escape_analysis,
+ bool eliminate_boxing);
// Second major entry point. From the TypeFunc signature, generate code
// to pass arguments from the Java calling convention to the C calling
diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp
index 9a7562d01fb..e55a01ba638 100644
--- a/hotspot/src/share/vm/opto/doCall.cpp
+++ b/hotspot/src/share/vm/opto/doCall.cpp
@@ -176,9 +176,12 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool
// Delay the inlining of this method to give us the
// opportunity to perform some high level optimizations
// first.
- if (should_delay_inlining(callee, jvms)) {
+ if (should_delay_string_inlining(callee, jvms)) {
assert(!delayed_forbidden, "strange");
return CallGenerator::for_string_late_inline(callee, cg);
+ } else if (should_delay_boxing_inlining(callee, jvms)) {
+ assert(!delayed_forbidden, "strange");
+ return CallGenerator::for_boxing_late_inline(callee, cg);
} else if ((should_delay || AlwaysIncrementalInline) && !delayed_forbidden) {
return CallGenerator::for_late_inline(callee, cg);
}
@@ -276,7 +279,7 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool
// Return true for methods that shouldn't be inlined early so that
// they are easier to analyze and optimize as intrinsics.
-bool Compile::should_delay_inlining(ciMethod* call_method, JVMState* jvms) {
+bool Compile::should_delay_string_inlining(ciMethod* call_method, JVMState* jvms) {
if (has_stringbuilder()) {
if ((call_method->holder() == C->env()->StringBuilder_klass() ||
@@ -327,6 +330,13 @@ bool Compile::should_delay_inlining(ciMethod* call_method, JVMState* jvms) {
return false;
}
+bool Compile::should_delay_boxing_inlining(ciMethod* call_method, JVMState* jvms) {
+ if (eliminate_boxing() && call_method->is_boxing_method()) {
+ set_has_boxed_value(true);
+ return true;
+ }
+ return false;
+}
// uncommon-trap call-sites where callee is unloaded, uninitialized or will not link
bool Parse::can_not_compile_call_site(ciMethod *dest_method, ciInstanceKlass* klass) {
diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp
index c5a93dfa68f..f29f82b3539 100644
--- a/hotspot/src/share/vm/opto/escape.cpp
+++ b/hotspot/src/share/vm/opto/escape.cpp
@@ -63,15 +63,19 @@ bool ConnectionGraph::has_candidates(Compile *C) {
// EA brings benefits only when the code has allocations and/or locks which
// are represented by ideal Macro nodes.
int cnt = C->macro_count();
- for( int i=0; i < cnt; i++ ) {
+ for (int i = 0; i < cnt; i++) {
Node *n = C->macro_node(i);
- if ( n->is_Allocate() )
+ if (n->is_Allocate())
return true;
- if( n->is_Lock() ) {
+ if (n->is_Lock()) {
Node* obj = n->as_Lock()->obj_node()->uncast();
- if( !(obj->is_Parm() || obj->is_Con()) )
+ if (!(obj->is_Parm() || obj->is_Con()))
return true;
}
+ if (n->is_CallStaticJava() &&
+ n->as_CallStaticJava()->is_boxing_method()) {
+ return true;
+ }
}
return false;
}
@@ -115,7 +119,7 @@ bool ConnectionGraph::compute_escape() {
{ Compile::TracePhase t3("connectionGraph", &Phase::_t_connectionGraph, true);
// 1. Populate Connection Graph (CG) with PointsTo nodes.
- ideal_nodes.map(C->unique(), NULL); // preallocate space
+ ideal_nodes.map(C->live_nodes(), NULL); // preallocate space
// Initialize worklist
if (C->root() != NULL) {
ideal_nodes.push(C->root());
@@ -152,8 +156,11 @@ bool ConnectionGraph::compute_escape() {
// escape status of the associated Allocate node some of them
// may be eliminated.
storestore_worklist.append(n);
+ } else if (n->is_MemBar() && (n->Opcode() == Op_MemBarRelease) &&
+ (n->req() > MemBarNode::Precedent)) {
+ record_for_optimizer(n);
#ifdef ASSERT
- } else if(n->is_AddP()) {
+ } else if (n->is_AddP()) {
// Collect address nodes for graph verification.
addp_worklist.append(n);
#endif
@@ -206,8 +213,15 @@ bool ConnectionGraph::compute_escape() {
int non_escaped_length = non_escaped_worklist.length();
for (int next = 0; next < non_escaped_length; next++) {
JavaObjectNode* ptn = non_escaped_worklist.at(next);
- if (ptn->escape_state() == PointsToNode::NoEscape &&
- ptn->scalar_replaceable()) {
+ bool noescape = (ptn->escape_state() == PointsToNode::NoEscape);
+ Node* n = ptn->ideal_node();
+ if (n->is_Allocate()) {
+ n->as_Allocate()->_is_non_escaping = noescape;
+ }
+ if (n->is_CallStaticJava()) {
+ n->as_CallStaticJava()->_is_non_escaping = noescape;
+ }
+ if (noescape && ptn->scalar_replaceable()) {
adjust_scalar_replaceable_state(ptn);
if (ptn->scalar_replaceable()) {
alloc_worklist.append(ptn->ideal_node());
@@ -330,8 +344,10 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de
// Don't mark as processed since call's arguments have to be processed.
delayed_worklist->push(n);
// Check if a call returns an object.
- if (n->as_Call()->returns_pointer() &&
- n->as_Call()->proj_out(TypeFunc::Parms) != NULL) {
+ if ((n->as_Call()->returns_pointer() &&
+ n->as_Call()->proj_out(TypeFunc::Parms) != NULL) ||
+ (n->is_CallStaticJava() &&
+ n->as_CallStaticJava()->is_boxing_method())) {
add_call_node(n->as_Call());
}
}
@@ -387,8 +403,8 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de
case Op_ConNKlass: {
// assume all oop constants globally escape except for null
PointsToNode::EscapeState es;
- if (igvn->type(n) == TypePtr::NULL_PTR ||
- igvn->type(n) == TypeNarrowOop::NULL_PTR) {
+ const Type* t = igvn->type(n);
+ if (t == TypePtr::NULL_PTR || t == TypeNarrowOop::NULL_PTR) {
es = PointsToNode::NoEscape;
} else {
es = PointsToNode::GlobalEscape;
@@ -468,6 +484,9 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de
Node* adr = n->in(MemNode::Address);
const Type *adr_type = igvn->type(adr);
adr_type = adr_type->make_ptr();
+ if (adr_type == NULL) {
+ break; // skip dead nodes
+ }
if (adr_type->isa_oopptr() ||
(opcode == Op_StoreP || opcode == Op_StoreN || opcode == Op_StoreNKlass) &&
(adr_type == TypeRawPtr::NOTNULL &&
@@ -660,14 +679,18 @@ void ConnectionGraph::add_final_edges(Node *n) {
case Op_GetAndSetP:
case Op_GetAndSetN: {
Node* adr = n->in(MemNode::Address);
- if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN) {
- const Type* t = _igvn->type(n);
- if (t->make_ptr() != NULL) {
- add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
- }
- }
const Type *adr_type = _igvn->type(adr);
adr_type = adr_type->make_ptr();
+#ifdef ASSERT
+ if (adr_type == NULL) {
+ n->dump(1);
+ assert(adr_type != NULL, "dead node should not be on list");
+ break;
+ }
+#endif
+ if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN) {
+ add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
+ }
if (adr_type->isa_oopptr() ||
(opcode == Op_StoreP || opcode == Op_StoreN || opcode == Op_StoreNKlass) &&
(adr_type == TypeRawPtr::NOTNULL &&
@@ -797,6 +820,18 @@ void ConnectionGraph::add_call_node(CallNode* call) {
// Returns a newly allocated unescaped object.
add_java_object(call, PointsToNode::NoEscape);
ptnode_adr(call_idx)->set_scalar_replaceable(false);
+ } else if (meth->is_boxing_method()) {
+ // Returns boxing object
+ PointsToNode::EscapeState es;
+ vmIntrinsics::ID intr = meth->intrinsic_id();
+ if (intr == vmIntrinsics::_floatValue || intr == vmIntrinsics::_doubleValue) {
+ // It does not escape if object is always allocated.
+ es = PointsToNode::NoEscape;
+ } else {
+ // It escapes globally if object could be loaded from cache.
+ es = PointsToNode::GlobalEscape;
+ }
+ add_java_object(call, es);
} else {
BCEscapeAnalyzer* call_analyzer = meth->get_bcea();
call_analyzer->copy_dependencies(_compile->dependencies());
@@ -943,6 +978,9 @@ void ConnectionGraph::process_call_arguments(CallNode *call) {
assert((name == NULL || strcmp(name, "uncommon_trap") != 0), "normal calls only");
#endif
ciMethod* meth = call->as_CallJava()->method();
+ if ((meth != NULL) && meth->is_boxing_method()) {
+ break; // Boxing methods do not modify any oops.
+ }
BCEscapeAnalyzer* call_analyzer = (meth !=NULL) ? meth->get_bcea() : NULL;
// fall-through if not a Java method or no analyzer information
if (call_analyzer != NULL) {
@@ -1791,9 +1829,8 @@ Node* ConnectionGraph::optimize_ptr_compare(Node* n) {
jobj2->ideal_node()->is_Con()) {
// Klass or String constants compare. Need to be careful with
// compressed pointers - compare types of ConN and ConP instead of nodes.
- const Type* t1 = jobj1->ideal_node()->bottom_type()->make_ptr();
- const Type* t2 = jobj2->ideal_node()->bottom_type()->make_ptr();
- assert(t1 != NULL && t2 != NULL, "sanity");
+ const Type* t1 = jobj1->ideal_node()->get_ptr_type();
+ const Type* t2 = jobj2->ideal_node()->get_ptr_type();
if (t1->make_ptr() == t2->make_ptr()) {
return _pcmp_eq;
} else {
@@ -2744,6 +2781,11 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist)
// so it could be eliminated if it has no uses.
alloc->as_Allocate()->_is_scalar_replaceable = true;
}
+ if (alloc->is_CallStaticJava()) {
+ // Set the scalar_replaceable flag for boxing method
+ // so it could be eliminated if it has no uses.
+ alloc->as_CallStaticJava()->_is_scalar_replaceable = true;
+ }
continue;
}
if (!n->is_CheckCastPP()) { // not unique CheckCastPP.
@@ -2782,6 +2824,11 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist)
// so it could be eliminated.
alloc->as_Allocate()->_is_scalar_replaceable = true;
}
+ if (alloc->is_CallStaticJava()) {
+ // Set the scalar_replaceable flag for boxing method
+ // so it could be eliminated.
+ alloc->as_CallStaticJava()->_is_scalar_replaceable = true;
+ }
set_escape_state(ptnode_adr(n->_idx), es); // CheckCastPP escape state
// in order for an object to be scalar-replaceable, it must be:
// - a direct allocation (not a call returning an object)
@@ -2911,7 +2958,9 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist)
// Load/store to instance's field
memnode_worklist.append_if_missing(use);
} else if (use->is_MemBar()) {
- memnode_worklist.append_if_missing(use);
+ if (use->in(TypeFunc::Memory) == n) { // Ignore precedent edge
+ memnode_worklist.append_if_missing(use);
+ }
} else if (use->is_AddP() && use->outcnt() > 0) { // No dead nodes
Node* addp2 = find_second_addp(use, n);
if (addp2 != NULL) {
@@ -3028,7 +3077,9 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist)
continue;
memnode_worklist.append_if_missing(use);
} else if (use->is_MemBar()) {
- memnode_worklist.append_if_missing(use);
+ if (use->in(TypeFunc::Memory) == n) { // Ignore precedent edge
+ memnode_worklist.append_if_missing(use);
+ }
#ifdef ASSERT
} else if(use->is_Mem()) {
assert(use->in(MemNode::Memory) != n, "EA: missing memory path");
@@ -3264,7 +3315,12 @@ void ConnectionGraph::dump(GrowableArray& ptnodes_worklist) {
if (ptn == NULL || !ptn->is_JavaObject())
continue;
PointsToNode::EscapeState es = ptn->escape_state();
- if (ptn->ideal_node()->is_Allocate() && (es == PointsToNode::NoEscape || Verbose)) {
+ if ((es != PointsToNode::NoEscape) && !Verbose) {
+ continue;
+ }
+ Node* n = ptn->ideal_node();
+ if (n->is_Allocate() || (n->is_CallStaticJava() &&
+ n->as_CallStaticJava()->is_boxing_method())) {
if (first) {
tty->cr();
tty->print("======== Connection graph for ");
diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp
index e2285916ce5..590770b7c72 100644
--- a/hotspot/src/share/vm/opto/graphKit.cpp
+++ b/hotspot/src/share/vm/opto/graphKit.cpp
@@ -333,6 +333,7 @@ void GraphKit::combine_exception_states(SafePointNode* ex_map, SafePointNode* ph
assert(ex_jvms->stkoff() == phi_map->_jvms->stkoff(), "matching locals");
assert(ex_jvms->sp() == phi_map->_jvms->sp(), "matching stack sizes");
assert(ex_jvms->monoff() == phi_map->_jvms->monoff(), "matching JVMS");
+ assert(ex_jvms->scloff() == phi_map->_jvms->scloff(), "matching scalar replaced objects");
assert(ex_map->req() == phi_map->req(), "matching maps");
uint tos = ex_jvms->stkoff() + ex_jvms->sp();
Node* hidden_merge_mark = root();
@@ -409,7 +410,7 @@ void GraphKit::combine_exception_states(SafePointNode* ex_map, SafePointNode* ph
while (dst->req() > orig_width) dst->del_req(dst->req()-1);
} else {
assert(dst->is_Phi(), "nobody else uses a hidden region");
- phi = (PhiNode*)dst;
+ phi = dst->as_Phi();
}
if (add_multiple && src->in(0) == ex_control) {
// Both are phis.
@@ -1438,7 +1439,12 @@ Node* GraphKit::make_load(Node* ctl, Node* adr, const Type* t, BasicType bt,
} else {
ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt);
}
- return _gvn.transform(ld);
+ ld = _gvn.transform(ld);
+ if ((bt == T_OBJECT) && C->do_escape_analysis() || C->eliminate_boxing()) {
+ // Improve graph before escape analysis and boxing elimination.
+ record_for_igvn(ld);
+ }
+ return ld;
}
Node* GraphKit::store_to_memory(Node* ctl, Node* adr, Node *val, BasicType bt,
@@ -3144,7 +3150,7 @@ Node* GraphKit::new_instance(Node* klass_node,
set_all_memory(mem); // Create new memory state
AllocateNode* alloc
- = new (C) AllocateNode(C, AllocateNode::alloc_type(),
+ = new (C) AllocateNode(C, AllocateNode::alloc_type(Type::TOP),
control(), mem, i_o(),
size, klass_node,
initial_slow_test);
@@ -3285,7 +3291,7 @@ Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable)
// Create the AllocateArrayNode and its result projections
AllocateArrayNode* alloc
- = new (C) AllocateArrayNode(C, AllocateArrayNode::alloc_type(),
+ = new (C) AllocateArrayNode(C, AllocateArrayNode::alloc_type(TypeInt::INT),
control(), mem, i_o(),
size, klass_node,
initial_slow_test,
@@ -3326,10 +3332,9 @@ AllocateNode* AllocateNode::Ideal_allocation(Node* ptr, PhaseTransform* phase) {
if (ptr == NULL) { // reduce dumb test in callers
return NULL;
}
- if (ptr->is_CheckCastPP()) { // strip a raw-to-oop cast
- ptr = ptr->in(1);
- if (ptr == NULL) return NULL;
- }
+ ptr = ptr->uncast(); // strip a raw-to-oop cast
+ if (ptr == NULL) return NULL;
+
if (ptr->is_Proj()) {
Node* allo = ptr->in(0);
if (allo != NULL && allo->is_Allocate()) {
@@ -3374,19 +3379,6 @@ InitializeNode* AllocateNode::initialization() {
return NULL;
}
-// Trace Allocate -> Proj[Parm] -> MemBarStoreStore
-MemBarStoreStoreNode* AllocateNode::storestore() {
- ProjNode* rawoop = proj_out(AllocateNode::RawAddress);
- if (rawoop == NULL) return NULL;
- for (DUIterator_Fast imax, i = rawoop->fast_outs(imax); i < imax; i++) {
- Node* storestore = rawoop->fast_out(i);
- if (storestore->is_MemBarStoreStore()) {
- return storestore->as_MemBarStoreStore();
- }
- }
- return NULL;
-}
-
//----------------------------- loop predicates ---------------------------
//------------------------------add_predicate_impl----------------------------
diff --git a/hotspot/src/share/vm/opto/idealGraphPrinter.hpp b/hotspot/src/share/vm/opto/idealGraphPrinter.hpp
index 7d1863f4a2a..f2892d5a9c3 100644
--- a/hotspot/src/share/vm/opto/idealGraphPrinter.hpp
+++ b/hotspot/src/share/vm/opto/idealGraphPrinter.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,9 +41,8 @@ class Node;
class InlineTree;
class ciMethod;
-class IdealGraphPrinter
-{
-private:
+class IdealGraphPrinter : public CHeapObj {
+ private:
static const char *INDENT;
static const char *TOP_ELEMENT;
@@ -121,7 +120,7 @@ private:
IdealGraphPrinter();
~IdealGraphPrinter();
-public:
+ public:
static void clean_up();
static IdealGraphPrinter *printer();
@@ -135,8 +134,6 @@ public:
void print_method(Compile* compile, const char *name, int level=1, bool clear_nodes = false);
void print(Compile* compile, const char *name, Node *root, int level=1, bool clear_nodes = false);
void print_xml(const char *name);
-
-
};
#endif
diff --git a/hotspot/src/share/vm/opto/ifnode.cpp b/hotspot/src/share/vm/opto/ifnode.cpp
index b506a03f587..3995446485b 100644
--- a/hotspot/src/share/vm/opto/ifnode.cpp
+++ b/hotspot/src/share/vm/opto/ifnode.cpp
@@ -673,7 +673,7 @@ const TypeInt* IfNode::filtered_int_type(PhaseGVN* gvn, Node *val, Node* if_proj
// / Region
//
Node* IfNode::fold_compares(PhaseGVN* phase) {
- if (!EliminateAutoBox || Opcode() != Op_If) return NULL;
+ if (!phase->C->eliminate_boxing() || Opcode() != Op_If) return NULL;
Node* this_cmp = in(1)->in(1);
if (this_cmp != NULL && this_cmp->Opcode() == Op_CmpI &&
diff --git a/hotspot/src/share/vm/opto/lcm.cpp b/hotspot/src/share/vm/opto/lcm.cpp
index ddb55d30e62..2b3eca478d9 100644
--- a/hotspot/src/share/vm/opto/lcm.cpp
+++ b/hotspot/src/share/vm/opto/lcm.cpp
@@ -219,9 +219,10 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe
// cannot reason about it; is probably not implicit null exception
} else {
const TypePtr* tptr;
- if (UseCompressedOops && Universe::narrow_oop_shift() == 0) {
+ if (UseCompressedOops && (Universe::narrow_oop_shift() == 0 ||
+ Universe::narrow_klass_shift() == 0)) {
// 32-bits narrow oop can be the base of address expressions
- tptr = base->bottom_type()->make_ptr();
+ tptr = base->get_ptr_type();
} else {
// only regular oops are expected here
tptr = base->bottom_type()->is_ptr();
diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp
index 1f4b58ebbbb..609b7022608 100644
--- a/hotspot/src/share/vm/opto/library_call.cpp
+++ b/hotspot/src/share/vm/opto/library_call.cpp
@@ -2783,7 +2783,7 @@ bool LibraryCallKit::inline_unsafe_load_store(BasicType type, LoadStoreKind kind
#ifdef _LP64
if (type == T_OBJECT && adr->bottom_type()->is_ptr_to_narrowoop() && kind == LS_xchg) {
- load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->bottom_type()->make_ptr()));
+ load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->get_ptr_type()));
}
#endif
@@ -3703,7 +3703,7 @@ LibraryCallKit::generate_method_call(vmIntrinsics::ID method_id, bool is_virtual
CallJavaNode* slow_call;
if (is_static) {
assert(!is_virtual, "");
- slow_call = new(C) CallStaticJavaNode(tf,
+ slow_call = new(C) CallStaticJavaNode(C, tf,
SharedRuntime::get_resolve_static_call_stub(),
method, bci());
} else if (is_virtual) {
@@ -3722,7 +3722,7 @@ LibraryCallKit::generate_method_call(vmIntrinsics::ID method_id, bool is_virtual
method, vtable_index, bci());
} else { // neither virtual nor static: opt_virtual
null_check_receiver();
- slow_call = new(C) CallStaticJavaNode(tf,
+ slow_call = new(C) CallStaticJavaNode(C, tf,
SharedRuntime::get_resolve_opt_virtual_call_stub(),
method, bci());
slow_call->set_optimized_virtual(true);
diff --git a/hotspot/src/share/vm/opto/loopPredicate.cpp b/hotspot/src/share/vm/opto/loopPredicate.cpp
index a9867a5ee8a..f29d9daab55 100644
--- a/hotspot/src/share/vm/opto/loopPredicate.cpp
+++ b/hotspot/src/share/vm/opto/loopPredicate.cpp
@@ -821,8 +821,8 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
loop->dump_head();
}
#endif
- } else if (cl != NULL && loop->is_range_check_if(iff, this, invar)) {
- assert(proj->_con == predicate_proj->_con, "must match");
+ } else if ((cl != NULL) && (proj->_con == predicate_proj->_con) &&
+ loop->is_range_check_if(iff, this, invar)) {
// Range check for counted loops
const Node* cmp = bol->in(1)->as_Cmp();
diff --git a/hotspot/src/share/vm/opto/loopnode.hpp b/hotspot/src/share/vm/opto/loopnode.hpp
index c45ea8421f1..df3eb4c0520 100644
--- a/hotspot/src/share/vm/opto/loopnode.hpp
+++ b/hotspot/src/share/vm/opto/loopnode.hpp
@@ -965,7 +965,7 @@ public:
// Has use internal to the vector set (ie. not in a phi at the loop head)
bool has_use_internal_to_set( Node* n, VectorSet& vset, IdealLoopTree *loop );
// clone "n" for uses that are outside of loop
- void clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, Node_List& worklist );
+ int clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, Node_List& worklist );
// clone "n" for special uses that are in the not_peeled region
void clone_for_special_use_inside_loop( IdealLoopTree *loop, Node* n,
VectorSet& not_peel, Node_List& sink_list, Node_List& worklist );
diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp
index 1db82d4ceb1..31b5d8a5b7b 100644
--- a/hotspot/src/share/vm/opto/loopopts.cpp
+++ b/hotspot/src/share/vm/opto/loopopts.cpp
@@ -1939,8 +1939,8 @@ bool PhaseIdealLoop::has_use_internal_to_set( Node* n, VectorSet& vset, IdealLoo
//------------------------------ clone_for_use_outside_loop -------------------------------------
// clone "n" for uses that are outside of loop
-void PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, Node_List& worklist ) {
-
+int PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, Node_List& worklist ) {
+ int cloned = 0;
assert(worklist.size() == 0, "should be empty");
for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
Node* use = n->fast_out(j);
@@ -1960,6 +1960,7 @@ void PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, N
// clone "n" and insert it between the inputs of "n" and the use outside the loop
Node* n_clone = n->clone();
_igvn.replace_input_of(use, j, n_clone);
+ cloned++;
Node* use_c;
if (!use->is_Phi()) {
use_c = has_ctrl(use) ? get_ctrl(use) : use->in(0);
@@ -1977,6 +1978,7 @@ void PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, N
}
#endif
}
+ return cloned;
}
@@ -2495,6 +2497,7 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
// Evacuate nodes in peel region into the not_peeled region if possible
uint new_phi_cnt = 0;
+ uint cloned_for_outside_use = 0;
for (i = 0; i < peel_list.size();) {
Node* n = peel_list.at(i);
#if !defined(PRODUCT)
@@ -2513,8 +2516,7 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
// if not pinned and not a load (which maybe anti-dependent on a store)
// and not a CMove (Matcher expects only bool->cmove).
if ( n->in(0) == NULL && !n->is_Load() && !n->is_CMove() ) {
- clone_for_use_outside_loop( loop, n, worklist );
-
+ cloned_for_outside_use += clone_for_use_outside_loop( loop, n, worklist );
sink_list.push(n);
peel >>= n->_idx; // delete n from peel set.
not_peel <<= n->_idx; // add n to not_peel set.
@@ -2551,6 +2553,12 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
// Inhibit more partial peeling on this loop
assert(!head->is_partial_peel_loop(), "not partial peeled");
head->mark_partial_peel_failed();
+ if (cloned_for_outside_use > 0) {
+ // Terminate this round of loop opts because
+ // the graph outside this loop was changed.
+ C->set_major_progress();
+ return true;
+ }
return false;
}
diff --git a/hotspot/src/share/vm/opto/machnode.cpp b/hotspot/src/share/vm/opto/machnode.cpp
index b9b014e050b..0d6ddf9aeed 100644
--- a/hotspot/src/share/vm/opto/machnode.cpp
+++ b/hotspot/src/share/vm/opto/machnode.cpp
@@ -349,11 +349,11 @@ const class TypePtr *MachNode::adr_type() const {
if (base == NodeSentinel) return TypePtr::BOTTOM;
const Type* t = base->bottom_type();
- if (UseCompressedOops && Universe::narrow_oop_shift() == 0) {
+ if (t->isa_narrowoop() && Universe::narrow_oop_shift() == 0) {
// 32-bit unscaled narrow oop can be the base of any address expression
t = t->make_ptr();
}
- if (UseCompressedKlassPointers && Universe::narrow_klass_shift() == 0) {
+ if (t->isa_narrowklass() && Universe::narrow_klass_shift() == 0) {
// 32-bit unscaled narrow oop can be the base of any address expression
t = t->make_ptr();
}
diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp
index aeb1b6226be..56b9c939147 100644
--- a/hotspot/src/share/vm/opto/macro.cpp
+++ b/hotspot/src/share/vm/opto/macro.cpp
@@ -666,7 +666,7 @@ bool PhaseMacroExpand::can_eliminate_allocation(AllocateNode *alloc, GrowableArr
alloc->dump();
else
res->dump();
- } else {
+ } else if (alloc->_is_scalar_replaceable) {
tty->print("NotScalar (%s)", fail_eliminate);
if (res == NULL)
alloc->dump();
@@ -834,7 +834,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray is_EncodeP()) {
field_val = field_val->in(1);
} else {
- field_val = transform_later(new (C) DecodeNNode(field_val, field_val->bottom_type()->make_ptr()));
+ field_val = transform_later(new (C) DecodeNNode(field_val, field_val->get_ptr_type()));
}
}
sfpt->add_req(field_val);
@@ -845,18 +845,14 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray debug_start();
int end = jvms->debug_end();
- for (int i = start; i < end; i++) {
- if (sfpt->in(i) == res) {
- sfpt->set_req(i, sobj);
- }
- }
+ sfpt->replace_edges_in_range(res, sobj, start, end);
safepoints_done.append_if_missing(sfpt); // keep it for rollback
}
return true;
}
// Process users of eliminated allocation.
-void PhaseMacroExpand::process_users_of_allocation(AllocateNode *alloc) {
+void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) {
Node* res = alloc->result_cast();
if (res != NULL) {
for (DUIterator_Last jmin, j = res->last_outs(jmin); j >= jmin; ) {
@@ -899,6 +895,17 @@ void PhaseMacroExpand::process_users_of_allocation(AllocateNode *alloc) {
// Process other users of allocation's projections
//
if (_resproj != NULL && _resproj->outcnt() != 0) {
+ // First disconnect stores captured by Initialize node.
+ // If Initialize node is eliminated first in the following code,
+ // it will kill such stores and DUIterator_Last will assert.
+ for (DUIterator_Fast jmax, j = _resproj->fast_outs(jmax); j < jmax; j++) {
+ Node *use = _resproj->fast_out(j);
+ if (use->is_AddP()) {
+ // raw memory addresses used only by the initialization
+ _igvn.replace_node(use, C->top());
+ --j; --jmax;
+ }
+ }
for (DUIterator_Last jmin, j = _resproj->last_outs(jmin); j >= jmin; ) {
Node *use = _resproj->last_out(j);
uint oc1 = _resproj->outcnt();
@@ -923,9 +930,6 @@ void PhaseMacroExpand::process_users_of_allocation(AllocateNode *alloc) {
#endif
_igvn.replace_node(mem_proj, mem);
}
- } else if (use->is_AddP()) {
- // raw memory addresses used only by the initialization
- _igvn.replace_node(use, C->top());
} else {
assert(false, "only Initialize or AddP expected");
}
@@ -953,8 +957,18 @@ void PhaseMacroExpand::process_users_of_allocation(AllocateNode *alloc) {
}
bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) {
-
- if (!EliminateAllocations || !alloc->_is_scalar_replaceable) {
+ if (!EliminateAllocations || !alloc->_is_non_escaping) {
+ return false;
+ }
+ Node* klass = alloc->in(AllocateNode::KlassNode);
+ const TypeKlassPtr* tklass = _igvn.type(klass)->is_klassptr();
+ Node* res = alloc->result_cast();
+ // Eliminate boxing allocations which are not used
+ // regardless scalar replacable status.
+ bool boxing_alloc = C->eliminate_boxing() &&
+ tklass->klass()->is_instance_klass() &&
+ tklass->klass()->as_instance_klass()->is_box_klass();
+ if (!alloc->_is_scalar_replaceable && (!boxing_alloc || (res != NULL))) {
return false;
}
@@ -965,14 +979,22 @@ bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) {
return false;
}
+ if (!alloc->_is_scalar_replaceable) {
+ assert(res == NULL, "sanity");
+ // We can only eliminate allocation if all debug info references
+ // are already replaced with SafePointScalarObject because
+ // we can't search for a fields value without instance_id.
+ if (safepoints.length() > 0) {
+ return false;
+ }
+ }
+
if (!scalar_replacement(alloc, safepoints)) {
return false;
}
CompileLog* log = C->log();
if (log != NULL) {
- Node* klass = alloc->in(AllocateNode::KlassNode);
- const TypeKlassPtr* tklass = _igvn.type(klass)->is_klassptr();
log->head("eliminate_allocation type='%d'",
log->identify(tklass->klass()));
JVMState* p = alloc->jvms();
@@ -997,6 +1019,43 @@ bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) {
return true;
}
+bool PhaseMacroExpand::eliminate_boxing_node(CallStaticJavaNode *boxing) {
+ // EA should remove all uses of non-escaping boxing node.
+ if (!C->eliminate_boxing() || boxing->proj_out(TypeFunc::Parms) != NULL) {
+ return false;
+ }
+
+ extract_call_projections(boxing);
+
+ const TypeTuple* r = boxing->tf()->range();
+ assert(r->cnt() > TypeFunc::Parms, "sanity");
+ const TypeInstPtr* t = r->field_at(TypeFunc::Parms)->isa_instptr();
+ assert(t != NULL, "sanity");
+
+ CompileLog* log = C->log();
+ if (log != NULL) {
+ log->head("eliminate_boxing type='%d'",
+ log->identify(t->klass()));
+ JVMState* p = boxing->jvms();
+ while (p != NULL) {
+ log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
+ p = p->caller();
+ }
+ log->tail("eliminate_boxing");
+ }
+
+ process_users_of_allocation(boxing);
+
+#ifndef PRODUCT
+ if (PrintEliminateAllocations) {
+ tty->print("++++ Eliminated: %d ", boxing->_idx);
+ boxing->method()->print_short_name(tty);
+ tty->cr();
+ }
+#endif
+
+ return true;
+}
//---------------------------set_eden_pointers-------------------------
void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_adr) {
@@ -2384,6 +2443,9 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
case Node::Class_AllocateArray:
success = eliminate_allocate_node(n->as_Allocate());
break;
+ case Node::Class_CallStaticJava:
+ success = eliminate_boxing_node(n->as_CallStaticJava());
+ break;
case Node::Class_Lock:
case Node::Class_Unlock:
assert(!n->as_AbstractLock()->is_eliminated(), "sanity");
@@ -2424,6 +2486,11 @@ bool PhaseMacroExpand::expand_macro_nodes() {
C->remove_macro_node(n);
_igvn._worklist.push(n);
success = true;
+ } else if (n->Opcode() == Op_CallStaticJava) {
+ // Remove it from macro list and put on IGVN worklist to optimize.
+ C->remove_macro_node(n);
+ _igvn._worklist.push(n);
+ success = true;
} else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
_igvn.replace_node(n, n->in(1));
success = true;
diff --git a/hotspot/src/share/vm/opto/macro.hpp b/hotspot/src/share/vm/opto/macro.hpp
index ba35c497f2b..7a72316dfc8 100644
--- a/hotspot/src/share/vm/opto/macro.hpp
+++ b/hotspot/src/share/vm/opto/macro.hpp
@@ -86,10 +86,11 @@ private:
Node *value_from_mem(Node *mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc);
Node *value_from_mem_phi(Node *mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc, Node_Stack *value_phis, int level);
+ bool eliminate_boxing_node(CallStaticJavaNode *boxing);
bool eliminate_allocate_node(AllocateNode *alloc);
bool can_eliminate_allocation(AllocateNode *alloc, GrowableArray & safepoints);
bool scalar_replacement(AllocateNode *alloc, GrowableArray & safepoints_done);
- void process_users_of_allocation(AllocateNode *alloc);
+ void process_users_of_allocation(CallNode *alloc);
void eliminate_card_mark(Node *cm);
void mark_eliminated_box(Node* box, Node* obj);
diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp
index a4dcdb7c9a8..fc59cebdc55 100644
--- a/hotspot/src/share/vm/opto/memnode.cpp
+++ b/hotspot/src/share/vm/opto/memnode.cpp
@@ -103,11 +103,15 @@ extern void print_alias_types();
#endif
-Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) {
- const TypeOopPtr *tinst = t_adr->isa_oopptr();
- if (tinst == NULL || !tinst->is_known_instance_field())
+Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypeOopPtr *t_oop, Node *load, PhaseGVN *phase) {
+ assert((t_oop != NULL), "sanity");
+ bool is_instance = t_oop->is_known_instance_field();
+ bool is_boxed_value_load = t_oop->is_ptr_to_boxed_value() &&
+ (load != NULL) && load->is_Load() &&
+ (phase->is_IterGVN() != NULL);
+ if (!(is_instance || is_boxed_value_load))
return mchain; // don't try to optimize non-instance types
- uint instance_id = tinst->instance_id();
+ uint instance_id = t_oop->instance_id();
Node *start_mem = phase->C->start()->proj_out(TypeFunc::Memory);
Node *prev = NULL;
Node *result = mchain;
@@ -122,15 +126,24 @@ Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr,
break; // hit one of our sentinels
} else if (proj_in->is_Call()) {
CallNode *call = proj_in->as_Call();
- if (!call->may_modify(t_adr, phase)) {
+ if (!call->may_modify(t_oop, phase)) { // returns false for instances
result = call->in(TypeFunc::Memory);
}
} else if (proj_in->is_Initialize()) {
AllocateNode* alloc = proj_in->as_Initialize()->allocation();
// Stop if this is the initialization for the object instance which
// which contains this memory slice, otherwise skip over it.
- if (alloc != NULL && alloc->_idx != instance_id) {
+ if ((alloc == NULL) || (alloc->_idx == instance_id)) {
+ break;
+ }
+ if (is_instance) {
result = proj_in->in(TypeFunc::Memory);
+ } else if (is_boxed_value_load) {
+ Node* klass = alloc->in(AllocateNode::KlassNode);
+ const TypeKlassPtr* tklass = phase->type(klass)->is_klassptr();
+ if (tklass->klass_is_exact() && !tklass->klass()->equals(t_oop->klass())) {
+ result = proj_in->in(TypeFunc::Memory); // not related allocation
+ }
}
} else if (proj_in->is_MemBar()) {
result = proj_in->in(TypeFunc::Memory);
@@ -138,25 +151,26 @@ Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr,
assert(false, "unexpected projection");
}
} else if (result->is_ClearArray()) {
- if (!ClearArrayNode::step_through(&result, instance_id, phase)) {
+ if (!is_instance || !ClearArrayNode::step_through(&result, instance_id, phase)) {
// Can not bypass initialization of the instance
// we are looking for.
break;
}
// Otherwise skip it (the call updated 'result' value).
} else if (result->is_MergeMem()) {
- result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty);
+ result = step_through_mergemem(phase, result->as_MergeMem(), t_oop, NULL, tty);
}
}
return result;
}
-Node *MemNode::optimize_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) {
- const TypeOopPtr *t_oop = t_adr->isa_oopptr();
- bool is_instance = (t_oop != NULL) && t_oop->is_known_instance_field();
+Node *MemNode::optimize_memory_chain(Node *mchain, const TypePtr *t_adr, Node *load, PhaseGVN *phase) {
+ const TypeOopPtr* t_oop = t_adr->isa_oopptr();
+ if (t_oop == NULL)
+ return mchain; // don't try to optimize non-oop types
+ Node* result = optimize_simple_memory_chain(mchain, t_oop, load, phase);
+ bool is_instance = t_oop->is_known_instance_field();
PhaseIterGVN *igvn = phase->is_IterGVN();
- Node *result = mchain;
- result = optimize_simple_memory_chain(result, t_adr, phase);
if (is_instance && igvn != NULL && result->is_Phi()) {
PhiNode *mphi = result->as_Phi();
assert(mphi->bottom_type() == Type::MEMORY, "memory phi required");
@@ -383,7 +397,7 @@ bool MemNode::all_controls_dominate(Node* dom, Node* sub) {
// Or Region for the check in LoadNode::Ideal();
// 'sub' should have sub->in(0) != NULL.
assert(sub->is_Allocate() || sub->is_Initialize() || sub->is_Start() ||
- sub->is_Region(), "expecting only these nodes");
+ sub->is_Region() || sub->is_Call(), "expecting only these nodes");
// Get control edge of 'sub'.
Node* orig_sub = sub;
@@ -957,11 +971,14 @@ uint LoadNode::hash() const {
// of aliasing.
Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const {
Node* ld_adr = in(MemNode::Address);
-
+ intptr_t ld_off = 0;
+ AllocateNode* ld_alloc = AllocateNode::Ideal_allocation(ld_adr, phase, ld_off);
const TypeInstPtr* tp = phase->type(ld_adr)->isa_instptr();
- Compile::AliasType* atp = tp != NULL ? phase->C->alias_type(tp) : NULL;
- if (EliminateAutoBox && atp != NULL && atp->index() >= Compile::AliasIdxRaw &&
- atp->field() != NULL && !atp->field()->is_volatile()) {
+ Compile::AliasType* atp = (tp != NULL) ? phase->C->alias_type(tp) : NULL;
+ // This is more general than load from boxing objects.
+ if (phase->C->eliminate_boxing() && (atp != NULL) &&
+ (atp->index() >= Compile::AliasIdxRaw) &&
+ (atp->field() != NULL) && !atp->field()->is_volatile()) {
uint alias_idx = atp->index();
bool final = atp->field()->is_final();
Node* result = NULL;
@@ -983,7 +1000,7 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const {
Node* new_st = merge->memory_at(alias_idx);
if (new_st == merge->base_memory()) {
// Keep searching
- current = merge->base_memory();
+ current = new_st;
continue;
}
// Save the new memory state for the slice and fall through
@@ -1010,9 +1027,7 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const {
intptr_t st_off = 0;
AllocateNode* alloc = AllocateNode::Ideal_allocation(st_adr, phase, st_off);
if (alloc == NULL) return NULL;
- intptr_t ld_off = 0;
- AllocateNode* allo2 = AllocateNode::Ideal_allocation(ld_adr, phase, ld_off);
- if (alloc != allo2) return NULL;
+ if (alloc != ld_alloc) return NULL;
if (ld_off != st_off) return NULL;
// At this point we have proven something like this setup:
// A = Allocate(...)
@@ -1029,14 +1044,12 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const {
return st->in(MemNode::ValueIn);
}
- intptr_t offset = 0; // scratch
-
// A load from a freshly-created object always returns zero.
// (This can happen after LoadNode::Ideal resets the load's memory input
// to find_captured_store, which returned InitializeNode::zero_memory.)
if (st->is_Proj() && st->in(0)->is_Allocate() &&
- st->in(0) == AllocateNode::Ideal_allocation(ld_adr, phase, offset) &&
- offset >= st->in(0)->as_Allocate()->minimum_header_size()) {
+ (st->in(0) == ld_alloc) &&
+ (ld_off >= st->in(0)->as_Allocate()->minimum_header_size())) {
// return a zero value for the load's basic type
// (This is one of the few places where a generic PhaseTransform
// can create new nodes. Think of it as lazily manifesting
@@ -1048,15 +1061,27 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const {
if (st->is_Proj() && st->in(0)->is_Initialize()) {
InitializeNode* init = st->in(0)->as_Initialize();
AllocateNode* alloc = init->allocation();
- if (alloc != NULL &&
- alloc == AllocateNode::Ideal_allocation(ld_adr, phase, offset)) {
+ if ((alloc != NULL) && (alloc == ld_alloc)) {
// examine a captured store value
- st = init->find_captured_store(offset, memory_size(), phase);
+ st = init->find_captured_store(ld_off, memory_size(), phase);
if (st != NULL)
continue; // take one more trip around
}
}
+ // Load boxed value from result of valueOf() call is input parameter.
+ if (this->is_Load() && ld_adr->is_AddP() &&
+ (tp != NULL) && tp->is_ptr_to_boxed_value()) {
+ intptr_t ignore = 0;
+ Node* base = AddPNode::Ideal_base_and_offset(ld_adr, phase, ignore);
+ if (base != NULL && base->is_Proj() &&
+ base->as_Proj()->_con == TypeFunc::Parms &&
+ base->in(0)->is_CallStaticJava() &&
+ base->in(0)->as_CallStaticJava()->is_boxing_method()) {
+ return base->in(0)->in(TypeFunc::Parms);
+ }
+ }
+
break;
}
@@ -1065,11 +1090,13 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const {
//----------------------is_instance_field_load_with_local_phi------------------
bool LoadNode::is_instance_field_load_with_local_phi(Node* ctrl) {
- if( in(MemNode::Memory)->is_Phi() && in(MemNode::Memory)->in(0) == ctrl &&
- in(MemNode::Address)->is_AddP() ) {
- const TypeOopPtr* t_oop = in(MemNode::Address)->bottom_type()->isa_oopptr();
- // Only instances.
- if( t_oop != NULL && t_oop->is_known_instance_field() &&
+ if( in(Memory)->is_Phi() && in(Memory)->in(0) == ctrl &&
+ in(Address)->is_AddP() ) {
+ const TypeOopPtr* t_oop = in(Address)->bottom_type()->isa_oopptr();
+ // Only instances and boxed values.
+ if( t_oop != NULL &&
+ (t_oop->is_ptr_to_boxed_value() ||
+ t_oop->is_known_instance_field()) &&
t_oop->offset() != Type::OffsetBot &&
t_oop->offset() != Type::OffsetTop) {
return true;
@@ -1083,7 +1110,7 @@ bool LoadNode::is_instance_field_load_with_local_phi(Node* ctrl) {
Node *LoadNode::Identity( PhaseTransform *phase ) {
// If the previous store-maker is the right kind of Store, and the store is
// to the same address, then we are equal to the value stored.
- Node* mem = in(MemNode::Memory);
+ Node* mem = in(Memory);
Node* value = can_see_stored_value(mem, phase);
if( value ) {
// byte, short & char stores truncate naturally.
@@ -1105,15 +1132,22 @@ Node *LoadNode::Identity( PhaseTransform *phase ) {
// instance's field to avoid infinite generation of phis in a loop.
Node *region = mem->in(0);
if (is_instance_field_load_with_local_phi(region)) {
- const TypePtr *addr_t = in(MemNode::Address)->bottom_type()->isa_ptr();
+ const TypeOopPtr *addr_t = in(Address)->bottom_type()->isa_oopptr();
int this_index = phase->C->get_alias_index(addr_t);
int this_offset = addr_t->offset();
- int this_id = addr_t->is_oopptr()->instance_id();
+ int this_iid = addr_t->instance_id();
+ if (!addr_t->is_known_instance() &&
+ addr_t->is_ptr_to_boxed_value()) {
+ // Use _idx of address base (could be Phi node) for boxed values.
+ intptr_t ignore = 0;
+ Node* base = AddPNode::Ideal_base_and_offset(in(Address), phase, ignore);
+ this_iid = base->_idx;
+ }
const Type* this_type = bottom_type();
for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
Node* phi = region->fast_out(i);
if (phi->is_Phi() && phi != mem &&
- phi->as_Phi()->is_same_inst_field(this_type, this_id, this_index, this_offset)) {
+ phi->as_Phi()->is_same_inst_field(this_type, this_iid, this_index, this_offset)) {
return phi;
}
}
@@ -1122,170 +1156,106 @@ Node *LoadNode::Identity( PhaseTransform *phase ) {
return this;
}
-
-// Returns true if the AliasType refers to the field that holds the
-// cached box array. Currently only handles the IntegerCache case.
-static bool is_autobox_cache(Compile::AliasType* atp) {
- if (atp != NULL && atp->field() != NULL) {
- ciField* field = atp->field();
- ciSymbol* klass = field->holder()->name();
- if (field->name() == ciSymbol::cache_field_name() &&
- field->holder()->uses_default_loader() &&
- klass == ciSymbol::java_lang_Integer_IntegerCache()) {
- return true;
- }
- }
- return false;
-}
-
-// Fetch the base value in the autobox array
-static bool fetch_autobox_base(Compile::AliasType* atp, int& cache_offset) {
- if (atp != NULL && atp->field() != NULL) {
- ciField* field = atp->field();
- ciSymbol* klass = field->holder()->name();
- if (field->name() == ciSymbol::cache_field_name() &&
- field->holder()->uses_default_loader() &&
- klass == ciSymbol::java_lang_Integer_IntegerCache()) {
- assert(field->is_constant(), "what?");
- ciObjArray* array = field->constant_value().as_object()->as_obj_array();
- // Fetch the box object at the base of the array and get its value
- ciInstance* box = array->obj_at(0)->as_instance();
- ciInstanceKlass* ik = box->klass()->as_instance_klass();
- if (ik->nof_nonstatic_fields() == 1) {
- // This should be true nonstatic_field_at requires calling
- // nof_nonstatic_fields so check it anyway
- ciConstant c = box->field_value(ik->nonstatic_field_at(0));
- cache_offset = c.as_int();
- }
- return true;
- }
- }
- return false;
-}
-
-// Returns true if the AliasType refers to the value field of an
-// autobox object. Currently only handles Integer.
-static bool is_autobox_object(Compile::AliasType* atp) {
- if (atp != NULL && atp->field() != NULL) {
- ciField* field = atp->field();
- ciSymbol* klass = field->holder()->name();
- if (field->name() == ciSymbol::value_name() &&
- field->holder()->uses_default_loader() &&
- klass == ciSymbol::java_lang_Integer()) {
- return true;
- }
- }
- return false;
-}
-
-
// We're loading from an object which has autobox behaviour.
// If this object is result of a valueOf call we'll have a phi
// merging a newly allocated object and a load from the cache.
// We want to replace this load with the original incoming
// argument to the valueOf call.
Node* LoadNode::eliminate_autobox(PhaseGVN* phase) {
- Node* base = in(Address)->in(AddPNode::Base);
- if (base->is_Phi() && base->req() == 3) {
- AllocateNode* allocation = NULL;
- int allocation_index = -1;
- int load_index = -1;
- for (uint i = 1; i < base->req(); i++) {
- allocation = AllocateNode::Ideal_allocation(base->in(i), phase);
- if (allocation != NULL) {
- allocation_index = i;
- load_index = 3 - allocation_index;
- break;
- }
- }
- bool has_load = ( allocation != NULL &&
- (base->in(load_index)->is_Load() ||
- base->in(load_index)->is_DecodeN() &&
- base->in(load_index)->in(1)->is_Load()) );
- if (has_load && in(Memory)->is_Phi() && in(Memory)->in(0) == base->in(0)) {
- // Push the loads from the phi that comes from valueOf up
- // through it to allow elimination of the loads and the recovery
- // of the original value.
- Node* mem_phi = in(Memory);
- Node* offset = in(Address)->in(AddPNode::Offset);
- Node* region = base->in(0);
-
- Node* in1 = clone();
- Node* in1_addr = in1->in(Address)->clone();
- in1_addr->set_req(AddPNode::Base, base->in(allocation_index));
- in1_addr->set_req(AddPNode::Address, base->in(allocation_index));
- in1_addr->set_req(AddPNode::Offset, offset);
- in1->set_req(0, region->in(allocation_index));
- in1->set_req(Address, in1_addr);
- in1->set_req(Memory, mem_phi->in(allocation_index));
-
- Node* in2 = clone();
- Node* in2_addr = in2->in(Address)->clone();
- in2_addr->set_req(AddPNode::Base, base->in(load_index));
- in2_addr->set_req(AddPNode::Address, base->in(load_index));
- in2_addr->set_req(AddPNode::Offset, offset);
- in2->set_req(0, region->in(load_index));
- in2->set_req(Address, in2_addr);
- in2->set_req(Memory, mem_phi->in(load_index));
-
- in1_addr = phase->transform(in1_addr);
- in1 = phase->transform(in1);
- in2_addr = phase->transform(in2_addr);
- in2 = phase->transform(in2);
-
- PhiNode* result = PhiNode::make_blank(region, this);
- result->set_req(allocation_index, in1);
- result->set_req(load_index, in2);
- return result;
- }
+ assert(phase->C->eliminate_boxing(), "sanity");
+ intptr_t ignore = 0;
+ Node* base = AddPNode::Ideal_base_and_offset(in(Address), phase, ignore);
+ if ((base == NULL) || base->is_Phi()) {
+ // Push the loads from the phi that comes from valueOf up
+ // through it to allow elimination of the loads and the recovery
+ // of the original value. It is done in split_through_phi().
+ return NULL;
} else if (base->is_Load() ||
base->is_DecodeN() && base->in(1)->is_Load()) {
- if (base->is_DecodeN()) {
- // Get LoadN node which loads cached Integer object
- base = base->in(1);
- }
- // Eliminate the load of Integer.value for integers from the cache
+ // Eliminate the load of boxed value for integer types from the cache
// array by deriving the value from the index into the array.
// Capture the offset of the load and then reverse the computation.
- Node* load_base = base->in(Address)->in(AddPNode::Base);
- if (load_base->is_DecodeN()) {
- // Get LoadN node which loads IntegerCache.cache field
- load_base = load_base->in(1);
+
+ // Get LoadN node which loads a boxing object from 'cache' array.
+ if (base->is_DecodeN()) {
+ base = base->in(1);
}
- if (load_base != NULL) {
- Compile::AliasType* atp = phase->C->alias_type(load_base->adr_type());
- intptr_t cache_offset;
- int shift = -1;
- Node* cache = NULL;
- if (is_autobox_cache(atp)) {
- shift = exact_log2(type2aelembytes(T_OBJECT));
- cache = AddPNode::Ideal_base_and_offset(load_base->in(Address), phase, cache_offset);
- }
- if (cache != NULL && base->in(Address)->is_AddP()) {
+ if (!base->in(Address)->is_AddP()) {
+ return NULL; // Complex address
+ }
+ AddPNode* address = base->in(Address)->as_AddP();
+ Node* cache_base = address->in(AddPNode::Base);
+ if ((cache_base != NULL) && cache_base->is_DecodeN()) {
+ // Get ConP node which is static 'cache' field.
+ cache_base = cache_base->in(1);
+ }
+ if ((cache_base != NULL) && cache_base->is_Con()) {
+ const TypeAryPtr* base_type = cache_base->bottom_type()->isa_aryptr();
+ if ((base_type != NULL) && base_type->is_autobox_cache()) {
Node* elements[4];
- int count = base->in(Address)->as_AddP()->unpack_offsets(elements, ARRAY_SIZE(elements));
- int cache_low;
- if (count > 0 && fetch_autobox_base(atp, cache_low)) {
- int offset = arrayOopDesc::base_offset_in_bytes(memory_type()) - (cache_low << shift);
- // Add up all the offsets making of the address of the load
- Node* result = elements[0];
- for (int i = 1; i < count; i++) {
- result = phase->transform(new (phase->C) AddXNode(result, elements[i]));
- }
- // Remove the constant offset from the address and then
- // remove the scaling of the offset to recover the original index.
- result = phase->transform(new (phase->C) AddXNode(result, phase->MakeConX(-offset)));
- if (result->Opcode() == Op_LShiftX && result->in(2) == phase->intcon(shift)) {
- // Peel the shift off directly but wrap it in a dummy node
- // since Ideal can't return existing nodes
- result = new (phase->C) RShiftXNode(result->in(1), phase->intcon(0));
- } else {
- result = new (phase->C) RShiftXNode(result, phase->intcon(shift));
- }
+ int shift = exact_log2(type2aelembytes(T_OBJECT));
+ int count = address->unpack_offsets(elements, ARRAY_SIZE(elements));
+ if ((count > 0) && elements[0]->is_Con() &&
+ ((count == 1) ||
+ (count == 2) && elements[1]->Opcode() == Op_LShiftX &&
+ elements[1]->in(2) == phase->intcon(shift))) {
+ ciObjArray* array = base_type->const_oop()->as_obj_array();
+ // Fetch the box object cache[0] at the base of the array and get its value
+ ciInstance* box = array->obj_at(0)->as_instance();
+ ciInstanceKlass* ik = box->klass()->as_instance_klass();
+ assert(ik->is_box_klass(), "sanity");
+ assert(ik->nof_nonstatic_fields() == 1, "change following code");
+ if (ik->nof_nonstatic_fields() == 1) {
+ // This should be true nonstatic_field_at requires calling
+ // nof_nonstatic_fields so check it anyway
+ ciConstant c = box->field_value(ik->nonstatic_field_at(0));
+ BasicType bt = c.basic_type();
+ // Only integer types have boxing cache.
+ assert(bt == T_BOOLEAN || bt == T_CHAR ||
+ bt == T_BYTE || bt == T_SHORT ||
+ bt == T_INT || bt == T_LONG, err_msg_res("wrong type = %s", type2name(bt)));
+ jlong cache_low = (bt == T_LONG) ? c.as_long() : c.as_int();
+ if (cache_low != (int)cache_low) {
+ return NULL; // should not happen since cache is array indexed by value
+ }
+ jlong offset = arrayOopDesc::base_offset_in_bytes(T_OBJECT) - (cache_low << shift);
+ if (offset != (int)offset) {
+ return NULL; // should not happen since cache is array indexed by value
+ }
+ // Add up all the offsets making of the address of the load
+ Node* result = elements[0];
+ for (int i = 1; i < count; i++) {
+ result = phase->transform(new (phase->C) AddXNode(result, elements[i]));
+ }
+ // Remove the constant offset from the address and then
+ result = phase->transform(new (phase->C) AddXNode(result, phase->MakeConX(-(int)offset)));
+ // remove the scaling of the offset to recover the original index.
+ if (result->Opcode() == Op_LShiftX && result->in(2) == phase->intcon(shift)) {
+ // Peel the shift off directly but wrap it in a dummy node
+ // since Ideal can't return existing nodes
+ result = new (phase->C) RShiftXNode(result->in(1), phase->intcon(0));
+ } else if (result->is_Add() && result->in(2)->is_Con() &&
+ result->in(1)->Opcode() == Op_LShiftX &&
+ result->in(1)->in(2) == phase->intcon(shift)) {
+ // We can't do general optimization: ((X<> Z ==> X + (Y>>Z)
+ // but for boxing cache access we know that X<C) RShiftXNode(result->in(2), phase->intcon(shift));
+ result = new (phase->C) AddXNode(result->in(1)->in(1), phase->transform(add_con));
+ } else {
+ result = new (phase->C) RShiftXNode(result, phase->intcon(shift));
+ }
#ifdef _LP64
- result = new (phase->C) ConvL2INode(phase->transform(result));
+ if (bt != T_LONG) {
+ result = new (phase->C) ConvL2INode(phase->transform(result));
+ }
+#else
+ if (bt == T_LONG) {
+ result = new (phase->C) ConvI2LNode(phase->transform(result));
+ }
#endif
- return result;
+ return result;
+ }
}
}
}
@@ -1293,65 +1263,131 @@ Node* LoadNode::eliminate_autobox(PhaseGVN* phase) {
return NULL;
}
-//------------------------------split_through_phi------------------------------
-// Split instance field load through Phi.
-Node *LoadNode::split_through_phi(PhaseGVN *phase) {
- Node* mem = in(MemNode::Memory);
- Node* address = in(MemNode::Address);
- const TypePtr *addr_t = phase->type(address)->isa_ptr();
- const TypeOopPtr *t_oop = addr_t->isa_oopptr();
-
- assert(mem->is_Phi() && (t_oop != NULL) &&
- t_oop->is_known_instance_field(), "invalide conditions");
-
- Node *region = mem->in(0);
+static bool stable_phi(PhiNode* phi, PhaseGVN *phase) {
+ Node* region = phi->in(0);
if (region == NULL) {
- return NULL; // Wait stable graph
+ return false; // Wait stable graph
}
- uint cnt = mem->req();
+ uint cnt = phi->req();
for (uint i = 1; i < cnt; i++) {
Node* rc = region->in(i);
if (rc == NULL || phase->type(rc) == Type::TOP)
- return NULL; // Wait stable graph
- Node *in = mem->in(i);
- if (in == NULL) {
+ return false; // Wait stable graph
+ Node* in = phi->in(i);
+ if (in == NULL || phase->type(in) == Type::TOP)
+ return false; // Wait stable graph
+ }
+ return true;
+}
+//------------------------------split_through_phi------------------------------
+// Split instance or boxed field load through Phi.
+Node *LoadNode::split_through_phi(PhaseGVN *phase) {
+ Node* mem = in(Memory);
+ Node* address = in(Address);
+ const TypeOopPtr *t_oop = phase->type(address)->isa_oopptr();
+
+ assert((t_oop != NULL) &&
+ (t_oop->is_known_instance_field() ||
+ t_oop->is_ptr_to_boxed_value()), "invalide conditions");
+
+ Compile* C = phase->C;
+ intptr_t ignore = 0;
+ Node* base = AddPNode::Ideal_base_and_offset(address, phase, ignore);
+ bool base_is_phi = (base != NULL) && base->is_Phi();
+ bool load_boxed_values = t_oop->is_ptr_to_boxed_value() && C->aggressive_unboxing() &&
+ (base != NULL) && (base == address->in(AddPNode::Base)) &&
+ phase->type(base)->higher_equal(TypePtr::NOTNULL);
+
+ if (!((mem->is_Phi() || base_is_phi) &&
+ (load_boxed_values || t_oop->is_known_instance_field()))) {
+ return NULL; // memory is not Phi
+ }
+
+ if (mem->is_Phi()) {
+ if (!stable_phi(mem->as_Phi(), phase)) {
return NULL; // Wait stable graph
}
- }
- // Check for loop invariant.
- if (cnt == 3) {
- for (uint i = 1; i < cnt; i++) {
- Node *in = mem->in(i);
- Node* m = MemNode::optimize_memory_chain(in, addr_t, phase);
- if (m == mem) {
- set_req(MemNode::Memory, mem->in(cnt - i)); // Skip this phi.
- return this;
+ uint cnt = mem->req();
+ // Check for loop invariant memory.
+ if (cnt == 3) {
+ for (uint i = 1; i < cnt; i++) {
+ Node* in = mem->in(i);
+ Node* m = optimize_memory_chain(in, t_oop, this, phase);
+ if (m == mem) {
+ set_req(Memory, mem->in(cnt - i));
+ return this; // made change
+ }
}
}
}
+ if (base_is_phi) {
+ if (!stable_phi(base->as_Phi(), phase)) {
+ return NULL; // Wait stable graph
+ }
+ uint cnt = base->req();
+ // Check for loop invariant memory.
+ if (cnt == 3) {
+ for (uint i = 1; i < cnt; i++) {
+ if (base->in(i) == base) {
+ return NULL; // Wait stable graph
+ }
+ }
+ }
+ }
+
+ bool load_boxed_phi = load_boxed_values && base_is_phi && (base->in(0) == mem->in(0));
+
// Split through Phi (see original code in loopopts.cpp).
- assert(phase->C->have_alias_type(addr_t), "instance should have alias type");
+ assert(C->have_alias_type(t_oop), "instance should have alias type");
// Do nothing here if Identity will find a value
// (to avoid infinite chain of value phis generation).
if (!phase->eqv(this, this->Identity(phase)))
return NULL;
- // Skip the split if the region dominates some control edge of the address.
- if (!MemNode::all_controls_dominate(address, region))
- return NULL;
+ // Select Region to split through.
+ Node* region;
+ if (!base_is_phi) {
+ assert(mem->is_Phi(), "sanity");
+ region = mem->in(0);
+ // Skip if the region dominates some control edge of the address.
+ if (!MemNode::all_controls_dominate(address, region))
+ return NULL;
+ } else if (!mem->is_Phi()) {
+ assert(base_is_phi, "sanity");
+ region = base->in(0);
+ // Skip if the region dominates some control edge of the memory.
+ if (!MemNode::all_controls_dominate(mem, region))
+ return NULL;
+ } else if (base->in(0) != mem->in(0)) {
+ assert(base_is_phi && mem->is_Phi(), "sanity");
+ if (MemNode::all_controls_dominate(mem, base->in(0))) {
+ region = base->in(0);
+ } else if (MemNode::all_controls_dominate(address, mem->in(0))) {
+ region = mem->in(0);
+ } else {
+ return NULL; // complex graph
+ }
+ } else {
+ assert(base->in(0) == mem->in(0), "sanity");
+ region = mem->in(0);
+ }
const Type* this_type = this->bottom_type();
- int this_index = phase->C->get_alias_index(addr_t);
- int this_offset = addr_t->offset();
- int this_iid = addr_t->is_oopptr()->instance_id();
- PhaseIterGVN *igvn = phase->is_IterGVN();
- Node *phi = new (igvn->C) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset);
+ int this_index = C->get_alias_index(t_oop);
+ int this_offset = t_oop->offset();
+ int this_iid = t_oop->instance_id();
+ if (!t_oop->is_known_instance() && load_boxed_values) {
+ // Use _idx of address base for boxed values.
+ this_iid = base->_idx;
+ }
+ PhaseIterGVN* igvn = phase->is_IterGVN();
+ Node* phi = new (C) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset);
for (uint i = 1; i < region->req(); i++) {
- Node *x;
+ Node* x;
Node* the_clone = NULL;
- if (region->in(i) == phase->C->top()) {
- x = phase->C->top(); // Dead path? Use a dead data op
+ if (region->in(i) == C->top()) {
+ x = C->top(); // Dead path? Use a dead data op
} else {
x = this->clone(); // Else clone up the data op
the_clone = x; // Remember for possible deletion.
@@ -1361,10 +1397,16 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) {
} else {
x->set_req(0, NULL);
}
- for (uint j = 1; j < this->req(); j++) {
- Node *in = this->in(j);
- if (in->is_Phi() && in->in(0) == region)
- x->set_req(j, in->in(i)); // Use pre-Phi input for the clone
+ if (mem->is_Phi() && (mem->in(0) == region)) {
+ x->set_req(Memory, mem->in(i)); // Use pre-Phi input for the clone.
+ }
+ if (address->is_Phi() && address->in(0) == region) {
+ x->set_req(Address, address->in(i)); // Use pre-Phi input for the clone
+ }
+ if (base_is_phi && (base->in(0) == region)) {
+ Node* base_x = base->in(i); // Clone address for loads from boxed objects.
+ Node* adr_x = phase->transform(new (C) AddPNode(base_x,base_x,address->in(AddPNode::Offset)));
+ x->set_req(Address, adr_x);
}
}
// Check for a 'win' on some paths
@@ -1394,7 +1436,7 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) {
if (y != x) {
x = y;
} else {
- y = igvn->hash_find(x);
+ y = igvn->hash_find_insert(x);
if (y) {
x = y;
} else {
@@ -1405,8 +1447,9 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) {
}
}
}
- if (x != the_clone && the_clone != NULL)
+ if (x != the_clone && the_clone != NULL) {
igvn->remove_dead_node(the_clone);
+ }
phi->set_req(i, x);
}
// Record Phi
@@ -1445,31 +1488,23 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// A method-invariant, non-null address (constant or 'this' argument).
set_req(MemNode::Control, NULL);
}
-
- if (EliminateAutoBox && can_reshape) {
- assert(!phase->type(base)->higher_equal(TypePtr::NULL_PTR), "the autobox pointer should be non-null");
- Compile::AliasType* atp = phase->C->alias_type(adr_type());
- if (is_autobox_object(atp)) {
- Node* result = eliminate_autobox(phase);
- if (result != NULL) return result;
- }
- }
}
Node* mem = in(MemNode::Memory);
const TypePtr *addr_t = phase->type(address)->isa_ptr();
- if (addr_t != NULL) {
+ if (can_reshape && (addr_t != NULL)) {
// try to optimize our memory input
- Node* opt_mem = MemNode::optimize_memory_chain(mem, addr_t, phase);
+ Node* opt_mem = MemNode::optimize_memory_chain(mem, addr_t, this, phase);
if (opt_mem != mem) {
set_req(MemNode::Memory, opt_mem);
if (phase->type( opt_mem ) == Type::TOP) return NULL;
return this;
}
const TypeOopPtr *t_oop = addr_t->isa_oopptr();
- if (can_reshape && opt_mem->is_Phi() &&
- (t_oop != NULL) && t_oop->is_known_instance_field()) {
+ if ((t_oop != NULL) &&
+ (t_oop->is_known_instance_field() ||
+ t_oop->is_ptr_to_boxed_value())) {
PhaseIterGVN *igvn = phase->is_IterGVN();
if (igvn != NULL && igvn->_worklist.member(opt_mem)) {
// Delay this transformation until memory Phi is processed.
@@ -1479,6 +1514,11 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// Split instance field load through Phi.
Node* result = split_through_phi(phase);
if (result != NULL) return result;
+
+ if (t_oop->is_ptr_to_boxed_value()) {
+ Node* result = eliminate_autobox(phase);
+ if (result != NULL) return result;
+ }
}
}
@@ -1587,18 +1627,23 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
// This can happen if a interface-typed array narrows to a class type.
jt = _type;
}
-
- if (EliminateAutoBox && adr->is_AddP()) {
+#ifdef ASSERT
+ if (phase->C->eliminate_boxing() && adr->is_AddP()) {
// The pointers in the autobox arrays are always non-null
Node* base = adr->in(AddPNode::Base);
- if (base != NULL &&
- !phase->type(base)->higher_equal(TypePtr::NULL_PTR)) {
- Compile::AliasType* atp = C->alias_type(base->adr_type());
- if (is_autobox_cache(atp)) {
- return jt->join(TypePtr::NOTNULL)->is_ptr();
+ if ((base != NULL) && base->is_DecodeN()) {
+ // Get LoadN node which loads IntegerCache.cache field
+ base = base->in(1);
+ }
+ if ((base != NULL) && base->is_Con()) {
+ const TypeAryPtr* base_type = base->bottom_type()->isa_aryptr();
+ if ((base_type != NULL) && base_type->is_autobox_cache()) {
+ // It could be narrow oop
+ assert(jt->make_ptr()->ptr() == TypePtr::NotNull,"sanity");
}
}
}
+#endif
return jt;
}
}
@@ -1638,6 +1683,10 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
// Optimizations for constant objects
ciObject* const_oop = tinst->const_oop();
if (const_oop != NULL) {
+ // For constant Boxed value treat the target field as a compile time constant.
+ if (tinst->is_ptr_to_boxed_value()) {
+ return tinst->get_const_boxed_value();
+ } else
// For constant CallSites treat the target field as a compile time constant.
if (const_oop->is_call_site()) {
ciCallSite* call_site = const_oop->as_call_site();
@@ -1759,7 +1808,8 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
// (Also allow a variable load from a fresh array to produce zero.)
const TypeOopPtr *tinst = tp->isa_oopptr();
bool is_instance = (tinst != NULL) && tinst->is_known_instance_field();
- if (ReduceFieldZeroing || is_instance) {
+ bool is_boxed_value = (tinst != NULL) && tinst->is_ptr_to_boxed_value();
+ if (ReduceFieldZeroing || is_instance || is_boxed_value) {
Node* value = can_see_stored_value(mem,phase);
if (value != NULL && value->is_Con()) {
assert(value->bottom_type()->higher_equal(_type),"sanity");
@@ -2883,24 +2933,38 @@ Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) {
if (in(0) && in(0)->is_top()) return NULL;
// Eliminate volatile MemBars for scalar replaced objects.
- if (can_reshape && req() == (Precedent+1) &&
- (Opcode() == Op_MemBarAcquire || Opcode() == Op_MemBarVolatile)) {
- // Volatile field loads and stores.
- Node* my_mem = in(MemBarNode::Precedent);
- if (my_mem != NULL && my_mem->is_Mem()) {
- const TypeOopPtr* t_oop = my_mem->in(MemNode::Address)->bottom_type()->isa_oopptr();
- // Check for scalar replaced object reference.
- if( t_oop != NULL && t_oop->is_known_instance_field() &&
- t_oop->offset() != Type::OffsetBot &&
- t_oop->offset() != Type::OffsetTop) {
- // Replace MemBar projections by its inputs.
- PhaseIterGVN* igvn = phase->is_IterGVN();
- igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory));
- igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control));
- // Must return either the original node (now dead) or a new node
- // (Do not return a top here, since that would break the uniqueness of top.)
- return new (phase->C) ConINode(TypeInt::ZERO);
+ if (can_reshape && req() == (Precedent+1)) {
+ bool eliminate = false;
+ int opc = Opcode();
+ if ((opc == Op_MemBarAcquire || opc == Op_MemBarVolatile)) {
+ // Volatile field loads and stores.
+ Node* my_mem = in(MemBarNode::Precedent);
+ if (my_mem != NULL && my_mem->is_Mem()) {
+ const TypeOopPtr* t_oop = my_mem->in(MemNode::Address)->bottom_type()->isa_oopptr();
+ // Check for scalar replaced object reference.
+ if( t_oop != NULL && t_oop->is_known_instance_field() &&
+ t_oop->offset() != Type::OffsetBot &&
+ t_oop->offset() != Type::OffsetTop) {
+ eliminate = true;
+ }
}
+ } else if (opc == Op_MemBarRelease) {
+ // Final field stores.
+ Node* alloc = AllocateNode::Ideal_allocation(in(MemBarNode::Precedent), phase);
+ if ((alloc != NULL) && alloc->is_Allocate() &&
+ alloc->as_Allocate()->_is_non_escaping) {
+ // The allocated object does not escape.
+ eliminate = true;
+ }
+ }
+ if (eliminate) {
+ // Replace MemBar projections by its inputs.
+ PhaseIterGVN* igvn = phase->is_IterGVN();
+ igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory));
+ igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control));
+ // Must return either the original node (now dead) or a new node
+ // (Do not return a top here, since that would break the uniqueness of top.)
+ return new (phase->C) ConINode(TypeInt::ZERO);
}
}
return NULL;
@@ -3113,9 +3177,7 @@ intptr_t InitializeNode::get_store_offset(Node* st, PhaseTransform* phase) {
// within the initialization without creating a vicious cycle, such as:
// { Foo p = new Foo(); p.next = p; }
// True for constants and parameters and small combinations thereof.
-bool InitializeNode::detect_init_independence(Node* n,
- bool st_is_pinned,
- int& count) {
+bool InitializeNode::detect_init_independence(Node* n, int& count) {
if (n == NULL) return true; // (can this really happen?)
if (n->is_Proj()) n = n->in(0);
if (n == this) return false; // found a cycle
@@ -3135,7 +3197,6 @@ bool InitializeNode::detect_init_independence(Node* n,
// a store is never pinned *before* the availability of its inputs.
if (!MemNode::all_controls_dominate(n, this))
return false; // failed to prove a good control
-
}
// Check data edges for possible dependencies on 'this'.
@@ -3145,7 +3206,7 @@ bool InitializeNode::detect_init_independence(Node* n,
if (m == NULL || m == n || m->is_top()) continue;
uint first_i = n->find_edge(m);
if (i != first_i) continue; // process duplicate edge just once
- if (!detect_init_independence(m, st_is_pinned, count)) {
+ if (!detect_init_independence(m, count)) {
return false;
}
}
@@ -3176,7 +3237,7 @@ intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase,
return FAIL; // wrong allocation! (store needs to float up)
Node* val = st->in(MemNode::ValueIn);
int complexity_count = 0;
- if (!detect_init_independence(val, true, complexity_count))
+ if (!detect_init_independence(val, complexity_count))
return FAIL; // stored value must be 'simple enough'
// The Store can be captured only if nothing after the allocation
diff --git a/hotspot/src/share/vm/opto/memnode.hpp b/hotspot/src/share/vm/opto/memnode.hpp
index 73b3e34c705..9a009908453 100644
--- a/hotspot/src/share/vm/opto/memnode.hpp
+++ b/hotspot/src/share/vm/opto/memnode.hpp
@@ -75,8 +75,8 @@ public:
PhaseTransform* phase);
static bool adr_phi_is_loop_invariant(Node* adr_phi, Node* cast);
- static Node *optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase);
- static Node *optimize_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase);
+ static Node *optimize_simple_memory_chain(Node *mchain, const TypeOopPtr *t_oop, Node *load, PhaseGVN *phase);
+ static Node *optimize_memory_chain(Node *mchain, const TypePtr *t_adr, Node *load, PhaseGVN *phase);
// This one should probably be a phase-specific function:
static bool all_controls_dominate(Node* dom, Node* sub);
@@ -1099,7 +1099,7 @@ public:
Node* make_raw_address(intptr_t offset, PhaseTransform* phase);
- bool detect_init_independence(Node* n, bool st_is_pinned, int& count);
+ bool detect_init_independence(Node* n, int& count);
void coalesce_subword_stores(intptr_t header_size, Node* size_in_bytes,
PhaseGVN* phase);
diff --git a/hotspot/src/share/vm/opto/multnode.cpp b/hotspot/src/share/vm/opto/multnode.cpp
index 28041410682..dca8dbe703c 100644
--- a/hotspot/src/share/vm/opto/multnode.cpp
+++ b/hotspot/src/share/vm/opto/multnode.cpp
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "opto/callnode.hpp"
#include "opto/matcher.hpp"
#include "opto/multnode.hpp"
#include "opto/opcodes.hpp"
@@ -73,13 +74,26 @@ bool ProjNode::is_CFG() const {
return (_con == TypeFunc::Control && def->is_CFG());
}
+const Type* ProjNode::proj_type(const Type* t) const {
+ if (t == Type::TOP) {
+ return Type::TOP;
+ }
+ if (t == Type::BOTTOM) {
+ return Type::BOTTOM;
+ }
+ t = t->is_tuple()->field_at(_con);
+ Node* n = in(0);
+ if ((_con == TypeFunc::Parms) &&
+ n->is_CallStaticJava() && n->as_CallStaticJava()->is_boxing_method()) {
+ // The result of autoboxing is always non-null on normal path.
+ t = t->join(TypePtr::NOTNULL);
+ }
+ return t;
+}
+
const Type *ProjNode::bottom_type() const {
- if (in(0) == NULL) return Type::TOP;
- const Type *tb = in(0)->bottom_type();
- if( tb == Type::TOP ) return Type::TOP;
- if( tb == Type::BOTTOM ) return Type::BOTTOM;
- const TypeTuple *t = tb->is_tuple();
- return t->field_at(_con);
+ if (in(0) == NULL) return Type::TOP;
+ return proj_type(in(0)->bottom_type());
}
const TypePtr *ProjNode::adr_type() const {
@@ -115,11 +129,8 @@ void ProjNode::check_con() const {
//------------------------------Value------------------------------------------
const Type *ProjNode::Value( PhaseTransform *phase ) const {
- if( !in(0) ) return Type::TOP;
- const Type *t = phase->type(in(0));
- if( t == Type::TOP ) return t;
- if( t == Type::BOTTOM ) return t;
- return t->is_tuple()->field_at(_con);
+ if (in(0) == NULL) return Type::TOP;
+ return proj_type(phase->type(in(0)));
}
//------------------------------out_RegMask------------------------------------
diff --git a/hotspot/src/share/vm/opto/multnode.hpp b/hotspot/src/share/vm/opto/multnode.hpp
index fba94e5b431..242e58f4850 100644
--- a/hotspot/src/share/vm/opto/multnode.hpp
+++ b/hotspot/src/share/vm/opto/multnode.hpp
@@ -60,6 +60,7 @@ protected:
virtual uint cmp( const Node &n ) const;
virtual uint size_of() const;
void check_con() const; // Called from constructor.
+ const Type* proj_type(const Type* t) const;
public:
ProjNode( Node *src, uint con, bool io_use = false )
@@ -83,6 +84,7 @@ public:
virtual const Type *Value( PhaseTransform *phase ) const;
virtual uint ideal_reg() const;
virtual const RegMask &out_RegMask() const;
+
#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const;
#endif
diff --git a/hotspot/src/share/vm/opto/node.cpp b/hotspot/src/share/vm/opto/node.cpp
index e1698b26be3..f2100040ffe 100644
--- a/hotspot/src/share/vm/opto/node.cpp
+++ b/hotspot/src/share/vm/opto/node.cpp
@@ -67,7 +67,8 @@ void Node::verify_construction() {
}
Compile::set_debug_idx(new_debug_idx);
set_debug_idx( new_debug_idx );
- assert(Compile::current()->unique() < (UINT_MAX - 1), "Node limit exceeded UINT_MAX");
+ assert(Compile::current()->unique() < (INT_MAX - 1), "Node limit exceeded INT_MAX");
+ assert(Compile::current()->live_nodes() < (uint)MaxNodeLimit, "Live Node limit exceeded limit");
if (BreakAtNode != 0 && (_debug_idx == BreakAtNode || (int)_idx == BreakAtNode)) {
tty->print_cr("BreakAtNode: _idx=%d _debug_idx=%d", _idx, _debug_idx);
BREAKPOINT;
@@ -471,9 +472,9 @@ Node::Node(Node *n0, Node *n1, Node *n2, Node *n3,
//------------------------------clone------------------------------------------
// Clone a Node.
Node *Node::clone() const {
- Compile *compile = Compile::current();
+ Compile* C = Compile::current();
uint s = size_of(); // Size of inherited Node
- Node *n = (Node*)compile->node_arena()->Amalloc_D(size_of() + _max*sizeof(Node*));
+ Node *n = (Node*)C->node_arena()->Amalloc_D(size_of() + _max*sizeof(Node*));
Copy::conjoint_words_to_lower((HeapWord*)this, (HeapWord*)n, s);
// Set the new input pointer array
n->_in = (Node**)(((char*)n)+s);
@@ -492,18 +493,18 @@ Node *Node::clone() const {
if (x != NULL) x->add_out(n);
}
if (is_macro())
- compile->add_macro_node(n);
+ C->add_macro_node(n);
if (is_expensive())
- compile->add_expensive_node(n);
+ C->add_expensive_node(n);
- n->set_idx(compile->next_unique()); // Get new unique index as well
+ n->set_idx(C->next_unique()); // Get new unique index as well
debug_only( n->verify_construction() );
NOT_PRODUCT(nodes_created++);
// Do not patch over the debug_idx of a clone, because it makes it
// impossible to break on the clone's moment of creation.
//debug_only( n->set_debug_idx( debug_idx() ) );
- compile->copy_node_notes_to(n, (Node*) this);
+ C->copy_node_notes_to(n, (Node*) this);
// MachNode clone
uint nopnds;
@@ -518,13 +519,12 @@ Node *Node::clone() const {
(const void*)(&mthis->_opnds), 1));
mach->_opnds = to;
for ( uint i = 0; i < nopnds; ++i ) {
- to[i] = from[i]->clone(compile);
+ to[i] = from[i]->clone(C);
}
}
// cloning CallNode may need to clone JVMState
if (n->is_Call()) {
- CallNode *call = n->as_Call();
- call->clone_jvms();
+ n->as_Call()->clone_jvms(C);
}
return n; // Return the clone
}
@@ -811,6 +811,21 @@ int Node::replace_edge(Node* old, Node* neww) {
return nrep;
}
+/**
+ * Replace input edges in the range pointing to 'old' node.
+ */
+int Node::replace_edges_in_range(Node* old, Node* neww, int start, int end) {
+ if (old == neww) return 0; // nothing to do
+ uint nrep = 0;
+ for (int i = start; i < end; i++) {
+ if (in(i) == old) {
+ set_req(i, neww);
+ nrep++;
+ }
+ }
+ return nrep;
+}
+
//-------------------------disconnect_inputs-----------------------------------
// NULL out all inputs to eliminate incoming Def-Use edges.
// Return the number of edges between 'n' and 'this'
@@ -1383,6 +1398,21 @@ const TypeLong* Node::find_long_type() const {
return NULL;
}
+
+/**
+ * Return a ptr type for nodes which should have it.
+ */
+const TypePtr* Node::get_ptr_type() const {
+ const TypePtr* tp = this->bottom_type()->make_ptr();
+#ifdef ASSERT
+ if (tp == NULL) {
+ this->dump(1);
+ assert((tp != NULL), "unexpected node type");
+ }
+#endif
+ return tp;
+}
+
// Get a double constant from a ConstNode.
// Returns the constant if it is a double ConstNode
jdouble Node::getd() const {
diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp
index f8f2c24e860..bb5e8f200d0 100644
--- a/hotspot/src/share/vm/opto/node.hpp
+++ b/hotspot/src/share/vm/opto/node.hpp
@@ -410,6 +410,7 @@ protected:
// Find first occurrence of n among my edges:
int find_edge(Node* n);
int replace_edge(Node* old, Node* neww);
+ int replace_edges_in_range(Node* old, Node* neww, int start, int end);
// NULL out all inputs to eliminate incoming Def-Use edges.
// Return the number of edges between 'n' and 'this'
int disconnect_inputs(Node *n, Compile *c);
@@ -964,6 +965,8 @@ public:
}
const TypeLong* find_long_type() const;
+ const TypePtr* get_ptr_type() const;
+
// These guys are called by code generated by ADLC:
intptr_t get_ptr() const;
intptr_t get_narrowcon() const;
diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp
index f5a1e08e169..f04ab721b97 100644
--- a/hotspot/src/share/vm/opto/output.cpp
+++ b/hotspot/src/share/vm/opto/output.cpp
@@ -929,7 +929,7 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
scval = new_loc_value( _regalloc, obj_reg, Location::oop );
}
} else {
- const TypePtr *tp = obj_node->bottom_type()->make_ptr();
+ const TypePtr *tp = obj_node->get_ptr_type();
scval = new ConstantOopWriteValue(tp->is_oopptr()->const_oop()->constant_encoding());
}
diff --git a/hotspot/src/share/vm/opto/parse.hpp b/hotspot/src/share/vm/opto/parse.hpp
index c38f96b6be8..91025bf56fb 100644
--- a/hotspot/src/share/vm/opto/parse.hpp
+++ b/hotspot/src/share/vm/opto/parse.hpp
@@ -330,6 +330,7 @@ class Parse : public GraphKit {
bool _wrote_final; // Did we write a final field?
bool _count_invocations; // update and test invocation counter
bool _method_data_update; // update method data oop
+ Node* _alloc_with_final; // An allocation node with final field
// Variables which track Java semantics during bytecode parsing:
@@ -370,6 +371,11 @@ class Parse : public GraphKit {
void set_wrote_final(bool z) { _wrote_final = z; }
bool count_invocations() const { return _count_invocations; }
bool method_data_update() const { return _method_data_update; }
+ Node* alloc_with_final() const { return _alloc_with_final; }
+ void set_alloc_with_final(Node* n) {
+ assert((_alloc_with_final == NULL) || (_alloc_with_final == n), "different init objects?");
+ _alloc_with_final = n;
+ }
Block* block() const { return _block; }
ciBytecodeStream& iter() { return _iter; }
@@ -512,7 +518,7 @@ class Parse : public GraphKit {
// loading from a constant field or the constant pool
// returns false if push failed (non-perm field constants only, not ldcs)
- bool push_constant(ciConstant con, bool require_constant = false);
+ bool push_constant(ciConstant con, bool require_constant = false, bool is_autobox_cache = false);
// implementation of object creation bytecodes
void emit_guard_for_new(ciInstanceKlass* klass);
diff --git a/hotspot/src/share/vm/opto/parse1.cpp b/hotspot/src/share/vm/opto/parse1.cpp
index f0f7c8b0a9c..10d98b92f08 100644
--- a/hotspot/src/share/vm/opto/parse1.cpp
+++ b/hotspot/src/share/vm/opto/parse1.cpp
@@ -390,6 +390,7 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses)
_expected_uses = expected_uses;
_depth = 1 + (caller->has_method() ? caller->depth() : 0);
_wrote_final = false;
+ _alloc_with_final = NULL;
_entry_bci = InvocationEntryBci;
_tf = NULL;
_block = NULL;
@@ -723,6 +724,8 @@ void Parse::build_exits() {
// Note: iophi and memphi are not transformed until do_exits.
Node* iophi = new (C) PhiNode(region, Type::ABIO);
Node* memphi = new (C) PhiNode(region, Type::MEMORY, TypePtr::BOTTOM);
+ gvn().set_type_bottom(iophi);
+ gvn().set_type_bottom(memphi);
_exits.set_i_o(iophi);
_exits.set_all_memory(memphi);
@@ -738,6 +741,7 @@ void Parse::build_exits() {
}
int ret_size = type2size[ret_type->basic_type()];
Node* ret_phi = new (C) PhiNode(region, ret_type);
+ gvn().set_type_bottom(ret_phi);
_exits.ensure_stack(ret_size);
assert((int)(tf()->range()->cnt() - TypeFunc::Parms) == ret_size, "good tf range");
assert(method()->return_type()->size() == ret_size, "tf agrees w/ method");
@@ -917,7 +921,7 @@ void Parse::do_exits() {
// such unusual early publications. But no barrier is needed on
// exceptional returns, since they cannot publish normally.
//
- _exits.insert_mem_bar(Op_MemBarRelease);
+ _exits.insert_mem_bar(Op_MemBarRelease, alloc_with_final());
#ifndef PRODUCT
if (PrintOpto && (Verbose || WizardMode)) {
method()->print_name();
diff --git a/hotspot/src/share/vm/opto/parse2.cpp b/hotspot/src/share/vm/opto/parse2.cpp
index 73be6aae570..c41ca257e62 100644
--- a/hotspot/src/share/vm/opto/parse2.cpp
+++ b/hotspot/src/share/vm/opto/parse2.cpp
@@ -987,7 +987,7 @@ void Parse::do_ifnull(BoolTest::mask btest, Node *c) {
uncommon_trap(Deoptimization::Reason_unreached,
Deoptimization::Action_reinterpret,
NULL, "cold");
- if (EliminateAutoBox) {
+ if (C->eliminate_boxing()) {
// Mark the successor blocks as parsed
branch_block->next_path_num();
next_block->next_path_num();
@@ -1012,7 +1012,7 @@ void Parse::do_ifnull(BoolTest::mask btest, Node *c) {
if (stopped()) { // Path is dead?
explicit_null_checks_elided++;
- if (EliminateAutoBox) {
+ if (C->eliminate_boxing()) {
// Mark the successor block as parsed
branch_block->next_path_num();
}
@@ -1032,7 +1032,7 @@ void Parse::do_ifnull(BoolTest::mask btest, Node *c) {
if (stopped()) { // Path is dead?
explicit_null_checks_elided++;
- if (EliminateAutoBox) {
+ if (C->eliminate_boxing()) {
// Mark the successor block as parsed
next_block->next_path_num();
}
@@ -1069,7 +1069,7 @@ void Parse::do_if(BoolTest::mask btest, Node* c) {
uncommon_trap(Deoptimization::Reason_unreached,
Deoptimization::Action_reinterpret,
NULL, "cold");
- if (EliminateAutoBox) {
+ if (C->eliminate_boxing()) {
// Mark the successor blocks as parsed
branch_block->next_path_num();
next_block->next_path_num();
@@ -1135,7 +1135,7 @@ void Parse::do_if(BoolTest::mask btest, Node* c) {
set_control(taken_branch);
if (stopped()) {
- if (EliminateAutoBox) {
+ if (C->eliminate_boxing()) {
// Mark the successor block as parsed
branch_block->next_path_num();
}
@@ -1154,7 +1154,7 @@ void Parse::do_if(BoolTest::mask btest, Node* c) {
// Branch not taken.
if (stopped()) {
- if (EliminateAutoBox) {
+ if (C->eliminate_boxing()) {
// Mark the successor block as parsed
next_block->next_path_num();
}
diff --git a/hotspot/src/share/vm/opto/parse3.cpp b/hotspot/src/share/vm/opto/parse3.cpp
index 9de92a2ae54..acabf4985f5 100644
--- a/hotspot/src/share/vm/opto/parse3.cpp
+++ b/hotspot/src/share/vm/opto/parse3.cpp
@@ -150,6 +150,23 @@ void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) {
// final field
if (field->is_static()) {
// final static field
+ if (C->eliminate_boxing()) {
+ // The pointers in the autobox arrays are always non-null.
+ ciSymbol* klass_name = field->holder()->name();
+ if (field->name() == ciSymbol::cache_field_name() &&
+ field->holder()->uses_default_loader() &&
+ (klass_name == ciSymbol::java_lang_Character_CharacterCache() ||
+ klass_name == ciSymbol::java_lang_Byte_ByteCache() ||
+ klass_name == ciSymbol::java_lang_Short_ShortCache() ||
+ klass_name == ciSymbol::java_lang_Integer_IntegerCache() ||
+ klass_name == ciSymbol::java_lang_Long_LongCache())) {
+ bool require_const = true;
+ bool autobox_cache = true;
+ if (push_constant(field->constant_value(), require_const, autobox_cache)) {
+ return;
+ }
+ }
+ }
if (push_constant(field->constant_value()))
return;
}
@@ -304,11 +321,18 @@ void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) {
// out of the constructor.
if (is_field && field->is_final()) {
set_wrote_final(true);
+ // Preserve allocation ptr to create precedent edge to it in membar
+ // generated on exit from constructor.
+ if (C->eliminate_boxing() &&
+ adr_type->isa_oopptr() && adr_type->is_oopptr()->is_ptr_to_boxed_value() &&
+ AllocateNode::Ideal_allocation(obj, &_gvn) != NULL) {
+ set_alloc_with_final(obj);
+ }
}
}
-bool Parse::push_constant(ciConstant constant, bool require_constant) {
+bool Parse::push_constant(ciConstant constant, bool require_constant, bool is_autobox_cache) {
switch (constant.basic_type()) {
case T_BOOLEAN: push( intcon(constant.as_boolean()) ); break;
case T_INT: push( intcon(constant.as_int()) ); break;
@@ -329,7 +353,7 @@ bool Parse::push_constant(ciConstant constant, bool require_constant) {
push( zerocon(T_OBJECT) );
break;
} else if (require_constant || oop_constant->should_be_constant()) {
- push( makecon(TypeOopPtr::make_from_constant(oop_constant, require_constant)) );
+ push( makecon(TypeOopPtr::make_from_constant(oop_constant, require_constant, is_autobox_cache)) );
break;
} else {
// we cannot inline the oop, but we can use it later to narrow a type
diff --git a/hotspot/src/share/vm/opto/parseHelper.cpp b/hotspot/src/share/vm/opto/parseHelper.cpp
index e9486088dc9..5d0c2f7befe 100644
--- a/hotspot/src/share/vm/opto/parseHelper.cpp
+++ b/hotspot/src/share/vm/opto/parseHelper.cpp
@@ -284,6 +284,11 @@ void Parse::do_new() {
klass == C->env()->StringBuffer_klass())) {
C->set_has_stringbuilder(true);
}
+
+ // Keep track of boxed values for EliminateAutoBox optimizations.
+ if (C->eliminate_boxing() && klass->is_box_klass()) {
+ C->set_has_boxed_value(true);
+ }
}
#ifndef PRODUCT
diff --git a/hotspot/src/share/vm/opto/phase.cpp b/hotspot/src/share/vm/opto/phase.cpp
index 0b88996d3cb..5359301575d 100644
--- a/hotspot/src/share/vm/opto/phase.cpp
+++ b/hotspot/src/share/vm/opto/phase.cpp
@@ -64,6 +64,7 @@ elapsedTimer Phase::_t_idealLoopVerify;
// Subtimers for _t_optimizer
elapsedTimer Phase::_t_iterGVN;
elapsedTimer Phase::_t_iterGVN2;
+elapsedTimer Phase::_t_incrInline;
// Subtimers for _t_registerAllocation
elapsedTimer Phase::_t_ctorChaitin;
@@ -110,6 +111,7 @@ void Phase::print_timers() {
tty->print_cr (" macroEliminate : %3.3f sec", Phase::_t_macroEliminate.seconds());
}
tty->print_cr (" iterGVN : %3.3f sec", Phase::_t_iterGVN.seconds());
+ tty->print_cr (" incrInline : %3.3f sec", Phase::_t_incrInline.seconds());
tty->print_cr (" idealLoop : %3.3f sec", Phase::_t_idealLoop.seconds());
tty->print_cr (" idealLoopVerify: %3.3f sec", Phase::_t_idealLoopVerify.seconds());
tty->print_cr (" ccp : %3.3f sec", Phase::_t_ccp.seconds());
diff --git a/hotspot/src/share/vm/opto/phase.hpp b/hotspot/src/share/vm/opto/phase.hpp
index 9faabf5430c..582a126db36 100644
--- a/hotspot/src/share/vm/opto/phase.hpp
+++ b/hotspot/src/share/vm/opto/phase.hpp
@@ -100,6 +100,7 @@ protected:
// Subtimers for _t_optimizer
static elapsedTimer _t_iterGVN;
static elapsedTimer _t_iterGVN2;
+ static elapsedTimer _t_incrInline;
// Subtimers for _t_registerAllocation
static elapsedTimer _t_ctorChaitin;
diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp
index a8c979662d2..654c6f724b9 100644
--- a/hotspot/src/share/vm/opto/phaseX.cpp
+++ b/hotspot/src/share/vm/opto/phaseX.cpp
@@ -882,7 +882,7 @@ void PhaseIterGVN::optimize() {
return;
}
Node *n = _worklist.pop();
- if (++loop_count >= K * C->unique()) {
+ if (++loop_count >= K * C->live_nodes()) {
debug_only(n->dump(4);)
assert(false, "infinite loop in PhaseIterGVN::optimize");
C->record_method_not_compilable("infinite loop in PhaseIterGVN::optimize");
diff --git a/hotspot/src/share/vm/opto/runtime.cpp b/hotspot/src/share/vm/opto/runtime.cpp
index 7edb97e0bba..d0aefad66b7 100644
--- a/hotspot/src/share/vm/opto/runtime.cpp
+++ b/hotspot/src/share/vm/opto/runtime.cpp
@@ -126,17 +126,15 @@ ExceptionBlob* OptoRuntime::_exception_blob;
// This should be called in an assertion at the start of OptoRuntime routines
// which are entered from compiled code (all of them)
-#ifndef PRODUCT
+#ifdef ASSERT
static bool check_compiled_frame(JavaThread* thread) {
assert(thread->last_frame().is_runtime_frame(), "cannot call runtime directly from compiled code");
-#ifdef ASSERT
RegisterMap map(thread, false);
frame caller = thread->last_frame().sender(&map);
assert(caller.is_compiled_frame(), "not being called from compiled like code");
-#endif /* ASSERT */
return true;
}
-#endif
+#endif // ASSERT
#define gen(env, var, type_func_gen, c_func, fancy_jump, pass_tls, save_arg_regs, return_pc) \
diff --git a/hotspot/src/share/vm/opto/subnode.cpp b/hotspot/src/share/vm/opto/subnode.cpp
index 70a64ba70cd..275b4d80dd1 100644
--- a/hotspot/src/share/vm/opto/subnode.cpp
+++ b/hotspot/src/share/vm/opto/subnode.cpp
@@ -863,10 +863,11 @@ const Type *CmpNNode::sub( const Type *t1, const Type *t2 ) const {
const TypePtr *r1 = t2->make_ptr();
// Undefined inputs makes for an undefined result
- if( TypePtr::above_centerline(r0->_ptr) ||
- TypePtr::above_centerline(r1->_ptr) )
+ if ((r0 == NULL) || (r1 == NULL) ||
+ TypePtr::above_centerline(r0->_ptr) ||
+ TypePtr::above_centerline(r1->_ptr)) {
return Type::TOP;
-
+ }
if (r0 == r1 && r0->singleton()) {
// Equal pointer constants (klasses, nulls, etc.)
return TypeInt::CC_EQ;
diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp
index 68f681342d9..fabcf1cad16 100644
--- a/hotspot/src/share/vm/opto/type.cpp
+++ b/hotspot/src/share/vm/opto/type.cpp
@@ -2372,7 +2372,12 @@ TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int
_klass_is_exact(xk),
_is_ptr_to_narrowoop(false),
_is_ptr_to_narrowklass(false),
+ _is_ptr_to_boxed_value(false),
_instance_id(instance_id) {
+ if (Compile::current()->eliminate_boxing() && (t == InstPtr) &&
+ (offset > 0) && xk && (k != 0) && k->is_instance_klass()) {
+ _is_ptr_to_boxed_value = k->as_instance_klass()->is_boxed_value_offset(offset);
+ }
#ifdef _LP64
if (_offset != 0) {
if (_offset == oopDesc::klass_offset_in_bytes()) {
@@ -2613,44 +2618,50 @@ const TypeOopPtr* TypeOopPtr::make_from_klass_common(ciKlass *klass, bool klass_
//------------------------------make_from_constant-----------------------------
// Make a java pointer from an oop constant
-const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_constant) {
- assert(!o->is_null_object(), "null object not yet handled here.");
- ciKlass* klass = o->klass();
- if (klass->is_instance_klass()) {
- // Element is an instance
- if (require_constant) {
- if (!o->can_be_constant()) return NULL;
- } else if (!o->should_be_constant()) {
- return TypeInstPtr::make(TypePtr::NotNull, klass, true, NULL, 0);
- }
- return TypeInstPtr::make(o);
- } else if (klass->is_obj_array_klass()) {
- // Element is an object array. Recursively call ourself.
- const Type *etype =
+const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o,
+ bool require_constant,
+ bool is_autobox_cache) {
+ assert(!o->is_null_object(), "null object not yet handled here.");
+ ciKlass* klass = o->klass();
+ if (klass->is_instance_klass()) {
+ // Element is an instance
+ if (require_constant) {
+ if (!o->can_be_constant()) return NULL;
+ } else if (!o->should_be_constant()) {
+ return TypeInstPtr::make(TypePtr::NotNull, klass, true, NULL, 0);
+ }
+ return TypeInstPtr::make(o);
+ } else if (klass->is_obj_array_klass()) {
+ // Element is an object array. Recursively call ourself.
+ const TypeOopPtr *etype =
TypeOopPtr::make_from_klass_raw(klass->as_obj_array_klass()->element_klass());
- const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
- // We used to pass NotNull in here, asserting that the sub-arrays
- // are all not-null. This is not true in generally, as code can
- // slam NULLs down in the subarrays.
- if (require_constant) {
- if (!o->can_be_constant()) return NULL;
- } else if (!o->should_be_constant()) {
- return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
- }
- const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
+ if (is_autobox_cache) {
+ // The pointers in the autobox arrays are always non-null.
+ etype = etype->cast_to_ptr_type(TypePtr::NotNull)->is_oopptr();
+ }
+ const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
+ // We used to pass NotNull in here, asserting that the sub-arrays
+ // are all not-null. This is not true in generally, as code can
+ // slam NULLs down in the subarrays.
+ if (require_constant) {
+ if (!o->can_be_constant()) return NULL;
+ } else if (!o->should_be_constant()) {
+ return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
+ }
+ const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0, InstanceBot, is_autobox_cache);
return arr;
- } else if (klass->is_type_array_klass()) {
- // Element is an typeArray
+ } else if (klass->is_type_array_klass()) {
+ // Element is an typeArray
const Type* etype =
(Type*)get_const_basic_type(klass->as_type_array_klass()->element_type());
- const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
- // We used to pass NotNull in here, asserting that the array pointer
- // is not-null. That was not true in general.
- if (require_constant) {
- if (!o->can_be_constant()) return NULL;
- } else if (!o->should_be_constant()) {
- return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
- }
+ const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
+ // We used to pass NotNull in here, asserting that the array pointer
+ // is not-null. That was not true in general.
+ if (require_constant) {
+ if (!o->can_be_constant()) return NULL;
+ } else if (!o->should_be_constant()) {
+ return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
+ }
const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
return arr;
}
@@ -2856,6 +2867,28 @@ const TypeInstPtr *TypeInstPtr::make(PTR ptr,
return result;
}
+/**
+ * Create constant type for a constant boxed value
+ */
+const Type* TypeInstPtr::get_const_boxed_value() const {
+ assert(is_ptr_to_boxed_value(), "should be called only for boxed value");
+ assert((const_oop() != NULL), "should be called only for constant object");
+ ciConstant constant = const_oop()->as_instance()->field_value_by_offset(offset());
+ BasicType bt = constant.basic_type();
+ switch (bt) {
+ case T_BOOLEAN: return TypeInt::make(constant.as_boolean());
+ case T_INT: return TypeInt::make(constant.as_int());
+ case T_CHAR: return TypeInt::make(constant.as_char());
+ case T_BYTE: return TypeInt::make(constant.as_byte());
+ case T_SHORT: return TypeInt::make(constant.as_short());
+ case T_FLOAT: return TypeF::make(constant.as_float());
+ case T_DOUBLE: return TypeD::make(constant.as_double());
+ case T_LONG: return TypeLong::make(constant.as_long());
+ default: break;
+ }
+ fatal(err_msg_res("Invalid boxed value type '%s'", type2name(bt)));
+ return NULL;
+}
//------------------------------cast_to_ptr_type-------------------------------
const Type *TypeInstPtr::cast_to_ptr_type(PTR ptr) const {
@@ -3330,18 +3363,18 @@ const TypeAryPtr *TypeAryPtr::make( PTR ptr, const TypeAry *ary, ciKlass* k, boo
if (!xk) xk = ary->ary_must_be_exact();
assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed");
if (!UseExactTypes) xk = (ptr == Constant);
- return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id))->hashcons();
+ return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id, false))->hashcons();
}
//------------------------------make-------------------------------------------
-const TypeAryPtr *TypeAryPtr::make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id ) {
+const TypeAryPtr *TypeAryPtr::make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, bool is_autobox_cache) {
assert(!(k == NULL && ary->_elem->isa_int()),
"integral arrays must be pre-equipped with a class");
assert( (ptr==Constant && o) || (ptr!=Constant && !o), "" );
if (!xk) xk = (o != NULL) || ary->ary_must_be_exact();
assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed");
if (!UseExactTypes) xk = (ptr == Constant);
- return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id))->hashcons();
+ return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id, is_autobox_cache))->hashcons();
}
//------------------------------cast_to_ptr_type-------------------------------
@@ -3397,8 +3430,20 @@ const TypeInt* TypeAryPtr::narrow_size_type(const TypeInt* size) const {
jint max_hi = max_array_length(elem()->basic_type());
//if (index_not_size) --max_hi; // type of a valid array index, FTR
bool chg = false;
- if (lo < min_lo) { lo = min_lo; chg = true; }
- if (hi > max_hi) { hi = max_hi; chg = true; }
+ if (lo < min_lo) {
+ lo = min_lo;
+ if (size->is_con()) {
+ hi = lo;
+ }
+ chg = true;
+ }
+ if (hi > max_hi) {
+ hi = max_hi;
+ if (size->is_con()) {
+ lo = hi;
+ }
+ chg = true;
+ }
// Negative length arrays will produce weird intermediate dead fast-path code
if (lo > hi)
return TypeInt::ZERO;
@@ -3630,7 +3675,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const {
//------------------------------xdual------------------------------------------
// Dual: compute field-by-field dual
const Type *TypeAryPtr::xdual() const {
- return new TypeAryPtr( dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance_id() );
+ return new TypeAryPtr( dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance_id(), is_autobox_cache() );
}
//----------------------interface_vs_oop---------------------------------------
diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp
index 7868b2f7856..0626cb53f52 100644
--- a/hotspot/src/share/vm/opto/type.hpp
+++ b/hotspot/src/share/vm/opto/type.hpp
@@ -234,6 +234,9 @@ public:
bool is_ptr_to_narrowoop() const;
bool is_ptr_to_narrowklass() const;
+ bool is_ptr_to_boxing_obj() const;
+
+
// Convenience access
float getf() const;
double getd() const;
@@ -794,6 +797,7 @@ protected:
bool _klass_is_exact;
bool _is_ptr_to_narrowoop;
bool _is_ptr_to_narrowklass;
+ bool _is_ptr_to_boxed_value;
// If not InstanceTop or InstanceBot, indicates that this is
// a particular instance of this type which is distinct.
@@ -826,7 +830,9 @@ public:
// If the object cannot be rendered as a constant,
// may return a non-singleton type.
// If require_constant, produce a NULL if a singleton is not possible.
- static const TypeOopPtr* make_from_constant(ciObject* o, bool require_constant = false);
+ static const TypeOopPtr* make_from_constant(ciObject* o,
+ bool require_constant = false,
+ bool not_null_elements = false);
// Make a generic (unclassed) pointer to an oop.
static const TypeOopPtr* make(PTR ptr, int offset, int instance_id);
@@ -839,7 +845,7 @@ public:
// compressed oop references.
bool is_ptr_to_narrowoop_nv() const { return _is_ptr_to_narrowoop; }
bool is_ptr_to_narrowklass_nv() const { return _is_ptr_to_narrowklass; }
-
+ bool is_ptr_to_boxed_value() const { return _is_ptr_to_boxed_value; }
bool is_known_instance() const { return _instance_id > 0; }
int instance_id() const { return _instance_id; }
bool is_known_instance_field() const { return is_known_instance() && _offset >= 0; }
@@ -912,6 +918,9 @@ class TypeInstPtr : public TypeOopPtr {
// Make a pointer to an oop.
static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = InstanceBot );
+ /** Create constant type for a constant boxed value */
+ const Type* get_const_boxed_value() const;
+
// If this is a java.lang.Class constant, return the type for it or NULL.
// Pass to Type::get_const_type to turn it to a type, which will usually
// be a TypeInstPtr, but may also be a TypeInt::INT for int.class, etc.
@@ -943,7 +952,12 @@ class TypeInstPtr : public TypeOopPtr {
//------------------------------TypeAryPtr-------------------------------------
// Class of Java array pointers
class TypeAryPtr : public TypeOopPtr {
- TypeAryPtr( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id ) : TypeOopPtr(AryPtr,ptr,k,xk,o,offset, instance_id), _ary(ary) {
+ TypeAryPtr( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk,
+ int offset, int instance_id, bool is_autobox_cache )
+ : TypeOopPtr(AryPtr,ptr,k,xk,o,offset, instance_id),
+ _ary(ary),
+ _is_autobox_cache(is_autobox_cache)
+ {
#ifdef ASSERT
if (k != NULL) {
// Verify that specified klass and TypeAryPtr::klass() follow the same rules.
@@ -964,6 +978,7 @@ class TypeAryPtr : public TypeOopPtr {
virtual bool eq( const Type *t ) const;
virtual int hash() const; // Type specific hashing
const TypeAry *_ary; // Array we point into
+ const bool _is_autobox_cache;
ciKlass* compute_klass(DEBUG_ONLY(bool verify = false)) const;
@@ -974,9 +989,11 @@ public:
const Type* elem() const { return _ary->_elem; }
const TypeInt* size() const { return _ary->_size; }
+ bool is_autobox_cache() const { return _is_autobox_cache; }
+
static const TypeAryPtr *make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot);
// Constant pointer to array
- static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot);
+ static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot, bool is_autobox_cache = false);
// Return a 'ptr' version of this type
virtual const Type *cast_to_ptr_type(PTR ptr) const;
@@ -1504,6 +1521,13 @@ inline bool Type::is_floatingpoint() const {
return false;
}
+inline bool Type::is_ptr_to_boxing_obj() const {
+ const TypeInstPtr* tp = isa_instptr();
+ return (tp != NULL) && (tp->offset() == 0) &&
+ tp->klass()->is_instance_klass() &&
+ tp->klass()->as_instance_klass()->is_box_klass();
+}
+
// ===============================================================
// Things that need to be 64-bits in the 64-bit build but
diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp
index 5f37992d0f5..2c81df1ab4e 100644
--- a/hotspot/src/share/vm/prims/jni.cpp
+++ b/hotspot/src/share/vm/prims/jni.cpp
@@ -5015,6 +5015,9 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
#ifndef PRODUCT
#include "gc_interface/collectedHeap.hpp"
+#if INCLUDE_ALL_GCS
+#include "gc_implementation/g1/heapRegionRemSet.hpp"
+#endif
#include "utilities/quickSort.hpp"
#if INCLUDE_VM_STRUCTS
#include "runtime/vmStructs.hpp"
@@ -5034,6 +5037,9 @@ void execute_internal_vm_tests() {
run_unit_test(AltHashing::test_alt_hash());
#if INCLUDE_VM_STRUCTS
run_unit_test(VMStructs::test());
+#endif
+#if INCLUDE_ALL_GCS
+ run_unit_test(HeapRegionRemSet::test_prt());
#endif
tty->print_cr("All internal VM tests passed");
}
diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp
index 5c31ea1e5ac..bedfc619035 100644
--- a/hotspot/src/share/vm/prims/jvm.cpp
+++ b/hotspot/src/share/vm/prims/jvm.cpp
@@ -1710,7 +1710,7 @@ JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method))
for (int i = 0; i < num_params; i++) {
MethodParametersElement* params = mh->method_parameters_start();
// For a 0 index, give a NULL symbol
- Symbol* const sym = 0 != params[i].name_cp_index ?
+ Symbol* sym = 0 != params[i].name_cp_index ?
mh->constants()->symbol_at(params[i].name_cp_index) : NULL;
int flags = params[i].flags;
oop param = Reflection::new_parameter(reflected_method, i, sym,
diff --git a/hotspot/src/share/vm/prims/jvmtiExport.cpp b/hotspot/src/share/vm/prims/jvmtiExport.cpp
index ab66dca33d6..f20dd4e492a 100644
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp
@@ -619,6 +619,9 @@ class JvmtiClassFileLoadHookPoster : public StackObj {
// data has been changed by the new retransformable agent
// and it hasn't already been cached, cache it
*_cached_data_ptr = (unsigned char *)os::malloc(_curr_len, mtInternal);
+ if (*_cached_data_ptr == NULL) {
+ vm_exit_out_of_memory(_curr_len, OOM_MALLOC_ERROR, "unable to allocate cached copy of original class bytes");
+ }
memcpy(*_cached_data_ptr, _curr_data, _curr_len);
*_cached_length_ptr = _curr_len;
}
@@ -1621,15 +1624,19 @@ void JvmtiExport::post_raw_field_modification(JavaThread *thread, Method* method
}
}
+ assert(sig_type != '[', "array should have sig_type == 'L'");
+ bool handle_created = false;
+
// convert oop to JNI handle.
- if (sig_type == 'L' || sig_type == '[') {
+ if (sig_type == 'L') {
+ handle_created = true;
value->l = (jobject)JNIHandles::make_local(thread, (oop)value->l);
}
post_field_modification(thread, method, location, field_klass, object, field, sig_type, value);
// Destroy the JNI handle allocated above.
- if (sig_type == 'L') {
+ if (handle_created) {
JNIHandles::destroy_local(value->l);
}
}
diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
index 4e8e8c0e097..c5715345f72 100644
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
@@ -160,7 +160,8 @@ void VM_RedefineClasses::doit() {
if (RC_TRACE_ENABLED(0x00004000)) {
#endif
RC_TRACE_WITH_THREAD(0x00004000, thread, ("calling check_class"));
- SystemDictionary::classes_do(check_class, thread);
+ CheckClass check_class(thread);
+ ClassLoaderDataGraph::classes_do(&check_class);
#ifdef PRODUCT
}
#endif
@@ -2653,29 +2654,35 @@ void VM_RedefineClasses::set_new_constant_pool(
} // end set_new_constant_pool()
-void VM_RedefineClasses::adjust_array_vtable(Klass* k_oop) {
- ArrayKlass* ak = ArrayKlass::cast(k_oop);
- bool trace_name_printed = false;
- ak->vtable()->adjust_method_entries(_matching_old_methods,
- _matching_new_methods,
- _matching_methods_length,
- &trace_name_printed);
-}
-
// Unevolving classes may point to methods of the_class directly
// from their constant pool caches, itables, and/or vtables. We
-// use the SystemDictionary::classes_do() facility and this helper
+// use the ClassLoaderDataGraph::classes_do() facility and this helper
// to fix up these pointers.
-//
-// Note: We currently don't support updating the vtable in
-// arrayKlassOops. See Open Issues in jvmtiRedefineClasses.hpp.
-void VM_RedefineClasses::adjust_cpool_cache_and_vtable(Klass* k_oop,
- ClassLoaderData* initiating_loader,
- TRAPS) {
- Klass *k = k_oop;
- if (k->oop_is_instance()) {
- HandleMark hm(THREAD);
- InstanceKlass *ik = (InstanceKlass *) k;
+
+// Adjust cpools and vtables closure
+void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
+
+ // This is a very busy routine. We don't want too much tracing
+ // printed out.
+ bool trace_name_printed = false;
+
+ // Very noisy: only enable this call if you are trying to determine
+ // that a specific class gets found by this routine.
+ // RC_TRACE macro has an embedded ResourceMark
+ // RC_TRACE_WITH_THREAD(0x00100000, THREAD,
+ // ("adjust check: name=%s", k->external_name()));
+ // trace_name_printed = true;
+
+ // If the class being redefined is java.lang.Object, we need to fix all
+ // array class vtables also
+ if (k->oop_is_array() && _the_class_oop == SystemDictionary::Object_klass()) {
+ k->vtable()->adjust_method_entries(_matching_old_methods,
+ _matching_new_methods,
+ _matching_methods_length,
+ &trace_name_printed);
+ } else if (k->oop_is_instance()) {
+ HandleMark hm(_thread);
+ InstanceKlass *ik = InstanceKlass::cast(k);
// HotSpot specific optimization! HotSpot does not currently
// support delegation from the bootstrap class loader to a
@@ -2695,23 +2702,6 @@ void VM_RedefineClasses::adjust_cpool_cache_and_vtable(Klass* k_oop,
return;
}
- // If the class being redefined is java.lang.Object, we need to fix all
- // array class vtables also
- if (_the_class_oop == SystemDictionary::Object_klass()) {
- ik->array_klasses_do(adjust_array_vtable);
- }
-
- // This is a very busy routine. We don't want too much tracing
- // printed out.
- bool trace_name_printed = false;
-
- // Very noisy: only enable this call if you are trying to determine
- // that a specific class gets found by this routine.
- // RC_TRACE macro has an embedded ResourceMark
- // RC_TRACE_WITH_THREAD(0x00100000, THREAD,
- // ("adjust check: name=%s", ik->external_name()));
- // trace_name_printed = true;
-
// Fix the vtable embedded in the_class and subclasses of the_class,
// if one exists. We discard scratch_class and we don't keep an
// InstanceKlass around to hold obsolete methods so we don't have
@@ -2719,7 +2709,7 @@ void VM_RedefineClasses::adjust_cpool_cache_and_vtable(Klass* k_oop,
// holds the Method*s for virtual (but not final) methods.
if (ik->vtable_length() > 0 && ik->is_subtype_of(_the_class_oop)) {
// ik->vtable() creates a wrapper object; rm cleans it up
- ResourceMark rm(THREAD);
+ ResourceMark rm(_thread);
ik->vtable()->adjust_method_entries(_matching_old_methods,
_matching_new_methods,
_matching_methods_length,
@@ -2735,7 +2725,7 @@ void VM_RedefineClasses::adjust_cpool_cache_and_vtable(Klass* k_oop,
if (ik->itable_length() > 0 && (_the_class_oop->is_interface()
|| ik->is_subclass_of(_the_class_oop))) {
// ik->itable() creates a wrapper object; rm cleans it up
- ResourceMark rm(THREAD);
+ ResourceMark rm(_thread);
ik->itable()->adjust_method_entries(_matching_old_methods,
_matching_new_methods,
_matching_methods_length,
@@ -2758,7 +2748,7 @@ void VM_RedefineClasses::adjust_cpool_cache_and_vtable(Klass* k_oop,
constantPoolHandle other_cp;
ConstantPoolCache* cp_cache;
- if (k_oop != _the_class_oop) {
+ if (ik != _the_class_oop) {
// this klass' constant pool cache may need adjustment
other_cp = constantPoolHandle(ik->constants());
cp_cache = other_cp->cache();
@@ -2770,7 +2760,7 @@ void VM_RedefineClasses::adjust_cpool_cache_and_vtable(Klass* k_oop,
}
}
{
- ResourceMark rm(THREAD);
+ ResourceMark rm(_thread);
// PreviousVersionInfo objects returned via PreviousVersionWalker
// contain a GrowableArray of handles. We have to clean up the
// GrowableArray _after_ the PreviousVersionWalker destructor
@@ -3208,7 +3198,7 @@ void VM_RedefineClasses::swap_annotations(instanceKlassHandle the_class,
// parts of the_class
// - adjusting constant pool caches and vtables in other classes
// that refer to methods in the_class. These adjustments use the
-// SystemDictionary::classes_do() facility which only allows
+// ClassLoaderDataGraph::classes_do() facility which only allows
// a helper method to be specified. The interesting parameters
// that we would like to pass to the helper method are saved in
// static global fields in the VM operation.
@@ -3366,6 +3356,10 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
}
#endif
+ // NULL out in scratch class to not delete twice. The class to be redefined
+ // always owns these bytes.
+ scratch_class->set_cached_class_file(NULL, 0);
+
// Replace inner_classes
Array* old_inner_classes = the_class->inner_classes();
the_class->set_inner_classes(scratch_class->inner_classes());
@@ -3438,7 +3432,8 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
// Adjust constantpool caches and vtables for all classes
// that reference methods of the evolved class.
- SystemDictionary::classes_do(adjust_cpool_cache_and_vtable, THREAD);
+ AdjustCpoolCacheAndVtable adjust_cpool_cache_and_vtable(THREAD);
+ ClassLoaderDataGraph::classes_do(&adjust_cpool_cache_and_vtable);
// JSR-292 support
MemberNameTable* mnt = the_class->member_names();
@@ -3499,34 +3494,33 @@ void VM_RedefineClasses::increment_class_counter(InstanceKlass *ik, TRAPS) {
}
}
-void VM_RedefineClasses::check_class(Klass* k_oop,
- ClassLoaderData* initiating_loader,
- TRAPS) {
- Klass *k = k_oop;
- if (k->oop_is_instance()) {
- HandleMark hm(THREAD);
- InstanceKlass *ik = (InstanceKlass *) k;
- bool no_old_methods = true; // be optimistic
- ResourceMark rm(THREAD);
+void VM_RedefineClasses::CheckClass::do_klass(Klass* k) {
+ bool no_old_methods = true; // be optimistic
- // a vtable should never contain old or obsolete methods
- if (ik->vtable_length() > 0 &&
- !ik->vtable()->check_no_old_or_obsolete_entries()) {
- if (RC_TRACE_ENABLED(0x00004000)) {
- RC_TRACE_WITH_THREAD(0x00004000, THREAD,
- ("klassVtable::check_no_old_or_obsolete_entries failure"
- " -- OLD or OBSOLETE method found -- class: %s",
- ik->signature_name()));
- ik->vtable()->dump_vtable();
- }
- no_old_methods = false;
+ // Both array and instance classes have vtables.
+ // a vtable should never contain old or obsolete methods
+ ResourceMark rm(_thread);
+ if (k->vtable_length() > 0 &&
+ !k->vtable()->check_no_old_or_obsolete_entries()) {
+ if (RC_TRACE_ENABLED(0x00004000)) {
+ RC_TRACE_WITH_THREAD(0x00004000, _thread,
+ ("klassVtable::check_no_old_or_obsolete_entries failure"
+ " -- OLD or OBSOLETE method found -- class: %s",
+ k->signature_name()));
+ k->vtable()->dump_vtable();
}
+ no_old_methods = false;
+ }
+
+ if (k->oop_is_instance()) {
+ HandleMark hm(_thread);
+ InstanceKlass *ik = InstanceKlass::cast(k);
// an itable should never contain old or obsolete methods
if (ik->itable_length() > 0 &&
!ik->itable()->check_no_old_or_obsolete_entries()) {
if (RC_TRACE_ENABLED(0x00004000)) {
- RC_TRACE_WITH_THREAD(0x00004000, THREAD,
+ RC_TRACE_WITH_THREAD(0x00004000, _thread,
("klassItable::check_no_old_or_obsolete_entries failure"
" -- OLD or OBSOLETE method found -- class: %s",
ik->signature_name()));
@@ -3540,7 +3534,7 @@ void VM_RedefineClasses::check_class(Klass* k_oop,
ik->constants()->cache() != NULL &&
!ik->constants()->cache()->check_no_old_or_obsolete_entries()) {
if (RC_TRACE_ENABLED(0x00004000)) {
- RC_TRACE_WITH_THREAD(0x00004000, THREAD,
+ RC_TRACE_WITH_THREAD(0x00004000, _thread,
("cp-cache::check_no_old_or_obsolete_entries failure"
" -- OLD or OBSOLETE method found -- class: %s",
ik->signature_name()));
@@ -3548,19 +3542,21 @@ void VM_RedefineClasses::check_class(Klass* k_oop,
}
no_old_methods = false;
}
+ }
- if (!no_old_methods) {
- if (RC_TRACE_ENABLED(0x00004000)) {
- dump_methods();
- } else {
- tty->print_cr("INFO: use the '-XX:TraceRedefineClasses=16384' option "
- "to see more info about the following guarantee() failure.");
- }
- guarantee(false, "OLD and/or OBSOLETE method(s) found");
+ // print and fail guarantee if old methods are found.
+ if (!no_old_methods) {
+ if (RC_TRACE_ENABLED(0x00004000)) {
+ dump_methods();
+ } else {
+ tty->print_cr("INFO: use the '-XX:TraceRedefineClasses=16384' option "
+ "to see more info about the following guarantee() failure.");
}
+ guarantee(false, "OLD and/or OBSOLETE method(s) found");
}
}
+
void VM_RedefineClasses::dump_methods() {
int j;
RC_TRACE(0x00004000, ("_old_methods --"));
diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp
index ffe9a7ed83b..3457e935bd8 100644
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp
@@ -87,7 +87,7 @@
// parts of the_class
// - adjusting constant pool caches and vtables in other classes
// that refer to methods in the_class. These adjustments use the
-// SystemDictionary::classes_do() facility which only allows
+// ClassLoaderDataGraph::classes_do() facility which only allows
// a helper method to be specified. The interesting parameters
// that we would like to pass to the helper method are saved in
// static global fields in the VM operation.
@@ -333,8 +333,8 @@
class VM_RedefineClasses: public VM_Operation {
private:
- // These static fields are needed by SystemDictionary::classes_do()
- // facility and the adjust_cpool_cache_and_vtable() helper:
+ // These static fields are needed by ClassLoaderDataGraph::classes_do()
+ // facility and the AdjustCpoolCacheAndVtable helper:
static Array* _old_methods;
static Array* _new_methods;
static Method** _matching_old_methods;
@@ -408,13 +408,6 @@ class VM_RedefineClasses: public VM_Operation {
int * emcp_method_count_p);
void transfer_old_native_function_registrations(instanceKlassHandle the_class);
- // Unevolving classes may point to methods of the_class directly
- // from their constant pool caches, itables, and/or vtables. We
- // use the SystemDictionary::classes_do() facility and this helper
- // to fix up these pointers.
- static void adjust_cpool_cache_and_vtable(Klass* k_oop, ClassLoaderData* initiating_loader, TRAPS);
- static void adjust_array_vtable(Klass* k_oop);
-
// Install the redefinition of a class
void redefine_single_class(jclass the_jclass,
Klass* scratch_class_oop, TRAPS);
@@ -480,10 +473,27 @@ class VM_RedefineClasses: public VM_Operation {
void flush_dependent_code(instanceKlassHandle k_h, TRAPS);
- static void check_class(Klass* k_oop, ClassLoaderData* initiating_loader,
- TRAPS);
static void dump_methods();
+ // Check that there are no old or obsolete methods
+ class CheckClass : public KlassClosure {
+ Thread* _thread;
+ public:
+ CheckClass(Thread* t) : _thread(t) {}
+ void do_klass(Klass* k);
+ };
+
+ // Unevolving classes may point to methods of the_class directly
+ // from their constant pool caches, itables, and/or vtables. We
+ // use the ClassLoaderDataGraph::classes_do() facility and this helper
+ // to fix up these pointers.
+ class AdjustCpoolCacheAndVtable : public KlassClosure {
+ Thread* _thread;
+ public:
+ AdjustCpoolCacheAndVtable(Thread* t) : _thread(t) {}
+ void do_klass(Klass* k);
+ };
+
public:
VM_RedefineClasses(jint class_count,
const jvmtiClassDefinition *class_defs,
diff --git a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp
index 99e4af5aa37..eb68b4296f5 100644
--- a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2857,7 +2857,7 @@ inline bool VM_HeapWalkOperation::iterate_over_class(oop java_class) {
// references from the constant pool
{
- ConstantPool* const pool = ik->constants();
+ ConstantPool* pool = ik->constants();
for (int i = 1; i < pool->length(); i++) {
constantTag tag = pool->tag_at(i).value();
if (tag.is_string() || tag.is_klass()) {
diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp
index 34104985237..58957eed067 100644
--- a/hotspot/src/share/vm/prims/methodHandles.cpp
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp
@@ -193,19 +193,15 @@ oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispa
flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
} else if (mods.is_static()) {
flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
- // Get vindex from itable if method holder is an interface.
- if (m->method_holder()->is_interface()) {
- vmindex = klassItable::compute_itable_index(m);
- }
} else if (receiver_limit != mklass &&
!receiver_limit->is_subtype_of(mklass)) {
return NULL; // bad receiver limit
- } else if (receiver_limit->is_interface() &&
+ } else if (do_dispatch && receiver_limit->is_interface() &&
mklass->is_interface()) {
flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
receiver_limit = mklass; // ignore passed-in limit; interfaces are interconvertible
vmindex = klassItable::compute_itable_index(m);
- } else if (mklass != receiver_limit && mklass->is_interface()) {
+ } else if (do_dispatch && mklass != receiver_limit && mklass->is_interface()) {
flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
// it is a miranda method, so m->vtable_index is not what we want
ResourceMark rm;
@@ -250,10 +246,25 @@ Handle MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, TRAPS
}
methodHandle m = info.resolved_method();
KlassHandle defc = info.resolved_klass();
- int vmindex = -1;
+ int vmindex = Method::invalid_vtable_index;
if (defc->is_interface() && m->method_holder()->is_interface()) {
- // LinkResolver does not report itable indexes! (fix this?)
- vmindex = klassItable::compute_itable_index(m());
+ // static interface methods do not reference vtable or itable
+ if (m->is_static()) {
+ vmindex = Method::nonvirtual_vtable_index;
+ }
+ // interface methods invoked via invokespecial also
+ // do not reference vtable or itable.
+ int ref_kind = ((java_lang_invoke_MemberName::flags(mname()) >>
+ REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK);
+ if (ref_kind == JVM_REF_invokeSpecial) {
+ vmindex = Method::nonvirtual_vtable_index;
+ }
+ // If neither m is static nor ref_kind is invokespecial,
+ // set it to itable index.
+ if (vmindex == Method::invalid_vtable_index) {
+ // LinkResolver does not report itable indexes! (fix this?)
+ vmindex = klassItable::compute_itable_index(m());
+ }
} else if (m->can_be_statically_bound()) {
// LinkResolver reports vtable index even for final methods!
vmindex = Method::nonvirtual_vtable_index;
@@ -665,11 +676,9 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
case IS_METHOD:
{
CallInfo result;
- bool do_dispatch = true; // default, neutral setting
{
assert(!HAS_PENDING_EXCEPTION, "");
if (ref_kind == JVM_REF_invokeStatic) {
- //do_dispatch = false; // no need, since statics are never dispatched
LinkResolver::resolve_static_call(result,
defc, name, type, KlassHandle(), false, false, THREAD);
} else if (ref_kind == JVM_REF_invokeInterface) {
@@ -680,7 +689,6 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
LinkResolver::resolve_handle_call(result,
defc, name, type, KlassHandle(), THREAD);
} else if (ref_kind == JVM_REF_invokeSpecial) {
- do_dispatch = false; // force non-virtual linkage
LinkResolver::resolve_special_call(result,
defc, name, type, KlassHandle(), false, THREAD);
} else if (ref_kind == JVM_REF_invokeVirtual) {
@@ -1298,6 +1306,28 @@ JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobjec
}
JVM_END
+/**
+ * Throws a java/lang/UnsupportedOperationException unconditionally.
+ * This is required by the specification of MethodHandle.invoke if
+ * invoked directly.
+ */
+JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
+ THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
+ return NULL;
+}
+JVM_END
+
+/**
+ * Throws a java/lang/UnsupportedOperationException unconditionally.
+ * This is required by the specification of MethodHandle.invokeExact if
+ * invoked directly.
+ */
+JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
+ THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invokeExact cannot be invoked reflectively");
+ return NULL;
+}
+JVM_END
+
/// JVM_RegisterMethodHandleMethods
#undef CS // Solaris builds complain
@@ -1317,7 +1347,7 @@ JVM_END
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
// These are the native methods on java.lang.invoke.MethodHandleNatives.
-static JNINativeMethod required_methods_JDK8[] = {
+static JNINativeMethod MHN_methods[] = {
{CC"init", CC"("MEM""OBJ")V", FN_PTR(MHN_init_Mem)},
{CC"expand", CC"("MEM")V", FN_PTR(MHN_expand_Mem)},
{CC"resolve", CC"("MEM""CLS")"MEM, FN_PTR(MHN_resolve_Mem)},
@@ -1335,8 +1365,28 @@ static JNINativeMethod required_methods_JDK8[] = {
{CC"getMemberVMInfo", CC"("MEM")"OBJ, FN_PTR(MHN_getMemberVMInfo)}
};
-// This one function is exported, used by NativeLookup.
+static JNINativeMethod MH_methods[] = {
+ // UnsupportedOperationException throwers
+ {CC"invoke", CC"(["OBJ")"OBJ, FN_PTR(MH_invoke_UOE)},
+ {CC"invokeExact", CC"(["OBJ")"OBJ, FN_PTR(MH_invokeExact_UOE)}
+};
+/**
+ * Helper method to register native methods.
+ */
+static bool register_natives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods) {
+ int status = env->RegisterNatives(clazz, methods, nMethods);
+ if (status != JNI_OK || env->ExceptionOccurred()) {
+ warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
+ env->ExceptionClear();
+ return false;
+ }
+ return true;
+}
+
+/**
+ * This one function is exported, used by NativeLookup.
+ */
JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
if (!EnableInvokeDynamic) {
warning("JSR 292 is disabled in this JVM. Use -XX:+UnlockDiagnosticVMOptions -XX:+EnableInvokeDynamic to enable.");
@@ -1354,16 +1404,14 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class))
MH_class = (jclass) JNIHandles::make_local(env, mirror);
}
- int status;
-
if (enable_MH) {
ThreadToNativeFromVM ttnfv(thread);
- status = env->RegisterNatives(MHN_class, required_methods_JDK8, sizeof(required_methods_JDK8)/sizeof(JNINativeMethod));
- if (status != JNI_OK || env->ExceptionOccurred()) {
- warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
- enable_MH = false;
- env->ExceptionClear();
+ if (enable_MH) {
+ enable_MH = register_natives(env, MHN_class, MHN_methods, sizeof(MHN_methods)/sizeof(JNINativeMethod));
+ }
+ if (enable_MH) {
+ enable_MH = register_natives(env, MH_class, MH_methods, sizeof(MH_methods)/sizeof(JNINativeMethod));
}
}
diff --git a/hotspot/src/share/vm/prims/nativeLookup.cpp b/hotspot/src/share/vm/prims/nativeLookup.cpp
index 6162ae85032..990600eea27 100644
--- a/hotspot/src/share/vm/prims/nativeLookup.cpp
+++ b/hotspot/src/share/vm/prims/nativeLookup.cpp
@@ -383,10 +383,7 @@ address NativeLookup::lookup_base(methodHandle method, bool& in_base_library, TR
address NativeLookup::lookup(methodHandle method, bool& in_base_library, TRAPS) {
if (!method->has_native_function()) {
- address entry =
- method->intrinsic_id() == vmIntrinsics::_invokeGeneric ?
- SharedRuntime::native_method_throw_unsupported_operation_exception_entry() :
- lookup_base(method, in_base_library, CHECK_NULL);
+ address entry = lookup_base(method, in_base_library, CHECK_NULL);
method->set_native_function(entry,
Method::native_bind_event_is_interesting);
// -verbose:jni printing
diff --git a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp
index 81c2b74739d..7d72ca7f3ea 100644
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp
@@ -68,7 +68,7 @@ void AdvancedThresholdPolicy::initialize() {
}
#endif
-
+ set_increase_threshold_at_ratio();
set_start_time(os::javaTimeMillis());
}
@@ -205,6 +205,17 @@ double AdvancedThresholdPolicy::threshold_scale(CompLevel level, int feedback_k)
double queue_size = CompileBroker::queue_size(level);
int comp_count = compiler_count(level);
double k = queue_size / (feedback_k * comp_count) + 1;
+
+ // Increase C1 compile threshold when the code cache is filled more
+ // than specified by IncreaseFirstTierCompileThresholdAt percentage.
+ // The main intention is to keep enough free space for C2 compiled code
+ // to achieve peak performance if the code cache is under stress.
+ if ((TieredStopAtLevel == CompLevel_full_optimization) && (level != CompLevel_full_optimization)) {
+ double current_reverse_free_ratio = CodeCache::reverse_free_ratio();
+ if (current_reverse_free_ratio > _increase_threshold_at_ratio) {
+ k *= exp(current_reverse_free_ratio - _increase_threshold_at_ratio);
+ }
+ }
return k;
}
diff --git a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp
index 90a1ca174b9..4ab7653581b 100644
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp
@@ -201,9 +201,12 @@ class AdvancedThresholdPolicy : public SimpleThresholdPolicy {
// Is method profiled enough?
bool is_method_profiled(Method* method);
+ double _increase_threshold_at_ratio;
+
protected:
void print_specific(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level);
+ void set_increase_threshold_at_ratio() { _increase_threshold_at_ratio = 100 / (100 - (double)IncreaseFirstTierCompileThresholdAt); }
void set_start_time(jlong t) { _start_time = t; }
jlong start_time() const { return _start_time; }
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
index bf149fcd007..83f4660a0c7 100644
--- a/hotspot/src/share/vm/runtime/arguments.cpp
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
@@ -1089,6 +1089,10 @@ void Arguments::set_tiered_flags() {
if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) {
FLAG_SET_DEFAULT(ReservedCodeCacheSize, ReservedCodeCacheSize * 5);
}
+ if (!UseInterpreter) { // -Xcomp
+ Tier3InvokeNotifyFreqLog = 0;
+ Tier4InvocationThreshold = 0;
+ }
}
#if INCLUDE_ALL_GCS
@@ -1669,6 +1673,20 @@ void Arguments::set_bytecode_flags() {
// Aggressive optimization flags -XX:+AggressiveOpts
void Arguments::set_aggressive_opts_flags() {
#ifdef COMPILER2
+ if (AggressiveUnboxing) {
+ if (FLAG_IS_DEFAULT(EliminateAutoBox)) {
+ FLAG_SET_DEFAULT(EliminateAutoBox, true);
+ } else if (!EliminateAutoBox) {
+ // warning("AggressiveUnboxing is disabled because EliminateAutoBox is disabled");
+ AggressiveUnboxing = false;
+ }
+ if (FLAG_IS_DEFAULT(DoEscapeAnalysis)) {
+ FLAG_SET_DEFAULT(DoEscapeAnalysis, true);
+ } else if (!DoEscapeAnalysis) {
+ // warning("AggressiveUnboxing is disabled because DoEscapeAnalysis is disabled");
+ AggressiveUnboxing = false;
+ }
+ }
if (AggressiveOpts || !FLAG_IS_DEFAULT(AutoBoxCacheMax)) {
if (FLAG_IS_DEFAULT(EliminateAutoBox)) {
FLAG_SET_DEFAULT(EliminateAutoBox, true);
@@ -1901,7 +1919,7 @@ bool Arguments::check_vm_args_consistency() {
status = false;
}
- status = status && verify_percentage(AdaptiveSizePolicyWeight,
+ status = status && verify_interval(AdaptiveSizePolicyWeight, 0, 100,
"AdaptiveSizePolicyWeight");
status = status && verify_percentage(ThresholdTolerance, "ThresholdTolerance");
status = status && verify_percentage(MinHeapFreeRatio, "MinHeapFreeRatio");
@@ -1961,8 +1979,6 @@ bool Arguments::check_vm_args_consistency() {
FLAG_SET_DEFAULT(UseGCOverheadLimit, false);
}
- status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
-
status = status && check_gc_consistency();
status = status && check_stack_pages();
@@ -2056,6 +2072,52 @@ bool Arguments::check_vm_args_consistency() {
status = status && verify_interval(G1ConcRSLogCacheSize, 0, 31,
"G1ConcRSLogCacheSize");
}
+ if (UseConcMarkSweepGC) {
+ status = status && verify_min_value(CMSOldPLABNumRefills, 1, "CMSOldPLABNumRefills");
+ status = status && verify_min_value(CMSOldPLABToleranceFactor, 1, "CMSOldPLABToleranceFactor");
+ status = status && verify_min_value(CMSOldPLABMax, 1, "CMSOldPLABMax");
+ status = status && verify_interval(CMSOldPLABMin, 1, CMSOldPLABMax, "CMSOldPLABMin");
+
+ status = status && verify_min_value(CMSYoungGenPerWorker, 1, "CMSYoungGenPerWorker");
+
+ status = status && verify_min_value(CMSSamplingGrain, 1, "CMSSamplingGrain");
+ status = status && verify_interval(CMS_SweepWeight, 0, 100, "CMS_SweepWeight");
+ status = status && verify_interval(CMS_FLSWeight, 0, 100, "CMS_FLSWeight");
+
+ status = status && verify_interval(FLSCoalescePolicy, 0, 4, "FLSCoalescePolicy");
+
+ status = status && verify_min_value(CMSRescanMultiple, 1, "CMSRescanMultiple");
+ status = status && verify_min_value(CMSConcMarkMultiple, 1, "CMSConcMarkMultiple");
+
+ status = status && verify_interval(CMSPrecleanIter, 0, 9, "CMSPrecleanIter");
+ status = status && verify_min_value(CMSPrecleanDenominator, 1, "CMSPrecleanDenominator");
+ status = status && verify_interval(CMSPrecleanNumerator, 0, CMSPrecleanDenominator - 1, "CMSPrecleanNumerator");
+
+ status = status && verify_percentage(CMSBootstrapOccupancy, "CMSBootstrapOccupancy");
+
+ status = status && verify_min_value(CMSPrecleanThreshold, 100, "CMSPrecleanThreshold");
+
+ status = status && verify_percentage(CMSScheduleRemarkEdenPenetration, "CMSScheduleRemarkEdenPenetration");
+ status = status && verify_min_value(CMSScheduleRemarkSamplingRatio, 1, "CMSScheduleRemarkSamplingRatio");
+ status = status && verify_min_value(CMSBitMapYieldQuantum, 1, "CMSBitMapYieldQuantum");
+ status = status && verify_percentage(CMSTriggerRatio, "CMSTriggerRatio");
+ status = status && verify_percentage(CMSIsTooFullPercentage, "CMSIsTooFullPercentage");
+ }
+
+ if (UseParallelGC || UseParallelOldGC) {
+ status = status && verify_interval(ParallelOldDeadWoodLimiterMean, 0, 100, "ParallelOldDeadWoodLimiterMean");
+ status = status && verify_interval(ParallelOldDeadWoodLimiterStdDev, 0, 100, "ParallelOldDeadWoodLimiterStdDev");
+
+ status = status && verify_percentage(YoungGenerationSizeIncrement, "YoungGenerationSizeIncrement");
+ status = status && verify_percentage(TenuredGenerationSizeIncrement, "TenuredGenerationSizeIncrement");
+
+ status = status && verify_min_value(YoungGenerationSizeSupplementDecay, 1, "YoungGenerationSizeSupplementDecay");
+ status = status && verify_min_value(TenuredGenerationSizeSupplementDecay, 1, "TenuredGenerationSizeSupplementDecay");
+
+ status = status && verify_min_value(ParGCCardsPerStrideChunk, 1, "ParGCCardsPerStrideChunk");
+
+ status = status && verify_min_value(ParallelOldGCSplitInterval, 0, "ParallelOldGCSplitInterval");
+ }
#endif // INCLUDE_ALL_GCS
status = status && verify_interval(RefDiscoveryPolicy,
@@ -2075,7 +2137,42 @@ bool Arguments::check_vm_args_consistency() {
status = status && verify_interval(MarkStackSizeMax,
1, (max_jint - 1), "MarkStackSizeMax");
+ status = status && verify_interval(NUMAChunkResizeWeight, 0, 100, "NUMAChunkResizeWeight");
+ status = status && verify_min_value(LogEventsBufferEntries, 1, "LogEventsBufferEntries");
+
+ status = status && verify_min_value(HeapSizePerGCThread, (uintx) os::vm_page_size(), "HeapSizePerGCThread");
+
+ status = status && verify_min_value(GCTaskTimeStampEntries, 1, "GCTaskTimeStampEntries");
+
+ status = status && verify_percentage(ParallelGCBufferWastePct, "ParallelGCBufferWastePct");
+ status = status && verify_interval(TargetPLABWastePct, 1, 100, "TargetPLABWastePct");
+
+ status = status && verify_min_value(ParGCStridesPerThread, 1, "ParGCStridesPerThread");
+
+ status = status && verify_min_value(MinRAMFraction, 1, "MinRAMFraction");
+ status = status && verify_min_value(InitialRAMFraction, 1, "InitialRAMFraction");
+ status = status && verify_min_value(MaxRAMFraction, 1, "MaxRAMFraction");
+ status = status && verify_min_value(DefaultMaxRAMFraction, 1, "DefaultMaxRAMFraction");
+
+ status = status && verify_interval(AdaptiveTimeWeight, 0, 100, "AdaptiveTimeWeight");
+ status = status && verify_min_value(AdaptiveSizeDecrementScaleFactor, 1, "AdaptiveSizeDecrementScaleFactor");
+
+ status = status && verify_interval(TLABAllocationWeight, 0, 100, "TLABAllocationWeight");
+ status = status && verify_min_value(MinTLABSize, 1, "MinTLABSize");
+ status = status && verify_min_value(TLABRefillWasteFraction, 1, "TLABRefillWasteFraction");
+
+ status = status && verify_percentage(YoungGenerationSizeSupplement, "YoungGenerationSizeSupplement");
+ status = status && verify_percentage(TenuredGenerationSizeSupplement, "TenuredGenerationSizeSupplement");
+
+ // the "age" field in the oop header is 4 bits; do not want to pull in markOop.hpp
+ // just for that, so hardcode here.
+ status = status && verify_interval(MaxTenuringThreshold, 0, 15, "MaxTenuringThreshold");
+ status = status && verify_interval(InitialTenuringThreshold, 0, MaxTenuringThreshold, "MaxTenuringThreshold");
+ status = status && verify_percentage(TargetSurvivorRatio, "TargetSurvivorRatio");
+ status = status && verify_percentage(MarkSweepDeadRatio, "MarkSweepDeadRatio");
+
+ status = status && verify_min_value(MarkSweepAlwaysCompactCount, 1, "MarkSweepAlwaysCompactCount");
#ifdef SPARC
if (UseConcMarkSweepGC || UseG1GC) {
// Issue a stern warning if the user has explicitly set
@@ -2100,6 +2197,26 @@ bool Arguments::check_vm_args_consistency() {
#endif
}
+ // Need to limit the extent of the padding to reasonable size.
+ // 8K is well beyond the reasonable HW cache line size, even with the
+ // aggressive prefetching, while still leaving the room for segregating
+ // among the distinct pages.
+ if (ContendedPaddingWidth < 0 || ContendedPaddingWidth > 8192) {
+ jio_fprintf(defaultStream::error_stream(),
+ "ContendedPaddingWidth=" INTX_FORMAT " must be the between %d and %d\n",
+ ContendedPaddingWidth, 0, 8192);
+ status = false;
+ }
+
+ // Need to enforce the padding not to break the existing field alignments.
+ // It is sufficient to check against the largest type size.
+ if ((ContendedPaddingWidth % BytesPerLong) != 0) {
+ jio_fprintf(defaultStream::error_stream(),
+ "ContendedPaddingWidth=" INTX_FORMAT " must be the multiple of %d\n",
+ ContendedPaddingWidth, BytesPerLong);
+ status = false;
+ }
+
return status;
}
@@ -2512,6 +2629,16 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
return JNI_EINVAL;
}
FLAG_SET_CMDLINE(uintx, ReservedCodeCacheSize, (uintx)long_ReservedCodeCacheSize);
+ //-XX:IncreaseFirstTierCompileThresholdAt=
+ } else if (match_option(option, "-XX:IncreaseFirstTierCompileThresholdAt=", &tail)) {
+ uintx uint_IncreaseFirstTierCompileThresholdAt = 0;
+ if (!parse_uintx(tail, &uint_IncreaseFirstTierCompileThresholdAt, 0) || uint_IncreaseFirstTierCompileThresholdAt > 99) {
+ jio_fprintf(defaultStream::error_stream(),
+ "Invalid value for IncreaseFirstTierCompileThresholdAt: %s. Should be between 0 and 99.\n",
+ option->optionString);
+ return JNI_EINVAL;
+ }
+ FLAG_SET_CMDLINE(uintx, IncreaseFirstTierCompileThresholdAt, (uintx)uint_IncreaseFirstTierCompileThresholdAt);
// -green
} else if (match_option(option, "-green", &tail)) {
jio_fprintf(defaultStream::error_stream(),
@@ -2965,6 +3092,11 @@ jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_req
set_mode_flags(_int);
}
+ // eventually fix up InitialTenuringThreshold if only MaxTenuringThreshold is set
+ if (FLAG_IS_DEFAULT(InitialTenuringThreshold) && (InitialTenuringThreshold > MaxTenuringThreshold)) {
+ FLAG_SET_ERGO(uintx, InitialTenuringThreshold, MaxTenuringThreshold);
+ }
+
#ifndef COMPILER2
// Don't degrade server performance for footprint
if (FLAG_IS_DEFAULT(UseLargePages) &&
@@ -3097,36 +3229,27 @@ jint Arguments::parse_options_environment_variable(const char* name, SysClassPat
}
void Arguments::set_shared_spaces_flags() {
- const bool must_share = DumpSharedSpaces || RequireSharedSpaces;
- const bool might_share = must_share || UseSharedSpaces;
+#ifdef _LP64
+ const bool must_share = DumpSharedSpaces || RequireSharedSpaces;
- // CompressedOops cannot be used with CDS. The offsets of oopmaps and
- // static fields are incorrect in the archive. With some more clever
- // initialization, this restriction can probably be lifted.
- // ??? UseLargePages might be okay now
- const bool cannot_share = UseCompressedOops ||
- (UseLargePages && FLAG_IS_CMDLINE(UseLargePages));
- if (cannot_share) {
- if (must_share) {
- warning("disabling large pages %s"
- "because of %s", "" LP64_ONLY("and compressed oops "),
- DumpSharedSpaces ? "-Xshare:dump" : "-Xshare:on");
- FLAG_SET_CMDLINE(bool, UseLargePages, false);
- LP64_ONLY(FLAG_SET_CMDLINE(bool, UseCompressedOops, false));
- LP64_ONLY(FLAG_SET_CMDLINE(bool, UseCompressedKlassPointers, false));
- } else {
- // Prefer compressed oops and large pages to class data sharing
- if (UseSharedSpaces && Verbose) {
- warning("turning off use of shared archive because of large pages%s",
- "" LP64_ONLY(" and/or compressed oops"));
+ // CompressedOops cannot be used with CDS. The offsets of oopmaps and
+ // static fields are incorrect in the archive. With some more clever
+ // initialization, this restriction can probably be lifted.
+ if (UseCompressedOops) {
+ if (must_share) {
+ warning("disabling compressed oops because of %s",
+ DumpSharedSpaces ? "-Xshare:dump" : "-Xshare:on");
+ FLAG_SET_CMDLINE(bool, UseCompressedOops, false);
+ FLAG_SET_CMDLINE(bool, UseCompressedKlassPointers, false);
+ } else {
+ // Prefer compressed oops to class data sharing
+ if (UseSharedSpaces && Verbose) {
+ warning("turning off use of shared archive because of compressed oops");
+ }
+ no_shared_spaces();
}
- no_shared_spaces();
}
- } else if (UseLargePages && might_share) {
- // Disable large pages to allow shared spaces. This is sub-optimal, since
- // there may not even be a shared archive to use.
- FLAG_SET_DEFAULT(UseLargePages, false);
- }
+#endif
if (DumpSharedSpaces) {
if (RequireSharedSpaces) {
@@ -3171,25 +3294,37 @@ static void force_serial_gc() {
}
#endif // INCLUDE_ALL_GCS
+// Sharing support
+// Construct the path to the archive
+static char* get_shared_archive_path() {
+ char *shared_archive_path;
+ if (SharedArchiveFile == NULL) {
+ char jvm_path[JVM_MAXPATHLEN];
+ os::jvm_path(jvm_path, sizeof(jvm_path));
+ char *end = strrchr(jvm_path, *os::file_separator());
+ if (end != NULL) *end = '\0';
+ size_t jvm_path_len = strlen(jvm_path);
+ size_t file_sep_len = strlen(os::file_separator());
+ shared_archive_path = NEW_C_HEAP_ARRAY(char, jvm_path_len +
+ file_sep_len + 20, mtInternal);
+ if (shared_archive_path != NULL) {
+ strncpy(shared_archive_path, jvm_path, jvm_path_len + 1);
+ strncat(shared_archive_path, os::file_separator(), file_sep_len);
+ strncat(shared_archive_path, "classes.jsa", 11);
+ }
+ } else {
+ shared_archive_path = NEW_C_HEAP_ARRAY(char, strlen(SharedArchiveFile) + 1, mtInternal);
+ if (shared_archive_path != NULL) {
+ strncpy(shared_archive_path, SharedArchiveFile, strlen(SharedArchiveFile) + 1);
+ }
+ }
+ return shared_archive_path;
+}
+
// Parse entry point called from JNI_CreateJavaVM
jint Arguments::parse(const JavaVMInitArgs* args) {
- // Sharing support
- // Construct the path to the archive
- char jvm_path[JVM_MAXPATHLEN];
- os::jvm_path(jvm_path, sizeof(jvm_path));
- char *end = strrchr(jvm_path, *os::file_separator());
- if (end != NULL) *end = '\0';
- char *shared_archive_path = NEW_C_HEAP_ARRAY(char, strlen(jvm_path) +
- strlen(os::file_separator()) + 20, mtInternal);
- if (shared_archive_path == NULL) return JNI_ENOMEM;
- strcpy(shared_archive_path, jvm_path);
- strcat(shared_archive_path, os::file_separator());
- strcat(shared_archive_path, "classes");
- strcat(shared_archive_path, ".jsa");
- SharedArchivePath = shared_archive_path;
-
// Remaining part of option string
const char* tail;
@@ -3280,6 +3415,12 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
return result;
}
+ // Call get_shared_archive_path() here, after possible SharedArchiveFile option got parsed.
+ SharedArchivePath = get_shared_archive_path();
+ if (SharedArchivePath == NULL) {
+ return JNI_ENOMEM;
+ }
+
// Delay warning until here so that we've had a chance to process
// the -XX:-PrintWarnings flag
if (needs_hotspotrc_warning) {
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index 54c91f6b355..aec1736a43c 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -286,12 +286,12 @@ class CounterSetting {
};
-class IntFlagSetting {
- intx val;
- intx* flag;
+class UIntFlagSetting {
+ uintx val;
+ uintx* flag;
public:
- IntFlagSetting(intx& fl, intx newValue) { flag = &fl; val = fl; fl = newValue; }
- ~IntFlagSetting() { *flag = val; }
+ UIntFlagSetting(uintx& fl, uintx newValue) { flag = &fl; val = fl; fl = newValue; }
+ ~UIntFlagSetting() { *flag = val; }
};
@@ -513,12 +513,12 @@ class CommandLineFlags {
product(bool, ForceNUMA, false, \
"Force NUMA optimizations on single-node/UMA systems") \
\
- product(intx, NUMAChunkResizeWeight, 20, \
- "Percentage (0-100) used to weight the current sample when " \
+ product(uintx, NUMAChunkResizeWeight, 20, \
+ "Percentage (0-100) used to weigh the current sample when " \
"computing exponentially decaying average for " \
"AdaptiveNUMAChunkSizing") \
\
- product(intx, NUMASpaceResizeRate, 1*G, \
+ product(uintx, NUMASpaceResizeRate, 1*G, \
"Do not reallocate more that this amount per collection") \
\
product(bool, UseAdaptiveNUMAChunkSizing, true, \
@@ -527,7 +527,7 @@ class CommandLineFlags {
product(bool, NUMAStats, false, \
"Print NUMA stats in detailed heap information") \
\
- product(intx, NUMAPageScanRate, 256, \
+ product(uintx, NUMAPageScanRate, 256, \
"Maximum number of pages to include in the page scan procedure") \
\
product_pd(bool, NeedsDeoptSuspend, \
@@ -715,7 +715,7 @@ class CommandLineFlags {
diagnostic(bool, LogEvents, true, \
"Enable the various ring buffer event logs") \
\
- diagnostic(intx, LogEventsBufferEntries, 10, \
+ diagnostic(uintx, LogEventsBufferEntries, 10, \
"Enable the various ring buffer event logs") \
\
product(bool, BytecodeVerificationRemote, true, \
@@ -1159,9 +1159,6 @@ class CommandLineFlags {
product(bool, CompactFields, true, \
"Allocate nonstatic fields in gaps between previous fields") \
\
- notproduct(bool, PrintCompactFieldsSavings, false, \
- "Print how many words were saved with CompactFields") \
- \
notproduct(bool, PrintFieldLayout, false, \
"Print field layout for each class") \
\
@@ -1432,16 +1429,17 @@ class CommandLineFlags {
product(bool, ParallelGCVerbose, false, \
"Verbose output for parallel GC.") \
\
- product(intx, ParallelGCBufferWastePct, 10, \
- "wasted fraction of parallel allocation buffer.") \
+ product(uintx, ParallelGCBufferWastePct, 10, \
+ "Wasted fraction of parallel allocation buffer.") \
\
diagnostic(bool, ParallelGCRetainPLAB, false, \
"Retain parallel allocation buffers across scavenges; " \
" -- disabled because this currently conflicts with " \
" parallel card scanning under certain conditions ") \
\
- product(intx, TargetPLABWastePct, 10, \
- "target wasted space in last buffer as pct of overall allocation")\
+ product(uintx, TargetPLABWastePct, 10, \
+ "Target wasted space in last buffer as percent of overall " \
+ "allocation") \
\
product(uintx, PLABWeight, 75, \
"Percentage (0-100) used to weight the current sample when" \
@@ -1519,7 +1517,7 @@ class CommandLineFlags {
product(bool, AlwaysPreTouch, false, \
"It forces all freshly committed pages to be pre-touched.") \
\
- product_pd(intx, CMSYoungGenPerWorker, \
+ product_pd(uintx, CMSYoungGenPerWorker, \
"The maximum size of young gen chosen by default per GC worker " \
"thread available") \
\
@@ -1837,7 +1835,7 @@ class CommandLineFlags {
product(bool, UseCMSInitiatingOccupancyOnly, false, \
"Only use occupancy as a crierion for starting a CMS collection") \
\
- product(intx, CMSIsTooFullPercentage, 98, \
+ product(uintx, CMSIsTooFullPercentage, 98, \
"An absolute ceiling above which CMS will always consider the " \
"unloading of classes when class unloading is enabled") \
\
@@ -1876,7 +1874,7 @@ class CommandLineFlags {
develop(uintx, PromotionFailureALotInterval, 5, \
"Total collections between promotion failures alot") \
\
- experimental(intx, WorkStealingSleepMillis, 1, \
+ experimental(uintx, WorkStealingSleepMillis, 1, \
"Sleep time when sleep is used for yields") \
\
experimental(uintx, WorkStealingYieldsBeforeSleep, 5000, \
@@ -2020,7 +2018,7 @@ class CommandLineFlags {
"Number of collections before the adaptive sizing is started") \
\
product(uintx, AdaptiveSizePolicyOutputInterval, 0, \
- "Collecton interval for printing information; zero => never") \
+ "Collection interval for printing information; zero means never") \
\
product(bool, UseAdaptiveSizePolicyFootprintGoal, true, \
"Use adaptive minimum footprint as a goal") \
@@ -3049,7 +3047,7 @@ class CommandLineFlags {
product(uintx, MaxMetaspaceExpansion, ScaleForWordSize(4*M), \
"Max expansion of Metaspace without full GC (in bytes)") \
\
- product(intx, QueuedAllocationWarningCount, 0, \
+ product(uintx, QueuedAllocationWarningCount, 0, \
"Number of times an allocation that queues behind a GC " \
"will retry before printing a warning") \
\
@@ -3077,7 +3075,7 @@ class CommandLineFlags {
"either completely full or completely empty. Par compact also" \
"has a smaller default value; see arguments.cpp.") \
\
- product(intx, MarkSweepAlwaysCompactCount, 4, \
+ product(uintx, MarkSweepAlwaysCompactCount, 4, \
"How often should we fully compact the heap (ignoring the dead " \
"space parameters)") \
\
@@ -3438,6 +3436,10 @@ class CommandLineFlags {
"Start profiling in interpreter if the counters exceed tier 3" \
"thresholds by the specified percentage") \
\
+ product(uintx, IncreaseFirstTierCompileThresholdAt, 50, \
+ "Increase the compile threshold for C1 compilation if the code" \
+ "cache is filled by the specified percentage.") \
+ \
product(intx, TieredRateUpdateMinTime, 1, \
"Minimum rate sampling interval (in milliseconds)") \
\
@@ -3680,6 +3682,9 @@ class CommandLineFlags {
product(bool , AllowNonVirtualCalls, false, \
"Obey the ACC_SUPER flag and allow invokenonvirtual calls") \
\
+ diagnostic(ccstr, SharedArchiveFile, NULL, \
+ "Override the default location of the CDS archive file") \
+ \
experimental(uintx, ArrayAllocatorMallocLimit, \
SOLARIS_ONLY(64*K) NOT_SOLARIS(max_uintx), \
"Allocation less than this value will be allocated " \
diff --git a/hotspot/src/share/vm/runtime/handles.cpp b/hotspot/src/share/vm/runtime/handles.cpp
index a62ff177d30..ebbdd9d7463 100644
--- a/hotspot/src/share/vm/runtime/handles.cpp
+++ b/hotspot/src/share/vm/runtime/handles.cpp
@@ -179,6 +179,22 @@ HandleMark::~HandleMark() {
_thread->set_last_handle_mark(previous_handle_mark());
}
+void* HandleMark::operator new(size_t size) {
+ return AllocateHeap(size, mtThread);
+}
+
+void* HandleMark::operator new [] (size_t size) {
+ return AllocateHeap(size, mtThread);
+}
+
+void HandleMark::operator delete(void* p) {
+ FreeHeap(p, mtThread);
+}
+
+void HandleMark::operator delete[](void* p) {
+ FreeHeap(p, mtThread);
+}
+
#ifdef ASSERT
NoHandleMark::NoHandleMark() {
diff --git a/hotspot/src/share/vm/runtime/handles.hpp b/hotspot/src/share/vm/runtime/handles.hpp
index 8c643d7c206..82506bd7049 100644
--- a/hotspot/src/share/vm/runtime/handles.hpp
+++ b/hotspot/src/share/vm/runtime/handles.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -281,7 +281,7 @@ class HandleArea: public Arena {
// across the HandleMark boundary.
// The base class of HandleMark should have been StackObj but we also heap allocate
-// a HandleMark when a thread is created.
+// a HandleMark when a thread is created. The operator new is for this special case.
class HandleMark {
private:
@@ -308,6 +308,11 @@ class HandleMark {
void push();
// called in the destructor of HandleMarkCleaner
void pop_and_restore();
+ // overloaded operators
+ void* operator new(size_t size);
+ void* operator new [](size_t size);
+ void operator delete(void* p);
+ void operator delete[](void* p);
};
//------------------------------------------------------------------------------------------------------------------------
diff --git a/hotspot/src/share/vm/runtime/jniHandles.cpp b/hotspot/src/share/vm/runtime/jniHandles.cpp
index 4dc83d3044c..d518dfa9398 100644
--- a/hotspot/src/share/vm/runtime/jniHandles.cpp
+++ b/hotspot/src/share/vm/runtime/jniHandles.cpp
@@ -188,7 +188,6 @@ long JNIHandles::weak_global_handle_memory_usage() {
class AlwaysAliveClosure: public BoolObjectClosure {
public:
bool do_object_b(oop obj) { return true; }
- void do_object(oop obj) { assert(false, "Don't call"); }
};
class CountHandleClosure: public OopClosure {
diff --git a/hotspot/src/share/vm/runtime/objectMonitor.hpp b/hotspot/src/share/vm/runtime/objectMonitor.hpp
index e4236f490af..df4b0279cc0 100644
--- a/hotspot/src/share/vm/runtime/objectMonitor.hpp
+++ b/hotspot/src/share/vm/runtime/objectMonitor.hpp
@@ -303,6 +303,18 @@ public:
public:
static int Knob_Verbose;
static int Knob_SpinLimit;
+ void* operator new (size_t size) {
+ return AllocateHeap(size, mtInternal);
+ }
+ void* operator new[] (size_t size) {
+ return operator new (size);
+ }
+ void operator delete(void* p) {
+ FreeHeap(p, mtInternal);
+ }
+ void operator delete[] (void *p) {
+ operator delete(p);
+ }
};
#undef TEVENT
diff --git a/hotspot/src/share/vm/runtime/reflectionUtils.hpp b/hotspot/src/share/vm/runtime/reflectionUtils.hpp
index 7641fa76923..d51b2ab7874 100644
--- a/hotspot/src/share/vm/runtime/reflectionUtils.hpp
+++ b/hotspot/src/share/vm/runtime/reflectionUtils.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -136,10 +136,10 @@ class FieldStream : public KlassStream {
}
};
-class FilteredField {
+class FilteredField : public CHeapObj {
private:
Klass* _klass;
- int _field_offset;
+ int _field_offset;
public:
FilteredField(Klass* klass, int field_offset) {
diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp
index 57af1f3bda7..114f27d20a8 100644
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp
@@ -883,15 +883,23 @@ address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
}
-JNI_ENTRY(void, throw_unsatisfied_link_error(JNIEnv* env, ...))
+/**
+ * Throws an java/lang/UnsatisfiedLinkError. The address of this method is
+ * installed in the native function entry of all native Java methods before
+ * they get linked to their actual native methods.
+ *
+ * \note
+ * This method actually never gets called! The reason is because
+ * the interpreter's native entries call NativeLookup::lookup() which
+ * throws the exception when the lookup fails. The exception is then
+ * caught and forwarded on the return from NativeLookup::lookup() call
+ * before the call to the native function. This might change in the future.
+ */
+JNI_ENTRY(void*, throw_unsatisfied_link_error(JNIEnv* env, ...))
{
- THROW(vmSymbols::java_lang_UnsatisfiedLinkError());
-}
-JNI_END
-
-JNI_ENTRY(void, throw_unsupported_operation_exception(JNIEnv* env, ...))
-{
- THROW(vmSymbols::java_lang_UnsupportedOperationException());
+ // We return a bad value here to make sure that the exception is
+ // forwarded before we look at the return value.
+ THROW_(vmSymbols::java_lang_UnsatisfiedLinkError(), (void*)badJNIHandle);
}
JNI_END
@@ -899,10 +907,6 @@ address SharedRuntime::native_method_throw_unsatisfied_link_error_entry() {
return CAST_FROM_FN_PTR(address, &throw_unsatisfied_link_error);
}
-address SharedRuntime::native_method_throw_unsupported_operation_exception_entry() {
- return CAST_FROM_FN_PTR(address, &throw_unsupported_operation_exception);
-}
-
#ifndef PRODUCT
JRT_ENTRY(intptr_t, SharedRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2))
diff --git a/hotspot/src/share/vm/runtime/unhandledOops.hpp b/hotspot/src/share/vm/runtime/unhandledOops.hpp
index 97fd8543128..5f65d153634 100644
--- a/hotspot/src/share/vm/runtime/unhandledOops.hpp
+++ b/hotspot/src/share/vm/runtime/unhandledOops.hpp
@@ -48,7 +48,7 @@
class oop;
class Thread;
-class UnhandledOopEntry {
+class UnhandledOopEntry : public CHeapObj {
friend class UnhandledOops;
private:
oop* _oop_ptr;
@@ -62,7 +62,7 @@ class UnhandledOopEntry {
};
-class UnhandledOops {
+class UnhandledOops : public CHeapObj {
friend class Thread;
private:
Thread* _thread;
diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
index b281d7ac39a..b3fdd1e7097 100644
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp
@@ -1057,6 +1057,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
c2_nonstatic_field(Compile, _save_argument_registers, const bool) \
c2_nonstatic_field(Compile, _subsume_loads, const bool) \
c2_nonstatic_field(Compile, _do_escape_analysis, const bool) \
+ c2_nonstatic_field(Compile, _eliminate_boxing, const bool) \
c2_nonstatic_field(Compile, _ilt, InlineTree*) \
\
c2_nonstatic_field(InlineTree, _caller_jvms, JVMState*) \
@@ -3119,15 +3120,15 @@ static int recursiveFindType(VMTypeEntry* origtypes, const char* typeName, bool
// Search for the base type by peeling off const and *
size_t len = strlen(typeName);
if (typeName[len-1] == '*') {
- char * s = new char[len];
+ char * s = NEW_C_HEAP_ARRAY(char, len, mtInternal);
strncpy(s, typeName, len - 1);
s[len-1] = '\0';
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
if (recursiveFindType(origtypes, s, true) == 1) {
- delete [] s;
+ FREE_C_HEAP_ARRAY(char, s, mtInternal);
return 1;
}
- delete [] s;
+ FREE_C_HEAP_ARRAY(char, s, mtInternal);
}
const char* start = NULL;
if (strstr(typeName, "GrowableArray<") == typeName) {
@@ -3138,15 +3139,15 @@ static int recursiveFindType(VMTypeEntry* origtypes, const char* typeName, bool
if (start != NULL) {
const char * end = strrchr(typeName, '>');
int len = end - start + 1;
- char * s = new char[len];
+ char * s = NEW_C_HEAP_ARRAY(char, len, mtInternal);
strncpy(s, start, len - 1);
s[len-1] = '\0';
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
if (recursiveFindType(origtypes, s, true) == 1) {
- delete [] s;
+ FREE_C_HEAP_ARRAY(char, s, mtInternal);
return 1;
}
- delete [] s;
+ FREE_C_HEAP_ARRAY(char, s, mtInternal);
}
if (strstr(typeName, "const ") == typeName) {
const char * s = typeName + strlen("const ");
diff --git a/hotspot/src/share/vm/utilities/debug.cpp b/hotspot/src/share/vm/utilities/debug.cpp
index a675c27bfad..1062b525fd5 100644
--- a/hotspot/src/share/vm/utilities/debug.cpp
+++ b/hotspot/src/share/vm/utilities/debug.cpp
@@ -665,152 +665,4 @@ void help() {
tty->print_cr(" ndebug() - undo debug");
}
-#if 0
-
-// BobV's command parser for debugging on windows when nothing else works.
-
-enum CommandID {
- CMDID_HELP,
- CMDID_QUIT,
- CMDID_HSFIND,
- CMDID_PSS,
- CMDID_PS,
- CMDID_PSF,
- CMDID_FINDM,
- CMDID_FINDNM,
- CMDID_PP,
- CMDID_BPT,
- CMDID_EXIT,
- CMDID_VERIFY,
- CMDID_THREADS,
- CMDID_ILLEGAL = 99
-};
-
-struct CommandParser {
- char *name;
- CommandID code;
- char *description;
-};
-
-struct CommandParser CommandList[] = {
- (char *)"help", CMDID_HELP, " Dump this list",
- (char *)"quit", CMDID_QUIT, " Return from this routine",
- (char *)"hsfind", CMDID_HSFIND, "Perform an hsfind on an address",
- (char *)"ps", CMDID_PS, " Print Current Thread Stack Trace",
- (char *)"pss", CMDID_PSS, " Print All Thread Stack Trace",
- (char *)"psf", CMDID_PSF, " Print All Stack Frames",
- (char *)"findm", CMDID_FINDM, " Find a Method* from a PC",
- (char *)"findnm", CMDID_FINDNM, "Find an nmethod from a PC",
- (char *)"pp", CMDID_PP, " Find out something about a pointer",
- (char *)"break", CMDID_BPT, " Execute a breakpoint",
- (char *)"exitvm", CMDID_EXIT, "Exit the VM",
- (char *)"verify", CMDID_VERIFY, "Perform a Heap Verify",
- (char *)"thread", CMDID_THREADS, "Dump Info on all Threads",
- (char *)0, CMDID_ILLEGAL
-};
-
-
-// get_debug_command()
-//
-// Read a command from standard input.
-// This is useful when you have a debugger
-// which doesn't support calling into functions.
-//
-void get_debug_command()
-{
- ssize_t count;
- int i,j;
- bool gotcommand;
- intptr_t addr;
- char buffer[256];
- nmethod *nm;
- Method* m;
-
- tty->print_cr("You have entered the diagnostic command interpreter");
- tty->print("The supported commands are:\n");
- for ( i=0; ; i++ ) {
- if ( CommandList[i].code == CMDID_ILLEGAL )
- break;
- tty->print_cr(" %s \n", CommandList[i].name );
- }
-
- while ( 1 ) {
- gotcommand = false;
- tty->print("Please enter a command: ");
- count = scanf("%s", buffer) ;
- if ( count >=0 ) {
- for ( i=0; ; i++ ) {
- if ( CommandList[i].code == CMDID_ILLEGAL ) {
- if (!gotcommand) tty->print("Invalid command, please try again\n");
- break;
- }
- if ( strcmp(buffer, CommandList[i].name) == 0 ) {
- gotcommand = true;
- switch ( CommandList[i].code ) {
- case CMDID_PS:
- ps();
- break;
- case CMDID_PSS:
- pss();
- break;
- case CMDID_PSF:
- psf();
- break;
- case CMDID_FINDM:
- tty->print("Please enter the hex addr to pass to findm: ");
- scanf("%I64X", &addr);
- m = (Method*)findm(addr);
- tty->print("findm(0x%I64X) returned 0x%I64X\n", addr, m);
- break;
- case CMDID_FINDNM:
- tty->print("Please enter the hex addr to pass to findnm: ");
- scanf("%I64X", &addr);
- nm = (nmethod*)findnm(addr);
- tty->print("findnm(0x%I64X) returned 0x%I64X\n", addr, nm);
- break;
- case CMDID_PP:
- tty->print("Please enter the hex addr to pass to pp: ");
- scanf("%I64X", &addr);
- pp((void*)addr);
- break;
- case CMDID_EXIT:
- exit(0);
- case CMDID_HELP:
- tty->print("Here are the supported commands: ");
- for ( j=0; ; j++ ) {
- if ( CommandList[j].code == CMDID_ILLEGAL )
- break;
- tty->print_cr(" %s -- %s\n", CommandList[j].name,
- CommandList[j].description );
- }
- break;
- case CMDID_QUIT:
- return;
- break;
- case CMDID_BPT:
- BREAKPOINT;
- break;
- case CMDID_VERIFY:
- verify();;
- break;
- case CMDID_THREADS:
- threads();;
- break;
- case CMDID_HSFIND:
- tty->print("Please enter the hex addr to pass to hsfind: ");
- scanf("%I64X", &addr);
- tty->print("Calling hsfind(0x%I64X)\n", addr);
- hsfind(addr);
- break;
- default:
- case CMDID_ILLEGAL:
- break;
- }
- }
- }
- }
- }
-}
-#endif
-
#endif // !PRODUCT
diff --git a/hotspot/src/share/vm/utilities/events.hpp b/hotspot/src/share/vm/utilities/events.hpp
index c2e543da976..804fe77df2d 100644
--- a/hotspot/src/share/vm/utilities/events.hpp
+++ b/hotspot/src/share/vm/utilities/events.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -69,7 +69,7 @@ class EventLog : public CHeapObj {
// semantics aren't appropriate. The name is used as the label of the
// log when it is dumped during a crash.
template class EventLogBase : public EventLog {
- template class EventRecord {
+ template class EventRecord : public CHeapObj {
public:
double timestamp;
Thread* thread;
diff --git a/hotspot/src/share/vm/utilities/hashtable.cpp b/hotspot/src/share/vm/utilities/hashtable.cpp
index 960474ababd..ecb43da83b0 100644
--- a/hotspot/src/share/vm/utilities/hashtable.cpp
+++ b/hotspot/src/share/vm/utilities/hashtable.cpp
@@ -33,6 +33,7 @@
#include "utilities/dtrace.hpp"
#include "utilities/hashtable.hpp"
#include "utilities/hashtable.inline.hpp"
+#include "utilities/numberSeq.hpp"
// This is a generic hashtable, designed to be used for the symbol
@@ -237,6 +238,57 @@ template void Hashtable::reverse(void* boundary) {
}
}
+template int Hashtable::literal_size(Symbol *symbol) {
+ return symbol->size() * HeapWordSize;
+}
+
+template int Hashtable::literal_size(oop oop) {
+ // NOTE: this would over-count if (pre-JDK8) java_lang_Class::has_offset_field() is true,
+ // and the String.value array is shared by several Strings. However, starting from JDK8,
+ // the String.value array is not shared anymore.
+ assert(oop != NULL && oop->klass() == SystemDictionary::String_klass(), "only strings are supported");
+ return (oop->size() + java_lang_String::value(oop)->size()) * HeapWordSize;
+}
+
+// Dump footprint and bucket length statistics
+//
+// Note: if you create a new subclass of Hashtable, you will need to
+// add a new function Hashtable::literal_size(MyNewType lit)
+
+template void Hashtable::dump_table(outputStream* st, const char *table_name) {
+ NumberSeq summary;
+ int literal_bytes = 0;
+ for (int i = 0; i < this->table_size(); ++i) {
+ int count = 0;
+ for (HashtableEntry* e = bucket(i);
+ e != NULL; e = e->next()) {
+ count++;
+ literal_bytes += literal_size(e->literal());
+ }
+ summary.add((double)count);
+ }
+ double num_buckets = summary.num();
+ double num_entries = summary.sum();
+
+ int bucket_bytes = (int)num_buckets * sizeof(bucket(0));
+ int entry_bytes = (int)num_entries * sizeof(HashtableEntry);
+ int total_bytes = literal_bytes + bucket_bytes + entry_bytes;
+
+ double bucket_avg = (num_buckets <= 0) ? 0 : (bucket_bytes / num_buckets);
+ double entry_avg = (num_entries <= 0) ? 0 : (entry_bytes / num_entries);
+ double literal_avg = (num_entries <= 0) ? 0 : (literal_bytes / num_entries);
+
+ st->print_cr("%s statistics:", table_name);
+ st->print_cr("Number of buckets : %9d = %9d bytes, avg %7.3f", (int)num_buckets, bucket_bytes, bucket_avg);
+ st->print_cr("Number of entries : %9d = %9d bytes, avg %7.3f", (int)num_entries, entry_bytes, entry_avg);
+ st->print_cr("Number of literals : %9d = %9d bytes, avg %7.3f", (int)num_entries, literal_bytes, literal_avg);
+ st->print_cr("Total footprint : %9s = %9d bytes", "", total_bytes);
+ st->print_cr("Average bucket size : %9.3f", summary.avg());
+ st->print_cr("Variance of bucket size : %9.3f", summary.variance());
+ st->print_cr("Std. dev. of bucket size: %9.3f", summary.sd());
+ st->print_cr("Maximum bucket size : %9d", (int)summary.maximum());
+}
+
// Dump the hash table buckets.
diff --git a/hotspot/src/share/vm/utilities/hashtable.hpp b/hotspot/src/share/vm/utilities/hashtable.hpp
index f170e6018e9..826823bdc13 100644
--- a/hotspot/src/share/vm/utilities/hashtable.hpp
+++ b/hotspot/src/share/vm/utilities/hashtable.hpp
@@ -282,6 +282,19 @@ protected:
static bool use_alternate_hashcode() { return _seed != 0; }
static jint seed() { return _seed; }
+ static int literal_size(Symbol *symbol);
+ static int literal_size(oop oop);
+
+ // The following two are currently not used, but are needed anyway because some
+ // C++ compilers (MacOS and Solaris) force the instantiation of
+ // Hashtable::dump_table() even though we never call this function
+ // in the VM code.
+ static int literal_size(ConstantPool *cp) {Unimplemented(); return 0;}
+ static int literal_size(Klass *k) {Unimplemented(); return 0;}
+
+public:
+ void dump_table(outputStream* st, const char *table_name);
+
private:
static jint _seed;
};
diff --git a/hotspot/src/share/vm/utilities/quickSort.cpp b/hotspot/src/share/vm/utilities/quickSort.cpp
index e3cfa1efa5e..0cb7f6ef833 100644
--- a/hotspot/src/share/vm/utilities/quickSort.cpp
+++ b/hotspot/src/share/vm/utilities/quickSort.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,11 @@
#include "runtime/os.hpp"
#include "utilities/quickSort.hpp"
+#include "memory/allocation.hpp"
+#include "memory/allocation.inline.hpp"
#include
+#ifdef ASSERT
static int test_comparator(int a, int b) {
if (a == b) {
return 0;
@@ -41,6 +44,7 @@ static int test_comparator(int a, int b) {
}
return 1;
}
+#endif // ASSERT
static int test_even_odd_comparator(int a, int b) {
bool a_is_odd = (a % 2) == 1;
@@ -187,8 +191,8 @@ void QuickSort::test_quick_sort() {
// test sorting random arrays
for (int i = 0; i < 1000; i++) {
int length = os::random() % 100;
- int* test_array = new int[length];
- int* expected_array = new int[length];
+ int* test_array = NEW_C_HEAP_ARRAY(int, length, mtInternal);
+ int* expected_array = NEW_C_HEAP_ARRAY(int, length, mtInternal);
for (int j = 0; j < length; j++) {
// Choose random values, but get a chance of getting duplicates
test_array[j] = os::random() % (length * 2);
@@ -210,8 +214,8 @@ void QuickSort::test_quick_sort() {
sort(test_array, length, test_even_odd_comparator, true);
assert(compare_arrays(test_array, expected_array, length), "Sorting already sorted array changed order of elements - not idempotent");
- delete[] test_array;
- delete[] expected_array;
+ FREE_C_HEAP_ARRAY(int, test_array, mtInternal);
+ FREE_C_HEAP_ARRAY(int, expected_array, mtInternal);
}
}
diff --git a/hotspot/src/share/vm/utilities/workgroup.cpp b/hotspot/src/share/vm/utilities/workgroup.cpp
index 5db6344fd72..479cd04029a 100644
--- a/hotspot/src/share/vm/utilities/workgroup.cpp
+++ b/hotspot/src/share/vm/utilities/workgroup.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -529,7 +529,7 @@ bool FreeIdSet::_safepoint;
FreeIdSet::FreeIdSet(int sz, Monitor* mon) :
_sz(sz), _mon(mon), _hd(0), _waiters(0), _index(-1), _claimed(0)
{
- _ids = new int[sz];
+ _ids = NEW_C_HEAP_ARRAY(int, sz, mtInternal);
for (int i = 0; i < sz; i++) _ids[i] = i+1;
_ids[sz-1] = end_of_list; // end of list.
if (_stat_init) {
@@ -549,6 +549,7 @@ FreeIdSet::FreeIdSet(int sz, Monitor* mon) :
FreeIdSet::~FreeIdSet() {
_sets[_index] = NULL;
+ FREE_C_HEAP_ARRAY(int, _ids, mtInternal);
}
void FreeIdSet::set_safepoint(bool b) {
diff --git a/hotspot/src/share/vm/utilities/workgroup.hpp b/hotspot/src/share/vm/utilities/workgroup.hpp
index 6a93536246b..e1184a67972 100644
--- a/hotspot/src/share/vm/utilities/workgroup.hpp
+++ b/hotspot/src/share/vm/utilities/workgroup.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -494,7 +494,7 @@ public:
};
// Represents a set of free small integer ids.
-class FreeIdSet {
+class FreeIdSet : public CHeapObj {
enum {
end_of_list = -1,
claimed = -2
diff --git a/hotspot/test/compiler/6934604/TestByteBoxing.java b/hotspot/test/compiler/6934604/TestByteBoxing.java
new file mode 100644
index 00000000000..ee5511a9818
--- /dev/null
+++ b/hotspot/test/compiler/6934604/TestByteBoxing.java
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6934604
+ * @summary enable parts of EliminateAutoBox by default
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox TestByteBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestByteBoxing.dummy -XX:CompileCommand=exclude,TestByteBoxing.foo -XX:CompileCommand=exclude,TestByteBoxing.foob TestByteBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestByteBoxing.dummy -XX:CompileCommand=exclude,TestByteBoxing.foo -XX:CompileCommand=exclude,TestByteBoxing.foob TestByteBoxing
+ *
+ */
+
+public class TestByteBoxing {
+
+ static final Byte ibc = new Byte((byte)1);
+
+ //===============================================
+ // Non-inlined methods to test deoptimization info
+ static void dummy() { }
+ static byte foo(byte i) { return i; }
+ static Byte foob(byte i) { return Byte.valueOf(i); }
+
+
+ static byte simple(byte i) {
+ Byte ib = new Byte(i);
+ return ib;
+ }
+
+ static byte simpleb(byte i) {
+ Byte ib = Byte.valueOf(i);
+ return ib;
+ }
+
+ static byte simplec() {
+ Byte ib = ibc;
+ return ib;
+ }
+
+ static byte simplef(byte i) {
+ Byte ib = foob(i);
+ return ib;
+ }
+
+ static byte simplep(Byte ib) {
+ return ib;
+ }
+
+ static byte simple2(byte i) {
+ Byte ib1 = new Byte(i);
+ Byte ib2 = new Byte((byte)(i+1));
+ return (byte)(ib1 + ib2);
+ }
+
+ static byte simpleb2(byte i) {
+ Byte ib1 = Byte.valueOf(i);
+ Byte ib2 = Byte.valueOf((byte)(i+1));
+ return (byte)(ib1 + ib2);
+ }
+
+ static byte simplem2(byte i) {
+ Byte ib1 = new Byte(i);
+ Byte ib2 = Byte.valueOf((byte)(i+1));
+ return (byte)(ib1 + ib2);
+ }
+
+ static byte simplep2(byte i, Byte ib1) {
+ Byte ib2 = Byte.valueOf((byte)(i+1));
+ return (byte)(ib1 + ib2);
+ }
+
+ static byte simplec2(byte i) {
+ Byte ib1 = ibc;
+ Byte ib2 = Byte.valueOf((byte)(i+1));
+ return (byte)(ib1 + ib2);
+ }
+
+ //===============================================
+ static byte test(byte i) {
+ Byte ib = new Byte(i);
+ if ((i&1) == 0)
+ ib = (byte)(i+1);
+ return ib;
+ }
+
+ static byte testb(byte i) {
+ Byte ib = i;
+ if ((i&1) == 0)
+ ib = (byte)(i+1);
+ return ib;
+ }
+
+ static byte testm(byte i) {
+ Byte ib = i;
+ if ((i&1) == 0)
+ ib = new Byte((byte)(i+1));
+ return ib;
+ }
+
+ static byte testp(byte i, Byte ib) {
+ if ((i&1) == 0)
+ ib = new Byte((byte)(i+1));
+ return ib;
+ }
+
+ static byte testc(byte i) {
+ Byte ib = ibc;
+ if ((i&1) == 0)
+ ib = new Byte((byte)(i+1));
+ return ib;
+ }
+
+ static byte test2(byte i) {
+ Byte ib1 = new Byte(i);
+ Byte ib2 = new Byte((byte)(i+1));
+ if ((i&1) == 0) {
+ ib1 = new Byte((byte)(i+1));
+ ib2 = new Byte((byte)(i+2));
+ }
+ return (byte)(ib1+ib2);
+ }
+
+ static byte testb2(byte i) {
+ Byte ib1 = i;
+ Byte ib2 = (byte)(i+1);
+ if ((i&1) == 0) {
+ ib1 = (byte)(i+1);
+ ib2 = (byte)(i+2);
+ }
+ return (byte)(ib1 + ib2);
+ }
+
+ static byte testm2(byte i) {
+ Byte ib1 = new Byte(i);
+ Byte ib2 = (byte)(i+1);
+ if ((i&1) == 0) {
+ ib1 = new Byte((byte)(i+1));
+ ib2 = (byte)(i+2);
+ }
+ return (byte)(ib1 + ib2);
+ }
+
+ static byte testp2(byte i, Byte ib1) {
+ Byte ib2 = (byte)(i+1);
+ if ((i&1) == 0) {
+ ib1 = new Byte((byte)(i+1));
+ ib2 = (byte)(i+2);
+ }
+ return (byte)(ib1 + ib2);
+ }
+
+ static byte testc2(byte i) {
+ Byte ib1 = ibc;
+ Byte ib2 = (byte)(i+1);
+ if ((i&1) == 0) {
+ ib1 = (byte)(ibc+1);
+ ib2 = (byte)(i+2);
+ }
+ return (byte)(ib1 + ib2);
+ }
+
+ //===============================================
+ static byte sum(byte[] a) {
+ byte result = 1;
+ for (Byte i : a)
+ result += i;
+ return result;
+ }
+
+ static byte sumb(byte[] a) {
+ Byte result = 1;
+ for (Byte i : a)
+ result = (byte)(result + i);
+ return result;
+ }
+
+ static byte sumc(byte[] a) {
+ Byte result = ibc;
+ for (Byte i : a)
+ result = (byte)(result + i);
+ return result;
+ }
+
+ static byte sumf(byte[] a) {
+ Byte result = foob((byte)1);
+ for (Byte i : a)
+ result = (byte)(result + i);
+ return result;
+ }
+
+ static byte sump(byte[] a, Byte result) {
+ for (Byte i : a)
+ result = (byte)(result + i);
+ return result;
+ }
+
+ static byte sum2(byte[] a) {
+ byte result1 = 1;
+ byte result2 = 1;
+ for (Byte i : a) {
+ result1 += i;
+ result2 += i + 1;
+ }
+ return (byte)(result1 + result2);
+ }
+
+ static byte sumb2(byte[] a) {
+ Byte result1 = 1;
+ Byte result2 = 1;
+ for (Byte i : a) {
+ result1 = (byte)(result1 + i);
+ result2 = (byte)(result2 + i + 1);
+ }
+ return (byte)(result1 + result2);
+ }
+
+ static byte summ2(byte[] a) {
+ Byte result1 = 1;
+ Byte result2 = new Byte((byte)1);
+ for (Byte i : a) {
+ result1 = (byte)(result1 + i);
+ result2 = (byte)(result2 + new Byte((byte)(i + 1)));
+ }
+ return (byte)(result1 + result2);
+ }
+
+ static byte sump2(byte[] a, Byte result2) {
+ Byte result1 = 1;
+ for (Byte i : a) {
+ result1 = (byte)(result1 + i);
+ result2 = (byte)(result2 + i + 1);
+ }
+ return (byte)(result1 + result2);
+ }
+
+ static byte sumc2(byte[] a) {
+ Byte result1 = 1;
+ Byte result2 = ibc;
+ for (Byte i : a) {
+ result1 = (byte)(result1 + i);
+ result2 = (byte)(result2 + i + ibc);
+ }
+ return (byte)(result1 + result2);
+ }
+
+ //===============================================
+ static byte remi_sum() {
+ Byte j = new Byte((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ j = new Byte((byte)(j + 1));
+ }
+ return j;
+ }
+
+ static byte remi_sumb() {
+ Byte j = Byte.valueOf((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ j = (byte)(j + 1);
+ }
+ return j;
+ }
+
+ static byte remi_sumf() {
+ Byte j = foob((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ j = (byte)(j + 1);
+ }
+ return j;
+ }
+
+ static byte remi_sump(Byte j) {
+ for (int i = 0; i< 1000; i++) {
+ j = new Byte((byte)(j + 1));
+ }
+ return j;
+ }
+
+ static byte remi_sumc() {
+ Byte j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ j = (byte)(j + ibc);
+ }
+ return j;
+ }
+
+ static byte remi_sum2() {
+ Byte j1 = new Byte((byte)1);
+ Byte j2 = new Byte((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Byte((byte)(j1 + 1));
+ j2 = new Byte((byte)(j2 + 2));
+ }
+ return (byte)(j1 + j2);
+ }
+
+ static byte remi_sumb2() {
+ Byte j1 = Byte.valueOf((byte)1);
+ Byte j2 = Byte.valueOf((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = (byte)(j1 + 1);
+ j2 = (byte)(j2 + 2);
+ }
+ return (byte)(j1 + j2);
+ }
+
+ static byte remi_summ2() {
+ Byte j1 = new Byte((byte)1);
+ Byte j2 = Byte.valueOf((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Byte((byte)(j1 + 1));
+ j2 = (byte)(j2 + 2);
+ }
+ return (byte)(j1 + j2);
+ }
+
+ static byte remi_sump2(Byte j1) {
+ Byte j2 = Byte.valueOf((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Byte((byte)(j1 + 1));
+ j2 = (byte)(j2 + 2);
+ }
+ return (byte)(j1 + j2);
+ }
+
+ static byte remi_sumc2() {
+ Byte j1 = ibc;
+ Byte j2 = Byte.valueOf((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = (byte)(j1 + ibc);
+ j2 = (byte)(j2 + 2);
+ }
+ return (byte)(j1 + j2);
+ }
+
+
+ //===============================================
+ // Safepointa and debug info for deoptimization
+ static byte simple_deop(byte i) {
+ Byte ib = new Byte(foo(i));
+ dummy();
+ return ib;
+ }
+
+ static byte simpleb_deop(byte i) {
+ Byte ib = Byte.valueOf(foo(i));
+ dummy();
+ return ib;
+ }
+
+ static byte simplef_deop(byte i) {
+ Byte ib = foob(i);
+ dummy();
+ return ib;
+ }
+
+ static byte simplep_deop(Byte ib) {
+ dummy();
+ return ib;
+ }
+
+ static byte simplec_deop(byte i) {
+ Byte ib = ibc;
+ dummy();
+ return ib;
+ }
+
+ static byte test_deop(byte i) {
+ Byte ib = new Byte(foo(i));
+ if ((i&1) == 0)
+ ib = foo((byte)(i+1));
+ dummy();
+ return ib;
+ }
+
+ static byte testb_deop(byte i) {
+ Byte ib = foo(i);
+ if ((i&1) == 0)
+ ib = foo((byte)(i+1));
+ dummy();
+ return ib;
+ }
+
+ static byte testf_deop(byte i) {
+ Byte ib = foob(i);
+ if ((i&1) == 0)
+ ib = foo((byte)(i+1));
+ dummy();
+ return ib;
+ }
+
+ static byte testp_deop(byte i, Byte ib) {
+ if ((i&1) == 0)
+ ib = foo((byte)(i+1));
+ dummy();
+ return ib;
+ }
+
+ static byte testc_deop(byte i) {
+ Byte ib = ibc;
+ if ((i&1) == 0)
+ ib = foo((byte)(i+1));
+ dummy();
+ return ib;
+ }
+
+ static byte sum_deop(byte[] a) {
+ byte result = 1;
+ for (Byte i : a)
+ result += foo(i);
+ dummy();
+ return result;
+ }
+
+ static byte sumb_deop(byte[] a) {
+ Byte result = 1;
+ for (Byte i : a)
+ result = (byte)(result + foo(i));
+ dummy();
+ return result;
+ }
+
+ static byte sumf_deop(byte[] a) {
+ Byte result = 1;
+ for (Byte i : a)
+ result = (byte)(result + foob(i));
+ dummy();
+ return result;
+ }
+
+ static byte sump_deop(byte[] a, Byte result) {
+ for (Byte i : a)
+ result = (byte)(result + foob(i));
+ dummy();
+ return result;
+ }
+
+ static byte sumc_deop(byte[] a) {
+ Byte result = ibc;
+ for (Byte i : a)
+ result = (byte)(result + foo(i));
+ dummy();
+ return result;
+ }
+
+ static byte remi_sum_deop() {
+ Byte j = new Byte(foo((byte)1));
+ for (int i = 0; i< 1000; i++) {
+ j = new Byte(foo((byte)(j + 1)));
+ }
+ dummy();
+ return j;
+ }
+
+ static byte remi_sumb_deop() {
+ Byte j = Byte.valueOf(foo((byte)1));
+ for (int i = 0; i< 1000; i++) {
+ j = foo((byte)(j + 1));
+ }
+ dummy();
+ return j;
+ }
+
+ static byte remi_sumf_deop() {
+ Byte j = foob((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ j = foo((byte)(j + 1));
+ }
+ dummy();
+ return j;
+ }
+
+ static byte remi_sump_deop(Byte j) {
+ for (int i = 0; i< 1000; i++) {
+ j = foo((byte)(j + 1));
+ }
+ dummy();
+ return j;
+ }
+
+ static byte remi_sumc_deop() {
+ Byte j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ j = foo((byte)(j + 1));
+ }
+ dummy();
+ return j;
+ }
+
+ //===============================================
+ // Conditional increment
+ static byte remi_sum_cond() {
+ Byte j = new Byte((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = new Byte((byte)(j + 1));
+ }
+ }
+ return j;
+ }
+
+ static byte remi_sumb_cond() {
+ Byte j = Byte.valueOf((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = (byte)(j + 1);
+ }
+ }
+ return j;
+ }
+
+ static byte remi_sumf_cond() {
+ Byte j = foob((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = (byte)(j + 1);
+ }
+ }
+ return j;
+ }
+
+ static byte remi_sump_cond(Byte j) {
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = (byte)(j + 1);
+ }
+ }
+ return j;
+ }
+
+ static byte remi_sumc_cond() {
+ Byte j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = (byte)(j + ibc);
+ }
+ }
+ return j;
+ }
+
+ static byte remi_sum2_cond() {
+ Byte j1 = new Byte((byte)1);
+ Byte j2 = new Byte((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Byte((byte)(j1 + 1));
+ } else {
+ j2 = new Byte((byte)(j2 + 2));
+ }
+ }
+ return (byte)(j1 + j2);
+ }
+
+ static byte remi_sumb2_cond() {
+ Byte j1 = Byte.valueOf((byte)1);
+ Byte j2 = Byte.valueOf((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = (byte)(j1 + 1);
+ } else {
+ j2 = (byte)(j2 + 2);
+ }
+ }
+ return (byte)(j1 + j2);
+ }
+
+ static byte remi_summ2_cond() {
+ Byte j1 = new Byte((byte)1);
+ Byte j2 = Byte.valueOf((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Byte((byte)(j1 + 1));
+ } else {
+ j2 = (byte)(j2 + 2);
+ }
+ }
+ return (byte)(j1 + j2);
+ }
+
+ static byte remi_sump2_cond(Byte j1) {
+ Byte j2 = Byte.valueOf((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Byte((byte)(j1 + 1));
+ } else {
+ j2 = (byte)(j2 + 2);
+ }
+ }
+ return (byte)(j1 + j2);
+ }
+
+ static byte remi_sumc2_cond() {
+ Byte j1 = ibc;
+ Byte j2 = Byte.valueOf((byte)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = (byte)(j1 + ibc);
+ } else {
+ j2 = (byte)(j2 + 2);
+ }
+ }
+ return (byte)(j1 + j2);
+ }
+
+
+ public static void main(String[] args) {
+ final int ntests = 70;
+
+ String[] test_name = new String[] {
+ "simple", "simpleb", "simplec", "simplef", "simplep",
+ "simple2", "simpleb2", "simplec2", "simplem2", "simplep2",
+ "simple_deop", "simpleb_deop", "simplec_deop", "simplef_deop", "simplep_deop",
+ "test", "testb", "testc", "testm", "testp",
+ "test2", "testb2", "testc2", "testm2", "testp2",
+ "test_deop", "testb_deop", "testc_deop", "testf_deop", "testp_deop",
+ "sum", "sumb", "sumc", "sumf", "sump",
+ "sum2", "sumb2", "sumc2", "summ2", "sump2",
+ "sum_deop", "sumb_deop", "sumc_deop", "sumf_deop", "sump_deop",
+ "remi_sum", "remi_sumb", "remi_sumc", "remi_sumf", "remi_sump",
+ "remi_sum2", "remi_sumb2", "remi_sumc2", "remi_summ2", "remi_sump2",
+ "remi_sum_deop", "remi_sumb_deop", "remi_sumc_deop", "remi_sumf_deop", "remi_sump_deop",
+ "remi_sum_cond", "remi_sumb_cond", "remi_sumc_cond", "remi_sumf_cond", "remi_sump_cond",
+ "remi_sum2_cond", "remi_sumb2_cond", "remi_sumc2_cond", "remi_summ2_cond", "remi_sump2_cond"
+ };
+
+ final int[] val = new int[] {
+ -5488, -5488, 12000, -5488, -5488,
+ 1024, 1024, -5552, 1024, 1024,
+ -5488, -5488, 12000, -5488, -5488,
+ 512, 512, 6256, 512, 512,
+ 13024, 13024, -5584, 13024, 13024,
+ 512, 512, 6256, 512, 512,
+ 45, 45, 45, 45, 45,
+ 66, 66, 66, 66, 66,
+ 45, 45, 45, 45, 45,
+ -23, -23, -23, -23, -23,
+ -70, -70, -70, -70, -70,
+ -23, -23, -23, -23, -23,
+ -11, -11, -11, -11, -11,
+ -34, -34, -34, -34, -34
+ };
+
+ int[] res = new int[ntests];
+ for (int i = 0; i < ntests; i++) {
+ res[i] = 0;
+ }
+
+
+ for (int i = 0; i < 12000; i++) {
+ res[0] += simple((byte)i);
+ res[1] += simpleb((byte)i);
+ res[2] += simplec();
+ res[3] += simplef((byte)i);
+ res[4] += simplep((byte)i);
+
+ res[5] += simple2((byte)i);
+ res[6] += simpleb2((byte)i);
+ res[7] += simplec2((byte)i);
+ res[8] += simplem2((byte)i);
+ res[9] += simplep2((byte)i, (byte)i);
+
+ res[10] += simple_deop((byte)i);
+ res[11] += simpleb_deop((byte)i);
+ res[12] += simplec_deop((byte)i);
+ res[13] += simplef_deop((byte)i);
+ res[14] += simplep_deop((byte)i);
+
+ res[15] += test((byte)i);
+ res[16] += testb((byte)i);
+ res[17] += testc((byte)i);
+ res[18] += testm((byte)i);
+ res[19] += testp((byte)i, (byte)i);
+
+ res[20] += test2((byte)i);
+ res[21] += testb2((byte)i);
+ res[22] += testc2((byte)i);
+ res[23] += testm2((byte)i);
+ res[24] += testp2((byte)i, (byte)i);
+
+ res[25] += test_deop((byte)i);
+ res[26] += testb_deop((byte)i);
+ res[27] += testc_deop((byte)i);
+ res[28] += testf_deop((byte)i);
+ res[29] += testp_deop((byte)i, (byte)i);
+ }
+
+ byte[] ia = new byte[1000];
+ for (int i = 0; i < 1000; i++) {
+ ia[i] = (byte)i;
+ }
+
+ for (int i = 0; i < 100; i++) {
+ res[30] = sum(ia);
+ res[31] = sumb(ia);
+ res[32] = sumc(ia);
+ res[33] = sumf(ia);
+ res[34] = sump(ia, (byte)1);
+
+ res[35] = sum2(ia);
+ res[36] = sumb2(ia);
+ res[37] = sumc2(ia);
+ res[38] = summ2(ia);
+ res[39] = sump2(ia, (byte)1);
+
+ res[40] = sum_deop(ia);
+ res[41] = sumb_deop(ia);
+ res[42] = sumc_deop(ia);
+ res[43] = sumf_deop(ia);
+ res[44] = sump_deop(ia, (byte)1);
+
+ res[45] = remi_sum();
+ res[46] = remi_sumb();
+ res[47] = remi_sumc();
+ res[48] = remi_sumf();
+ res[49] = remi_sump((byte)1);
+
+ res[50] = remi_sum2();
+ res[51] = remi_sumb2();
+ res[52] = remi_sumc2();
+ res[53] = remi_summ2();
+ res[54] = remi_sump2((byte)1);
+
+ res[55] = remi_sum_deop();
+ res[56] = remi_sumb_deop();
+ res[57] = remi_sumc_deop();
+ res[58] = remi_sumf_deop();
+ res[59] = remi_sump_deop((byte)1);
+
+ res[60] = remi_sum_cond();
+ res[61] = remi_sumb_cond();
+ res[62] = remi_sumc_cond();
+ res[63] = remi_sumf_cond();
+ res[64] = remi_sump_cond((byte)1);
+
+ res[65] = remi_sum2_cond();
+ res[66] = remi_sumb2_cond();
+ res[67] = remi_sumc2_cond();
+ res[68] = remi_summ2_cond();
+ res[69] = remi_sump2_cond((byte)1);
+ }
+
+ int failed = 0;
+ for (int i = 0; i < ntests; i++) {
+ if (res[i] != val[i]) {
+ System.err.println(test_name[i] + ": " + res[i] + " != " + val[i]);
+ failed++;
+ }
+ }
+ if (failed > 0) {
+ System.err.println("Failed " + failed + " tests.");
+ throw new InternalError();
+ } else {
+ System.out.println("Passed.");
+ }
+ }
+}
diff --git a/hotspot/test/compiler/6934604/TestDoubleBoxing.java b/hotspot/test/compiler/6934604/TestDoubleBoxing.java
new file mode 100644
index 00000000000..7b76ac95655
--- /dev/null
+++ b/hotspot/test/compiler/6934604/TestDoubleBoxing.java
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6934604
+ * @summary enable parts of EliminateAutoBox by default
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox TestDoubleBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestDoubleBoxing.dummy -XX:CompileCommand=exclude,TestDoubleBoxing.foo -XX:CompileCommand=exclude,TestDoubleBoxing.foob TestDoubleBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestDoubleBoxing.dummy -XX:CompileCommand=exclude,TestDoubleBoxing.foo -XX:CompileCommand=exclude,TestDoubleBoxing.foob TestDoubleBoxing
+ *
+ */
+
+public class TestDoubleBoxing {
+
+ static final Double ibc = new Double(1.);
+
+ //===============================================
+ // Non-inlined methods to test deoptimization info
+ static void dummy() { }
+ static double foo(double i) { return i; }
+ static Double foob(double i) { return Double.valueOf(i); }
+
+
+ static double simple(double i) {
+ Double ib = new Double(i);
+ return ib;
+ }
+
+ static double simpleb(double i) {
+ Double ib = Double.valueOf(i);
+ return ib;
+ }
+
+ static double simplec() {
+ Double ib = ibc;
+ return ib;
+ }
+
+ static double simplef(double i) {
+ Double ib = foob(i);
+ return ib;
+ }
+
+ static double simplep(Double ib) {
+ return ib;
+ }
+
+ static double simple2(double i) {
+ Double ib1 = new Double(i);
+ Double ib2 = new Double(i+1.);
+ return ib1 + ib2;
+ }
+
+ static double simpleb2(double i) {
+ Double ib1 = Double.valueOf(i);
+ Double ib2 = Double.valueOf(i+1.);
+ return ib1 + ib2;
+ }
+
+ static double simplem2(double i) {
+ Double ib1 = new Double(i);
+ Double ib2 = Double.valueOf(i+1.);
+ return ib1 + ib2;
+ }
+
+ static double simplep2(double i, Double ib1) {
+ Double ib2 = Double.valueOf(i+1.);
+ return ib1 + ib2;
+ }
+
+ static double simplec2(double i) {
+ Double ib1 = ibc;
+ Double ib2 = Double.valueOf(i+1.);
+ return ib1 + ib2;
+ }
+
+ //===============================================
+ static double test(double f, int i) {
+ Double ib = new Double(f);
+ if ((i&1) == 0)
+ ib = f+1.;
+ return ib;
+ }
+
+ static double testb(double f, int i) {
+ Double ib = f;
+ if ((i&1) == 0)
+ ib = (f+1.);
+ return ib;
+ }
+
+ static double testm(double f, int i) {
+ Double ib = f;
+ if ((i&1) == 0)
+ ib = new Double(f+1.);
+ return ib;
+ }
+
+ static double testp(double f, int i, Double ib) {
+ if ((i&1) == 0)
+ ib = new Double(f+1.);
+ return ib;
+ }
+
+ static double testc(double f, int i) {
+ Double ib = ibc;
+ if ((i&1) == 0)
+ ib = new Double(f+1.);
+ return ib;
+ }
+
+ static double test2(double f, int i) {
+ Double ib1 = new Double(f);
+ Double ib2 = new Double(f+1.);
+ if ((i&1) == 0) {
+ ib1 = new Double(f+1.);
+ ib2 = new Double(f+2.);
+ }
+ return ib1+ib2;
+ }
+
+ static double testb2(double f, int i) {
+ Double ib1 = f;
+ Double ib2 = f+1.;
+ if ((i&1) == 0) {
+ ib1 = (f+1.);
+ ib2 = (f+2.);
+ }
+ return ib1+ib2;
+ }
+
+ static double testm2(double f, int i) {
+ Double ib1 = new Double(f);
+ Double ib2 = f+1.;
+ if ((i&1) == 0) {
+ ib1 = new Double(f+1.);
+ ib2 = (f+2.);
+ }
+ return ib1+ib2;
+ }
+
+ static double testp2(double f, int i, Double ib1) {
+ Double ib2 = f+1.;
+ if ((i&1) == 0) {
+ ib1 = new Double(f+1.);
+ ib2 = (f+2.);
+ }
+ return ib1+ib2;
+ }
+
+ static double testc2(double f, int i) {
+ Double ib1 = ibc;
+ Double ib2 = f+1.;
+ if ((i&1) == 0) {
+ ib1 = (ibc+1.);
+ ib2 = (f+2.);
+ }
+ return ib1+ib2;
+ }
+
+ //===============================================
+ static double sum(double[] a) {
+ double result = 1.;
+ for (Double i : a)
+ result += i;
+ return result;
+ }
+
+ static double sumb(double[] a) {
+ Double result = 1.;
+ for (Double i : a)
+ result += i;
+ return result;
+ }
+
+ static double sumc(double[] a) {
+ Double result = ibc;
+ for (Double i : a)
+ result += i;
+ return result;
+ }
+
+ static double sumf(double[] a) {
+ Double result = foob(1.);
+ for (Double i : a)
+ result += i;
+ return result;
+ }
+
+ static double sump(double[] a, Double result) {
+ for (Double i : a)
+ result += i;
+ return result;
+ }
+
+ static double sum2(double[] a) {
+ double result1 = 1.;
+ double result2 = 1.;
+ for (Double i : a) {
+ result1 += i;
+ result2 += i + 1.;
+ }
+ return result1 + result2;
+ }
+
+ static double sumb2(double[] a) {
+ Double result1 = 1.;
+ Double result2 = 1.;
+ for (Double i : a) {
+ result1 += i;
+ result2 += i + 1.;
+ }
+ return result1 + result2;
+ }
+
+ static double summ2(double[] a) {
+ Double result1 = 1.;
+ Double result2 = new Double(1.);
+ for (Double i : a) {
+ result1 += i;
+ result2 += new Double(i + 1.);
+ }
+ return result1 + result2;
+ }
+
+ static double sump2(double[] a, Double result2) {
+ Double result1 = 1.;
+ for (Double i : a) {
+ result1 += i;
+ result2 += i + 1.;
+ }
+ return result1 + result2;
+ }
+
+ static double sumc2(double[] a) {
+ Double result1 = 1.;
+ Double result2 = ibc;
+ for (Double i : a) {
+ result1 += i;
+ result2 += i + ibc;
+ }
+ return result1 + result2;
+ }
+
+ //===============================================
+ static double remi_sum() {
+ Double j = new Double(1.);
+ for (int i = 0; i< 1000; i++) {
+ j = new Double(j + 1.);
+ }
+ return j;
+ }
+
+ static double remi_sumb() {
+ Double j = Double.valueOf(1.);
+ for (int i = 0; i< 1000; i++) {
+ j = j + 1.;
+ }
+ return j;
+ }
+
+ static double remi_sumf() {
+ Double j = foob(1.);
+ for (int i = 0; i< 1000; i++) {
+ j = j + 1.;
+ }
+ return j;
+ }
+
+ static double remi_sump(Double j) {
+ for (int i = 0; i< 1000; i++) {
+ j = new Double(j + 1.);
+ }
+ return j;
+ }
+
+ static double remi_sumc() {
+ Double j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ j = j + ibc;
+ }
+ return j;
+ }
+
+ static double remi_sum2() {
+ Double j1 = new Double(1.);
+ Double j2 = new Double(1.);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Double(j1 + 1.);
+ j2 = new Double(j2 + 2.);
+ }
+ return j1 + j2;
+ }
+
+ static double remi_sumb2() {
+ Double j1 = Double.valueOf(1.);
+ Double j2 = Double.valueOf(1.);
+ for (int i = 0; i< 1000; i++) {
+ j1 = j1 + 1.;
+ j2 = j2 + 2.;
+ }
+ return j1 + j2;
+ }
+
+ static double remi_summ2() {
+ Double j1 = new Double(1.);
+ Double j2 = Double.valueOf(1.);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Double(j1 + 1.);
+ j2 = j2 + 2.;
+ }
+ return j1 + j2;
+ }
+
+ static double remi_sump2(Double j1) {
+ Double j2 = Double.valueOf(1.);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Double(j1 + 1.);
+ j2 = j2 + 2.;
+ }
+ return j1 + j2;
+ }
+
+ static double remi_sumc2() {
+ Double j1 = ibc;
+ Double j2 = Double.valueOf(1.);
+ for (int i = 0; i< 1000; i++) {
+ j1 = j1 + ibc;
+ j2 = j2 + 2.;
+ }
+ return j1 + j2;
+ }
+
+
+ //===============================================
+ // Safepointa and debug info for deoptimization
+ static double simple_deop(double i) {
+ Double ib = new Double(foo(i));
+ dummy();
+ return ib;
+ }
+
+ static double simpleb_deop(double i) {
+ Double ib = Double.valueOf(foo(i));
+ dummy();
+ return ib;
+ }
+
+ static double simplef_deop(double i) {
+ Double ib = foob(i);
+ dummy();
+ return ib;
+ }
+
+ static double simplep_deop(Double ib) {
+ dummy();
+ return ib;
+ }
+
+ static double simplec_deop(double i) {
+ Double ib = ibc;
+ dummy();
+ return ib;
+ }
+
+ static double test_deop(double f, int i) {
+ Double ib = new Double(foo(f));
+ if ((i&1) == 0)
+ ib = foo(f+1.);
+ dummy();
+ return ib;
+ }
+
+ static double testb_deop(double f, int i) {
+ Double ib = foo(f);
+ if ((i&1) == 0)
+ ib = foo(f+1.);
+ dummy();
+ return ib;
+ }
+
+ static double testf_deop(double f, int i) {
+ Double ib = foob(f);
+ if ((i&1) == 0)
+ ib = foo(f+1.);
+ dummy();
+ return ib;
+ }
+
+ static double testp_deop(double f, int i, Double ib) {
+ if ((i&1) == 0)
+ ib = foo(f+1.);
+ dummy();
+ return ib;
+ }
+
+ static double testc_deop(double f, int i) {
+ Double ib = ibc;
+ if ((i&1) == 0)
+ ib = foo(f+1.);
+ dummy();
+ return ib;
+ }
+
+ static double sum_deop(double[] a) {
+ double result = 1.;
+ for (Double i : a)
+ result += foo(i);
+ dummy();
+ return result;
+ }
+
+ static double sumb_deop(double[] a) {
+ Double result = 1.;
+ for (Double i : a)
+ result += foo(i);
+ dummy();
+ return result;
+ }
+
+ static double sumf_deop(double[] a) {
+ Double result = 1.;
+ for (Double i : a)
+ result += foob(i);
+ dummy();
+ return result;
+ }
+
+ static double sump_deop(double[] a, Double result) {
+ for (Double i : a)
+ result += foob(i);
+ dummy();
+ return result;
+ }
+
+ static double sumc_deop(double[] a) {
+ Double result = ibc;
+ for (Double i : a)
+ result += foo(i);
+ dummy();
+ return result;
+ }
+
+ static double remi_sum_deop() {
+ Double j = new Double(foo(1.));
+ for (int i = 0; i< 1000; i++) {
+ j = new Double(foo(j + 1.));
+ }
+ dummy();
+ return j;
+ }
+
+ static double remi_sumb_deop() {
+ Double j = Double.valueOf(foo(1.));
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1.);
+ }
+ dummy();
+ return j;
+ }
+
+ static double remi_sumf_deop() {
+ Double j = foob(1.);
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1.);
+ }
+ dummy();
+ return j;
+ }
+
+ static double remi_sump_deop(Double j) {
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1.);
+ }
+ dummy();
+ return j;
+ }
+
+ static double remi_sumc_deop() {
+ Double j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1.);
+ }
+ dummy();
+ return j;
+ }
+
+ //===============================================
+ // Conditional increment
+ static double remi_sum_cond() {
+ Double j = new Double(1.);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = new Double(j + 1.);
+ }
+ }
+ return j;
+ }
+
+ static double remi_sumb_cond() {
+ Double j = Double.valueOf(1.);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + 1.;
+ }
+ }
+ return j;
+ }
+
+ static double remi_sumf_cond() {
+ Double j = foob(1.);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + 1.;
+ }
+ }
+ return j;
+ }
+
+ static double remi_sump_cond(Double j) {
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + 1.;
+ }
+ }
+ return j;
+ }
+
+ static double remi_sumc_cond() {
+ Double j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + ibc;
+ }
+ }
+ return j;
+ }
+
+ static double remi_sum2_cond() {
+ Double j1 = new Double(1.);
+ Double j2 = new Double(1.);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Double(j1 + 1.);
+ } else {
+ j2 = new Double(j2 + 2.);
+ }
+ }
+ return j1 + j2;
+ }
+
+ static double remi_sumb2_cond() {
+ Double j1 = Double.valueOf(1.);
+ Double j2 = Double.valueOf(1.);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = j1 + 1.;
+ } else {
+ j2 = j2 + 2.;
+ }
+ }
+ return j1 + j2;
+ }
+
+ static double remi_summ2_cond() {
+ Double j1 = new Double(1.);
+ Double j2 = Double.valueOf(1.);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Double(j1 + 1.);
+ } else {
+ j2 = j2 + 2.;
+ }
+ }
+ return j1 + j2;
+ }
+
+ static double remi_sump2_cond(Double j1) {
+ Double j2 = Double.valueOf(1.);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Double(j1 + 1.);
+ } else {
+ j2 = j2 + 2.;
+ }
+ }
+ return j1 + j2;
+ }
+
+ static double remi_sumc2_cond() {
+ Double j1 = ibc;
+ Double j2 = Double.valueOf(1.);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = j1 + ibc;
+ } else {
+ j2 = j2 + 2;
+ }
+ }
+ return j1 + j2;
+ }
+
+
+ public static void main(String[] args) {
+ final int ntests = 70;
+
+ String[] test_name = new String[] {
+ "simple", "simpleb", "simplec", "simplef", "simplep",
+ "simple2", "simpleb2", "simplec2", "simplem2", "simplep2",
+ "simple_deop", "simpleb_deop", "simplec_deop", "simplef_deop", "simplep_deop",
+ "test", "testb", "testc", "testm", "testp",
+ "test2", "testb2", "testc2", "testm2", "testp2",
+ "test_deop", "testb_deop", "testc_deop", "testf_deop", "testp_deop",
+ "sum", "sumb", "sumc", "sumf", "sump",
+ "sum2", "sumb2", "sumc2", "summ2", "sump2",
+ "sum_deop", "sumb_deop", "sumc_deop", "sumf_deop", "sump_deop",
+ "remi_sum", "remi_sumb", "remi_sumc", "remi_sumf", "remi_sump",
+ "remi_sum2", "remi_sumb2", "remi_sumc2", "remi_summ2", "remi_sump2",
+ "remi_sum_deop", "remi_sumb_deop", "remi_sumc_deop", "remi_sumf_deop", "remi_sump_deop",
+ "remi_sum_cond", "remi_sumb_cond", "remi_sumc_cond", "remi_sumf_cond", "remi_sump_cond",
+ "remi_sum2_cond", "remi_sumb2_cond", "remi_sumc2_cond", "remi_summ2_cond", "remi_sump2_cond"
+ };
+
+ final double[] val = new double[] {
+ 71994000., 71994000., 12000., 71994000., 71994000.,
+ 144000000., 144000000., 72018000., 144000000., 144000000.,
+ 71994000., 71994000., 12000., 71994000., 71994000.,
+ 72000000., 72000000., 36006000., 72000000., 72000000.,
+ 144012000., 144012000., 72030000., 144012000., 144012000.,
+ 72000000., 72000000., 36006000., 72000000., 72000000.,
+ 499501., 499501., 499501., 499501., 499501.,
+ 1000002., 1000002., 1000002., 1000002., 1000002.,
+ 499501., 499501., 499501., 499501., 499501.,
+ 1001., 1001., 1001., 1001., 1001.,
+ 3002., 3002., 3002., 3002., 3002.,
+ 1001., 1001., 1001., 1001., 1001.,
+ 501., 501., 501., 501., 501.,
+ 1502., 1502., 1502., 1502., 1502.
+ };
+
+ double[] res = new double[ntests];
+ for (int i = 0; i < ntests; i++) {
+ res[i] = 0.;
+ }
+
+
+ for (int i = 0; i < 12000; i++) {
+ res[0] += simple(i);
+ res[1] += simpleb(i);
+ res[2] += simplec();
+ res[3] += simplef(i);
+ res[4] += simplep((double)i);
+
+ res[5] += simple2((double)i);
+ res[6] += simpleb2((double)i);
+ res[7] += simplec2((double)i);
+ res[8] += simplem2((double)i);
+ res[9] += simplep2((double)i, (double)i);
+
+ res[10] += simple_deop((double)i);
+ res[11] += simpleb_deop((double)i);
+ res[12] += simplec_deop((double)i);
+ res[13] += simplef_deop((double)i);
+ res[14] += simplep_deop((double)i);
+
+ res[15] += test((double)i, i);
+ res[16] += testb((double)i, i);
+ res[17] += testc((double)i, i);
+ res[18] += testm((double)i, i);
+ res[19] += testp((double)i, i, (double)i);
+
+ res[20] += test2((double)i, i);
+ res[21] += testb2((double)i, i);
+ res[22] += testc2((double)i, i);
+ res[23] += testm2((double)i, i);
+ res[24] += testp2((double)i, i, (double)i);
+
+ res[25] += test_deop((double)i, i);
+ res[26] += testb_deop((double)i, i);
+ res[27] += testc_deop((double)i, i);
+ res[28] += testf_deop((double)i, i);
+ res[29] += testp_deop((double)i, i, (double)i);
+ }
+
+ double[] ia = new double[1000];
+ for (int i = 0; i < 1000; i++) {
+ ia[i] = i;
+ }
+
+ for (int i = 0; i < 100; i++) {
+ res[30] = sum(ia);
+ res[31] = sumb(ia);
+ res[32] = sumc(ia);
+ res[33] = sumf(ia);
+ res[34] = sump(ia, 1.);
+
+ res[35] = sum2(ia);
+ res[36] = sumb2(ia);
+ res[37] = sumc2(ia);
+ res[38] = summ2(ia);
+ res[39] = sump2(ia, 1.);
+
+ res[40] = sum_deop(ia);
+ res[41] = sumb_deop(ia);
+ res[42] = sumc_deop(ia);
+ res[43] = sumf_deop(ia);
+ res[44] = sump_deop(ia, 1.);
+
+ res[45] = remi_sum();
+ res[46] = remi_sumb();
+ res[47] = remi_sumc();
+ res[48] = remi_sumf();
+ res[49] = remi_sump(1.);
+
+ res[50] = remi_sum2();
+ res[51] = remi_sumb2();
+ res[52] = remi_sumc2();
+ res[53] = remi_summ2();
+ res[54] = remi_sump2(1.);
+
+ res[55] = remi_sum_deop();
+ res[56] = remi_sumb_deop();
+ res[57] = remi_sumc_deop();
+ res[58] = remi_sumf_deop();
+ res[59] = remi_sump_deop(1.);
+
+ res[60] = remi_sum_cond();
+ res[61] = remi_sumb_cond();
+ res[62] = remi_sumc_cond();
+ res[63] = remi_sumf_cond();
+ res[64] = remi_sump_cond(1.);
+
+ res[65] = remi_sum2_cond();
+ res[66] = remi_sumb2_cond();
+ res[67] = remi_sumc2_cond();
+ res[68] = remi_summ2_cond();
+ res[69] = remi_sump2_cond(1.);
+ }
+
+ int failed = 0;
+ for (int i = 0; i < ntests; i++) {
+ if (res[i] != val[i]) {
+ System.err.println(test_name[i] + ": " + res[i] + " != " + val[i]);
+ failed++;
+ }
+ }
+ if (failed > 0) {
+ System.err.println("Failed " + failed + " tests.");
+ throw new InternalError();
+ } else {
+ System.out.println("Passed.");
+ }
+ }
+}
diff --git a/hotspot/test/compiler/6934604/TestFloatBoxing.java b/hotspot/test/compiler/6934604/TestFloatBoxing.java
new file mode 100644
index 00000000000..45716730109
--- /dev/null
+++ b/hotspot/test/compiler/6934604/TestFloatBoxing.java
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6934604
+ * @summary enable parts of EliminateAutoBox by default
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox TestFloatBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestFloatBoxing.dummy -XX:CompileCommand=exclude,TestFloatBoxing.foo -XX:CompileCommand=exclude,TestFloatBoxing.foob TestFloatBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestFloatBoxing.dummy -XX:CompileCommand=exclude,TestFloatBoxing.foo -XX:CompileCommand=exclude,TestFloatBoxing.foob TestFloatBoxing
+ *
+ */
+
+public class TestFloatBoxing {
+
+ static final Float ibc = new Float(1.f);
+
+ //===============================================
+ // Non-inlined methods to test deoptimization info
+ static void dummy() { }
+ static float foo(float i) { return i; }
+ static Float foob(float i) { return Float.valueOf(i); }
+
+
+ static float simple(float i) {
+ Float ib = new Float(i);
+ return ib;
+ }
+
+ static float simpleb(float i) {
+ Float ib = Float.valueOf(i);
+ return ib;
+ }
+
+ static float simplec() {
+ Float ib = ibc;
+ return ib;
+ }
+
+ static float simplef(float i) {
+ Float ib = foob(i);
+ return ib;
+ }
+
+ static float simplep(Float ib) {
+ return ib;
+ }
+
+ static float simple2(float i) {
+ Float ib1 = new Float(i);
+ Float ib2 = new Float(i+1.f);
+ return ib1 + ib2;
+ }
+
+ static float simpleb2(float i) {
+ Float ib1 = Float.valueOf(i);
+ Float ib2 = Float.valueOf(i+1.f);
+ return ib1 + ib2;
+ }
+
+ static float simplem2(float i) {
+ Float ib1 = new Float(i);
+ Float ib2 = Float.valueOf(i+1.f);
+ return ib1 + ib2;
+ }
+
+ static float simplep2(float i, Float ib1) {
+ Float ib2 = Float.valueOf(i+1.f);
+ return ib1 + ib2;
+ }
+
+ static float simplec2(float i) {
+ Float ib1 = ibc;
+ Float ib2 = Float.valueOf(i+1.f);
+ return ib1 + ib2;
+ }
+
+ //===============================================
+ static float test(float f, int i) {
+ Float ib = new Float(f);
+ if ((i&1) == 0)
+ ib = f+1.f;
+ return ib;
+ }
+
+ static float testb(float f, int i) {
+ Float ib = f;
+ if ((i&1) == 0)
+ ib = (f+1.f);
+ return ib;
+ }
+
+ static float testm(float f, int i) {
+ Float ib = f;
+ if ((i&1) == 0)
+ ib = new Float(f+1.f);
+ return ib;
+ }
+
+ static float testp(float f, int i, Float ib) {
+ if ((i&1) == 0)
+ ib = new Float(f+1.f);
+ return ib;
+ }
+
+ static float testc(float f, int i) {
+ Float ib = ibc;
+ if ((i&1) == 0)
+ ib = new Float(f+1.f);
+ return ib;
+ }
+
+ static float test2(float f, int i) {
+ Float ib1 = new Float(f);
+ Float ib2 = new Float(f+1.f);
+ if ((i&1) == 0) {
+ ib1 = new Float(f+1.f);
+ ib2 = new Float(f+2.f);
+ }
+ return ib1+ib2;
+ }
+
+ static float testb2(float f, int i) {
+ Float ib1 = f;
+ Float ib2 = f+1.f;
+ if ((i&1) == 0) {
+ ib1 = (f+1.f);
+ ib2 = (f+2.f);
+ }
+ return ib1+ib2;
+ }
+
+ static float testm2(float f, int i) {
+ Float ib1 = new Float(f);
+ Float ib2 = f+1.f;
+ if ((i&1) == 0) {
+ ib1 = new Float(f+1.f);
+ ib2 = (f+2.f);
+ }
+ return ib1+ib2;
+ }
+
+ static float testp2(float f, int i, Float ib1) {
+ Float ib2 = f+1.f;
+ if ((i&1) == 0) {
+ ib1 = new Float(f+1.f);
+ ib2 = (f+2.f);
+ }
+ return ib1+ib2;
+ }
+
+ static float testc2(float f, int i) {
+ Float ib1 = ibc;
+ Float ib2 = f+1.f;
+ if ((i&1) == 0) {
+ ib1 = (ibc+1.f);
+ ib2 = (f+2.f);
+ }
+ return ib1+ib2;
+ }
+
+ //===============================================
+ static float sum(float[] a) {
+ float result = 1.f;
+ for (Float i : a)
+ result += i;
+ return result;
+ }
+
+ static float sumb(float[] a) {
+ Float result = 1.f;
+ for (Float i : a)
+ result += i;
+ return result;
+ }
+
+ static float sumc(float[] a) {
+ Float result = ibc;
+ for (Float i : a)
+ result += i;
+ return result;
+ }
+
+ static float sumf(float[] a) {
+ Float result = foob(1.f);
+ for (Float i : a)
+ result += i;
+ return result;
+ }
+
+ static float sump(float[] a, Float result) {
+ for (Float i : a)
+ result += i;
+ return result;
+ }
+
+ static float sum2(float[] a) {
+ float result1 = 1.f;
+ float result2 = 1.f;
+ for (Float i : a) {
+ result1 += i;
+ result2 += i + 1.f;
+ }
+ return result1 + result2;
+ }
+
+ static float sumb2(float[] a) {
+ Float result1 = 1.f;
+ Float result2 = 1.f;
+ for (Float i : a) {
+ result1 += i;
+ result2 += i + 1.f;
+ }
+ return result1 + result2;
+ }
+
+ static float summ2(float[] a) {
+ Float result1 = 1.f;
+ Float result2 = new Float(1.f);
+ for (Float i : a) {
+ result1 += i;
+ result2 += new Float(i + 1.f);
+ }
+ return result1 + result2;
+ }
+
+ static float sump2(float[] a, Float result2) {
+ Float result1 = 1.f;
+ for (Float i : a) {
+ result1 += i;
+ result2 += i + 1.f;
+ }
+ return result1 + result2;
+ }
+
+ static float sumc2(float[] a) {
+ Float result1 = 1.f;
+ Float result2 = ibc;
+ for (Float i : a) {
+ result1 += i;
+ result2 += i + ibc;
+ }
+ return result1 + result2;
+ }
+
+ //===============================================
+ static float remi_sum() {
+ Float j = new Float(1.f);
+ for (int i = 0; i< 1000; i++) {
+ j = new Float(j + 1.f);
+ }
+ return j;
+ }
+
+ static float remi_sumb() {
+ Float j = Float.valueOf(1.f);
+ for (int i = 0; i< 1000; i++) {
+ j = j + 1.f;
+ }
+ return j;
+ }
+
+ static float remi_sumf() {
+ Float j = foob(1.f);
+ for (int i = 0; i< 1000; i++) {
+ j = j + 1.f;
+ }
+ return j;
+ }
+
+ static float remi_sump(Float j) {
+ for (int i = 0; i< 1000; i++) {
+ j = new Float(j + 1.f);
+ }
+ return j;
+ }
+
+ static float remi_sumc() {
+ Float j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ j = j + ibc;
+ }
+ return j;
+ }
+
+ static float remi_sum2() {
+ Float j1 = new Float(1.f);
+ Float j2 = new Float(1.f);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Float(j1 + 1.f);
+ j2 = new Float(j2 + 2.f);
+ }
+ return j1 + j2;
+ }
+
+ static float remi_sumb2() {
+ Float j1 = Float.valueOf(1.f);
+ Float j2 = Float.valueOf(1.f);
+ for (int i = 0; i< 1000; i++) {
+ j1 = j1 + 1.f;
+ j2 = j2 + 2.f;
+ }
+ return j1 + j2;
+ }
+
+ static float remi_summ2() {
+ Float j1 = new Float(1.f);
+ Float j2 = Float.valueOf(1.f);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Float(j1 + 1.f);
+ j2 = j2 + 2.f;
+ }
+ return j1 + j2;
+ }
+
+ static float remi_sump2(Float j1) {
+ Float j2 = Float.valueOf(1.f);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Float(j1 + 1.f);
+ j2 = j2 + 2.f;
+ }
+ return j1 + j2;
+ }
+
+ static float remi_sumc2() {
+ Float j1 = ibc;
+ Float j2 = Float.valueOf(1.f);
+ for (int i = 0; i< 1000; i++) {
+ j1 = j1 + ibc;
+ j2 = j2 + 2.f;
+ }
+ return j1 + j2;
+ }
+
+
+ //===============================================
+ // Safepointa and debug info for deoptimization
+ static float simple_deop(float i) {
+ Float ib = new Float(foo(i));
+ dummy();
+ return ib;
+ }
+
+ static float simpleb_deop(float i) {
+ Float ib = Float.valueOf(foo(i));
+ dummy();
+ return ib;
+ }
+
+ static float simplef_deop(float i) {
+ Float ib = foob(i);
+ dummy();
+ return ib;
+ }
+
+ static float simplep_deop(Float ib) {
+ dummy();
+ return ib;
+ }
+
+ static float simplec_deop(float i) {
+ Float ib = ibc;
+ dummy();
+ return ib;
+ }
+
+ static float test_deop(float f, int i) {
+ Float ib = new Float(foo(f));
+ if ((i&1) == 0)
+ ib = foo(f+1.f);
+ dummy();
+ return ib;
+ }
+
+ static float testb_deop(float f, int i) {
+ Float ib = foo(f);
+ if ((i&1) == 0)
+ ib = foo(f+1.f);
+ dummy();
+ return ib;
+ }
+
+ static float testf_deop(float f, int i) {
+ Float ib = foob(f);
+ if ((i&1) == 0)
+ ib = foo(f+1.f);
+ dummy();
+ return ib;
+ }
+
+ static float testp_deop(float f, int i, Float ib) {
+ if ((i&1) == 0)
+ ib = foo(f+1.f);
+ dummy();
+ return ib;
+ }
+
+ static float testc_deop(float f, int i) {
+ Float ib = ibc;
+ if ((i&1) == 0)
+ ib = foo(f+1.f);
+ dummy();
+ return ib;
+ }
+
+ static float sum_deop(float[] a) {
+ float result = 1.f;
+ for (Float i : a)
+ result += foo(i);
+ dummy();
+ return result;
+ }
+
+ static float sumb_deop(float[] a) {
+ Float result = 1.f;
+ for (Float i : a)
+ result += foo(i);
+ dummy();
+ return result;
+ }
+
+ static float sumf_deop(float[] a) {
+ Float result = 1.f;
+ for (Float i : a)
+ result += foob(i);
+ dummy();
+ return result;
+ }
+
+ static float sump_deop(float[] a, Float result) {
+ for (Float i : a)
+ result += foob(i);
+ dummy();
+ return result;
+ }
+
+ static float sumc_deop(float[] a) {
+ Float result = ibc;
+ for (Float i : a)
+ result += foo(i);
+ dummy();
+ return result;
+ }
+
+ static float remi_sum_deop() {
+ Float j = new Float(foo(1.f));
+ for (int i = 0; i< 1000; i++) {
+ j = new Float(foo(j + 1.f));
+ }
+ dummy();
+ return j;
+ }
+
+ static float remi_sumb_deop() {
+ Float j = Float.valueOf(foo(1.f));
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1.f);
+ }
+ dummy();
+ return j;
+ }
+
+ static float remi_sumf_deop() {
+ Float j = foob(1.f);
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1.f);
+ }
+ dummy();
+ return j;
+ }
+
+ static float remi_sump_deop(Float j) {
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1.f);
+ }
+ dummy();
+ return j;
+ }
+
+ static float remi_sumc_deop() {
+ Float j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1.f);
+ }
+ dummy();
+ return j;
+ }
+
+ //===============================================
+ // Conditional increment
+ static float remi_sum_cond() {
+ Float j = new Float(1.f);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = new Float(j + 1.f);
+ }
+ }
+ return j;
+ }
+
+ static float remi_sumb_cond() {
+ Float j = Float.valueOf(1.f);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + 1.f;
+ }
+ }
+ return j;
+ }
+
+ static float remi_sumf_cond() {
+ Float j = foob(1.f);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + 1.f;
+ }
+ }
+ return j;
+ }
+
+ static float remi_sump_cond(Float j) {
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + 1.f;
+ }
+ }
+ return j;
+ }
+
+ static float remi_sumc_cond() {
+ Float j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + ibc;
+ }
+ }
+ return j;
+ }
+
+ static float remi_sum2_cond() {
+ Float j1 = new Float(1.f);
+ Float j2 = new Float(1.f);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Float(j1 + 1.f);
+ } else {
+ j2 = new Float(j2 + 2.f);
+ }
+ }
+ return j1 + j2;
+ }
+
+ static float remi_sumb2_cond() {
+ Float j1 = Float.valueOf(1.f);
+ Float j2 = Float.valueOf(1.f);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = j1 + 1.f;
+ } else {
+ j2 = j2 + 2.f;
+ }
+ }
+ return j1 + j2;
+ }
+
+ static float remi_summ2_cond() {
+ Float j1 = new Float(1.f);
+ Float j2 = Float.valueOf(1.f);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Float(j1 + 1.f);
+ } else {
+ j2 = j2 + 2.f;
+ }
+ }
+ return j1 + j2;
+ }
+
+ static float remi_sump2_cond(Float j1) {
+ Float j2 = Float.valueOf(1.f);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Float(j1 + 1.f);
+ } else {
+ j2 = j2 + 2.f;
+ }
+ }
+ return j1 + j2;
+ }
+
+ static float remi_sumc2_cond() {
+ Float j1 = ibc;
+ Float j2 = Float.valueOf(1.f);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = j1 + ibc;
+ } else {
+ j2 = j2 + 2;
+ }
+ }
+ return j1 + j2;
+ }
+
+
+ public static void main(String[] args) {
+ final int ntests = 70;
+
+ String[] test_name = new String[] {
+ "simple", "simpleb", "simplec", "simplef", "simplep",
+ "simple2", "simpleb2", "simplec2", "simplem2", "simplep2",
+ "simple_deop", "simpleb_deop", "simplec_deop", "simplef_deop", "simplep_deop",
+ "test", "testb", "testc", "testm", "testp",
+ "test2", "testb2", "testc2", "testm2", "testp2",
+ "test_deop", "testb_deop", "testc_deop", "testf_deop", "testp_deop",
+ "sum", "sumb", "sumc", "sumf", "sump",
+ "sum2", "sumb2", "sumc2", "summ2", "sump2",
+ "sum_deop", "sumb_deop", "sumc_deop", "sumf_deop", "sump_deop",
+ "remi_sum", "remi_sumb", "remi_sumc", "remi_sumf", "remi_sump",
+ "remi_sum2", "remi_sumb2", "remi_sumc2", "remi_summ2", "remi_sump2",
+ "remi_sum_deop", "remi_sumb_deop", "remi_sumc_deop", "remi_sumf_deop", "remi_sump_deop",
+ "remi_sum_cond", "remi_sumb_cond", "remi_sumc_cond", "remi_sumf_cond", "remi_sump_cond",
+ "remi_sum2_cond", "remi_sumb2_cond", "remi_sumc2_cond", "remi_summ2_cond", "remi_sump2_cond"
+ };
+
+ final float[] val = new float[] {
+ 71990896.f, 71990896.f, 12000.f, 71990896.f, 71990896.f,
+ 144000000.f, 144000000.f, 72014896.f, 144000000.f, 144000000.f,
+ 71990896.f, 71990896.f, 12000.f, 71990896.f, 71990896.f,
+ 72000000.f, 72000000.f, 36004096.f, 72000000.f, 72000000.f,
+ 144012288.f, 144012288.f, 72033096.f, 144012288.f, 144012288.f,
+ 72000000.f, 72000000.f, 36004096.f, 72000000.f, 72000000.f,
+ 499501.f, 499501.f, 499501.f, 499501.f, 499501.f,
+ 1000002.f, 1000002.f, 1000002.f, 1000002.f, 1000002.f,
+ 499501.f, 499501.f, 499501.f, 499501.f, 499501.f,
+ 1001.f, 1001.f, 1001.f, 1001.f, 1001.f,
+ 3002.f, 3002.f, 3002.f, 3002.f, 3002.f,
+ 1001.f, 1001.f, 1001.f, 1001.f, 1001.f,
+ 501.f, 501.f, 501.f, 501.f, 501.f,
+ 1502.f, 1502.f, 1502.f, 1502.f, 1502.f
+ };
+
+ float[] res = new float[ntests];
+ for (int i = 0; i < ntests; i++) {
+ res[i] = 0.f;
+ }
+
+
+ for (int i = 0; i < 12000; i++) {
+ res[0] += simple(i);
+ res[1] += simpleb(i);
+ res[2] += simplec();
+ res[3] += simplef(i);
+ res[4] += simplep((float)i);
+
+ res[5] += simple2((float)i);
+ res[6] += simpleb2((float)i);
+ res[7] += simplec2((float)i);
+ res[8] += simplem2((float)i);
+ res[9] += simplep2((float)i, (float)i);
+
+ res[10] += simple_deop((float)i);
+ res[11] += simpleb_deop((float)i);
+ res[12] += simplec_deop((float)i);
+ res[13] += simplef_deop((float)i);
+ res[14] += simplep_deop((float)i);
+
+ res[15] += test((float)i, i);
+ res[16] += testb((float)i, i);
+ res[17] += testc((float)i, i);
+ res[18] += testm((float)i, i);
+ res[19] += testp((float)i, i, (float)i);
+
+ res[20] += test2((float)i, i);
+ res[21] += testb2((float)i, i);
+ res[22] += testc2((float)i, i);
+ res[23] += testm2((float)i, i);
+ res[24] += testp2((float)i, i, (float)i);
+
+ res[25] += test_deop((float)i, i);
+ res[26] += testb_deop((float)i, i);
+ res[27] += testc_deop((float)i, i);
+ res[28] += testf_deop((float)i, i);
+ res[29] += testp_deop((float)i, i, (float)i);
+ }
+
+ float[] ia = new float[1000];
+ for (int i = 0; i < 1000; i++) {
+ ia[i] = i;
+ }
+
+ for (int i = 0; i < 100; i++) {
+ res[30] = sum(ia);
+ res[31] = sumb(ia);
+ res[32] = sumc(ia);
+ res[33] = sumf(ia);
+ res[34] = sump(ia, 1.f);
+
+ res[35] = sum2(ia);
+ res[36] = sumb2(ia);
+ res[37] = sumc2(ia);
+ res[38] = summ2(ia);
+ res[39] = sump2(ia, 1.f);
+
+ res[40] = sum_deop(ia);
+ res[41] = sumb_deop(ia);
+ res[42] = sumc_deop(ia);
+ res[43] = sumf_deop(ia);
+ res[44] = sump_deop(ia, 1.f);
+
+ res[45] = remi_sum();
+ res[46] = remi_sumb();
+ res[47] = remi_sumc();
+ res[48] = remi_sumf();
+ res[49] = remi_sump(1.f);
+
+ res[50] = remi_sum2();
+ res[51] = remi_sumb2();
+ res[52] = remi_sumc2();
+ res[53] = remi_summ2();
+ res[54] = remi_sump2(1.f);
+
+ res[55] = remi_sum_deop();
+ res[56] = remi_sumb_deop();
+ res[57] = remi_sumc_deop();
+ res[58] = remi_sumf_deop();
+ res[59] = remi_sump_deop(1.f);
+
+ res[60] = remi_sum_cond();
+ res[61] = remi_sumb_cond();
+ res[62] = remi_sumc_cond();
+ res[63] = remi_sumf_cond();
+ res[64] = remi_sump_cond(1.f);
+
+ res[65] = remi_sum2_cond();
+ res[66] = remi_sumb2_cond();
+ res[67] = remi_sumc2_cond();
+ res[68] = remi_summ2_cond();
+ res[69] = remi_sump2_cond(1.f);
+ }
+
+ int failed = 0;
+ for (int i = 0; i < ntests; i++) {
+ if (res[i] != val[i]) {
+ System.err.println(test_name[i] + ": " + res[i] + " != " + val[i]);
+ failed++;
+ }
+ }
+ if (failed > 0) {
+ System.err.println("Failed " + failed + " tests.");
+ throw new InternalError();
+ } else {
+ System.out.println("Passed.");
+ }
+ }
+}
diff --git a/hotspot/test/compiler/6934604/TestIntBoxing.java b/hotspot/test/compiler/6934604/TestIntBoxing.java
new file mode 100644
index 00000000000..d1ad10b070c
--- /dev/null
+++ b/hotspot/test/compiler/6934604/TestIntBoxing.java
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6934604
+ * @summary enable parts of EliminateAutoBox by default
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox TestIntBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestIntBoxing.dummy -XX:CompileCommand=exclude,TestIntBoxing.foo -XX:CompileCommand=exclude,TestIntBoxing.foob TestIntBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestIntBoxing.dummy -XX:CompileCommand=exclude,TestIntBoxing.foo -XX:CompileCommand=exclude,TestIntBoxing.foob TestIntBoxing
+ *
+ */
+
+public class TestIntBoxing {
+
+ static final Integer ibc = new Integer(1);
+
+ //===============================================
+ // Non-inlined methods to test deoptimization info
+ static void dummy() { }
+ static int foo(int i) { return i; }
+ static Integer foob(int i) { return Integer.valueOf(i); }
+
+
+ static int simple(int i) {
+ Integer ib = new Integer(i);
+ return ib;
+ }
+
+ static int simpleb(int i) {
+ Integer ib = Integer.valueOf(i);
+ return ib;
+ }
+
+ static int simplec() {
+ Integer ib = ibc;
+ return ib;
+ }
+
+ static int simplef(int i) {
+ Integer ib = foob(i);
+ return ib;
+ }
+
+ static int simplep(Integer ib) {
+ return ib;
+ }
+
+ static int simple2(int i) {
+ Integer ib1 = new Integer(i);
+ Integer ib2 = new Integer(i+1);
+ return ib1 + ib2;
+ }
+
+ static int simpleb2(int i) {
+ Integer ib1 = Integer.valueOf(i);
+ Integer ib2 = Integer.valueOf(i+1);
+ return ib1 + ib2;
+ }
+
+ static int simplem2(int i) {
+ Integer ib1 = new Integer(i);
+ Integer ib2 = Integer.valueOf(i+1);
+ return ib1 + ib2;
+ }
+
+ static int simplep2(int i, Integer ib1) {
+ Integer ib2 = Integer.valueOf(i+1);
+ return ib1 + ib2;
+ }
+
+ static int simplec2(int i) {
+ Integer ib1 = ibc;
+ Integer ib2 = Integer.valueOf(i+1);
+ return ib1 + ib2;
+ }
+
+ //===============================================
+ static int test(int i) {
+ Integer ib = new Integer(i);
+ if ((i&1) == 0)
+ ib = i+1;
+ return ib;
+ }
+
+ static int testb(int i) {
+ Integer ib = i;
+ if ((i&1) == 0)
+ ib = (i+1);
+ return ib;
+ }
+
+ static int testm(int i) {
+ Integer ib = i;
+ if ((i&1) == 0)
+ ib = new Integer(i+1);
+ return ib;
+ }
+
+ static int testp(int i, Integer ib) {
+ if ((i&1) == 0)
+ ib = new Integer(i+1);
+ return ib;
+ }
+
+ static int testc(int i) {
+ Integer ib = ibc;
+ if ((i&1) == 0)
+ ib = new Integer(i+1);
+ return ib;
+ }
+
+ static int test2(int i) {
+ Integer ib1 = new Integer(i);
+ Integer ib2 = new Integer(i+1);
+ if ((i&1) == 0) {
+ ib1 = new Integer(i+1);
+ ib2 = new Integer(i+2);
+ }
+ return ib1+ib2;
+ }
+
+ static int testb2(int i) {
+ Integer ib1 = i;
+ Integer ib2 = i+1;
+ if ((i&1) == 0) {
+ ib1 = (i+1);
+ ib2 = (i+2);
+ }
+ return ib1+ib2;
+ }
+
+ static int testm2(int i) {
+ Integer ib1 = new Integer(i);
+ Integer ib2 = i+1;
+ if ((i&1) == 0) {
+ ib1 = new Integer(i+1);
+ ib2 = (i+2);
+ }
+ return ib1+ib2;
+ }
+
+ static int testp2(int i, Integer ib1) {
+ Integer ib2 = i+1;
+ if ((i&1) == 0) {
+ ib1 = new Integer(i+1);
+ ib2 = (i+2);
+ }
+ return ib1+ib2;
+ }
+
+ static int testc2(int i) {
+ Integer ib1 = ibc;
+ Integer ib2 = i+1;
+ if ((i&1) == 0) {
+ ib1 = (ibc+1);
+ ib2 = (i+2);
+ }
+ return ib1+ib2;
+ }
+
+ //===============================================
+ static int sum(int[] a) {
+ int result = 1;
+ for (Integer i : a)
+ result += i;
+ return result;
+ }
+
+ static int sumb(int[] a) {
+ Integer result = 1;
+ for (Integer i : a)
+ result += i;
+ return result;
+ }
+
+ static int sumc(int[] a) {
+ Integer result = ibc;
+ for (Integer i : a)
+ result += i;
+ return result;
+ }
+
+ static int sumf(int[] a) {
+ Integer result = foob(1);
+ for (Integer i : a)
+ result += i;
+ return result;
+ }
+
+ static int sump(int[] a, Integer result) {
+ for (Integer i : a)
+ result += i;
+ return result;
+ }
+
+ static int sum2(int[] a) {
+ int result1 = 1;
+ int result2 = 1;
+ for (Integer i : a) {
+ result1 += i;
+ result2 += i + 1;
+ }
+ return result1 + result2;
+ }
+
+ static int sumb2(int[] a) {
+ Integer result1 = 1;
+ Integer result2 = 1;
+ for (Integer i : a) {
+ result1 += i;
+ result2 += i + 1;
+ }
+ return result1 + result2;
+ }
+
+ static int summ2(int[] a) {
+ Integer result1 = 1;
+ Integer result2 = new Integer(1);
+ for (Integer i : a) {
+ result1 += i;
+ result2 += new Integer(i + 1);
+ }
+ return result1 + result2;
+ }
+
+ static int sump2(int[] a, Integer result2) {
+ Integer result1 = 1;
+ for (Integer i : a) {
+ result1 += i;
+ result2 += i + 1;
+ }
+ return result1 + result2;
+ }
+
+ static int sumc2(int[] a) {
+ Integer result1 = 1;
+ Integer result2 = ibc;
+ for (Integer i : a) {
+ result1 += i;
+ result2 += i + ibc;
+ }
+ return result1 + result2;
+ }
+
+ //===============================================
+ static int remi_sum() {
+ Integer j = new Integer(1);
+ for (int i = 0; i< 1000; i++) {
+ j = new Integer(j + 1);
+ }
+ return j;
+ }
+
+ static int remi_sumb() {
+ Integer j = Integer.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ j = j + 1;
+ }
+ return j;
+ }
+
+ static int remi_sumf() {
+ Integer j = foob(1);
+ for (int i = 0; i< 1000; i++) {
+ j = j + 1;
+ }
+ return j;
+ }
+
+ static int remi_sump(Integer j) {
+ for (int i = 0; i< 1000; i++) {
+ j = new Integer(j + 1);
+ }
+ return j;
+ }
+
+ static int remi_sumc() {
+ Integer j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ j = j + ibc;
+ }
+ return j;
+ }
+
+ static int remi_sum2() {
+ Integer j1 = new Integer(1);
+ Integer j2 = new Integer(1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Integer(j1 + 1);
+ j2 = new Integer(j2 + 2);
+ }
+ return j1 + j2;
+ }
+
+ static int remi_sumb2() {
+ Integer j1 = Integer.valueOf(1);
+ Integer j2 = Integer.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = j1 + 1;
+ j2 = j2 + 2;
+ }
+ return j1 + j2;
+ }
+
+ static int remi_summ2() {
+ Integer j1 = new Integer(1);
+ Integer j2 = Integer.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Integer(j1 + 1);
+ j2 = j2 + 2;
+ }
+ return j1 + j2;
+ }
+
+ static int remi_sump2(Integer j1) {
+ Integer j2 = Integer.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Integer(j1 + 1);
+ j2 = j2 + 2;
+ }
+ return j1 + j2;
+ }
+
+ static int remi_sumc2() {
+ Integer j1 = ibc;
+ Integer j2 = Integer.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = j1 + ibc;
+ j2 = j2 + 2;
+ }
+ return j1 + j2;
+ }
+
+
+ //===============================================
+ // Safepointa and debug info for deoptimization
+ static int simple_deop(int i) {
+ Integer ib = new Integer(foo(i));
+ dummy();
+ return ib;
+ }
+
+ static int simpleb_deop(int i) {
+ Integer ib = Integer.valueOf(foo(i));
+ dummy();
+ return ib;
+ }
+
+ static int simplef_deop(int i) {
+ Integer ib = foob(i);
+ dummy();
+ return ib;
+ }
+
+ static int simplep_deop(Integer ib) {
+ dummy();
+ return ib;
+ }
+
+ static int simplec_deop(int i) {
+ Integer ib = ibc;
+ dummy();
+ return ib;
+ }
+
+ static int test_deop(int i) {
+ Integer ib = new Integer(foo(i));
+ if ((i&1) == 0)
+ ib = foo(i+1);
+ dummy();
+ return ib;
+ }
+
+ static int testb_deop(int i) {
+ Integer ib = foo(i);
+ if ((i&1) == 0)
+ ib = foo(i+1);
+ dummy();
+ return ib;
+ }
+
+ static int testf_deop(int i) {
+ Integer ib = foob(i);
+ if ((i&1) == 0)
+ ib = foo(i+1);
+ dummy();
+ return ib;
+ }
+
+ static int testp_deop(int i, Integer ib) {
+ if ((i&1) == 0)
+ ib = foo(i+1);
+ dummy();
+ return ib;
+ }
+
+ static int testc_deop(int i) {
+ Integer ib = ibc;
+ if ((i&1) == 0)
+ ib = foo(i+1);
+ dummy();
+ return ib;
+ }
+
+ static int sum_deop(int[] a) {
+ int result = 1;
+ for (Integer i : a)
+ result += foo(i);
+ dummy();
+ return result;
+ }
+
+ static int sumb_deop(int[] a) {
+ Integer result = 1;
+ for (Integer i : a)
+ result += foo(i);
+ dummy();
+ return result;
+ }
+
+ static int sumf_deop(int[] a) {
+ Integer result = 1;
+ for (Integer i : a)
+ result += foob(i);
+ dummy();
+ return result;
+ }
+
+ static int sump_deop(int[] a, Integer result) {
+ for (Integer i : a)
+ result += foob(i);
+ dummy();
+ return result;
+ }
+
+ static int sumc_deop(int[] a) {
+ Integer result = ibc;
+ for (Integer i : a)
+ result += foo(i);
+ dummy();
+ return result;
+ }
+
+ static int remi_sum_deop() {
+ Integer j = new Integer(foo(1));
+ for (int i = 0; i< 1000; i++) {
+ j = new Integer(foo(j + 1));
+ }
+ dummy();
+ return j;
+ }
+
+ static int remi_sumb_deop() {
+ Integer j = Integer.valueOf(foo(1));
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1);
+ }
+ dummy();
+ return j;
+ }
+
+ static int remi_sumf_deop() {
+ Integer j = foob(1);
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1);
+ }
+ dummy();
+ return j;
+ }
+
+ static int remi_sump_deop(Integer j) {
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1);
+ }
+ dummy();
+ return j;
+ }
+
+ static int remi_sumc_deop() {
+ Integer j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1);
+ }
+ dummy();
+ return j;
+ }
+
+ //===============================================
+ // Conditional increment
+ static int remi_sum_cond() {
+ Integer j = new Integer(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = new Integer(j + 1);
+ }
+ }
+ return j;
+ }
+
+ static int remi_sumb_cond() {
+ Integer j = Integer.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + 1;
+ }
+ }
+ return j;
+ }
+
+ static int remi_sumf_cond() {
+ Integer j = foob(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + 1;
+ }
+ }
+ return j;
+ }
+
+ static int remi_sump_cond(Integer j) {
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + 1;
+ }
+ }
+ return j;
+ }
+
+ static int remi_sumc_cond() {
+ Integer j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + ibc;
+ }
+ }
+ return j;
+ }
+
+ static int remi_sum2_cond() {
+ Integer j1 = new Integer(1);
+ Integer j2 = new Integer(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Integer(j1 + 1);
+ } else {
+ j2 = new Integer(j2 + 2);
+ }
+ }
+ return j1 + j2;
+ }
+
+ static int remi_sumb2_cond() {
+ Integer j1 = Integer.valueOf(1);
+ Integer j2 = Integer.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = j1 + 1;
+ } else {
+ j2 = j2 + 2;
+ }
+ }
+ return j1 + j2;
+ }
+
+ static int remi_summ2_cond() {
+ Integer j1 = new Integer(1);
+ Integer j2 = Integer.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Integer(j1 + 1);
+ } else {
+ j2 = j2 + 2;
+ }
+ }
+ return j1 + j2;
+ }
+
+ static int remi_sump2_cond(Integer j1) {
+ Integer j2 = Integer.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Integer(j1 + 1);
+ } else {
+ j2 = j2 + 2;
+ }
+ }
+ return j1 + j2;
+ }
+
+ static int remi_sumc2_cond() {
+ Integer j1 = ibc;
+ Integer j2 = Integer.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = j1 + ibc;
+ } else {
+ j2 = j2 + 2;
+ }
+ }
+ return j1 + j2;
+ }
+
+
+ public static void main(String[] args) {
+ final int ntests = 70;
+
+ String[] test_name = new String[] {
+ "simple", "simpleb", "simplec", "simplef", "simplep",
+ "simple2", "simpleb2", "simplec2", "simplem2", "simplep2",
+ "simple_deop", "simpleb_deop", "simplec_deop", "simplef_deop", "simplep_deop",
+ "test", "testb", "testc", "testm", "testp",
+ "test2", "testb2", "testc2", "testm2", "testp2",
+ "test_deop", "testb_deop", "testc_deop", "testf_deop", "testp_deop",
+ "sum", "sumb", "sumc", "sumf", "sump",
+ "sum2", "sumb2", "sumc2", "summ2", "sump2",
+ "sum_deop", "sumb_deop", "sumc_deop", "sumf_deop", "sump_deop",
+ "remi_sum", "remi_sumb", "remi_sumc", "remi_sumf", "remi_sump",
+ "remi_sum2", "remi_sumb2", "remi_sumc2", "remi_summ2", "remi_sump2",
+ "remi_sum_deop", "remi_sumb_deop", "remi_sumc_deop", "remi_sumf_deop", "remi_sump_deop",
+ "remi_sum_cond", "remi_sumb_cond", "remi_sumc_cond", "remi_sumf_cond", "remi_sump_cond",
+ "remi_sum2_cond", "remi_sumb2_cond", "remi_sumc2_cond", "remi_summ2_cond", "remi_sump2_cond"
+ };
+
+ final int[] val = new int[] {
+ 71994000, 71994000, 12000, 71994000, 71994000,
+ 144000000, 144000000, 72018000, 144000000, 144000000,
+ 71994000, 71994000, 12000, 71994000, 71994000,
+ 72000000, 72000000, 36006000, 72000000, 72000000,
+ 144012000, 144012000, 72030000, 144012000, 144012000,
+ 72000000, 72000000, 36006000, 72000000, 72000000,
+ 499501, 499501, 499501, 499501, 499501,
+ 1000002, 1000002, 1000002, 1000002, 1000002,
+ 499501, 499501, 499501, 499501, 499501,
+ 1001, 1001, 1001, 1001, 1001,
+ 3002, 3002, 3002, 3002, 3002,
+ 1001, 1001, 1001, 1001, 1001,
+ 501, 501, 501, 501, 501,
+ 1502, 1502, 1502, 1502, 1502
+ };
+
+ int[] res = new int[ntests];
+ for (int i = 0; i < ntests; i++) {
+ res[i] = 0;
+ }
+
+
+ for (int i = 0; i < 12000; i++) {
+ res[0] += simple(i);
+ res[1] += simpleb(i);
+ res[2] += simplec();
+ res[3] += simplef(i);
+ res[4] += simplep(i);
+
+ res[5] += simple2(i);
+ res[6] += simpleb2(i);
+ res[7] += simplec2(i);
+ res[8] += simplem2(i);
+ res[9] += simplep2(i, i);
+
+ res[10] += simple_deop(i);
+ res[11] += simpleb_deop(i);
+ res[12] += simplec_deop(i);
+ res[13] += simplef_deop(i);
+ res[14] += simplep_deop(i);
+
+ res[15] += test(i);
+ res[16] += testb(i);
+ res[17] += testc(i);
+ res[18] += testm(i);
+ res[19] += testp(i, i);
+
+ res[20] += test2(i);
+ res[21] += testb2(i);
+ res[22] += testc2(i);
+ res[23] += testm2(i);
+ res[24] += testp2(i, i);
+
+ res[25] += test_deop(i);
+ res[26] += testb_deop(i);
+ res[27] += testc_deop(i);
+ res[28] += testf_deop(i);
+ res[29] += testp_deop(i, i);
+ }
+
+ int[] ia = new int[1000];
+ for (int i = 0; i < 1000; i++) {
+ ia[i] = i;
+ }
+
+ for (int i = 0; i < 100; i++) {
+ res[30] = sum(ia);
+ res[31] = sumb(ia);
+ res[32] = sumc(ia);
+ res[33] = sumf(ia);
+ res[34] = sump(ia, 1);
+
+ res[35] = sum2(ia);
+ res[36] = sumb2(ia);
+ res[37] = sumc2(ia);
+ res[38] = summ2(ia);
+ res[39] = sump2(ia, 1);
+
+ res[40] = sum_deop(ia);
+ res[41] = sumb_deop(ia);
+ res[42] = sumc_deop(ia);
+ res[43] = sumf_deop(ia);
+ res[44] = sump_deop(ia, 1);
+
+ res[45] = remi_sum();
+ res[46] = remi_sumb();
+ res[47] = remi_sumc();
+ res[48] = remi_sumf();
+ res[49] = remi_sump(1);
+
+ res[50] = remi_sum2();
+ res[51] = remi_sumb2();
+ res[52] = remi_sumc2();
+ res[53] = remi_summ2();
+ res[54] = remi_sump2(1);
+
+ res[55] = remi_sum_deop();
+ res[56] = remi_sumb_deop();
+ res[57] = remi_sumc_deop();
+ res[58] = remi_sumf_deop();
+ res[59] = remi_sump_deop(1);
+
+ res[60] = remi_sum_cond();
+ res[61] = remi_sumb_cond();
+ res[62] = remi_sumc_cond();
+ res[63] = remi_sumf_cond();
+ res[64] = remi_sump_cond(1);
+
+ res[65] = remi_sum2_cond();
+ res[66] = remi_sumb2_cond();
+ res[67] = remi_sumc2_cond();
+ res[68] = remi_summ2_cond();
+ res[69] = remi_sump2_cond(1);
+ }
+
+ int failed = 0;
+ for (int i = 0; i < ntests; i++) {
+ if (res[i] != val[i]) {
+ System.err.println(test_name[i] + ": " + res[i] + " != " + val[i]);
+ failed++;
+ }
+ }
+ if (failed > 0) {
+ System.err.println("Failed " + failed + " tests.");
+ throw new InternalError();
+ } else {
+ System.out.println("Passed.");
+ }
+ }
+}
diff --git a/hotspot/test/compiler/6934604/TestLongBoxing.java b/hotspot/test/compiler/6934604/TestLongBoxing.java
new file mode 100644
index 00000000000..b92a01c962b
--- /dev/null
+++ b/hotspot/test/compiler/6934604/TestLongBoxing.java
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6934604
+ * @summary enable parts of EliminateAutoBox by default
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox TestLongBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestLongBoxing.dummy -XX:CompileCommand=exclude,TestLongBoxing.foo -XX:CompileCommand=exclude,TestLongBoxing.foob TestLongBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestLongBoxing.dummy -XX:CompileCommand=exclude,TestLongBoxing.foo -XX:CompileCommand=exclude,TestLongBoxing.foob TestLongBoxing
+ *
+ */
+
+public class TestLongBoxing {
+
+ static final Long ibc = new Long(1);
+
+ //===============================================
+ // Non-inlined methods to test deoptimization info
+ static void dummy() { }
+ static long foo(long i) { return i; }
+ static Long foob(long i) { return Long.valueOf(i); }
+
+
+ static long simple(long i) {
+ Long ib = new Long(i);
+ return ib;
+ }
+
+ static long simpleb(long i) {
+ Long ib = Long.valueOf(i);
+ return ib;
+ }
+
+ static long simplec() {
+ Long ib = ibc;
+ return ib;
+ }
+
+ static long simplef(long i) {
+ Long ib = foob(i);
+ return ib;
+ }
+
+ static long simplep(Long ib) {
+ return ib;
+ }
+
+ static long simple2(long i) {
+ Long ib1 = new Long(i);
+ Long ib2 = new Long(i+1);
+ return ib1 + ib2;
+ }
+
+ static long simpleb2(long i) {
+ Long ib1 = Long.valueOf(i);
+ Long ib2 = Long.valueOf(i+1);
+ return ib1 + ib2;
+ }
+
+ static long simplem2(long i) {
+ Long ib1 = new Long(i);
+ Long ib2 = Long.valueOf(i+1);
+ return ib1 + ib2;
+ }
+
+ static long simplep2(long i, Long ib1) {
+ Long ib2 = Long.valueOf(i+1);
+ return ib1 + ib2;
+ }
+
+ static long simplec2(long i) {
+ Long ib1 = ibc;
+ Long ib2 = Long.valueOf(i+1);
+ return ib1 + ib2;
+ }
+
+ //===============================================
+ static long test(long i) {
+ Long ib = new Long(i);
+ if ((i&1) == 0)
+ ib = i+1;
+ return ib;
+ }
+
+ static long testb(long i) {
+ Long ib = i;
+ if ((i&1) == 0)
+ ib = (i+1);
+ return ib;
+ }
+
+ static long testm(long i) {
+ Long ib = i;
+ if ((i&1) == 0)
+ ib = new Long(i+1);
+ return ib;
+ }
+
+ static long testp(long i, Long ib) {
+ if ((i&1) == 0)
+ ib = new Long(i+1);
+ return ib;
+ }
+
+ static long testc(long i) {
+ Long ib = ibc;
+ if ((i&1) == 0)
+ ib = new Long(i+1);
+ return ib;
+ }
+
+ static long test2(long i) {
+ Long ib1 = new Long(i);
+ Long ib2 = new Long(i+1);
+ if ((i&1) == 0) {
+ ib1 = new Long(i+1);
+ ib2 = new Long(i+2);
+ }
+ return ib1+ib2;
+ }
+
+ static long testb2(long i) {
+ Long ib1 = i;
+ Long ib2 = i+1;
+ if ((i&1) == 0) {
+ ib1 = (i+1);
+ ib2 = (i+2);
+ }
+ return ib1+ib2;
+ }
+
+ static long testm2(long i) {
+ Long ib1 = new Long(i);
+ Long ib2 = i+1;
+ if ((i&1) == 0) {
+ ib1 = new Long(i+1);
+ ib2 = (i+2);
+ }
+ return ib1+ib2;
+ }
+
+ static long testp2(long i, Long ib1) {
+ Long ib2 = i+1;
+ if ((i&1) == 0) {
+ ib1 = new Long(i+1);
+ ib2 = (i+2);
+ }
+ return ib1+ib2;
+ }
+
+ static long testc2(long i) {
+ Long ib1 = ibc;
+ Long ib2 = i+1;
+ if ((i&1) == 0) {
+ ib1 = (ibc+1);
+ ib2 = (i+2);
+ }
+ return ib1+ib2;
+ }
+
+ //===============================================
+ static long sum(long[] a) {
+ long result = 1;
+ for (Long i : a)
+ result += i;
+ return result;
+ }
+
+ static long sumb(long[] a) {
+ Long result = 1l;
+ for (Long i : a)
+ result += i;
+ return result;
+ }
+
+ static long sumc(long[] a) {
+ Long result = ibc;
+ for (Long i : a)
+ result += i;
+ return result;
+ }
+
+ static long sumf(long[] a) {
+ Long result = foob(1);
+ for (Long i : a)
+ result += i;
+ return result;
+ }
+
+ static long sump(long[] a, Long result) {
+ for (Long i : a)
+ result += i;
+ return result;
+ }
+
+ static long sum2(long[] a) {
+ long result1 = 1;
+ long result2 = 1;
+ for (Long i : a) {
+ result1 += i;
+ result2 += i + 1;
+ }
+ return result1 + result2;
+ }
+
+ static long sumb2(long[] a) {
+ Long result1 = 1l;
+ Long result2 = 1l;
+ for (Long i : a) {
+ result1 += i;
+ result2 += i + 1;
+ }
+ return result1 + result2;
+ }
+
+ static long summ2(long[] a) {
+ Long result1 = 1l;
+ Long result2 = new Long(1);
+ for (Long i : a) {
+ result1 += i;
+ result2 += new Long(i + 1);
+ }
+ return result1 + result2;
+ }
+
+ static long sump2(long[] a, Long result2) {
+ Long result1 = 1l;
+ for (Long i : a) {
+ result1 += i;
+ result2 += i + 1;
+ }
+ return result1 + result2;
+ }
+
+ static long sumc2(long[] a) {
+ Long result1 = 1l;
+ Long result2 = ibc;
+ for (Long i : a) {
+ result1 += i;
+ result2 += i + ibc;
+ }
+ return result1 + result2;
+ }
+
+ //===============================================
+ static long remi_sum() {
+ Long j = new Long(1);
+ for (int i = 0; i< 1000; i++) {
+ j = new Long(j + 1);
+ }
+ return j;
+ }
+
+ static long remi_sumb() {
+ Long j = Long.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ j = j + 1;
+ }
+ return j;
+ }
+
+ static long remi_sumf() {
+ Long j = foob(1);
+ for (int i = 0; i< 1000; i++) {
+ j = j + 1;
+ }
+ return j;
+ }
+
+ static long remi_sump(Long j) {
+ for (int i = 0; i< 1000; i++) {
+ j = new Long(j + 1);
+ }
+ return j;
+ }
+
+ static long remi_sumc() {
+ Long j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ j = j + ibc;
+ }
+ return j;
+ }
+
+ static long remi_sum2() {
+ Long j1 = new Long(1);
+ Long j2 = new Long(1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Long(j1 + 1);
+ j2 = new Long(j2 + 2);
+ }
+ return j1 + j2;
+ }
+
+ static long remi_sumb2() {
+ Long j1 = Long.valueOf(1);
+ Long j2 = Long.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = j1 + 1;
+ j2 = j2 + 2;
+ }
+ return j1 + j2;
+ }
+
+ static long remi_summ2() {
+ Long j1 = new Long(1);
+ Long j2 = Long.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Long(j1 + 1);
+ j2 = j2 + 2;
+ }
+ return j1 + j2;
+ }
+
+ static long remi_sump2(Long j1) {
+ Long j2 = Long.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Long(j1 + 1);
+ j2 = j2 + 2;
+ }
+ return j1 + j2;
+ }
+
+ static long remi_sumc2() {
+ Long j1 = ibc;
+ Long j2 = Long.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = j1 + ibc;
+ j2 = j2 + 2;
+ }
+ return j1 + j2;
+ }
+
+
+ //===============================================
+ // Safepointa and debug info for deoptimization
+ static long simple_deop(long i) {
+ Long ib = new Long(foo(i));
+ dummy();
+ return ib;
+ }
+
+ static long simpleb_deop(long i) {
+ Long ib = Long.valueOf(foo(i));
+ dummy();
+ return ib;
+ }
+
+ static long simplef_deop(long i) {
+ Long ib = foob(i);
+ dummy();
+ return ib;
+ }
+
+ static long simplep_deop(Long ib) {
+ dummy();
+ return ib;
+ }
+
+ static long simplec_deop(long i) {
+ Long ib = ibc;
+ dummy();
+ return ib;
+ }
+
+ static long test_deop(long i) {
+ Long ib = new Long(foo(i));
+ if ((i&1) == 0)
+ ib = foo(i+1);
+ dummy();
+ return ib;
+ }
+
+ static long testb_deop(long i) {
+ Long ib = foo(i);
+ if ((i&1) == 0)
+ ib = foo(i+1);
+ dummy();
+ return ib;
+ }
+
+ static long testf_deop(long i) {
+ Long ib = foob(i);
+ if ((i&1) == 0)
+ ib = foo(i+1);
+ dummy();
+ return ib;
+ }
+
+ static long testp_deop(long i, Long ib) {
+ if ((i&1) == 0)
+ ib = foo(i+1);
+ dummy();
+ return ib;
+ }
+
+ static long testc_deop(long i) {
+ Long ib = ibc;
+ if ((i&1) == 0)
+ ib = foo(i+1);
+ dummy();
+ return ib;
+ }
+
+ static long sum_deop(long[] a) {
+ long result = 1;
+ for (Long i : a)
+ result += foo(i);
+ dummy();
+ return result;
+ }
+
+ static long sumb_deop(long[] a) {
+ Long result = 1l;
+ for (Long i : a)
+ result += foo(i);
+ dummy();
+ return result;
+ }
+
+ static long sumf_deop(long[] a) {
+ Long result = 1l;
+ for (Long i : a)
+ result += foob(i);
+ dummy();
+ return result;
+ }
+
+ static long sump_deop(long[] a, Long result) {
+ for (Long i : a)
+ result += foob(i);
+ dummy();
+ return result;
+ }
+
+ static long sumc_deop(long[] a) {
+ Long result = ibc;
+ for (Long i : a)
+ result += foo(i);
+ dummy();
+ return result;
+ }
+
+ static long remi_sum_deop() {
+ Long j = new Long(foo(1));
+ for (int i = 0; i< 1000; i++) {
+ j = new Long(foo(j + 1));
+ }
+ dummy();
+ return j;
+ }
+
+ static long remi_sumb_deop() {
+ Long j = Long.valueOf(foo(1));
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1);
+ }
+ dummy();
+ return j;
+ }
+
+ static long remi_sumf_deop() {
+ Long j = foob(1);
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1);
+ }
+ dummy();
+ return j;
+ }
+
+ static long remi_sump_deop(Long j) {
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1);
+ }
+ dummy();
+ return j;
+ }
+
+ static long remi_sumc_deop() {
+ Long j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ j = foo(j + 1);
+ }
+ dummy();
+ return j;
+ }
+
+ //===============================================
+ // Conditional increment
+ static long remi_sum_cond() {
+ Long j = new Long(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = new Long(j + 1);
+ }
+ }
+ return j;
+ }
+
+ static long remi_sumb_cond() {
+ Long j = Long.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + 1;
+ }
+ }
+ return j;
+ }
+
+ static long remi_sumf_cond() {
+ Long j = foob(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + 1;
+ }
+ }
+ return j;
+ }
+
+ static long remi_sump_cond(Long j) {
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + 1;
+ }
+ }
+ return j;
+ }
+
+ static long remi_sumc_cond() {
+ Long j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = j + ibc;
+ }
+ }
+ return j;
+ }
+
+ static long remi_sum2_cond() {
+ Long j1 = new Long(1);
+ Long j2 = new Long(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Long(j1 + 1);
+ } else {
+ j2 = new Long(j2 + 2);
+ }
+ }
+ return j1 + j2;
+ }
+
+ static long remi_sumb2_cond() {
+ Long j1 = Long.valueOf(1);
+ Long j2 = Long.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = j1 + 1;
+ } else {
+ j2 = j2 + 2;
+ }
+ }
+ return j1 + j2;
+ }
+
+ static long remi_summ2_cond() {
+ Long j1 = new Long(1);
+ Long j2 = Long.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Long(j1 + 1);
+ } else {
+ j2 = j2 + 2;
+ }
+ }
+ return j1 + j2;
+ }
+
+ static long remi_sump2_cond(Long j1) {
+ Long j2 = Long.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Long(j1 + 1);
+ } else {
+ j2 = j2 + 2;
+ }
+ }
+ return j1 + j2;
+ }
+
+ static long remi_sumc2_cond() {
+ Long j1 = ibc;
+ Long j2 = Long.valueOf(1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = j1 + ibc;
+ } else {
+ j2 = j2 + 2;
+ }
+ }
+ return j1 + j2;
+ }
+
+
+ public static void main(String[] args) {
+ final int ntests = 70;
+
+ String[] test_name = new String[] {
+ "simple", "simpleb", "simplec", "simplef", "simplep",
+ "simple2", "simpleb2", "simplec2", "simplem2", "simplep2",
+ "simple_deop", "simpleb_deop", "simplec_deop", "simplef_deop", "simplep_deop",
+ "test", "testb", "testc", "testm", "testp",
+ "test2", "testb2", "testc2", "testm2", "testp2",
+ "test_deop", "testb_deop", "testc_deop", "testf_deop", "testp_deop",
+ "sum", "sumb", "sumc", "sumf", "sump",
+ "sum2", "sumb2", "sumc2", "summ2", "sump2",
+ "sum_deop", "sumb_deop", "sumc_deop", "sumf_deop", "sump_deop",
+ "remi_sum", "remi_sumb", "remi_sumc", "remi_sumf", "remi_sump",
+ "remi_sum2", "remi_sumb2", "remi_sumc2", "remi_summ2", "remi_sump2",
+ "remi_sum_deop", "remi_sumb_deop", "remi_sumc_deop", "remi_sumf_deop", "remi_sump_deop",
+ "remi_sum_cond", "remi_sumb_cond", "remi_sumc_cond", "remi_sumf_cond", "remi_sump_cond",
+ "remi_sum2_cond", "remi_sumb2_cond", "remi_sumc2_cond", "remi_summ2_cond", "remi_sump2_cond"
+ };
+
+ final long[] val = new long[] {
+ 71994000, 71994000, 12000, 71994000, 71994000,
+ 144000000, 144000000, 72018000, 144000000, 144000000,
+ 71994000, 71994000, 12000, 71994000, 71994000,
+ 72000000, 72000000, 36006000, 72000000, 72000000,
+ 144012000, 144012000, 72030000, 144012000, 144012000,
+ 72000000, 72000000, 36006000, 72000000, 72000000,
+ 499501, 499501, 499501, 499501, 499501,
+ 1000002, 1000002, 1000002, 1000002, 1000002,
+ 499501, 499501, 499501, 499501, 499501,
+ 1001, 1001, 1001, 1001, 1001,
+ 3002, 3002, 3002, 3002, 3002,
+ 1001, 1001, 1001, 1001, 1001,
+ 501, 501, 501, 501, 501,
+ 1502, 1502, 1502, 1502, 1502
+ };
+
+ long[] res = new long[ntests];
+ for (int i = 0; i < ntests; i++) {
+ res[i] = 0;
+ }
+
+
+ for (long i = 0; i < 12000; i++) {
+ res[0] += simple(i);
+ res[1] += simpleb(i);
+ res[2] += simplec();
+ res[3] += simplef(i);
+ res[4] += simplep(i);
+
+ res[5] += simple2(i);
+ res[6] += simpleb2(i);
+ res[7] += simplec2(i);
+ res[8] += simplem2(i);
+ res[9] += simplep2(i, i);
+
+ res[10] += simple_deop(i);
+ res[11] += simpleb_deop(i);
+ res[12] += simplec_deop(i);
+ res[13] += simplef_deop(i);
+ res[14] += simplep_deop(i);
+
+ res[15] += test(i);
+ res[16] += testb(i);
+ res[17] += testc(i);
+ res[18] += testm(i);
+ res[19] += testp(i, i);
+
+ res[20] += test2(i);
+ res[21] += testb2(i);
+ res[22] += testc2(i);
+ res[23] += testm2(i);
+ res[24] += testp2(i, i);
+
+ res[25] += test_deop(i);
+ res[26] += testb_deop(i);
+ res[27] += testc_deop(i);
+ res[28] += testf_deop(i);
+ res[29] += testp_deop(i, i);
+ }
+
+ long[] ia = new long[1000];
+ for (int i = 0; i < 1000; i++) {
+ ia[i] = i;
+ }
+
+ for (int i = 0; i < 100; i++) {
+ res[30] = sum(ia);
+ res[31] = sumb(ia);
+ res[32] = sumc(ia);
+ res[33] = sumf(ia);
+ res[34] = sump(ia, (long)1);
+
+ res[35] = sum2(ia);
+ res[36] = sumb2(ia);
+ res[37] = sumc2(ia);
+ res[38] = summ2(ia);
+ res[39] = sump2(ia, (long)1);
+
+ res[40] = sum_deop(ia);
+ res[41] = sumb_deop(ia);
+ res[42] = sumc_deop(ia);
+ res[43] = sumf_deop(ia);
+ res[44] = sump_deop(ia, (long)1);
+
+ res[45] = remi_sum();
+ res[46] = remi_sumb();
+ res[47] = remi_sumc();
+ res[48] = remi_sumf();
+ res[49] = remi_sump((long)1);
+
+ res[50] = remi_sum2();
+ res[51] = remi_sumb2();
+ res[52] = remi_sumc2();
+ res[53] = remi_summ2();
+ res[54] = remi_sump2((long)1);
+
+ res[55] = remi_sum_deop();
+ res[56] = remi_sumb_deop();
+ res[57] = remi_sumc_deop();
+ res[58] = remi_sumf_deop();
+ res[59] = remi_sump_deop((long)1);
+
+ res[60] = remi_sum_cond();
+ res[61] = remi_sumb_cond();
+ res[62] = remi_sumc_cond();
+ res[63] = remi_sumf_cond();
+ res[64] = remi_sump_cond((long)1);
+
+ res[65] = remi_sum2_cond();
+ res[66] = remi_sumb2_cond();
+ res[67] = remi_sumc2_cond();
+ res[68] = remi_summ2_cond();
+ res[69] = remi_sump2_cond((long)1);
+ }
+
+ int failed = 0;
+ for (int i = 0; i < ntests; i++) {
+ if (res[i] != val[i]) {
+ System.err.println(test_name[i] + ": " + res[i] + " != " + val[i]);
+ failed++;
+ }
+ }
+ if (failed > 0) {
+ System.err.println("Failed " + failed + " tests.");
+ throw new InternalError();
+ } else {
+ System.out.println("Passed.");
+ }
+ }
+}
diff --git a/hotspot/test/compiler/6934604/TestShortBoxing.java b/hotspot/test/compiler/6934604/TestShortBoxing.java
new file mode 100644
index 00000000000..0f065af3c63
--- /dev/null
+++ b/hotspot/test/compiler/6934604/TestShortBoxing.java
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6934604
+ * @summary enable parts of EliminateAutoBox by default
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox TestShortBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestShortBoxing.dummy -XX:CompileCommand=exclude,TestShortBoxing.foo -XX:CompileCommand=exclude,TestShortBoxing.foob TestShortBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestShortBoxing.dummy -XX:CompileCommand=exclude,TestShortBoxing.foo -XX:CompileCommand=exclude,TestShortBoxing.foob TestShortBoxing
+ *
+ */
+
+public class TestShortBoxing {
+
+ static final Short ibc = new Short((short)1);
+
+ //===============================================
+ // Non-inlined methods to test deoptimization info
+ static void dummy() { }
+ static short foo(short i) { return i; }
+ static Short foob(short i) { return Short.valueOf(i); }
+
+
+ static short simple(short i) {
+ Short ib = new Short(i);
+ return ib;
+ }
+
+ static short simpleb(short i) {
+ Short ib = Short.valueOf(i);
+ return ib;
+ }
+
+ static short simplec() {
+ Short ib = ibc;
+ return ib;
+ }
+
+ static short simplef(short i) {
+ Short ib = foob(i);
+ return ib;
+ }
+
+ static short simplep(Short ib) {
+ return ib;
+ }
+
+ static short simple2(short i) {
+ Short ib1 = new Short(i);
+ Short ib2 = new Short((short)(i+1));
+ return (short)(ib1 + ib2);
+ }
+
+ static short simpleb2(short i) {
+ Short ib1 = Short.valueOf(i);
+ Short ib2 = Short.valueOf((short)(i+1));
+ return (short)(ib1 + ib2);
+ }
+
+ static short simplem2(short i) {
+ Short ib1 = new Short(i);
+ Short ib2 = Short.valueOf((short)(i+1));
+ return (short)(ib1 + ib2);
+ }
+
+ static short simplep2(short i, Short ib1) {
+ Short ib2 = Short.valueOf((short)(i+1));
+ return (short)(ib1 + ib2);
+ }
+
+ static short simplec2(short i) {
+ Short ib1 = ibc;
+ Short ib2 = Short.valueOf((short)(i+1));
+ return (short)(ib1 + ib2);
+ }
+
+ //===============================================
+ static short test(short i) {
+ Short ib = new Short(i);
+ if ((i&1) == 0)
+ ib = (short)(i+1);
+ return ib;
+ }
+
+ static short testb(short i) {
+ Short ib = i;
+ if ((i&1) == 0)
+ ib = (short)(i+1);
+ return ib;
+ }
+
+ static short testm(short i) {
+ Short ib = i;
+ if ((i&1) == 0)
+ ib = new Short((short)(i+1));
+ return ib;
+ }
+
+ static short testp(short i, Short ib) {
+ if ((i&1) == 0)
+ ib = new Short((short)(i+1));
+ return ib;
+ }
+
+ static short testc(short i) {
+ Short ib = ibc;
+ if ((i&1) == 0)
+ ib = new Short((short)(i+1));
+ return ib;
+ }
+
+ static short test2(short i) {
+ Short ib1 = new Short(i);
+ Short ib2 = new Short((short)(i+1));
+ if ((i&1) == 0) {
+ ib1 = new Short((short)(i+1));
+ ib2 = new Short((short)(i+2));
+ }
+ return (short)(ib1+ib2);
+ }
+
+ static short testb2(short i) {
+ Short ib1 = i;
+ Short ib2 = (short)(i+1);
+ if ((i&1) == 0) {
+ ib1 = (short)(i+1);
+ ib2 = (short)(i+2);
+ }
+ return (short)(ib1 + ib2);
+ }
+
+ static short testm2(short i) {
+ Short ib1 = new Short(i);
+ Short ib2 = (short)(i+1);
+ if ((i&1) == 0) {
+ ib1 = new Short((short)(i+1));
+ ib2 = (short)(i+2);
+ }
+ return (short)(ib1 + ib2);
+ }
+
+ static short testp2(short i, Short ib1) {
+ Short ib2 = (short)(i+1);
+ if ((i&1) == 0) {
+ ib1 = new Short((short)(i+1));
+ ib2 = (short)(i+2);
+ }
+ return (short)(ib1 + ib2);
+ }
+
+ static short testc2(short i) {
+ Short ib1 = ibc;
+ Short ib2 = (short)(i+1);
+ if ((i&1) == 0) {
+ ib1 = (short)(ibc+1);
+ ib2 = (short)(i+2);
+ }
+ return (short)(ib1 + ib2);
+ }
+
+ //===============================================
+ static short sum(short[] a) {
+ short result = 1;
+ for (Short i : a)
+ result += i;
+ return result;
+ }
+
+ static short sumb(short[] a) {
+ Short result = 1;
+ for (Short i : a)
+ result = (short)(result + i);
+ return result;
+ }
+
+ static short sumc(short[] a) {
+ Short result = ibc;
+ for (Short i : a)
+ result = (short)(result + i);
+ return result;
+ }
+
+ static short sumf(short[] a) {
+ Short result = foob((short)1);
+ for (Short i : a)
+ result = (short)(result + i);
+ return result;
+ }
+
+ static short sump(short[] a, Short result) {
+ for (Short i : a)
+ result = (short)(result + i);
+ return result;
+ }
+
+ static short sum2(short[] a) {
+ short result1 = 1;
+ short result2 = 1;
+ for (Short i : a) {
+ result1 += i;
+ result2 += i + 1;
+ }
+ return (short)(result1 + result2);
+ }
+
+ static short sumb2(short[] a) {
+ Short result1 = 1;
+ Short result2 = 1;
+ for (Short i : a) {
+ result1 = (short)(result1 + i);
+ result2 = (short)(result2 + i + 1);
+ }
+ return (short)(result1 + result2);
+ }
+
+ static short summ2(short[] a) {
+ Short result1 = 1;
+ Short result2 = new Short((short)1);
+ for (Short i : a) {
+ result1 = (short)(result1 + i);
+ result2 = (short)(result2 + new Short((short)(i + 1)));
+ }
+ return (short)(result1 + result2);
+ }
+
+ static short sump2(short[] a, Short result2) {
+ Short result1 = 1;
+ for (Short i : a) {
+ result1 = (short)(result1 + i);
+ result2 = (short)(result2 + i + 1);
+ }
+ return (short)(result1 + result2);
+ }
+
+ static short sumc2(short[] a) {
+ Short result1 = 1;
+ Short result2 = ibc;
+ for (Short i : a) {
+ result1 = (short)(result1 + i);
+ result2 = (short)(result2 + i + ibc);
+ }
+ return (short)(result1 + result2);
+ }
+
+ //===============================================
+ static short remi_sum() {
+ Short j = new Short((short)1);
+ for (int i = 0; i< 1000; i++) {
+ j = new Short((short)(j + 1));
+ }
+ return j;
+ }
+
+ static short remi_sumb() {
+ Short j = Short.valueOf((short)1);
+ for (int i = 0; i< 1000; i++) {
+ j = (short)(j + 1);
+ }
+ return j;
+ }
+
+ static short remi_sumf() {
+ Short j = foob((short)1);
+ for (int i = 0; i< 1000; i++) {
+ j = (short)(j + 1);
+ }
+ return j;
+ }
+
+ static short remi_sump(Short j) {
+ for (int i = 0; i< 1000; i++) {
+ j = new Short((short)(j + 1));
+ }
+ return j;
+ }
+
+ static short remi_sumc() {
+ Short j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ j = (short)(j + ibc);
+ }
+ return j;
+ }
+
+ static short remi_sum2() {
+ Short j1 = new Short((short)1);
+ Short j2 = new Short((short)1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Short((short)(j1 + 1));
+ j2 = new Short((short)(j2 + 2));
+ }
+ return (short)(j1 + j2);
+ }
+
+ static short remi_sumb2() {
+ Short j1 = Short.valueOf((short)1);
+ Short j2 = Short.valueOf((short)1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = (short)(j1 + 1);
+ j2 = (short)(j2 + 2);
+ }
+ return (short)(j1 + j2);
+ }
+
+ static short remi_summ2() {
+ Short j1 = new Short((short)1);
+ Short j2 = Short.valueOf((short)1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Short((short)(j1 + 1));
+ j2 = (short)(j2 + 2);
+ }
+ return (short)(j1 + j2);
+ }
+
+ static short remi_sump2(Short j1) {
+ Short j2 = Short.valueOf((short)1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = new Short((short)(j1 + 1));
+ j2 = (short)(j2 + 2);
+ }
+ return (short)(j1 + j2);
+ }
+
+ static short remi_sumc2() {
+ Short j1 = ibc;
+ Short j2 = Short.valueOf((short)1);
+ for (int i = 0; i< 1000; i++) {
+ j1 = (short)(j1 + ibc);
+ j2 = (short)(j2 + 2);
+ }
+ return (short)(j1 + j2);
+ }
+
+
+ //===============================================
+ // Safepointa and debug info for deoptimization
+ static short simple_deop(short i) {
+ Short ib = new Short(foo(i));
+ dummy();
+ return ib;
+ }
+
+ static short simpleb_deop(short i) {
+ Short ib = Short.valueOf(foo(i));
+ dummy();
+ return ib;
+ }
+
+ static short simplef_deop(short i) {
+ Short ib = foob(i);
+ dummy();
+ return ib;
+ }
+
+ static short simplep_deop(Short ib) {
+ dummy();
+ return ib;
+ }
+
+ static short simplec_deop(short i) {
+ Short ib = ibc;
+ dummy();
+ return ib;
+ }
+
+ static short test_deop(short i) {
+ Short ib = new Short(foo(i));
+ if ((i&1) == 0)
+ ib = foo((short)(i+1));
+ dummy();
+ return ib;
+ }
+
+ static short testb_deop(short i) {
+ Short ib = foo(i);
+ if ((i&1) == 0)
+ ib = foo((short)(i+1));
+ dummy();
+ return ib;
+ }
+
+ static short testf_deop(short i) {
+ Short ib = foob(i);
+ if ((i&1) == 0)
+ ib = foo((short)(i+1));
+ dummy();
+ return ib;
+ }
+
+ static short testp_deop(short i, Short ib) {
+ if ((i&1) == 0)
+ ib = foo((short)(i+1));
+ dummy();
+ return ib;
+ }
+
+ static short testc_deop(short i) {
+ Short ib = ibc;
+ if ((i&1) == 0)
+ ib = foo((short)(i+1));
+ dummy();
+ return ib;
+ }
+
+ static short sum_deop(short[] a) {
+ short result = 1;
+ for (Short i : a)
+ result += foo(i);
+ dummy();
+ return result;
+ }
+
+ static short sumb_deop(short[] a) {
+ Short result = 1;
+ for (Short i : a)
+ result = (short)(result + foo(i));
+ dummy();
+ return result;
+ }
+
+ static short sumf_deop(short[] a) {
+ Short result = 1;
+ for (Short i : a)
+ result = (short)(result + foob(i));
+ dummy();
+ return result;
+ }
+
+ static short sump_deop(short[] a, Short result) {
+ for (Short i : a)
+ result = (short)(result + foob(i));
+ dummy();
+ return result;
+ }
+
+ static short sumc_deop(short[] a) {
+ Short result = ibc;
+ for (Short i : a)
+ result = (short)(result + foo(i));
+ dummy();
+ return result;
+ }
+
+ static short remi_sum_deop() {
+ Short j = new Short(foo((short)1));
+ for (int i = 0; i< 1000; i++) {
+ j = new Short(foo((short)(j + 1)));
+ }
+ dummy();
+ return j;
+ }
+
+ static short remi_sumb_deop() {
+ Short j = Short.valueOf(foo((short)1));
+ for (int i = 0; i< 1000; i++) {
+ j = foo((short)(j + 1));
+ }
+ dummy();
+ return j;
+ }
+
+ static short remi_sumf_deop() {
+ Short j = foob((short)1);
+ for (int i = 0; i< 1000; i++) {
+ j = foo((short)(j + 1));
+ }
+ dummy();
+ return j;
+ }
+
+ static short remi_sump_deop(Short j) {
+ for (int i = 0; i< 1000; i++) {
+ j = foo((short)(j + 1));
+ }
+ dummy();
+ return j;
+ }
+
+ static short remi_sumc_deop() {
+ Short j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ j = foo((short)(j + 1));
+ }
+ dummy();
+ return j;
+ }
+
+ //===============================================
+ // Conditional increment
+ static short remi_sum_cond() {
+ Short j = new Short((short)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = new Short((short)(j + 1));
+ }
+ }
+ return j;
+ }
+
+ static short remi_sumb_cond() {
+ Short j = Short.valueOf((short)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = (short)(j + 1);
+ }
+ }
+ return j;
+ }
+
+ static short remi_sumf_cond() {
+ Short j = foob((short)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = (short)(j + 1);
+ }
+ }
+ return j;
+ }
+
+ static short remi_sump_cond(Short j) {
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = (short)(j + 1);
+ }
+ }
+ return j;
+ }
+
+ static short remi_sumc_cond() {
+ Short j = ibc;
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j = (short)(j + ibc);
+ }
+ }
+ return j;
+ }
+
+ static short remi_sum2_cond() {
+ Short j1 = new Short((short)1);
+ Short j2 = new Short((short)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Short((short)(j1 + 1));
+ } else {
+ j2 = new Short((short)(j2 + 2));
+ }
+ }
+ return (short)(j1 + j2);
+ }
+
+ static short remi_sumb2_cond() {
+ Short j1 = Short.valueOf((short)1);
+ Short j2 = Short.valueOf((short)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = (short)(j1 + 1);
+ } else {
+ j2 = (short)(j2 + 2);
+ }
+ }
+ return (short)(j1 + j2);
+ }
+
+ static short remi_summ2_cond() {
+ Short j1 = new Short((short)1);
+ Short j2 = Short.valueOf((short)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Short((short)(j1 + 1));
+ } else {
+ j2 = (short)(j2 + 2);
+ }
+ }
+ return (short)(j1 + j2);
+ }
+
+ static short remi_sump2_cond(Short j1) {
+ Short j2 = Short.valueOf((short)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = new Short((short)(j1 + 1));
+ } else {
+ j2 = (short)(j2 + 2);
+ }
+ }
+ return (short)(j1 + j2);
+ }
+
+ static short remi_sumc2_cond() {
+ Short j1 = ibc;
+ Short j2 = Short.valueOf((short)1);
+ for (int i = 0; i< 1000; i++) {
+ if ((i&1) == 0) {
+ j1 = (short)(j1 + ibc);
+ } else {
+ j2 = (short)(j2 + 2);
+ }
+ }
+ return (short)(j1 + j2);
+ }
+
+
+ public static void main(String[] args) {
+ final int ntests = 70;
+
+ String[] test_name = new String[] {
+ "simple", "simpleb", "simplec", "simplef", "simplep",
+ "simple2", "simpleb2", "simplec2", "simplem2", "simplep2",
+ "simple_deop", "simpleb_deop", "simplec_deop", "simplef_deop", "simplep_deop",
+ "test", "testb", "testc", "testm", "testp",
+ "test2", "testb2", "testc2", "testm2", "testp2",
+ "test_deop", "testb_deop", "testc_deop", "testf_deop", "testp_deop",
+ "sum", "sumb", "sumc", "sumf", "sump",
+ "sum2", "sumb2", "sumc2", "summ2", "sump2",
+ "sum_deop", "sumb_deop", "sumc_deop", "sumf_deop", "sump_deop",
+ "remi_sum", "remi_sumb", "remi_sumc", "remi_sumf", "remi_sump",
+ "remi_sum2", "remi_sumb2", "remi_sumc2", "remi_summ2", "remi_sump2",
+ "remi_sum_deop", "remi_sumb_deop", "remi_sumc_deop", "remi_sumf_deop", "remi_sump_deop",
+ "remi_sum_cond", "remi_sumb_cond", "remi_sumc_cond", "remi_sumf_cond", "remi_sump_cond",
+ "remi_sum2_cond", "remi_sumb2_cond", "remi_sumc2_cond", "remi_summ2_cond", "remi_sump2_cond"
+ };
+
+ final int[] val = new int[] {
+ 71994000, 71994000, 12000, 71994000, 71994000,
+ 144000000, 144000000, 72018000, 144000000, 144000000,
+ 71994000, 71994000, 12000, 71994000, 71994000,
+ 72000000, 72000000, 36006000, 72000000, 72000000,
+ 144012000, 144012000, 72030000, 144012000, 144012000,
+ 72000000, 72000000, 36006000, 72000000, 72000000,
+ -24787, -24787, -24787, -24787, -24787,
+ 16962, 16962, 16962, 16962, 16962,
+ -24787, -24787, -24787, -24787, -24787,
+ 1001, 1001, 1001, 1001, 1001,
+ 3002, 3002, 3002, 3002, 3002,
+ 1001, 1001, 1001, 1001, 1001,
+ 501, 501, 501, 501, 501,
+ 1502, 1502, 1502, 1502, 1502
+ };
+
+ int[] res = new int[ntests];
+ for (int i = 0; i < ntests; i++) {
+ res[i] = 0;
+ }
+
+
+ for (int i = 0; i < 12000; i++) {
+ res[0] += simple((short)i);
+ res[1] += simpleb((short)i);
+ res[2] += simplec();
+ res[3] += simplef((short)i);
+ res[4] += simplep((short)i);
+
+ res[5] += simple2((short)i);
+ res[6] += simpleb2((short)i);
+ res[7] += simplec2((short)i);
+ res[8] += simplem2((short)i);
+ res[9] += simplep2((short)i, (short)i);
+
+ res[10] += simple_deop((short)i);
+ res[11] += simpleb_deop((short)i);
+ res[12] += simplec_deop((short)i);
+ res[13] += simplef_deop((short)i);
+ res[14] += simplep_deop((short)i);
+
+ res[15] += test((short)i);
+ res[16] += testb((short)i);
+ res[17] += testc((short)i);
+ res[18] += testm((short)i);
+ res[19] += testp((short)i, (short)i);
+
+ res[20] += test2((short)i);
+ res[21] += testb2((short)i);
+ res[22] += testc2((short)i);
+ res[23] += testm2((short)i);
+ res[24] += testp2((short)i, (short)i);
+
+ res[25] += test_deop((short)i);
+ res[26] += testb_deop((short)i);
+ res[27] += testc_deop((short)i);
+ res[28] += testf_deop((short)i);
+ res[29] += testp_deop((short)i, (short)i);
+ }
+
+ short[] ia = new short[1000];
+ for (int i = 0; i < 1000; i++) {
+ ia[i] = (short)i;
+ }
+
+ for (int i = 0; i < 100; i++) {
+ res[30] = sum(ia);
+ res[31] = sumb(ia);
+ res[32] = sumc(ia);
+ res[33] = sumf(ia);
+ res[34] = sump(ia, (short)1);
+
+ res[35] = sum2(ia);
+ res[36] = sumb2(ia);
+ res[37] = sumc2(ia);
+ res[38] = summ2(ia);
+ res[39] = sump2(ia, (short)1);
+
+ res[40] = sum_deop(ia);
+ res[41] = sumb_deop(ia);
+ res[42] = sumc_deop(ia);
+ res[43] = sumf_deop(ia);
+ res[44] = sump_deop(ia, (short)1);
+
+ res[45] = remi_sum();
+ res[46] = remi_sumb();
+ res[47] = remi_sumc();
+ res[48] = remi_sumf();
+ res[49] = remi_sump((short)1);
+
+ res[50] = remi_sum2();
+ res[51] = remi_sumb2();
+ res[52] = remi_sumc2();
+ res[53] = remi_summ2();
+ res[54] = remi_sump2((short)1);
+
+ res[55] = remi_sum_deop();
+ res[56] = remi_sumb_deop();
+ res[57] = remi_sumc_deop();
+ res[58] = remi_sumf_deop();
+ res[59] = remi_sump_deop((short)1);
+
+ res[60] = remi_sum_cond();
+ res[61] = remi_sumb_cond();
+ res[62] = remi_sumc_cond();
+ res[63] = remi_sumf_cond();
+ res[64] = remi_sump_cond((short)1);
+
+ res[65] = remi_sum2_cond();
+ res[66] = remi_sumb2_cond();
+ res[67] = remi_sumc2_cond();
+ res[68] = remi_summ2_cond();
+ res[69] = remi_sump2_cond((short)1);
+ }
+
+ int failed = 0;
+ for (int i = 0; i < ntests; i++) {
+ if (res[i] != val[i]) {
+ System.err.println(test_name[i] + ": " + res[i] + " != " + val[i]);
+ failed++;
+ }
+ }
+ if (failed > 0) {
+ System.err.println("Failed " + failed + " tests.");
+ throw new InternalError();
+ } else {
+ System.out.println("Passed.");
+ }
+ }
+}
diff --git a/hotspot/test/compiler/8009761/Test8009761.java b/hotspot/test/compiler/8009761/Test8009761.java
index f588b82cd23..401458b6b92 100644
--- a/hotspot/test/compiler/8009761/Test8009761.java
+++ b/hotspot/test/compiler/8009761/Test8009761.java
@@ -25,7 +25,7 @@
* @test
* @bug 8009761
* @summary Deoptimization on sparc doesn't set Llast_SP correctly in the interpreter frames it creates
- * @run main/othervm -Xmixed -XX:-UseOnStackReplacement -XX:-BackgroundCompilation Test8009761
+ * @run main/othervm -XX:CompileCommand=exclude,Test8009761::m2 -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -Xss256K Test8009761
*
*/
@@ -249,7 +249,7 @@ public class Test8009761 {
System.out.println("Failed: init recursive calls: " + c1 + ". After deopt " + count);
System.exit(97);
} else {
- System.out.println("PASSED");
+ System.out.println("PASSED " + c1);
}
}
}
diff --git a/hotspot/test/compiler/8010927/Test8010927.java b/hotspot/test/compiler/8010927/Test8010927.java
new file mode 100644
index 00000000000..6c9d9ab3d69
--- /dev/null
+++ b/hotspot/test/compiler/8010927/Test8010927.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8010927
+ * @summary Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
+ * @library /testlibrary/whitebox /testlibrary
+ * @build Test8010927
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. -Xmx64m -XX:NewSize=20971520 -XX:MaxNewSize=32m -XX:-UseTLAB -XX:-UseParNewGC -XX:-UseAdaptiveSizePolicy Test8010927
+ */
+
+import sun.hotspot.WhiteBox;
+import java.lang.reflect.Field;
+import sun.misc.Unsafe;
+
+/**
+ * The test creates uncommitted space between oldgen and young gen
+ * by specifying MaxNewSize bigger than NewSize.
+ * NewSize = 20971520 = (512*4K) * 10 for 4k pages
+ * Then it tries to execute arraycopy() with elements type check
+ * to the array at the end of survive space near unused space.
+ */
+
+public class Test8010927 {
+
+ private static final Unsafe U;
+
+ static {
+ try {
+ Field unsafe = Unsafe.class.getDeclaredField("theUnsafe");
+ unsafe.setAccessible(true);
+ U = (Unsafe) unsafe.get(null);
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+ }
+
+ public static Object[] o;
+
+ public static final boolean debug = Boolean.getBoolean("debug");
+
+ // 2 different obect arrays but same element types
+ static Test8010927[] masterA;
+ static Object[] masterB;
+ static final Test8010927 elem = new Test8010927();
+ static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+ static final int obj_header_size = U.ARRAY_OBJECT_BASE_OFFSET;
+ static final int heap_oop_size = wb.getHeapOopSize();
+ static final int card_size = 512;
+ static final int one_card = (card_size - obj_header_size)/heap_oop_size;
+
+ static final int surv_size = 2112 * 1024;
+
+ // The size is big to not fit into survive space.
+ static final Object[] cache = new Object[(surv_size / card_size)];
+
+ public static void main(String[] args) {
+ masterA = new Test8010927[one_card];
+ masterB = new Object[one_card];
+ for (int i = 0; i < one_card; ++i) {
+ masterA[i] = elem;
+ masterB[i] = elem;
+ }
+
+ // Move cache[] to the old gen.
+ long low_limit = wb.getObjectAddress(cache);
+ System.gc();
+ // Move 'cache' to oldgen.
+ long upper_limit = wb.getObjectAddress(cache);
+ if ((low_limit - upper_limit) > 0) { // substaction works with unsigned values
+ // OldGen is placed before youngger for ParallelOldGC.
+ upper_limit = low_limit + 21000000l; // +20971520
+ }
+ // Each A[one_card] size is 512 bytes,
+ // it will take about 40000 allocations to trigger GC.
+ // cache[] has 8192 elements so GC should happen
+ // each 5th iteration.
+ for(long l = 0; l < 20; l++) {
+ fill_heap();
+ if (debug) {
+ System.out.println("test oop_disjoint_arraycopy");
+ }
+ testA_arraycopy();
+ if (debug) {
+ System.out.println("test checkcast_arraycopy");
+ }
+ testB_arraycopy();
+ // Execute arraycopy to the topmost array in young gen
+ if (debug) {
+ int top_index = get_top_address(low_limit, upper_limit);
+ if (top_index >= 0) {
+ long addr = wb.getObjectAddress(cache[top_index]);
+ System.out.println("top_addr: 0x" + Long.toHexString(addr) + ", 0x" + Long.toHexString(addr + 512));
+ }
+ }
+ }
+ }
+ static void fill_heap() {
+ for (int i = 0; i < cache.length; ++i) {
+ o = new Test8010927[one_card];
+ System.arraycopy(masterA, 0, o, 0, masterA.length);
+ cache[i] = o;
+ }
+ for (long j = 0; j < 256; ++j) {
+ o = new Long[10000]; // to trigger GC
+ }
+ }
+ static void testA_arraycopy() {
+ for (int i = 0; i < cache.length; ++i) {
+ System.arraycopy(masterA, 0, cache[i], 0, masterA.length);
+ }
+ }
+ static void testB_arraycopy() {
+ for (int i = 0; i < cache.length; ++i) {
+ System.arraycopy(masterB, 0, cache[i], 0, masterB.length);
+ }
+ }
+ static int get_top_address(long min, long max) {
+ int index = -1;
+ long addr = min;
+ for (int i = 0; i < cache.length; ++i) {
+ long test = wb.getObjectAddress(cache[i]);
+ if (((test - addr) > 0) && ((max - test) > 0)) { // substaction works with unsigned values
+ addr = test;
+ index = i;
+ }
+ }
+ return index;
+ }
+}
diff --git a/hotspot/test/compiler/ciReplay/TestSA.sh b/hotspot/test/compiler/ciReplay/TestSA.sh
index daaec61d05a..6ea2c53a6ce 100644
--- a/hotspot/test/compiler/ciReplay/TestSA.sh
+++ b/hotspot/test/compiler/ciReplay/TestSA.sh
@@ -77,10 +77,11 @@ then
"replay data wasn't generated by SA"
fi
-diff --brief ${replay_data} replay_vm.txt
-if [ $? -ne 0 ]
+diff ${replay_data} replay_vm.txt > replay.diff 2>&1
+if [ -s replay.diff ]
then
- echo WARNING: replay.txt from SA != replay.txt from VM
+ echo WARNING: replay.txt from SA != replay.txt from VM:
+ cat replay.diff
fi
common_tests 10
diff --git a/hotspot/test/compiler/ciReplay/common.sh b/hotspot/test/compiler/ciReplay/common.sh
index 6b6ccd09b16..ec3b7fe33cf 100644
--- a/hotspot/test/compiler/ciReplay/common.sh
+++ b/hotspot/test/compiler/ciReplay/common.sh
@@ -182,8 +182,11 @@ echo "is_tiered=$is_tiered"
# crash vm in compiler thread with generation replay data and 'small' dump-file
# $@ - additional vm opts
generate_replay() {
- # enable core dump
- ulimit -c unlimited
+ if [ $VM_OS != "windows" ]
+ then
+ # enable core dump
+ ulimit -c unlimited
+ fi
cmd="${JAVA} ${TESTVMOPTS} $@ \
-Xms8m \
@@ -206,29 +209,24 @@ generate_replay() {
echo GENERATION OF REPLAY.TXT:
echo $cmd
- ${cmd} 2>&1 > crash.out
+ ${cmd} > crash.out 2>&1
core_locations=`grep -i core crash.out | grep "location:" | \
sed -e 's/.*location: //'`
rm crash.out
# processing core locations for *nix
- if [ $OS != "windows" ]
+ if [ $VM_OS != "windows" ]
then
# remove 'or' between '/core.' and 'core'
core_locations=`echo $core_locations | \
sed -e 's/\([^ ]*\) or \([^ ]*\)/\1 \2/'`
# add /core. core.
- core=`echo $core_locations | awk '{print $1}'`
- dir=`dirname $core`
- core=`basename $core`
- if [ -n ${core} ]
+ core_with_dir=`echo $core_locations | awk '{print $1}'`
+ dir=`dirname $core_with_dir`
+ core_with_pid=`echo $core_locations | awk '{print $2}'`
+ if [ -n ${core_with_pid} ]
then
- core_locations="$core_locations $dir${FS}$core"
- fi
- core=`echo $core_locations | awk '{print $2}'`
- if [ -n ${core} ]
- then
- core_locations="$core_locations $dir${FS}$core"
+ core_locations="$core_locations $dir${FS}$core_with_pid $core_with_pid"
fi
fi
diff --git a/hotspot/test/gc/arguments/TestCMSHeapSizeFlags.java b/hotspot/test/gc/arguments/TestCMSHeapSizeFlags.java
new file mode 100644
index 00000000000..3dc688ce8ab
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestCMSHeapSizeFlags.java
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestCMSHeapSizeFlags
+ * @key gc
+ * @bug 8006088
+ * @summary Tests argument processing for initial and maximum heap size for the CMS collector
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestCMSHeapSizeFlags TestMaxHeapSizeTools
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm TestCMSHeapSizeFlags
+ * @author thomas.schatzl@oracle.com
+ */
+
+public class TestCMSHeapSizeFlags {
+
+ public static void main(String args[]) throws Exception {
+ final String gcName = "-XX:+UseConcMarkSweepGC";
+
+ TestMaxHeapSizeTools.checkMinInitialMaxHeapFlags(gcName);
+
+ TestMaxHeapSizeTools.checkGenMaxHeapErgo(gcName);
+ }
+}
+
diff --git a/hotspot/test/gc/arguments/TestG1HeapSizeFlags.java b/hotspot/test/gc/arguments/TestG1HeapSizeFlags.java
new file mode 100644
index 00000000000..31ab5e333c0
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestG1HeapSizeFlags.java
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestG1HeapSizeFlags
+ * @key gc
+ * @bug 8006088
+ * @summary Tests argument processing for initial and maximum heap size for the G1 collector
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestG1HeapSizeFlags TestMaxHeapSizeTools
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm TestG1HeapSizeFlags
+ * @author thomas.schatzl@oracle.com
+ */
+
+public class TestG1HeapSizeFlags {
+
+ public static void main(String args[]) throws Exception {
+ final String gcName = "-XX:+UseG1GC";
+
+ TestMaxHeapSizeTools.checkMinInitialMaxHeapFlags(gcName);
+
+ TestMaxHeapSizeTools.checkGenMaxHeapErgo(gcName);
+ }
+}
+
diff --git a/hotspot/test/gc/arguments/TestInitialTenuringThreshold.java b/hotspot/test/gc/arguments/TestInitialTenuringThreshold.java
new file mode 100644
index 00000000000..2c97ccd8fff
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestInitialTenuringThreshold.java
@@ -0,0 +1,75 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestInitialTenuringThreshold
+ * @key gc
+ * @bug 8014765
+ * @summary Tests argument processing for initial tenuring threshold
+ * @library /testlibrary
+ * @run main/othervm TestInitialTenuringThreshold
+ * @author thomas.schatzl@oracle.com
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class TestInitialTenuringThreshold {
+
+ public static void runWithThresholds(int initial, int max, boolean shouldfail) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:InitialTenuringThreshold=" + String.valueOf(initial),
+ "-XX:MaxTenuringThreshold=" + String.valueOf(max),
+ "-version"
+ );
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ if (shouldfail) {
+ output.shouldHaveExitValue(1);
+ } else {
+ output.shouldHaveExitValue(0);
+ }
+ }
+
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ // some value below the default value of InitialTenuringThreshold of 7
+ "-XX:MaxTenuringThreshold=1",
+ "-version"
+ );
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldHaveExitValue(0);
+ // successful tests
+ runWithThresholds(0, 10, false);
+ runWithThresholds(5, 5, false);
+ // failing tests
+ runWithThresholds(10, 0, true);
+ runWithThresholds(9, 8, true);
+ runWithThresholds(-1, 8, true);
+ runWithThresholds(8, -1, true);
+ runWithThresholds(8, 16, true);
+ runWithThresholds(16, 8, true);
+ }
+}
+
diff --git a/hotspot/test/gc/arguments/TestMaxHeapSizeTools.java b/hotspot/test/gc/arguments/TestMaxHeapSizeTools.java
new file mode 100644
index 00000000000..cb7d841355e
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestMaxHeapSizeTools.java
@@ -0,0 +1,295 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import com.oracle.java.testlibrary.*;
+import sun.hotspot.WhiteBox;
+
+class ErgoArgsPrinter {
+ public static void main(String[] args) throws Exception {
+ WhiteBox wb = WhiteBox.getWhiteBox();
+ wb.printHeapSizes();
+ }
+}
+
+final class MinInitialMaxValues {
+ public long minHeapSize;
+ public long initialHeapSize;
+ public long maxHeapSize;
+
+ public long minAlignment;
+ public long maxAlignment;
+}
+
+class TestMaxHeapSizeTools {
+
+ public static void checkMinInitialMaxHeapFlags(String gcflag) throws Exception {
+ checkInvalidMinInitialHeapCombinations(gcflag);
+ checkValidMinInitialHeapCombinations(gcflag);
+ checkInvalidInitialMaxHeapCombinations(gcflag);
+ checkValidInitialMaxHeapCombinations(gcflag);
+ }
+
+ public static void checkMinInitialErgonomics(String gcflag) throws Exception {
+ // heap sizing ergonomics use the value NewSize + OldSize as default values
+ // for ergonomics calculation. Retrieve these values.
+ long[] values = new long[2];
+ getNewOldSize(gcflag, values);
+
+ // we check cases with values smaller and larger than this default value.
+ long newPlusOldSize = values[0] + values[1];
+ long smallValue = newPlusOldSize / 2;
+ long largeValue = newPlusOldSize * 2;
+
+ // -Xms is not set
+ checkErgonomics(new String[] { gcflag, "-Xmx16M" }, values, -1, -1);
+ checkErgonomics(new String[] { gcflag, "-Xmx16M", "-XX:InitialHeapSize=" + smallValue }, values, smallValue, smallValue);
+ checkErgonomics(new String[] { gcflag, "-Xmx16M", "-XX:InitialHeapSize=" + largeValue }, values, -1, largeValue);
+ checkErgonomics(new String[] { gcflag, "-Xmx16M", "-XX:InitialHeapSize=0" }, values, -1, -1);
+
+ // -Xms is set to zero
+ checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms0" }, values, -1, -1);
+ checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms0", "-XX:InitialHeapSize=" + smallValue }, values, smallValue, smallValue);
+ checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms0", "-XX:InitialHeapSize=" + largeValue }, values, -1, largeValue);
+ checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms0", "-XX:InitialHeapSize=0" }, values, -1, -1);
+
+ // -Xms is set to small value
+ checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + smallValue }, values, -1, -1);
+ checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + smallValue, "-XX:InitialHeapSize=" + smallValue }, values, smallValue, smallValue);
+ checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + smallValue, "-XX:InitialHeapSize=" + largeValue }, values, smallValue, largeValue);
+ checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + smallValue, "-XX:InitialHeapSize=0" }, values, smallValue, -1);
+
+ // -Xms is set to large value
+ checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + largeValue }, values, largeValue, largeValue);
+ // the next case has already been checked elsewhere and gives an error
+ // checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + largeValue, "-XX:InitialHeapSize=" + smallValue }, values, smallValue, smallValue);
+ // the next case has already been checked elsewhere too
+ // checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + largeValue, "-XX:InitialHeapSize=" + largeValue }, values, values[0], largeValue);
+ checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + largeValue, "-XX:InitialHeapSize=0" }, values, largeValue, -1);
+ }
+
+ private static long align_up(long value, long alignment) {
+ long alignmentMinusOne = alignment - 1;
+ return (value + alignmentMinusOne) & ~alignmentMinusOne;
+ }
+
+ private static void getNewOldSize(String gcflag, long[] values) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(gcflag,
+ "-XX:+PrintFlagsFinal", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldHaveExitValue(0);
+
+ String stdout = output.getStdout();
+ values[0] = getFlagValue(" NewSize", stdout);
+ values[1] = getFlagValue(" OldSize", stdout);
+ }
+
+ public static void checkGenMaxHeapErgo(String gcflag) throws Exception {
+ TestMaxHeapSizeTools.checkGenMaxHeapSize(gcflag, 3);
+ TestMaxHeapSizeTools.checkGenMaxHeapSize(gcflag, 4);
+ TestMaxHeapSizeTools.checkGenMaxHeapSize(gcflag, 5);
+ }
+
+ private static void checkInvalidMinInitialHeapCombinations(String gcflag) throws Exception {
+ expectError(new String[] { gcflag, "-Xms8M", "-XX:InitialHeapSize=4M", "-version" });
+ }
+
+ private static void checkValidMinInitialHeapCombinations(String gcflag) throws Exception {
+ expectValid(new String[] { gcflag, "-XX:InitialHeapSize=8M", "-Xms4M", "-version" });
+ expectValid(new String[] { gcflag, "-Xms4M", "-XX:InitialHeapSize=8M", "-version" });
+ expectValid(new String[] { gcflag, "-XX:InitialHeapSize=8M", "-Xms8M", "-version" });
+ // the following is not an error as -Xms sets both minimal and initial heap size
+ expectValid(new String[] { gcflag, "-XX:InitialHeapSize=4M", "-Xms8M", "-version" });
+ }
+
+ private static void checkInvalidInitialMaxHeapCombinations(String gcflag) throws Exception {
+ expectError(new String[] { gcflag, "-XX:MaxHeapSize=4M", "-XX:InitialHeapSize=8M", "-version" });
+ expectError(new String[] { gcflag, "-XX:InitialHeapSize=8M", "-XX:MaxHeapSize=4M", "-version" });
+ }
+
+ private static void checkValidInitialMaxHeapCombinations(String gcflag) throws Exception {
+ expectValid(new String[] { gcflag, "-XX:InitialHeapSize=4M", "-XX:MaxHeapSize=8M", "-version" });
+ expectValid(new String[] { gcflag, "-XX:MaxHeapSize=8M", "-XX:InitialHeapSize=4M", "-version" });
+ expectValid(new String[] { gcflag, "-XX:MaxHeapSize=4M", "-XX:InitialHeapSize=4M", "-version" });
+ // a value of "0" for initial heap size means auto-detect
+ expectValid(new String[] { gcflag, "-XX:MaxHeapSize=4M", "-XX:InitialHeapSize=0M", "-version" });
+ }
+
+ private static long valueAfter(String source, String match) {
+ int start = source.indexOf(match) + match.length();
+ String tail = source.substring(start).split(" ")[0];
+ return Long.parseLong(tail);
+ }
+
+ /**
+ * Executes a new VM process with the given class and parameters.
+ * @param vmargs Arguments to the VM to run
+ * @param classname Name of the class to run
+ * @param arguments Arguments to the class
+ * @param useTestDotJavaDotOpts Use test.java.opts as part of the VM argument string
+ * @return The OutputAnalyzer with the results for the invocation.
+ */
+ public static OutputAnalyzer runWhiteBoxTest(String[] vmargs, String classname, String[] arguments, boolean useTestDotJavaDotOpts) throws Exception {
+ ArrayList finalargs = new ArrayList();
+
+ String[] whiteboxOpts = new String[] {
+ "-Xbootclasspath/a:.",
+ "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+ "-cp", System.getProperty("java.class.path"),
+ };
+
+ if (useTestDotJavaDotOpts) {
+ // System.getProperty("test.java.opts") is '' if no options is set,
+ // we need to skip such a result
+ String[] externalVMOpts = new String[0];
+ if (System.getProperty("test.java.opts") != null && System.getProperty("test.java.opts").length() != 0) {
+ externalVMOpts = System.getProperty("test.java.opts").split(" ");
+ }
+ finalargs.addAll(Arrays.asList(externalVMOpts));
+ }
+
+ finalargs.addAll(Arrays.asList(vmargs));
+ finalargs.addAll(Arrays.asList(whiteboxOpts));
+ finalargs.add(classname);
+ finalargs.addAll(Arrays.asList(arguments));
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0]));
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldHaveExitValue(0);
+
+ return output;
+ }
+
+ private static void getMinInitialMaxHeap(String[] args, MinInitialMaxValues val) throws Exception {
+ OutputAnalyzer output = runWhiteBoxTest(args, ErgoArgsPrinter.class.getName(), new String[] {}, false);
+
+ // the output we watch for has the following format:
+ //
+ // "Minimum heap X Initial heap Y Maximum heap Z Min alignment A Max Alignment B"
+ //
+ // where A, B, X, Y and Z are sizes in bytes.
+ // Unfortunately there is no other way to retrieve the minimum heap size and
+ // the alignments.
+
+ Matcher m = Pattern.compile("Minimum heap \\d+ Initial heap \\d+ Maximum heap \\d+ Min alignment \\d+ Max alignment \\d+").
+ matcher(output.getStdout());
+ if (!m.find()) {
+ throw new RuntimeException("Could not find heap size string.");
+ }
+
+ String match = m.group();
+
+ // actual values
+ val.minHeapSize = valueAfter(match, "Minimum heap ");
+ val.initialHeapSize = valueAfter(match, "Initial heap ");
+ val.maxHeapSize = valueAfter(match, "Maximum heap ");
+ val.minAlignment = valueAfter(match, "Min alignment ");
+ val.maxAlignment = valueAfter(match, "Max alignment ");
+ }
+
+ /**
+ * Verify whether the VM automatically synchronizes minimum and initial heap size if only
+ * one is given for the GC specified.
+ */
+ public static void checkErgonomics(String[] args, long[] newoldsize,
+ long expectedMin, long expectedInitial) throws Exception {
+
+ MinInitialMaxValues v = new MinInitialMaxValues();
+ getMinInitialMaxHeap(args, v);
+
+ if ((expectedMin != -1) && (align_up(expectedMin, v.minAlignment) != v.minHeapSize)) {
+ throw new RuntimeException("Actual minimum heap size of " + v.minHeapSize +
+ " differs from expected minimum heap size of " + expectedMin);
+ }
+
+ if ((expectedInitial != -1) && (align_up(expectedInitial, v.minAlignment) != v.initialHeapSize)) {
+ throw new RuntimeException("Actual initial heap size of " + v.initialHeapSize +
+ " differs from expected initial heap size of " + expectedInitial);
+ }
+
+ // always check the invariant min <= initial <= max heap size
+ if (!(v.minHeapSize <= v.initialHeapSize && v.initialHeapSize <= v.maxHeapSize)) {
+ throw new RuntimeException("Inconsistent min/initial/max heap sizes, they are " +
+ v.minHeapSize + "/" + v.initialHeapSize + "/" + v.maxHeapSize);
+ }
+ }
+
+ /**
+ * Verify whether the VM respects the given maximum heap size in MB for the
+ * GC specified.
+ * @param gcflag The garbage collector to test as command line flag. E.g. -XX:+UseG1GC
+ * @param maxHeapSize the maximum heap size to verify, in MB.
+ */
+ public static void checkGenMaxHeapSize(String gcflag, long maxHeapsize) throws Exception {
+ final long K = 1024;
+
+ MinInitialMaxValues v = new MinInitialMaxValues();
+ getMinInitialMaxHeap(new String[] { gcflag, "-XX:MaxHeapSize=" + maxHeapsize + "M" }, v);
+
+ long expectedHeapSize = align_up(maxHeapsize * K * K, v.maxAlignment);
+ long actualHeapSize = v.maxHeapSize;
+
+ if (actualHeapSize > expectedHeapSize) {
+ throw new RuntimeException("Heap has " + actualHeapSize +
+ " bytes, expected to be less than " + expectedHeapSize);
+ }
+ }
+
+ private static long getFlagValue(String flag, String where) {
+ Matcher m = Pattern.compile(flag + "\\s+:?=\\s+\\d+").matcher(where);
+ if (!m.find()) {
+ throw new RuntimeException("Could not find value for flag " + flag + " in output string");
+ }
+ String match = m.group();
+ return Long.parseLong(match.substring(match.lastIndexOf(" ") + 1, match.length()));
+ }
+
+ private static void shouldContainOrNot(OutputAnalyzer output, boolean contains, String message) throws Exception {
+ if (contains) {
+ output.shouldContain(message);
+ } else {
+ output.shouldNotContain(message);
+ }
+ }
+
+ private static void expect(String[] flags, boolean hasWarning, boolean hasError, int errorcode) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags);
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ shouldContainOrNot(output, hasWarning, "Warning");
+ shouldContainOrNot(output, hasError, "Error");
+ output.shouldHaveExitValue(errorcode);
+ }
+
+ private static void expectError(String[] flags) throws Exception {
+ expect(flags, false, true, 1);
+ }
+
+ private static void expectValid(String[] flags) throws Exception {
+ expect(flags, false, false, 0);
+ }
+}
+
diff --git a/hotspot/test/gc/arguments/TestMinInitialErgonomics.java b/hotspot/test/gc/arguments/TestMinInitialErgonomics.java
new file mode 100644
index 00000000000..8352d92c8b0
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestMinInitialErgonomics.java
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/**
+ * @test TestMinInitialErgonomics
+ * @key gc
+ * @bug 8006088
+ * @summary Test ergonomics decisions related to minimum and initial heap size.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestMinInitialErgonomics TestMaxHeapSizeTools
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm TestMinInitialErgonomics
+ * @author thomas.schatzl@oracle.com
+ */
+
+public class TestMinInitialErgonomics {
+
+ public static void main(String args[]) throws Exception {
+ final String gcName = "-XX:+UseParallelGC";
+ // check ergonomic decisions about minimum and initial heap size in
+ // a single gc only as ergonomics are the same everywhere.
+ TestMaxHeapSizeTools.checkMinInitialErgonomics(gcName);
+ }
+}
+
diff --git a/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java b/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java
new file mode 100644
index 00000000000..2de2826ed5b
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestParallelHeapSizeFlags
+ * @key gc
+ * @bug 8006088
+ * @summary Tests argument processing for initial and maximum heap size for the
+ * parallel collectors.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestParallelHeapSizeFlags TestMaxHeapSizeTools
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm TestParallelHeapSizeFlags
+ * @author thomas.schatzl@oracle.com
+ */
+
+public class TestParallelHeapSizeFlags {
+
+ public static void main(String args[]) throws Exception {
+ // just pick one of the parallel generational collectors. Sizing logic is the
+ // same.
+ final String gcName = "-XX:+UseParallelOldGC";
+
+ TestMaxHeapSizeTools.checkMinInitialMaxHeapFlags(gcName);
+
+ TestMaxHeapSizeTools.checkGenMaxHeapErgo(gcName);
+ }
+}
+
diff --git a/hotspot/test/gc/arguments/TestSerialHeapSizeFlags.java b/hotspot/test/gc/arguments/TestSerialHeapSizeFlags.java
new file mode 100644
index 00000000000..967adf64147
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestSerialHeapSizeFlags.java
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestSerialHeapSizeFlags
+ * @key gc
+ * @bug 8006088
+ * @summary Tests argument processing for initial and maximum heap size for the Serial collector
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestSerialHeapSizeFlags TestMaxHeapSizeTools
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm TestSerialHeapSizeFlags
+ * @author thomas.schatzl@oracle.com
+ */
+
+public class TestSerialHeapSizeFlags {
+
+ public static void main(String args[]) throws Exception {
+ final String gcName = "-XX:+UseSerialGC";
+
+ TestMaxHeapSizeTools.checkMinInitialMaxHeapFlags(gcName);
+
+ TestMaxHeapSizeTools.checkGenMaxHeapErgo(gcName);
+ }
+}
+
diff --git a/hotspot/test/gc/g1/TestPrintGCDetails.java b/hotspot/test/gc/g1/TestPrintGCDetails.java
new file mode 100644
index 00000000000..4280a19cd25
--- /dev/null
+++ b/hotspot/test/gc/g1/TestPrintGCDetails.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestPrintGCDetails
+ * @bug 8010738
+ * @summary Ensure that the PrintGCDetails for a full GC with G1 includes Metaspace.
+ * @key gc
+ * @key regression
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class TestPrintGCDetails {
+ public static void main(String[] args) throws Exception {
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
+ "-XX:+PrintGCDetails",
+ SystemGCTest.class.getName());
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+ System.out.println("Output:\n" + output.getOutput());
+
+ output.shouldContain("Metaspace");
+ output.shouldHaveExitValue(0);
+ }
+
+ static class SystemGCTest {
+ public static void main(String [] args) {
+ System.out.println("Calling System.gc()");
+ System.gc();
+ }
+ }
+}
diff --git a/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java b/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java
new file mode 100644
index 00000000000..417b2cc1a39
--- /dev/null
+++ b/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test TestPrintRegionRememberedSetInfo
+ * @key gc
+ * @bug 8014240
+ * @summary Test output of G1PrintRegionRememberedSetInfo
+ * @library /testlibrary
+ * @build TestPrintRegionRememberedSetInfo
+ * @author thomas.schatzl@oracle.com
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.lang.Thread;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+class RunAndWaitForMarking {
+ public static void main(String[] args) {
+ System.gc();
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ }
+ }
+}
+
+public class TestPrintRegionRememberedSetInfo {
+
+ public static String runTest(String arg) throws Exception {
+ ArrayList finalargs = new ArrayList();
+ String[] defaultArgs = new String[] {
+ "-XX:+UseG1GC",
+ "-Xmx10m",
+ "-XX:+ExplicitGCInvokesConcurrent",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+G1PrintRegionLivenessInfo",
+ "-XX:G1HeapRegionSize=1M",
+ "-XX:InitiatingHeapOccupancyPercent=0",
+ };
+
+ finalargs.addAll(Arrays.asList(defaultArgs));
+ finalargs.add(arg);
+
+ finalargs.add(RunAndWaitForMarking.class.getName());
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ finalargs.toArray(new String[0]));
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldHaveExitValue(0);
+
+ String result = output.getStdout();
+ return result;
+ }
+
+ public static void main(String[] args) throws Exception {
+ String result;
+
+ result = runTest("-XX:+G1PrintRegionLivenessInfo");
+ // check that we got region statistics output
+ if (result.indexOf("PHASE") == -1) {
+ throw new RuntimeException("Unexpected output from -XX:+PrintRegionLivenessInfo found.");
+ }
+
+ result = runTest("-XX:-G1PrintRegionLivenessInfo");
+ if (result.indexOf("remset") != -1) {
+ throw new RuntimeException("Should find remembered set information in output.");
+ }
+ }
+}
+
diff --git a/hotspot/test/runtime/7158804/Test7158804.sh b/hotspot/test/runtime/7158804/Test7158804.sh
deleted file mode 100644
index b5380ec8eb4..00000000000
--- a/hotspot/test/runtime/7158804/Test7158804.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-
-##
-## @test Test7158804.sh
-## @bug 7158804
-## @summary Improve config file parsing
-## @run shell Test7158804.sh
-##
-if [ "${TESTSRC}" = "" ]
-then
- TESTSRC=${PWD}
- echo "TESTSRC not set. Using "${TESTSRC}" as default"
-fi
-echo "TESTSRC=${TESTSRC}"
-## Adding common setup Variables for running shell tests.
-. ${TESTSRC}/../../test_env.sh
-
-rm -f .hotspotrc
-echo -XX:+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >.hotspotrc
-${TESTJAVA}/bin/java ${TESTVMOPTS} -XX:+IgnoreUnrecognizedVMOptions -XX:Flags=.hotspotrc -version
-if [ $? -ne 0 ]
-then
- echo "Test Failed"
- exit 1
-fi
-rm -f .hotspotrc
-exit 0
diff --git a/hotspot/test/runtime/CommandLine/ConfigFileParsing.java b/hotspot/test/runtime/CommandLine/ConfigFileParsing.java
new file mode 100644
index 00000000000..10a8c0b46d7
--- /dev/null
+++ b/hotspot/test/runtime/CommandLine/ConfigFileParsing.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test ConfigFileParsing
+ * @bug 7158804
+ * @summary Improve config file parsing
+ * @library /testlibrary
+ */
+
+import java.io.PrintWriter;
+import com.oracle.java.testlibrary.*;
+
+public class ConfigFileParsing {
+ public static void main(String[] args) throws Exception {
+ String testFileName = ".hotspotrc";
+
+ // Create really long invalid option
+ String reallyLongInvalidOption = "";
+ for (int i=0; i<5000; i++)
+ reallyLongInvalidOption+='a';
+
+ // Populate the options file with really long string
+ PrintWriter pw = new PrintWriter(testFileName);
+ pw.println("-XX:+" + reallyLongInvalidOption);
+ pw.close();
+
+ // start VM
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+IgnoreUnrecognizedVMOptions", "-XX:Flags=.hotspotrc", "-version");
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldHaveExitValue(0);
+ }
+}
diff --git a/hotspot/test/runtime/RedefineObject/Agent.java b/hotspot/test/runtime/RedefineObject/Agent.java
new file mode 100644
index 00000000000..7927094d8aa
--- /dev/null
+++ b/hotspot/test/runtime/RedefineObject/Agent.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.security.*;
+import java.lang.instrument.*;
+
+public class Agent implements ClassFileTransformer {
+ public synchronized byte[] transform(final ClassLoader classLoader,
+ final String className,
+ Class> classBeingRedefined,
+ ProtectionDomain protectionDomain,
+ byte[] classfileBuffer) {
+ //System.out.println("Transforming class " + className);
+ return classfileBuffer;
+ }
+
+ public static void premain(String agentArgs, Instrumentation instrumentation) {
+
+ Agent transformer = new Agent();
+
+ instrumentation.addTransformer(transformer, true);
+
+ Class c = Object.class;
+ try {
+ instrumentation.retransformClasses(c);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ instrumentation.removeTransformer(transformer);
+ }
+
+ public static void main(String[] args) {
+ byte[] ba = new byte[0];
+
+ // If it survives 1000 GC's, it's good.
+ for (int i = 0; i < 1000 ; i++) {
+ System.gc();
+ ba.clone();
+ }
+ }
+}
diff --git a/hotspot/test/runtime/RedefineObject/TestRedefineObject.java b/hotspot/test/runtime/RedefineObject/TestRedefineObject.java
new file mode 100644
index 00000000000..bd5003a588a
--- /dev/null
+++ b/hotspot/test/runtime/RedefineObject/TestRedefineObject.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.io.PrintWriter;
+import com.oracle.java.testlibrary.*;
+
+/*
+ * Test to redefine java/lang/Object and verify that it doesn't crash on vtable
+ * call on basic array type.
+ *
+ * @test
+ * @bug 8005056
+ * @library /testlibrary
+ * @build Agent
+ * @run main ClassFileInstaller Agent
+ * @run main TestRedefineObject
+ * @run main/othervm -javaagent:agent.jar Agent
+ */
+public class TestRedefineObject {
+ public static void main(String[] args) throws Exception {
+
+ PrintWriter pw = new PrintWriter("MANIFEST.MF");
+ pw.println("Premain-Class: Agent");
+ pw.println("Can-Retransform-Classes: true");
+ pw.close();
+
+ ProcessBuilder pb = new ProcessBuilder();
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jar"), "cmf", "MANIFEST.MF", "agent.jar", "Agent.class"});
+ pb.start().waitFor();
+ }
+}
diff --git a/hotspot/test/runtime/SharedArchiveFile/SharedArchiveFile.java b/hotspot/test/runtime/SharedArchiveFile/SharedArchiveFile.java
new file mode 100644
index 00000000000..802e251bd03
--- /dev/null
+++ b/hotspot/test/runtime/SharedArchiveFile/SharedArchiveFile.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8014138
+ * @summary Testing new -XX:SharedArchiveFile= option
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class SharedArchiveFile {
+ public static void main(String[] args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ try {
+ output.shouldContain("Loading classes to share");
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("sharing");
+ output.shouldHaveExitValue(0);
+
+ } catch (RuntimeException e) {
+ output.shouldContain("Unable to use shared archive");
+ output.shouldHaveExitValue(1);
+ }
+ }
+}
diff --git a/hotspot/test/runtime/8003985/Test8003985.java b/hotspot/test/runtime/contended/Basic.java
similarity index 99%
rename from hotspot/test/runtime/8003985/Test8003985.java
rename to hotspot/test/runtime/contended/Basic.java
index 5e30f670257..e15461451a7 100644
--- a/hotspot/test/runtime/8003985/Test8003985.java
+++ b/hotspot/test/runtime/contended/Basic.java
@@ -43,9 +43,9 @@ import sun.misc.Contended;
* @bug 8003985
* @summary Support Contended Annotation - JEP 142
*
- * @run main/othervm -XX:-RestrictContended Test8003985
+ * @run main/othervm -XX:-RestrictContended Basic
*/
-public class Test8003985 {
+public class Basic {
private static final Unsafe U;
private static int ADDRESS_SIZE;
diff --git a/hotspot/test/runtime/contended/DefaultValue.java b/hotspot/test/runtime/contended/DefaultValue.java
new file mode 100644
index 00000000000..6f60672428b
--- /dev/null
+++ b/hotspot/test/runtime/contended/DefaultValue.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.lang.Class;
+import java.lang.String;
+import java.lang.System;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CyclicBarrier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import sun.misc.Unsafe;
+import sun.misc.Contended;
+
+/*
+ * @test
+ * @bug 8014509
+ * @summary \@Contended: explicit default value behaves differently from the implicit value
+ *
+ * @run main/othervm -XX:-RestrictContended DefaultValue
+ */
+public class DefaultValue {
+
+ private static final Unsafe U;
+ private static int ADDRESS_SIZE;
+ private static int HEADER_SIZE;
+
+ static {
+ // steal Unsafe
+ try {
+ Field unsafe = Unsafe.class.getDeclaredField("theUnsafe");
+ unsafe.setAccessible(true);
+ U = (Unsafe) unsafe.get(null);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ }
+
+ // When running with CompressedOops on 64-bit platform, the address size
+ // reported by Unsafe is still 8, while the real reference fields are 4 bytes long.
+ // Try to guess the reference field size with this naive trick.
+ try {
+ long off1 = U.objectFieldOffset(CompressedOopsClass.class.getField("obj1"));
+ long off2 = U.objectFieldOffset(CompressedOopsClass.class.getField("obj2"));
+ ADDRESS_SIZE = (int) Math.abs(off2 - off1);
+ HEADER_SIZE = (int) Math.min(off1, off2);
+ } catch (NoSuchFieldException e) {
+ ADDRESS_SIZE = -1;
+ }
+ }
+
+ static class CompressedOopsClass {
+ public Object obj1;
+ public Object obj2;
+ }
+
+ public static boolean arePaddedPairwise(Class klass, String field1, String field2) throws Exception {
+ Field f1 = klass.getField(field1);
+ Field f2 = klass.getField(field2);
+
+ int diff = offset(f1) - offset(f2);
+ if (diff < 0) {
+ // f1 is first
+ return (offset(f2) - (offset(f1) + getSize(f1))) > 64;
+ } else {
+ // f2 is first
+ return (offset(f1) - (offset(f2) + getSize(f2))) > 64;
+ }
+ }
+
+ public static boolean sameLayout(Class klass1, Class klass2) throws Exception {
+ for (Field f1 : klass1.getDeclaredFields()) {
+ Field f2 = klass2.getDeclaredField(f1.getName());
+ if (offset(f1) != offset(f2)) {
+ return false;
+ }
+ }
+
+ for (Field f2 : klass1.getDeclaredFields()) {
+ Field f1 = klass2.getDeclaredField(f2.getName());
+ if (offset(f1) != offset(f2)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static boolean isStatic(Field field) {
+ return Modifier.isStatic(field.getModifiers());
+ }
+
+ public static int offset(Field field) {
+ if (isStatic(field)) {
+ return (int) U.staticFieldOffset(field);
+ } else {
+ return (int) U.objectFieldOffset(field);
+ }
+ }
+
+ public static int getSize(Field field) {
+ Class type = field.getType();
+ if (type == byte.class) { return 1; }
+ if (type == boolean.class) { return 1; }
+ if (type == short.class) { return 2; }
+ if (type == char.class) { return 2; }
+ if (type == int.class) { return 4; }
+ if (type == float.class) { return 4; }
+ if (type == long.class) { return 8; }
+ if (type == double.class) { return 8; }
+ return ADDRESS_SIZE;
+ }
+
+ public static void main(String[] args) throws Exception {
+ boolean endResult = true;
+
+ if (!arePaddedPairwise(R1.class, "int1", "int2")) {
+ System.err.println("R1 failed");
+ endResult &= false;
+ }
+
+ if (!arePaddedPairwise(R2.class, "int1", "int2")) {
+ System.err.println("R2 failed");
+ endResult &= false;
+ }
+
+ if (!arePaddedPairwise(R3.class, "int1", "int2")) {
+ System.err.println("R3 failed");
+ endResult &= false;
+ }
+
+ System.out.println(endResult ? "Test PASSES" : "Test FAILS");
+ if (!endResult) {
+ throw new Error("Test failed");
+ }
+ }
+
+ public static class R1 {
+ @Contended
+ public int int1;
+ @Contended
+ public int int2;
+ }
+
+ public static class R2 {
+ @Contended("")
+ public int int1;
+ @Contended("")
+ public int int2;
+ }
+
+ public static class R3 {
+ @Contended()
+ public int int1;
+ @Contended()
+ public int int2;
+ }
+
+}
+
diff --git a/hotspot/test/runtime/contended/Inheritance1.java b/hotspot/test/runtime/contended/Inheritance1.java
new file mode 100644
index 00000000000..70b8e4c71bc
--- /dev/null
+++ b/hotspot/test/runtime/contended/Inheritance1.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.lang.Class;
+import java.lang.String;
+import java.lang.System;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CyclicBarrier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import sun.misc.Unsafe;
+import sun.misc.Contended;
+
+/*
+ * @test
+ * @bug 8012939
+ * @summary \@Contended doesn't work correctly with inheritance
+ *
+ * @run main/othervm -XX:-RestrictContended Inheritance1
+ */
+public class Inheritance1 {
+
+ private static final Unsafe U;
+ private static int ADDRESS_SIZE;
+ private static int HEADER_SIZE;
+
+ static {
+ // steal Unsafe
+ try {
+ Field unsafe = Unsafe.class.getDeclaredField("theUnsafe");
+ unsafe.setAccessible(true);
+ U = (Unsafe) unsafe.get(null);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ }
+
+ // When running with CompressedOops on 64-bit platform, the address size
+ // reported by Unsafe is still 8, while the real reference fields are 4 bytes long.
+ // Try to guess the reference field size with this naive trick.
+ try {
+ long off1 = U.objectFieldOffset(CompressedOopsClass.class.getField("obj1"));
+ long off2 = U.objectFieldOffset(CompressedOopsClass.class.getField("obj2"));
+ ADDRESS_SIZE = (int) Math.abs(off2 - off1);
+ HEADER_SIZE = (int) Math.min(off1, off2);
+ } catch (NoSuchFieldException e) {
+ ADDRESS_SIZE = -1;
+ }
+ }
+
+ static class CompressedOopsClass {
+ public Object obj1;
+ public Object obj2;
+ }
+
+ public static boolean arePaddedPairwise(Class klass, String field1, String field2) throws Exception {
+ Field f1 = klass.getField(field1);
+ Field f2 = klass.getField(field2);
+
+ int diff = offset(f1) - offset(f2);
+ if (diff < 0) {
+ // f1 is first
+ return (offset(f2) - (offset(f1) + getSize(f1))) > 64;
+ } else {
+ // f2 is first
+ return (offset(f1) - (offset(f2) + getSize(f2))) > 64;
+ }
+ }
+
+ public static boolean sameLayout(Class klass1, Class klass2) throws Exception {
+ for (Field f1 : klass1.getDeclaredFields()) {
+ Field f2 = klass2.getDeclaredField(f1.getName());
+ if (offset(f1) != offset(f2)) {
+ return false;
+ }
+ }
+
+ for (Field f2 : klass1.getDeclaredFields()) {
+ Field f1 = klass2.getDeclaredField(f2.getName());
+ if (offset(f1) != offset(f2)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static boolean isStatic(Field field) {
+ return Modifier.isStatic(field.getModifiers());
+ }
+
+ public static int offset(Field field) {
+ if (isStatic(field)) {
+ return (int) U.staticFieldOffset(field);
+ } else {
+ return (int) U.objectFieldOffset(field);
+ }
+ }
+
+ public static int getSize(Field field) {
+ Class type = field.getType();
+ if (type == byte.class) { return 1; }
+ if (type == boolean.class) { return 1; }
+ if (type == short.class) { return 2; }
+ if (type == char.class) { return 2; }
+ if (type == int.class) { return 4; }
+ if (type == float.class) { return 4; }
+ if (type == long.class) { return 8; }
+ if (type == double.class) { return 8; }
+ return ADDRESS_SIZE;
+ }
+
+ public static void main(String[] args) throws Exception {
+ boolean endResult = true;
+
+ // --------------- INSTANCE FIELDS ---------------------
+
+ if (!arePaddedPairwise(A2_R1.class, "int1", "int2")) {
+ System.err.println("A2_R1 failed");
+ endResult &= false;
+ }
+
+ if (!arePaddedPairwise(A3_R1.class, "int1", "int2")) {
+ System.err.println("A3_R1 failed");
+ endResult &= false;
+ }
+
+ if (!arePaddedPairwise(A1_R2.class, "int1", "int2")) {
+ System.err.println("A1_R2 failed");
+ endResult &= false;
+ }
+
+ if (!arePaddedPairwise(A2_R2.class, "int1", "int2")) {
+ System.err.println("A2_R2 failed");
+ endResult &= false;
+ }
+
+ if (!arePaddedPairwise(A3_R2.class, "int1", "int2")) {
+ System.err.println("A3_R2 failed");
+ endResult &= false;
+ }
+
+ if (!arePaddedPairwise(A1_R3.class, "int1", "int2")) {
+ System.err.println("A1_R3 failed");
+ endResult &= false;
+ }
+
+ if (!arePaddedPairwise(A2_R3.class, "int1", "int2")) {
+ System.err.println("A2_R3 failed");
+ endResult &= false;
+ }
+
+ if (!arePaddedPairwise(A3_R3.class, "int1", "int2")) {
+ System.err.println("A3_R3 failed");
+ endResult &= false;
+ }
+
+ System.out.println(endResult ? "Test PASSES" : "Test FAILS");
+ if (!endResult) {
+ throw new Error("Test failed");
+ }
+ }
+
+ public static class R1 {
+ public int int1;
+ }
+
+ public static class R2 {
+ @Contended
+ public int int1;
+ }
+
+ @Contended
+ public static class R3 {
+ public int int1;
+ }
+
+ public static class A1_R1 extends R1 {
+ public int int2;
+ }
+
+ public static class A2_R1 extends R1 {
+ @Contended
+ public int int2;
+ }
+
+ @Contended
+ public static class A3_R1 extends R1 {
+ public int int2;
+ }
+
+ public static class A1_R2 extends R2 {
+ public int int2;
+ }
+
+ public static class A2_R2 extends R2 {
+ @Contended
+ public int int2;
+ }
+
+ @Contended
+ public static class A3_R2 extends R2 {
+ public int int2;
+ }
+
+ public static class A1_R3 extends R3 {
+ public int int2;
+ }
+
+ public static class A2_R3 extends R3 {
+ @Contended
+ public int int2;
+ }
+
+ @Contended
+ public static class A3_R3 extends R3 {
+ public int int2;
+ }
+
+
+}
+
diff --git a/hotspot/test/testlibrary/ClassFileInstaller.java b/hotspot/test/testlibrary/ClassFileInstaller.java
index 694223e77f3..303e96e5a87 100644
--- a/hotspot/test/testlibrary/ClassFileInstaller.java
+++ b/hotspot/test/testlibrary/ClassFileInstaller.java
@@ -45,7 +45,9 @@ public class ClassFileInstaller {
// Create the class file's package directory
Path p = Paths.get(pathName);
- Files.createDirectories(p.getParent());
+ if (pathName.contains("/")) {
+ Files.createDirectories(p.getParent());
+ }
// Create the class file
Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
}
diff --git a/jaxp/.hgtags b/jaxp/.hgtags
index 62e9fbe5fe0..e23e9fa8292 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -211,3 +211,5 @@ ca71ec37b2efc9c3f0971ebabb3a6eb1213d76de jdk8-b86
eddbc8ad2435a89f64729512337c9f2669e4dd85 jdk8-b87
7122f7bb0fcc8a39e5254402119b2ee3fa0ad313 jdk8-b88
893d2ba8bbea3a8d090e51d8eaea285b390789ea jdk8-b89
+668acc0e1034bc1bec6d02be92e0dd4a63d0667e jdk8-b90
+e3065fb07877c7e96e8b93416fe2ab9a4c9eb2a5 jdk8-b91
diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/generic/BasicType.java b/jaxp/src/com/sun/org/apache/bcel/internal/generic/BasicType.java
index 978478476b6..c7340a62b15 100644
--- a/jaxp/src/com/sun/org/apache/bcel/internal/generic/BasicType.java
+++ b/jaxp/src/com/sun/org/apache/bcel/internal/generic/BasicType.java
@@ -97,8 +97,14 @@ public final class BasicType extends Type {
/** @return true if both type objects refer to the same type
*/
+ @Override
public boolean equals(Object type) {
return (type instanceof BasicType)?
((BasicType)type).type == this.type : false;
}
+
+ @Override
+ public int hashCode() {
+ return type;
+ }
}
diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java b/jaxp/src/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java
index d9a76251201..36960f8438f 100644
--- a/jaxp/src/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java
+++ b/jaxp/src/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java
@@ -93,6 +93,7 @@ public abstract class BranchInstruction extends Instruction implements Instructi
* Dump instruction as byte code to stream out.
* @param out Output stream
*/
+ @Override
public void dump(DataOutputStream out) throws IOException {
out.writeByte(opcode);
@@ -153,6 +154,7 @@ public abstract class BranchInstruction extends Instruction implements Instructi
* @param verbose long/short format switch
* @return mnemonic for instruction
*/
+ @Override
public String toString(boolean verbose) {
String s = super.toString(verbose);
String t = "null";
@@ -184,6 +186,7 @@ public abstract class BranchInstruction extends Instruction implements Instructi
* @param wide wide prefix?
* @see InstructionList
*/
+ @Override
protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException
{
length = 3;
@@ -204,26 +207,41 @@ public abstract class BranchInstruction extends Instruction implements Instructi
* Set branch target
* @param target branch target
*/
- public void setTarget(InstructionHandle target) {
- notifyTarget(this.target, target, this);
+ public final void setTarget(InstructionHandle target) {
+ notifyTargetChanging(this.target, this);
this.target = target;
+ notifyTargetChanged(this.target, this);
}
/**
- * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen
+ * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen.
+ * Must be called before the target is actually changed in the
+ * InstructionTargeter.
*/
- static final void notifyTarget(InstructionHandle old_ih, InstructionHandle new_ih,
+ static void notifyTargetChanging(InstructionHandle old_ih,
InstructionTargeter t) {
- if(old_ih != null)
+ if(old_ih != null) {
old_ih.removeTargeter(t);
- if(new_ih != null)
+ }
+ }
+
+ /**
+ * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen.
+ * Must be called after the target is actually changed in the
+ * InstructionTargeter.
+ */
+ static void notifyTargetChanged(InstructionHandle new_ih,
+ InstructionTargeter t) {
+ if(new_ih != null) {
new_ih.addTargeter(t);
+ }
}
/**
* @param old_ih old target
* @param new_ih new target
*/
+ @Override
public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
if(target == old_ih)
setTarget(new_ih);
@@ -234,6 +252,7 @@ public abstract class BranchInstruction extends Instruction implements Instructi
/**
* @return true, if ih is target of this instruction
*/
+ @Override
public boolean containsTarget(InstructionHandle ih) {
return (target == ih);
}
@@ -241,6 +260,7 @@ public abstract class BranchInstruction extends Instruction implements Instructi
/**
* Inform target that it's not targeted anymore.
*/
+ @Override
void dispose() {
setTarget(null);
index=-1;
diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java b/jaxp/src/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java
index 96c32fafdc2..0fb252ba576 100644
--- a/jaxp/src/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java
+++ b/jaxp/src/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java
@@ -58,7 +58,6 @@ package com.sun.org.apache.bcel.internal.generic;
* .
*/
-import com.sun.org.apache.bcel.internal.Constants;
import com.sun.org.apache.bcel.internal.classfile.*;
/**
@@ -118,31 +117,35 @@ public final class CodeExceptionGen
/* Set start of handler
* @param start_pc Start of handled region (inclusive)
*/
- public void setStartPC(InstructionHandle start_pc) {
- BranchInstruction.notifyTarget(this.start_pc, start_pc, this);
+ public final void setStartPC(InstructionHandle start_pc) {
+ BranchInstruction.notifyTargetChanging(this.start_pc, this);
this.start_pc = start_pc;
+ BranchInstruction.notifyTargetChanged(this.start_pc, this);
}
/* Set end of handler
* @param end_pc End of handled region (inclusive)
*/
- public void setEndPC(InstructionHandle end_pc) {
- BranchInstruction.notifyTarget(this.end_pc, end_pc, this);
+ public final void setEndPC(InstructionHandle end_pc) {
+ BranchInstruction.notifyTargetChanging(this.end_pc, this);
this.end_pc = end_pc;
+ BranchInstruction.notifyTargetChanged(this.end_pc, this);
}
/* Set handler code
* @param handler_pc Start of handler
*/
- public void setHandlerPC(InstructionHandle handler_pc) {
- BranchInstruction.notifyTarget(this.handler_pc, handler_pc, this);
+ public final void setHandlerPC(InstructionHandle handler_pc) {
+ BranchInstruction.notifyTargetChanging(this.handler_pc, this);
this.handler_pc = handler_pc;
+ BranchInstruction.notifyTargetChanged(this.handler_pc, this);
}
/**
* @param old_ih old target, either start or end
* @param new_ih new target
*/
+ @Override
public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
boolean targeted = false;
@@ -169,6 +172,7 @@ public final class CodeExceptionGen
/**
* @return true, if ih is target of this handler
*/
+ @Override
public boolean containsTarget(InstructionHandle ih) {
return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih);
}
@@ -190,10 +194,12 @@ public final class CodeExceptionGen
*/
public InstructionHandle getHandlerPC() { return handler_pc; }
+ @Override
public String toString() {
return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")";
}
+ @Override
public Object clone() {
try {
return super.clone();
diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java b/jaxp/src/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java
index e191e01a056..a8427a8c812 100644
--- a/jaxp/src/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java
+++ b/jaxp/src/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java
@@ -58,7 +58,6 @@ package com.sun.org.apache.bcel.internal.generic;
* .
*/
-import com.sun.org.apache.bcel.internal.Constants;
import com.sun.org.apache.bcel.internal.classfile.*;
/**
@@ -88,6 +87,7 @@ public class LineNumberGen
/**
* @return true, if ih is target of this line number
*/
+ @Override
public boolean containsTarget(InstructionHandle ih) {
return this.ih == ih;
}
@@ -96,6 +96,7 @@ public class LineNumberGen
* @param old_ih old target
* @param new_ih new target
*/
+ @Override
public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
if(old_ih != ih)
throw new ClassGenException("Not targeting " + old_ih + ", but " + ih + "}");
@@ -113,12 +114,13 @@ public class LineNumberGen
return new LineNumber(ih.getPosition(), src_line);
}
- public void setInstruction(InstructionHandle ih) {
- BranchInstruction.notifyTarget(this.ih, ih, this);
-
+ public final void setInstruction(InstructionHandle ih) {
+ BranchInstruction.notifyTargetChanging(this.ih, this);
this.ih = ih;
+ BranchInstruction.notifyTargetChanged(this.ih, this);
}
+ @Override
public Object clone() {
try {
return super.clone();
diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java b/jaxp/src/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java
index d9a7130133a..1f2fd868e40 100644
--- a/jaxp/src/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java
+++ b/jaxp/src/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java
@@ -60,6 +60,7 @@ package com.sun.org.apache.bcel.internal.generic;
import com.sun.org.apache.bcel.internal.Constants;
import com.sun.org.apache.bcel.internal.classfile.*;
+import java.util.Objects;
/**
* This class represents a local variable within a method. It contains its
@@ -75,7 +76,7 @@ public class LocalVariableGen
implements InstructionTargeter, NamedAndTyped, Cloneable,
java.io.Serializable
{
- private int index;
+ private final int index;
private String name;
private Type type;
private InstructionHandle start, end;
@@ -131,30 +132,96 @@ public class LocalVariableGen
signature_index, index, cp.getConstantPool());
}
- public void setIndex(int index) { this.index = index; }
- public int getIndex() { return index; }
+ public int getIndex() { return index; }
+ @Override
public void setName(String name) { this.name = name; }
+ @Override
public String getName() { return name; }
+ @Override
public void setType(Type type) { this.type = type; }
+ @Override
public Type getType() { return type; }
public InstructionHandle getStart() { return start; }
public InstructionHandle getEnd() { return end; }
- public void setStart(InstructionHandle start) {
- BranchInstruction.notifyTarget(this.start, start, this);
- this.start = start;
+ /**
+ * Remove this from any known HashSet in which it might be registered.
+ */
+ void notifyTargetChanging() {
+ // hashCode depends on 'index', 'start', and 'end'.
+ // Therefore before changing any of these values we
+ // need to unregister 'this' from any HashSet where
+ // this is registered, and then we need to add it
+ // back...
+
+ // Unregister 'this' from the HashSet held by 'start'.
+ BranchInstruction.notifyTargetChanging(this.start, this);
+ if (this.end != this.start) {
+ // Since hashCode() is going to change we need to unregister
+ // 'this' both form 'start' and 'end'.
+ // Unregister 'this' from the HashSet held by 'end'.
+ BranchInstruction.notifyTargetChanging(this.end, this);
+ }
}
- public void setEnd(InstructionHandle end) {
- BranchInstruction.notifyTarget(this.end, end, this);
+ /**
+ * Add back 'this' in all HashSet in which it should be registered.
+ **/
+ void notifyTargetChanged() {
+ // hashCode depends on 'index', 'start', and 'end'.
+ // Therefore before changing any of these values we
+ // need to unregister 'this' from any HashSet where
+ // this is registered, and then we need to add it
+ // back...
+
+ // Register 'this' in the HashSet held by start.
+ BranchInstruction.notifyTargetChanged(this.start, this);
+ if (this.end != this.start) {
+ // Since hashCode() has changed we need to register
+ // 'this' again in 'end'.
+ // Add back 'this' in the HashSet held by 'end'.
+ BranchInstruction.notifyTargetChanged(this.end, this);
+ }
+ }
+
+ public final void setStart(InstructionHandle start) {
+
+ // Call notifyTargetChanging *before* modifying this,
+ // as the code triggered by notifyTargetChanging
+ // depends on this pointing to the 'old' start.
+ notifyTargetChanging();
+
+ this.start = start;
+
+ // call notifyTargetChanged *after* modifying this,
+ // as the code triggered by notifyTargetChanged
+ // depends on this pointing to the 'new' start.
+ notifyTargetChanged();
+ }
+
+ public final void setEnd(InstructionHandle end) {
+ // call notifyTargetChanging *before* modifying this,
+ // as the code triggered by notifyTargetChanging
+ // depends on this pointing to the 'old' end.
+ // Unregister 'this' from the HashSet held by the 'old' end.
+ notifyTargetChanging();
+
this.end = end;
+
+ // call notifyTargetChanged *after* modifying this,
+ // as the code triggered by notifyTargetChanged
+ // depends on this pointing to the 'new' end.
+ // Register 'this' in the HashSet held by the 'new' end.
+ notifyTargetChanged();
+
}
/**
* @param old_ih old target, either start or end
* @param new_ih new target
*/
+ @Override
public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
boolean targeted = false;
@@ -176,15 +243,20 @@ public class LocalVariableGen
/**
* @return true, if ih is target of this variable
*/
+ @Override
public boolean containsTarget(InstructionHandle ih) {
return (start == ih) || (end == ih);
}
/**
- * We consider to local variables to be equal, if the use the same index and
+ * We consider two local variables to be equal, if they use the same index and
* are valid in the same range.
*/
+ @Override
public boolean equals(Object o) {
+ if (o==this)
+ return true;
+
if(!(o instanceof LocalVariableGen))
return false;
@@ -192,10 +264,21 @@ public class LocalVariableGen
return (l.index == index) && (l.start == start) && (l.end == end);
}
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 59 * hash + this.index;
+ hash = 59 * hash + Objects.hashCode(this.start);
+ hash = 59 * hash + Objects.hashCode(this.end);
+ return hash;
+ }
+
+ @Override
public String toString() {
return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")";
}
+ @Override
public Object clone() {
try {
return super.clone();
diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java b/jaxp/src/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java
index 659d7247ef8..501efdd09ec 100644
--- a/jaxp/src/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java
+++ b/jaxp/src/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java
@@ -58,7 +58,7 @@ package com.sun.org.apache.bcel.internal.generic;
* .
*/
import com.sun.org.apache.bcel.internal.Constants;
-import com.sun.org.apache.bcel.internal.generic.InstructionHandle;
+import java.util.Objects;
/**
* Returnaddress, the type JSR or JSR_W instructions push upon the stack.
@@ -86,9 +86,15 @@ public class ReturnaddressType extends Type {
this.returnTarget = returnTarget;
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.returnTarget);
+ }
+
/**
* Returns if the two Returnaddresses refer to the same target.
*/
+ @Override
public boolean equals(Object rat){
if(!(rat instanceof ReturnaddressType))
return false;
diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/generic/Select.java b/jaxp/src/com/sun/org/apache/bcel/internal/generic/Select.java
index dfdf8a7a250..0cf47f634ca 100644
--- a/jaxp/src/com/sun/org/apache/bcel/internal/generic/Select.java
+++ b/jaxp/src/com/sun/org/apache/bcel/internal/generic/Select.java
@@ -97,8 +97,9 @@ public abstract class Select extends BranchInstruction
super(opcode, target);
this.targets = targets;
- for(int i=0; i < targets.length; i++)
- notifyTarget(null, targets[i], this);
+ for(int i=0; i < targets.length; i++) {
+ BranchInstruction.notifyTargetChanged(targets[i], this);
+ }
this.match = match;
@@ -121,6 +122,7 @@ public abstract class Select extends BranchInstruction
* @param max_offset the maximum offset that may be caused by these instructions
* @return additional offset caused by possible change of this instruction's length
*/
+ @Override
protected int updatePosition(int offset, int max_offset) {
position += offset; // Additional offset caused by preceding SWITCHs, GOTOs, etc.
@@ -138,6 +140,7 @@ public abstract class Select extends BranchInstruction
* Dump instruction as byte code to stream out.
* @param out Output stream
*/
+ @Override
public void dump(DataOutputStream out) throws IOException {
out.writeByte(opcode);
@@ -151,6 +154,7 @@ public abstract class Select extends BranchInstruction
/**
* Read needed data (e.g. index) from file.
*/
+ @Override
protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException
{
padding = (4 - (bytes.getIndex() % 4)) % 4; // Compute number of pad bytes
@@ -166,8 +170,9 @@ public abstract class Select extends BranchInstruction
/**
* @return mnemonic for instruction
*/
+ @Override
public String toString(boolean verbose) {
- StringBuffer buf = new StringBuffer(super.toString(verbose));
+ final StringBuilder buf = new StringBuilder(super.toString(verbose));
if(verbose) {
for(int i=0; i < match_length; i++) {
@@ -176,7 +181,8 @@ public abstract class Select extends BranchInstruction
if(targets[i] != null)
s = targets[i].getInstruction().toString();
- buf.append("(" + match[i] + ", " + s + " = {" + indices[i] + "})");
+ buf.append("(").append(match[i]).append(", ")
+ .append(s).append(" = {").append(indices[i]).append("})");
}
}
else
@@ -188,15 +194,17 @@ public abstract class Select extends BranchInstruction
/**
* Set branch target for `i'th case
*/
- public void setTarget(int i, InstructionHandle target) {
- notifyTarget(targets[i], target, this);
+ public final void setTarget(int i, InstructionHandle target) {
+ notifyTargetChanging(targets[i], this);
targets[i] = target;
+ notifyTargetChanged(targets[i], this);
}
/**
* @param old_ih old target
* @param new_ih new target
*/
+ @Override
public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
boolean targeted = false;
@@ -219,6 +227,7 @@ public abstract class Select extends BranchInstruction
/**
* @return true, if ih is target of this instruction
*/
+ @Override
public boolean containsTarget(InstructionHandle ih) {
if(target == ih)
return true;
@@ -233,6 +242,7 @@ public abstract class Select extends BranchInstruction
/**
* Inform targets that they're not targeted anymore.
*/
+ @Override
void dispose() {
super.dispose();
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java b/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java
index 6fdccc023c7..82756c198ea 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java
@@ -25,9 +25,7 @@
package com.sun.org.apache.xalan.internal;
-import com.sun.org.apache.xerces.internal.impl.*;
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
+import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
/**
* Commonly used constants.
@@ -42,19 +40,99 @@ public final class XalanConstants {
// Constants
//
// Oracle Feature:
- /**
- * Use Service Mechanism
- *
- *
- * -
- *
true instructs the implementation to use service mechanism to find implementation.
- * This is the default behavior.
+ /**
+ * Use Service Mechanism
+ *
+ *
+ * -
+ * {@code true} instruct an object to use service mechanism to
+ * find a service implementation. This is the default behavior.
*
* -
- *
false instructs the implementation to skip service mechanism and use the default implementation.
- *
- *
- */
+ * {@code false} instruct an object to skip service mechanism and
+ * use the default implementation for that service.
+ *
+ *
+ */
+
public static final String ORACLE_FEATURE_SERVICE_MECHANISM = "http://www.oracle.com/feature/use-service-mechanism";
+ /** Oracle JAXP property prefix ("http://www.oracle.com/xml/jaxp/properties/"). */
+ public static final String ORACLE_JAXP_PROPERTY_PREFIX =
+ "http://www.oracle.com/xml/jaxp/properties/";
+
+ //System Properties corresponding to ACCESS_EXTERNAL_* properties
+ public static final String SP_ACCESS_EXTERNAL_STYLESHEET = "javax.xml.accessExternalStylesheet";
+ public static final String SP_ACCESS_EXTERNAL_DTD = "javax.xml.accessExternalDTD";
+
+
+ //all access keyword
+ public static final String ACCESS_EXTERNAL_ALL = "all";
+
+ /**
+ * Default value when FEATURE_SECURE_PROCESSING (FSP) is set to true
+ */
+ public static final String EXTERNAL_ACCESS_DEFAULT_FSP = "";
+ /**
+ * JDK version by which the default is to restrict external connection
+ */
+ public static final int RESTRICT_BY_DEFAULT_JDK_VERSION = 8;
+ /**
+ * FEATURE_SECURE_PROCESSING (FSP) is false by default
+ */
+ public static final String EXTERNAL_ACCESS_DEFAULT = getExternalAccessDefault(false);
+
+ /**
+ * Determine the default value of the external access properties
+ *
+ * jaxp 1.5 does not require implementations to restrict by default
+ *
+ * For JDK8:
+ * The default value is 'file' (including jar:file); The keyword "all" grants permission
+ * to all protocols. When {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} is on,
+ * the default value is an empty string indicating no access is allowed.
+ *
+ * For JDK7:
+ * The default value is 'all' granting permission to all protocols. If by default,
+ * {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} is true, it should
+ * not change the default value. However, if {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING}
+ * is set explicitly, the values of the properties shall be set to an empty string
+ * indicating no access is allowed.
+ *
+ * @param isSecureProcessing indicating if Secure Processing is set
+ * @return default value
+ */
+ public static String getExternalAccessDefault(boolean isSecureProcessing) {
+ String defaultValue = "all";
+ if (isJDKandAbove(RESTRICT_BY_DEFAULT_JDK_VERSION)) {
+ defaultValue = "file";
+ if (isSecureProcessing) {
+ defaultValue = EXTERNAL_ACCESS_DEFAULT_FSP;
+ }
+ }
+ return defaultValue;
+ }
+
+ /*
+ * Check the version of the current JDK against that specified in the
+ * parameter
+ *
+ * There is a proposal to change the java version string to:
+ * MAJOR.MINOR.FU.CPU.PSU-BUILDNUMBER_BUGIDNUMBER_OPTIONAL
+ * This method would work with both the current format and that proposed
+ *
+ * @param compareTo a JDK version to be compared to
+ * @return true if the current version is the same or above that represented
+ * by the parameter
+ */
+ public static boolean isJDKandAbove(int compareTo) {
+ String javaVersion = SecuritySupport.getSystemProperty("java.version");
+ String versions[] = javaVersion.split("\\.", 3);
+ if (Integer.parseInt(versions[0]) >= compareTo ||
+ Integer.parseInt(versions[1]) >= compareTo) {
+ return true;
+ }
+ return false;
+ }
+
} // class Constants
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java b/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java
index b813b4c0d28..e418fd55275 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java
@@ -26,7 +26,9 @@ package com.sun.org.apache.xalan.internal.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.io.InputStream;
+import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -36,6 +38,7 @@ import java.util.ListResourceBundle;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
+import java.util.Properties;
/**
* This class is duplicated for each subpackage so keep it in sync. It is
@@ -200,7 +203,141 @@ public final class SecuritySupport {
})).longValue();
}
-
- private SecuritySupport() {
+ /**
+ * Strip off path from an URI
+ *
+ * @param uri an URI with full path
+ * @return the file name only
+ */
+ public static String sanitizePath(String uri) {
+ if (uri == null) {
+ return "";
+ }
+ int i = uri.lastIndexOf("/");
+ if (i > 0) {
+ return uri.substring(i+1, uri.length());
+ }
+ return "";
}
+
+ /**
+ * Check the protocol used in the systemId against allowed protocols
+ *
+ * @param systemId the Id of the URI
+ * @param allowedProtocols a list of allowed protocols separated by comma
+ * @param accessAny keyword to indicate allowing any protocol
+ * @return the name of the protocol if rejected, null otherwise
+ */
+ public static String checkAccess(String systemId, String allowedProtocols, String accessAny) throws IOException {
+ if (systemId == null || allowedProtocols.equalsIgnoreCase(accessAny)) {
+ return null;
+ }
+
+ String protocol;
+ if (systemId.indexOf(":")==-1) {
+ protocol = "file";
+ } else {
+ URL url = new URL(systemId);
+ protocol = url.getProtocol();
+ if (protocol.equalsIgnoreCase("jar")) {
+ String path = url.getPath();
+ protocol = path.substring(0, path.indexOf(":"));
+ }
+ }
+
+ if (isProtocolAllowed(protocol, allowedProtocols)) {
+ //access allowed
+ return null;
+ } else {
+ return protocol;
+ }
+ }
+
+ /**
+ * Check if the protocol is in the allowed list of protocols. The check
+ * is case-insensitive while ignoring whitespaces.
+ *
+ * @param protocol a protocol
+ * @param allowedProtocols a list of allowed protocols
+ * @return true if the protocol is in the list
+ */
+ private static boolean isProtocolAllowed(String protocol, String allowedProtocols) {
+ String temp[] = allowedProtocols.split(",");
+ for (String t : temp) {
+ t = t.trim();
+ if (t.equalsIgnoreCase(protocol)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Read from $java.home/lib/jaxp.properties for the specified property
+ *
+ * @param propertyId the Id of the property
+ * @return the value of the property
+ */
+ public static String getDefaultAccessProperty(String sysPropertyId, String defaultVal) {
+ String accessExternal = SecuritySupport.getSystemProperty(sysPropertyId);
+ if (accessExternal == null) {
+ accessExternal = readJAXPProperty(sysPropertyId);
+ if (accessExternal == null) {
+ accessExternal = defaultVal;
+ }
+ }
+ return accessExternal;
+ }
+
+ /**
+ * Read from $java.home/lib/jaxp.properties for the specified property
+ * The program
+ *
+ * @param propertyId the Id of the property
+ * @return the value of the property
+ */
+ static String readJAXPProperty(String propertyId) {
+ String value = null;
+ InputStream is = null;
+ try {
+ if (firstTime) {
+ synchronized (cacheProps) {
+ if (firstTime) {
+ String configFile = getSystemProperty("java.home") + File.separator +
+ "lib" + File.separator + "jaxp.properties";
+ File f = new File(configFile);
+ if (getFileExists(f)) {
+ is = getFileInputStream(f);
+ cacheProps.load(is);
+ }
+ firstTime = false;
+ }
+ }
+ }
+ value = cacheProps.getProperty(propertyId);
+
+ }
+ catch (Exception ex) {}
+ finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ex) {}
+ }
+ }
+
+ return value;
+ }
+
+ /**
+ * Cache for properties in java.home/lib/jaxp.properties
+ */
+ static final Properties cacheProps = new Properties();
+
+ /**
+ * Flag indicating if the program has tried reading java.home/lib/jaxp.properties
+ */
+ static volatile boolean firstTime = true;
+
+ private SecuritySupport () {}
}
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java
index f4f903b2be9..76c4643f21b 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java
@@ -54,6 +54,7 @@ import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ReferenceType;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
+import java.util.Objects;
/**
* @author Jacek Ambroziak
@@ -156,8 +157,15 @@ class FunctionCall extends Expression {
this.type = type;
this.distance = distance;
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.type);
+ }
+
+ @Override
public boolean equals(Object query){
- return query.equals(type);
+ return query != null && query.equals(type);
}
}
@@ -277,6 +285,7 @@ class FunctionCall extends Expression {
return(_fname.toString());
}
+ @Override
public void setParser(Parser parser) {
super.setParser(parser);
if (_arguments != null) {
@@ -319,6 +328,7 @@ class FunctionCall extends Expression {
* Type check a function call. Since different type conversions apply,
* type checking is different for standard and external (Java) functions.
*/
+ @Override
public Type typeCheck(SymbolTable stable)
throws TypeCheckError
{
@@ -680,6 +690,7 @@ class FunctionCall extends Expression {
* Compile the function call and treat as an expression
* Update true/false-lists.
*/
+ @Override
public void translateDesynthesized(ClassGenerator classGen,
MethodGenerator methodGen)
{
@@ -700,6 +711,7 @@ class FunctionCall extends Expression {
* Translate a function call. The compiled code will leave the function's
* return value on the JVM's stack.
*/
+ @Override
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
final int n = argumentCount();
final ConstantPoolGen cpg = classGen.getConstantPool();
@@ -857,6 +869,7 @@ class FunctionCall extends Expression {
}
}
+ @Override
public String toString() {
return "funcall(" + _fname + ", " + _arguments + ')';
}
@@ -1069,7 +1082,7 @@ class FunctionCall extends Expression {
protected static String replaceDash(String name)
{
char dash = '-';
- StringBuffer buff = new StringBuffer("");
+ final StringBuilder buff = new StringBuilder("");
for (int i = 0; i < name.length(); i++) {
if (i > 0 && name.charAt(i-1) == dash)
buff.append(Character.toUpperCase(name.charAt(i)));
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java
index b2d33e940f2..fdfbe178d1d 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java
@@ -23,18 +23,19 @@
package com.sun.org.apache.xalan.internal.xsltc.compiler;
-import java.io.File;
-import java.net.URL;
-import java.net.MalformedURLException;
-import java.util.Enumeration;
-
-import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
+import com.sun.org.apache.xalan.internal.XalanConstants;
+import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
-
+import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
+import java.io.File;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.util.Enumeration;
+import javax.xml.XMLConstants;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
@@ -84,6 +85,17 @@ final class Import extends TopLevelElement {
// No SourceLoader or not resolved by SourceLoader
if (input == null) {
docToLoad = SystemIDResolver.getAbsoluteURI(docToLoad, currLoadedDoc);
+ String accessError = SecuritySupport.checkAccess(docToLoad,
+ xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET),
+ XalanConstants.ACCESS_EXTERNAL_ALL);
+
+ if (accessError != null) {
+ final ErrorMsg msg = new ErrorMsg(ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ SecuritySupport.sanitizePath(docToLoad), accessError,
+ this);
+ parser.reportError(Constants.FATAL, msg);
+ return;
+ }
input = new InputSource(docToLoad);
}
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java
index 3d549f47402..71c129f7cca 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java
@@ -23,19 +23,20 @@
package com.sun.org.apache.xalan.internal.xsltc.compiler;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Enumeration;
-
-import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
+import com.sun.org.apache.xalan.internal.XalanConstants;
+import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
-
+import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import javax.xml.XMLConstants;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
@@ -85,6 +86,17 @@ final class Include extends TopLevelElement {
// No SourceLoader or not resolved by SourceLoader
if (input == null) {
docToLoad = SystemIDResolver.getAbsoluteURI(docToLoad, currLoadedDoc);
+ String accessError = SecuritySupport.checkAccess(docToLoad,
+ xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET),
+ XalanConstants.ACCESS_EXTERNAL_ALL);
+
+ if (accessError != null) {
+ final ErrorMsg msg = new ErrorMsg(ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ SecuritySupport.sanitizePath(docToLoad), accessError,
+ this);
+ parser.reportError(Constants.FATAL, msg);
+ return;
+ }
input = new InputSource(docToLoad);
}
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java
index 80ce77bb8b8..9669bf734ad 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java
@@ -23,6 +23,16 @@
package com.sun.org.apache.xalan.internal.xsltc.compiler;
+import com.sun.java_cup.internal.runtime.Symbol;
+import com.sun.org.apache.xalan.internal.XalanConstants;
+import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
+import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
+import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
+import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
+import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType;
+import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
+import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
+import com.sun.org.apache.xml.internal.serializer.utils.SystemIDResolver;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
@@ -33,27 +43,18 @@ import java.util.Properties;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.Vector;
-
-import com.sun.java_cup.internal.runtime.Symbol;
import javax.xml.XMLConstants;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
-
-import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
-import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType;
-import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
-import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
-import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
-import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
import org.xml.sax.Attributes;
-import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.AttributesImpl;
/**
* @author Jacek Ambroziak
@@ -475,6 +476,8 @@ public class Parser implements Constants, ContentHandler {
factory.setNamespaceAware(true);
}
final SAXParser parser = factory.newSAXParser();
+ parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
+ _xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
final XMLReader reader = parser.getXMLReader();
return(parse(reader, input));
}
@@ -547,6 +550,25 @@ public class Parser implements Constants, ContentHandler {
return(element);
}
else {
+ try {
+ String path = _target;
+ if (path.indexOf(":")==-1) {
+ path = "file:" + path;
+ }
+ path = SystemIDResolver.getAbsoluteURI(path);
+ String accessError = SecuritySupport.checkAccess(path,
+ _xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET),
+ XalanConstants.ACCESS_EXTERNAL_ALL);
+ if (accessError != null) {
+ ErrorMsg msg = new ErrorMsg(ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ SecuritySupport.sanitizePath(_target), accessError,
+ root);
+ throw new CompilerException(msg.toString());
+ }
+ } catch (IOException ex) {
+ throw new CompilerException(ex);
+ }
+
return(loadExternalStylesheet(_target));
}
}
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableRefBase.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableRefBase.java
index 100c0e761b3..76cee04a87a 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableRefBase.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableRefBase.java
@@ -25,6 +25,7 @@ package com.sun.org.apache.xalan.internal.xsltc.compiler;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
+import java.util.Objects;
/**
* @author Morten Jorgensen
@@ -97,13 +98,15 @@ class VariableRefBase extends Expression {
* Two variable references are deemed equal if they refer to the
* same variable.
*/
+ @Override
public boolean equals(Object obj) {
- try {
- return (_variable == ((VariableRefBase) obj)._variable);
- }
- catch (ClassCastException e) {
- return false;
- }
+ return obj == this || (obj instanceof VariableRefBase)
+ && (_variable == ((VariableRefBase) obj)._variable);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this._variable);
}
/**
@@ -111,10 +114,12 @@ class VariableRefBase extends Expression {
* format 'variable-ref()'.
* @return Variable reference description
*/
+ @Override
public String toString() {
return "variable-ref("+_variable.getName()+'/'+_variable.getType()+')';
}
+ @Override
public Type typeCheck(SymbolTable stable)
throws TypeCheckError
{
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java
index 454027819b8..97fff3bf2e0 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java
@@ -39,8 +39,10 @@ import java.util.Vector;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
+import javax.xml.XMLConstants;
import com.sun.org.apache.bcel.internal.classfile.JavaClass;
+import com.sun.org.apache.xalan.internal.XalanConstants;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;
@@ -135,6 +137,16 @@ public final class XSLTC {
private boolean _useServicesMechanism = true;
+ /**
+ * protocols allowed for external references set by the stylesheet processing instruction, Import and Include element.
+ */
+ private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+ /**
+ * protocols allowed for external DTD references in source file and/or stylesheet.
+ */
+ private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+
+
/**
* XSLTC compiler constructor
*/
@@ -169,6 +181,31 @@ public final class XSLTC {
_useServicesMechanism = flag;
}
+ /**
+ * Return allowed protocols for accessing external stylesheet.
+ */
+ public String getProperty(String name) {
+ if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) {
+ return _accessExternalStylesheet;
+ }
+ else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
+ return _accessExternalDTD;
+ }
+ return null;
+ }
+
+ /**
+ * Set allowed protocols for accessing external stylesheet.
+ */
+ public void setProperty(String name, String value) {
+ if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) {
+ _accessExternalStylesheet = (String)value;
+ }
+ else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
+ _accessExternalDTD = (String)value;
+ }
+ }
+
/**
* Only for user by the internal TrAX implementation.
*/
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java
index de3783997e2..90655c6fe45 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java
@@ -445,6 +445,12 @@ public class ErrorMessages extends ListResourceBundle {
{ErrorMsg.MISSING_XSLT_TARGET_ERR,
"Could not find stylesheet target ''{0}''."},
+ /*
+ * Note to translators: access to the stylesheet target is denied
+ */
+ {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
/*
* Note to translators: This message represents an internal error in
* condition in XSLTC. The substitution text is the class name in XSLTC
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ca.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ca.java
index 1d615bf5b17..fa28ddc2d2f 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ca.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ca.java
@@ -443,6 +443,12 @@ public class ErrorMessages_ca extends ListResourceBundle {
{ErrorMsg.MISSING_XSLT_TARGET_ERR,
"No s''ha trobat la destinaci\u00f3 ''{0}'' del full d''estils."},
+ /*
+ * Note to translators: access to the stylesheet target is denied
+ */
+ {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
/*
* Note to translators: This message represents an internal error in
* condition in XSLTC. The substitution text is the class name in XSLTC
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_cs.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_cs.java
index 739b6703dea..4220efd8f04 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_cs.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_cs.java
@@ -443,6 +443,12 @@ public class ErrorMessages_cs extends ListResourceBundle {
{ErrorMsg.MISSING_XSLT_TARGET_ERR,
"Nelze naj\u00edt c\u00edlovou p\u0159edlohu se stylem ''{0}''."},
+ /*
+ * Note to translators: access to the stylesheet target is denied
+ */
+ {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
/*
* Note to translators: This message represents an internal error in
* condition in XSLTC. The substitution text is the class name in XSLTC
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java
index e0473d45f97..1ae98c19170 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java
@@ -443,6 +443,12 @@ public class ErrorMessages_de extends ListResourceBundle {
{ErrorMsg.MISSING_XSLT_TARGET_ERR,
"Stylesheet-Ziel \"{0}\" konnte nicht gefunden werden."},
+ /*
+ * Note to translators: access to the stylesheet target is denied
+ */
+ {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
/*
* Note to translators: This message represents an internal error in
* condition in XSLTC. The substitution text is the class name in XSLTC
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java
index ffb9bcc588d..7aa0deb8c0a 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java
@@ -443,6 +443,12 @@ public class ErrorMessages_es extends ListResourceBundle {
{ErrorMsg.MISSING_XSLT_TARGET_ERR,
"No se ha encontrado el destino de hoja de estilo ''{0}''."},
+ /*
+ * Note to translators: access to the stylesheet target is denied
+ */
+ {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
/*
* Note to translators: This message represents an internal error in
* condition in XSLTC. The substitution text is the class name in XSLTC
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java
index 4c7087e1367..39151c785b9 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java
@@ -443,6 +443,12 @@ public class ErrorMessages_fr extends ListResourceBundle {
{ErrorMsg.MISSING_XSLT_TARGET_ERR,
"Cible de feuille de style ''{0}'' introuvable."},
+ /*
+ * Note to translators: access to the stylesheet target is denied
+ */
+ {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
/*
* Note to translators: This message represents an internal error in
* condition in XSLTC. The substitution text is the class name in XSLTC
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java
index 4c33c19a1d2..b8f68b95aac 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java
@@ -443,6 +443,12 @@ public class ErrorMessages_it extends ListResourceBundle {
{ErrorMsg.MISSING_XSLT_TARGET_ERR,
"Impossibile trovare la destinazione ''{0}'' del foglio di stile."},
+ /*
+ * Note to translators: access to the stylesheet target is denied
+ */
+ {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
/*
* Note to translators: This message represents an internal error in
* condition in XSLTC. The substitution text is the class name in XSLTC
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java
index eec29e921ca..28c15eaf02b 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java
@@ -443,6 +443,12 @@ public class ErrorMessages_ja extends ListResourceBundle {
{ErrorMsg.MISSING_XSLT_TARGET_ERR,
"\u30B9\u30BF\u30A4\u30EB\u30B7\u30FC\u30C8\u30FB\u30BF\u30FC\u30B2\u30C3\u30C8''{0}''\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002"},
+ /*
+ * Note to translators: access to the stylesheet target is denied
+ */
+ {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
/*
* Note to translators: This message represents an internal error in
* condition in XSLTC. The substitution text is the class name in XSLTC
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java
index 9a2c5b47ce5..33853810638 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java
@@ -443,6 +443,12 @@ public class ErrorMessages_ko extends ListResourceBundle {
{ErrorMsg.MISSING_XSLT_TARGET_ERR,
"\uC2A4\uD0C0\uC77C\uC2DC\uD2B8 \uB300\uC0C1 ''{0}''\uC744(\uB97C) \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
+ /*
+ * Note to translators: access to the stylesheet target is denied
+ */
+ {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
/*
* Note to translators: This message represents an internal error in
* condition in XSLTC. The substitution text is the class name in XSLTC
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java
index a0c31428854..c6b369edc1b 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java
@@ -443,6 +443,12 @@ public class ErrorMessages_pt_BR extends ListResourceBundle {
{ErrorMsg.MISSING_XSLT_TARGET_ERR,
"N\u00E3o foi poss\u00EDvel localizar o alvo da folha de estilos ''{0}''."},
+ /*
+ * Note to translators: access to the stylesheet target is denied
+ */
+ {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
/*
* Note to translators: This message represents an internal error in
* condition in XSLTC. The substitution text is the class name in XSLTC
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sk.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sk.java
index cc0ba4bb88c..1a76afc2403 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sk.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sk.java
@@ -443,6 +443,12 @@ public class ErrorMessages_sk extends ListResourceBundle {
{ErrorMsg.MISSING_XSLT_TARGET_ERR,
"Nebolo mo\u017en\u00e9 n\u00e1js\u0165 cie\u013e \u0161t\u00fdlu dokumentu ''{0}''."},
+ /*
+ * Note to translators: access to the stylesheet target is denied
+ */
+ {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
/*
* Note to translators: This message represents an internal error in
* condition in XSLTC. The substitution text is the class name in XSLTC
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java
index 62d2f7a6ae5..07aa76cb122 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java
@@ -443,6 +443,12 @@ public class ErrorMessages_sv extends ListResourceBundle {
{ErrorMsg.MISSING_XSLT_TARGET_ERR,
"Hittade inte formatmallen ''{0}''."},
+ /*
+ * Note to translators: access to the stylesheet target is denied
+ */
+ {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
/*
* Note to translators: This message represents an internal error in
* condition in XSLTC. The substitution text is the class name in XSLTC
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java
index 683ea33991e..1b12156b326 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java
@@ -443,6 +443,12 @@ public class ErrorMessages_zh_CN extends ListResourceBundle {
{ErrorMsg.MISSING_XSLT_TARGET_ERR,
"\u627E\u4E0D\u5230\u6837\u5F0F\u8868\u76EE\u6807 ''{0}''\u3002"},
+ /*
+ * Note to translators: access to the stylesheet target is denied
+ */
+ {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
/*
* Note to translators: This message represents an internal error in
* condition in XSLTC. The substitution text is the class name in XSLTC
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java
index 892a2e8f353..f813e667d1c 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java
@@ -443,6 +443,12 @@ public class ErrorMessages_zh_TW extends ListResourceBundle {
{ErrorMsg.MISSING_XSLT_TARGET_ERR,
"\u627E\u4E0D\u5230\u6A23\u5F0F\u8868\u76EE\u6A19 ''{0}''\u3002"},
+ /*
+ * Note to translators: access to the stylesheet target is denied
+ */
+ {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
/*
* Note to translators: This message represents an internal error in
* condition in XSLTC. The substitution text is the class name in XSLTC
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java
index faa7e99c26a..102f354593e 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java
@@ -95,6 +95,7 @@ public final class ErrorMsg {
public static final String UNSUPPORTED_EXT_ERR = "UNSUPPORTED_EXT_ERR";
public static final String MISSING_XSLT_URI_ERR = "MISSING_XSLT_URI_ERR";
public static final String MISSING_XSLT_TARGET_ERR = "MISSING_XSLT_TARGET_ERR";
+ public static final String ACCESSING_XSLT_TARGET_ERR = "ACCESSING_XSLT_TARGET_ERR";
public static final String NOT_IMPLEMENTED_ERR = "NOT_IMPLEMENTED_ERR";
public static final String NOT_STYLESHEET_ERR = "NOT_STYLESHEET_ERR";
public static final String ELEMENT_PARSE_ERR = "ELEMENT_PARSE_ERR";
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java
index de87c5622dc..f3e28791a2f 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java
@@ -23,6 +23,7 @@
package com.sun.org.apache.xalan.internal.xsltc.dom;
+import com.sun.org.apache.xalan.internal.XalanConstants;
import java.io.FileNotFoundException;
import javax.xml.transform.stream.StreamSource;
@@ -31,8 +32,10 @@ import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.DOMCache;
import com.sun.org.apache.xalan.internal.xsltc.DOMEnhancedForDTM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
+import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
+import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.dtm.DTMManager;
@@ -199,6 +202,13 @@ public final class LoadDocument {
throw new TransletException(e);
}
} else {
+ String accessError = SecuritySupport.checkAccess(uri, translet.getAllowedProtocols(), XalanConstants.ACCESS_EXTERNAL_ALL);
+ if (accessError != null) {
+ ErrorMsg msg = new ErrorMsg(ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+ SecuritySupport.sanitizePath(uri), accessError);
+ throw new Exception(msg.toString());
+ }
+
// Parse the input document and construct DOM object
// Trust the DTMManager to pick the right parser and
// set up the DOM correctly.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java
index 71e1e4abf7a..9eddf5ce423 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java
@@ -23,6 +23,7 @@
package com.sun.org.apache.xalan.internal.xsltc.runtime;
+import com.sun.org.apache.xalan.internal.XalanConstants;
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
import java.io.File;
import java.io.FileOutputStream;
@@ -110,6 +111,11 @@ public abstract class AbstractTranslet implements Translet {
private boolean _useServicesMechanism;
+ /**
+ * protocols allowed for external references set by the stylesheet processing instruction, Document() function, Import and Include element.
+ */
+ private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+
/************************************************************************
* Debugging
************************************************************************/
@@ -758,6 +764,20 @@ public abstract class AbstractTranslet implements Translet {
_useServicesMechanism = flag;
}
+ /**
+ * Return allowed protocols for accessing external stylesheet.
+ */
+ public String getAllowedProtocols() {
+ return _accessExternalStylesheet;
+ }
+
+ /**
+ * Set allowed protocols for accessing external stylesheet.
+ */
+ public void setAllowedProtocols(String protocols) {
+ _accessExternalStylesheet = protocols;
+ }
+
/************************************************************************
* DOMImplementation caching for basis library
************************************************************************/
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java
index 2eb161dafee..879c1cb4de0 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java
@@ -99,6 +99,12 @@ public class TemplatesHandlerImpl
if (tfactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING))
xsltc.setSecureProcessing(true);
+ xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET,
+ (String)tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET));
+ xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
+ (String)tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_DTD));
+
+
if ("true".equals(tfactory.getAttribute(TransformerFactoryImpl.ENABLE_INLINING)))
xsltc.setTemplateInlining(true);
else
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java
index a3bd7f6d1ab..e6d9cc3cf95 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java
@@ -23,6 +23,7 @@
package com.sun.org.apache.xalan.internal.xsltc.trax;
+import com.sun.org.apache.xalan.internal.XalanConstants;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -124,6 +125,11 @@ public final class TemplatesImpl implements Templates, Serializable {
private boolean _useServicesMechanism;
+ /**
+ * protocols allowed for external references set by the stylesheet processing instruction, Import and Include element.
+ */
+ private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+
static final class TransletClassLoader extends ClassLoader {
TransletClassLoader(ClassLoader parent) {
super(parent);
@@ -171,6 +177,7 @@ public final class TemplatesImpl implements Templates, Serializable {
_indentNumber = indentNumber;
_tfactory = tfactory;
_useServicesMechanism = tfactory.useServicesMechnism();
+ _accessExternalStylesheet = (String) tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET);
}
/**
* Need for de-serialization, see readObject().
@@ -381,6 +388,7 @@ public final class TemplatesImpl implements Templates, Serializable {
translet.postInitialization();
translet.setTemplates(this);
translet.setServicesMechnism(_useServicesMechanism);
+ translet.setAllowedProtocols(_accessExternalStylesheet);
if (_auxClasses != null) {
translet.setAuxiliaryClasses(_auxClasses);
}
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java
index 78d96aa0479..2675268d555 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java
@@ -224,6 +224,16 @@ public class TransformerFactoryImpl
*/
private boolean _useServicesMechanism;
+ /**
+ * protocols allowed for external references set by the stylesheet processing instruction, Import and Include element.
+ */
+ private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+ /**
+ * protocols allowed for external DTD references in source file and/or stylesheet.
+ */
+ private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+
+
/**
* javax.xml.transform.sax.TransformerFactory implementation.
*/
@@ -238,10 +248,17 @@ public class TransformerFactoryImpl
private TransformerFactoryImpl(boolean useServicesMechanism) {
this.m_DTMManagerClass = XSLTCDTMManager.getDTMManagerClass(useServicesMechanism);
this._useServicesMechanism = useServicesMechanism;
+
+ String defaultAccess = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
if (System.getSecurityManager() != null) {
_isSecureMode = true;
_isNotSecureProcessing = false;
+ defaultAccess = XalanConstants.getExternalAccessDefault(true);
}
+ _accessExternalStylesheet = SecuritySupport.getDefaultAccessProperty(
+ XalanConstants.SP_ACCESS_EXTERNAL_STYLESHEET, defaultAccess);
+ _accessExternalDTD = SecuritySupport.getDefaultAccessProperty(
+ XalanConstants.SP_ACCESS_EXTERNAL_DTD, defaultAccess);
}
/**
@@ -301,6 +318,12 @@ public class TransformerFactoryImpl
else
return Boolean.FALSE;
}
+ else if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) {
+ return _accessExternalStylesheet;
+ }
+ else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
+ return _accessExternalDTD;
+ }
// Throw an exception for all other attributes
ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_INVALID_ATTR_ERR, name);
@@ -401,6 +424,14 @@ public class TransformerFactoryImpl
return;
}
}
+ else if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) {
+ _accessExternalStylesheet = (String)value;
+ return;
+ }
+ else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
+ _accessExternalDTD = (String)value;
+ return;
+ }
// Throw an exception for all other attributes
final ErrorMsg err
@@ -444,7 +475,12 @@ public class TransformerFactoryImpl
throw new TransformerConfigurationException(err.toString());
}
_isNotSecureProcessing = !value;
- // all done processing feature
+
+ // set restriction, allowing no access to external stylesheet
+ if (value) {
+ _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP;
+ _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP;
+ }
return;
}
else if (name.equals(XalanConstants.ORACLE_FEATURE_SERVICE_MECHANISM)) {
@@ -799,6 +835,8 @@ public class TransformerFactoryImpl
xsltc.setTemplateInlining(false);
if (!_isNotSecureProcessing) xsltc.setSecureProcessing(true);
+ xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, _accessExternalStylesheet);
+ xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
xsltc.init();
// Set a document loader (for xsl:include/import) if defined
@@ -880,15 +918,20 @@ public class TransformerFactoryImpl
// Check that the transformation went well before returning
if (bytecodes == null) {
-
Vector errs = xsltc.getErrors();
ErrorMsg err = null;
if (errs != null) {
- err = (ErrorMsg)errs.get(errs.size()-1);
+ err = (ErrorMsg)errs.elementAt(errs.size()-1);
} else {
err = new ErrorMsg(ErrorMsg.JAXP_COMPILE_ERR);
}
- TransformerConfigurationException exc = new TransformerConfigurationException(err.toString(), err.getCause());
+ Throwable cause = err.getCause();
+ TransformerConfigurationException exc;
+ if (cause != null) {
+ exc = new TransformerConfigurationException(cause.getMessage(), cause);
+ } else {
+ exc = new TransformerConfigurationException(err.toString());
+ }
// Pass compiler errors to the error listener
if (_errorListener != null) {
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
index 16e178eba9a..a32ab8267f8 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
@@ -23,6 +23,7 @@
package com.sun.org.apache.xalan.internal.xsltc.trax;
+import com.sun.org.apache.xalan.internal.XalanConstants;
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
import java.io.File;
import java.io.FileOutputStream;
@@ -61,6 +62,7 @@ import javax.xml.transform.stax.StAXResult;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
+import javax.xml.XMLConstants;
import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
@@ -207,6 +209,14 @@ public final class TransformerImpl extends Transformer
* Note the default value (false) is the safe option..
*/
private boolean _useServicesMechanism;
+ /**
+ * protocols allowed for external references set by the stylesheet processing instruction, Import and Include element.
+ */
+ private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+ /**
+ * protocols allowed for external DTD references in source file and/or stylesheet.
+ */
+ private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
/**
* A hashtable to store parameters for the identity transform. These
@@ -260,7 +270,10 @@ public final class TransformerImpl extends Transformer
_indentNumber = indentNumber;
_tfactory = tfactory;
_useServicesMechanism = _tfactory.useServicesMechnism();
+ _accessExternalStylesheet = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET);
+ _accessExternalDTD = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_DTD);
_readerManager = XMLReaderManager.getInstance(_useServicesMechanism);
+ _readerManager.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
//_isIncremental = tfactory._incremental;
}
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java
index f5e1c85b98c..bef160df947 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java
@@ -105,6 +105,8 @@ public final class Util {
if (reader == null) {
try {
reader= XMLReaderFactory.createXMLReader();
+ reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
+ xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
} catch (Exception e ) {
try {
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java
index ad11c0416ee..23be56b5b58 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java
@@ -20,18 +20,6 @@
package com.sun.org.apache.xerces.internal.dom;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Vector;
-
-import com.sun.org.apache.xerces.internal.util.PropertyState;
-import com.sun.org.apache.xerces.internal.util.Status;
-import org.w3c.dom.DOMConfiguration;
-import org.w3c.dom.DOMErrorHandler;
-import org.w3c.dom.DOMStringList;
-
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
@@ -42,7 +30,10 @@ import com.sun.org.apache.xerces.internal.util.DOMEntityResolverWrapper;
import com.sun.org.apache.xerces.internal.util.DOMErrorHandlerWrapper;
import com.sun.org.apache.xerces.internal.util.MessageFormatter;
import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings;
+import com.sun.org.apache.xerces.internal.util.PropertyState;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
+import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
@@ -55,12 +46,19 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
-import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Vector;
+import javax.xml.XMLConstants;
+import org.w3c.dom.DOMConfiguration;
+import org.w3c.dom.DOMErrorHandler;
import org.w3c.dom.DOMException;
+import org.w3c.dom.DOMStringList;
import org.w3c.dom.ls.LSResourceResolver;
-
/**
* Xerces implementation of DOMConfiguration that maintains a table of recognized parameters.
*
@@ -158,6 +156,14 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings
protected static final String SCHEMA_DV_FACTORY =
Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY;
+ /** Property identifier: access to external dtd */
+ protected static final String ACCESS_EXTERNAL_DTD =
+ XMLConstants.ACCESS_EXTERNAL_DTD;
+
+ /** Property identifier: access to external schema */
+ protected static final String ACCESS_EXTERNAL_SCHEMA =
+ XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
//
// Data
//
@@ -276,7 +282,9 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings
JAXP_SCHEMA_SOURCE,
JAXP_SCHEMA_LANGUAGE,
DTD_VALIDATOR_FACTORY_PROPERTY,
- SCHEMA_DV_FACTORY
+ SCHEMA_DV_FACTORY,
+ ACCESS_EXTERNAL_DTD,
+ ACCESS_EXTERNAL_SCHEMA
};
addRecognizedProperties(recognizedProperties);
@@ -310,6 +318,14 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings
fValidationManager = createValidationManager();
setProperty(VALIDATION_MANAGER, fValidationManager);
+ //For DOM, the secure feature is set to true by default
+ String accessExternal = SecuritySupport.getDefaultAccessProperty(
+ Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT);
+ setProperty(ACCESS_EXTERNAL_DTD, accessExternal);
+
+ accessExternal = SecuritySupport.getDefaultAccessProperty(
+ Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT);
+ setProperty(ACCESS_EXTERNAL_SCHEMA, accessExternal);
// add message formatters
if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java
index d6f457db839..ec8a1117ebc 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java
@@ -20,6 +20,7 @@
package com.sun.org.apache.xerces.internal.impl;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
import java.util.Enumeration;
import java.util.NoSuchElementException;
@@ -138,6 +139,21 @@ public final class Constants {
public static final String FEATURE_SECURE_PROCESSING = "http://javax.xml.XMLConstants/feature/secure-processing";
+ // Oracle Feature:
+ /**
+ * Use Service Mechanism
+ *
+ *
+ * -
+ * {@code true} instruct an object to use service mechanism to
+ * find a service implementation. This is the default behavior.
+ *
+ * -
+ * {@code false} instruct an object to skip service mechanism and
+ * use the default implementation for that service.
+ *
+ *
+ */
public static final String ORACLE_FEATURE_SERVICE_MECHANISM = "http://www.oracle.com/feature/use-service-mechanism";
/** Document XML version property ("document-xml-version"). */
@@ -160,6 +176,34 @@ public final class Constants {
public static final String SYSTEM_PROPERTY_ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ;
+ /** JAXP Standard property prefix ("http://javax.xml.XMLConstants/property/"). */
+ public static final String JAXPAPI_PROPERTY_PREFIX =
+ "http://javax.xml.XMLConstants/property/";
+
+ /** Oracle JAXP property prefix ("http://www.oracle.com/xml/jaxp/properties/"). */
+ public static final String ORACLE_JAXP_PROPERTY_PREFIX =
+ "http://www.oracle.com/xml/jaxp/properties/";
+
+ //System Properties corresponding to ACCESS_EXTERNAL_* properties
+ public static final String SP_ACCESS_EXTERNAL_DTD = "javax.xml.accessExternalDTD";
+ public static final String SP_ACCESS_EXTERNAL_SCHEMA = "javax.xml.accessExternalSchema";
+ //all access keyword
+ public static final String ACCESS_EXTERNAL_ALL = "all";
+
+ /**
+ * Default value when FEATURE_SECURE_PROCESSING (FSP) is set to true
+ */
+ public static final String EXTERNAL_ACCESS_DEFAULT_FSP = "";
+ /**
+ * JDK version by which the default is to restrict external connection
+ */
+ public static final int RESTRICT_BY_DEFAULT_JDK_VERSION = 8;
+
+ /**
+ * FEATURE_SECURE_PROCESSING (FSP) is true by default
+ */
+ public static final String EXTERNAL_ACCESS_DEFAULT = getExternalAccessDefault(true);
+
//
// DOM features
//
@@ -653,6 +697,59 @@ public final class Constants {
? new ArrayEnumeration(fgXercesProperties) : fgEmptyEnumeration;
} // getXercesProperties():Enumeration
+ /**
+ * Determine the default value of the external access properties
+ *
+ * jaxp 1.5 does not require implementations to restrict by default
+ *
+ * For JDK8:
+ * The default value is 'file' (including jar:file); The keyword "all" grants permission
+ * to all protocols. When {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} is on,
+ * the default value is an empty string indicating no access is allowed.
+ *
+ * For JDK7:
+ * The default value is 'all' granting permission to all protocols. If by default,
+ * {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} is true, it should
+ * not change the default value. However, if {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING}
+ * is set explicitly, the values of the properties shall be set to an empty string
+ * indicating no access is allowed.
+ *
+ * @param isSecureProcessing indicating if Secure Processing is set
+ * @return default value
+ */
+ public static String getExternalAccessDefault(boolean isSecureProcessing) {
+ String defaultValue = "all";
+ if (isJDKandAbove(RESTRICT_BY_DEFAULT_JDK_VERSION)) {
+ defaultValue = "file";
+ if (isSecureProcessing) {
+ defaultValue = EXTERNAL_ACCESS_DEFAULT_FSP;
+ }
+ }
+ return defaultValue;
+ }
+
+ /*
+ * Check the version of the current JDK against that specified in the
+ * parameter
+ *
+ * There is a proposal to change the java version string to:
+ * MAJOR.MINOR.FU.CPU.PSU-BUILDNUMBER_BUGIDNUMBER_OPTIONAL
+ * This method would work with both the current format and that proposed
+ *
+ * @param compareTo a JDK version to be compared to
+ * @return true if the current version is the same or above that represented
+ * by the parameter
+ */
+ public static boolean isJDKandAbove(int compareTo) {
+ String javaVersion = SecuritySupport.getSystemProperty("java.version");
+ String versions[] = javaVersion.split("\\.", 3);
+ if (Integer.parseInt(versions[0]) >= compareTo ||
+ Integer.parseInt(versions[1]) >= compareTo) {
+ return true;
+ }
+ return false;
+ }
+
//
// Classes
//
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java
index ead08fe0393..b85ea503fa3 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java
@@ -25,13 +25,14 @@
package com.sun.org.apache.xerces.internal.impl;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
+import com.sun.xml.internal.stream.StaxEntityResolverWrapper;
import java.util.HashMap;
+import javax.xml.XMLConstants;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLResolver;
-import com.sun.xml.internal.stream.StaxEntityResolverWrapper;
-
/**
* This class manages different properties related to Stax specification and its implementation.
* This class constructor also takes itself (PropertyManager object) as parameter and initializes the
@@ -51,6 +52,12 @@ public class PropertyManager {
private static final String STRING_INTERNING = "http://xml.org/sax/features/string-interning";
+ /** Property identifier: access to external dtd */
+ protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+ /** Property identifier: access to external schema */
+ protected static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
HashMap supportedProps = new HashMap();
public static final int CONTEXT_READER = 1;
@@ -117,6 +124,15 @@ public class PropertyManager {
supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE, new Boolean(false));
supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE, new Boolean(false));
supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE, new Boolean(false));
+
+ //For DOM/SAX, the secure feature is set to true by default
+ String accessExternal = SecuritySupport.getDefaultAccessProperty(
+ Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT);
+ supportedProps.put(ACCESS_EXTERNAL_DTD, accessExternal);
+
+ accessExternal = SecuritySupport.getDefaultAccessProperty(
+ Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT);
+ supportedProps.put(ACCESS_EXTERNAL_SCHEMA, accessExternal);
}
private void initWriterProps(){
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java
index abbd696bb03..82c009bbdd3 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java
@@ -52,7 +52,10 @@ import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler;
import com.sun.org.apache.xerces.internal.util.SecurityManager;
import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
+import com.sun.xml.internal.stream.Entity;
+import javax.xml.XMLConstants;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.events.XMLEvent;
@@ -159,6 +162,18 @@ public class XMLDocumentFragmentScannerImpl
protected static final String ENTITY_RESOLVER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
+ /** Feature identifier: standard uri conformant */
+ protected static final String STANDARD_URI_CONFORMANT =
+ Constants.XERCES_FEATURE_PREFIX +Constants.STANDARD_URI_CONFORMANT_FEATURE;
+
+ /** property identifier: access external dtd. */
+ protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+ /** access external dtd: file protocol
+ * For DOM/SAX, the secure feature is set to true by default
+ */
+ final static String EXTERNAL_ACCESS_DEFAULT = Constants.EXTERNAL_ACCESS_DEFAULT;
+
// recognized features and properties
/** Recognized features. */
@@ -184,6 +199,7 @@ public class XMLDocumentFragmentScannerImpl
SYMBOL_TABLE,
ERROR_REPORTER,
ENTITY_MANAGER,
+ ACCESS_EXTERNAL_DTD
};
/** Property defaults. */
@@ -191,6 +207,7 @@ public class XMLDocumentFragmentScannerImpl
null,
null,
null,
+ EXTERNAL_ACCESS_DEFAULT
};
private static final char [] cdata = {'[','C','D','A','T','A','['};
@@ -297,6 +314,17 @@ public class XMLDocumentFragmentScannerImpl
protected String fDeclaredEncoding = null;
/** Xerces Feature: Disallow doctype declaration. */
protected boolean fDisallowDoctype = false;
+ /**
+ * comma-delimited list of protocols that are allowed for the purpose
+ * of accessing external dtd or entity references
+ */
+ protected String fAccessExternalDTD = EXTERNAL_ACCESS_DEFAULT;
+
+ /**
+ * standard uri conformant (strict uri).
+ * http://apache.org/xml/features/standard-uri-conformant
+ */
+ protected boolean fStrictURI;
// drivers
@@ -413,17 +441,6 @@ public class XMLDocumentFragmentScannerImpl
*
* @return True if there is more to scan, false otherwise.
*/
- /* public boolean scanDocument(boolean complete)
- throws IOException, XNIException {
-
- // keep dispatching "events"
- fEntityManager.setEntityHandler(this);
-
- return true;
-
- } // scanDocument(boolean):boolean
- */
-
public boolean scanDocument(boolean complete)
throws IOException, XNIException {
@@ -579,6 +596,9 @@ public class XMLDocumentFragmentScannerImpl
//xxx: external entities are supported in Xerces
// it would be good to define feature for this case
fSupportExternalEntities = true;
+ fSupportExternalEntities = true;
+ fSupportExternalEntities = true;
+ fSupportExternalEntities = true;
fReplaceEntityReferences = true;
fIsCoalesce = false;
@@ -589,6 +609,9 @@ public class XMLDocumentFragmentScannerImpl
dtdGrammarUtil = null;
+ // JAXP 1.5 features and properties
+ fAccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD, EXTERNAL_ACCESS_DEFAULT);
+ fStrictURI = componentManager.getFeature(STANDARD_URI_CONFORMANT, false);
//fEntityManager.test();
} // reset(XMLComponentManager)
@@ -639,6 +662,9 @@ public class XMLDocumentFragmentScannerImpl
dtdGrammarUtil = null;
+ // Oracle jdk feature
+ fAccessExternalDTD = (String) propertyManager.getProperty(ACCESS_EXTERNAL_DTD);
+
} // reset(XMLComponentManager)
/**
@@ -735,6 +761,14 @@ public class XMLDocumentFragmentScannerImpl
return;
}
+ //JAXP 1.5 properties
+ if (propertyId.startsWith(Constants.JAXPAPI_PROPERTY_PREFIX)) {
+ if (propertyId.equals(ACCESS_EXTERNAL_DTD))
+ {
+ fAccessExternalDTD = (String)value;
+ }
+ }
+
} // setProperty(String,Object)
/**
@@ -1846,7 +1880,8 @@ public class XMLDocumentFragmentScannerImpl
//1. if the entity is external and support to external entities is not required
// 2. or entities should not be replaced
//3. or if it is built in entity reference.
- if((fEntityStore.isExternalEntity(name) && !fSupportExternalEntities) || (!fEntityStore.isExternalEntity(name) && !fReplaceEntityReferences) || foundBuiltInRefs){
+ boolean isEE = fEntityStore.isExternalEntity(name);
+ if((isEE && !fSupportExternalEntities) || (!isEE && !fReplaceEntityReferences) || foundBuiltInRefs){
fScannerState = SCANNER_STATE_REFERENCE;
return ;
}
@@ -1996,6 +2031,12 @@ public class XMLDocumentFragmentScannerImpl
} // getDriverName():String
+ String checkAccess(String systemId, String allowedProtocols) throws IOException {
+ String baseSystemId = fEntityScanner.getBaseSystemId();
+ String expandedSystemId = fEntityManager.expandSystemId(systemId, baseSystemId,fStrictURI);
+ return SecuritySupport.checkAccess(expandedSystemId, allowedProtocols, Constants.ACCESS_EXTERNAL_ALL);
+ }
+
//
// Classes
//
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java
index b6ef755a473..b043c9d3be1 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java
@@ -21,6 +21,22 @@
package com.sun.org.apache.xerces.internal.impl;
+import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDDescription;
+import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
+import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
+import com.sun.org.apache.xerces.internal.util.XMLChar;
+import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl;
+import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
+import com.sun.org.apache.xerces.internal.xni.Augmentations;
+import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
+import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
+import com.sun.org.apache.xerces.internal.xni.XMLString;
+import com.sun.org.apache.xerces.internal.xni.XNIException;
+import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
+import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
+import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner;
+import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import com.sun.xml.internal.stream.Entity;
import com.sun.xml.internal.stream.StaxXMLInputSource;
import com.sun.xml.internal.stream.dtd.DTDGrammarUtil;
@@ -29,23 +45,6 @@ import java.io.IOException;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.events.XMLEvent;
-import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
-import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
-import com.sun.org.apache.xerces.internal.util.XMLChar;
-import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl;
-import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
-import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
-import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
-import com.sun.org.apache.xerces.internal.xni.XMLString;
-import com.sun.org.apache.xerces.internal.xni.XNIException;
-import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
-import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
-import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
-import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner;
-import com.sun.org.apache.xerces.internal.xni.Augmentations;
-import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDDescription;
-import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentScanner;
-
/**
* This class is responsible for scanning XML document structure
@@ -148,7 +147,7 @@ public class XMLDocumentScannerImpl
/** Property defaults. */
private static final Object[] PROPERTY_DEFAULTS = {
- null,
+ null,
null
};
@@ -920,7 +919,6 @@ public class XMLDocumentScannerImpl
reportFatalError("DoctypeNotAllowed", null);
}
-
if (fSeenDoctypeDecl) {
reportFatalError("AlreadySeenDoctype", null);
}
@@ -952,15 +950,18 @@ public class XMLDocumentScannerImpl
if (fDoctypeSystemId != null) {
if (((fValidation || fLoadExternalDTD)
&& (fValidationManager == null || !fValidationManager.isCachedDTD()))) {
- if (fSupportDTD)
- setScannerState(SCANNER_STATE_DTD_EXTERNAL);
- else
- setScannerState(SCANNER_STATE_PROLOG);
- setDriver(fContentDriver);
- if(fDTDDriver == null)
- fDTDDriver = new DTDDriver();
- return fDTDDriver.next();
+ if (fSupportDTD) {
+ setScannerState(SCANNER_STATE_DTD_EXTERNAL);
+ } else {
+ setScannerState(SCANNER_STATE_PROLOG);
+ }
+ setDriver(fContentDriver);
+ if(fDTDDriver == null) {
+ fDTDDriver = new DTDDriver();
+ }
+
+ return fDTDDriver.next();
}
}
else if (fExternalSubsetSource != null) {
@@ -1149,9 +1150,21 @@ public class XMLDocumentScannerImpl
resourceIdentifier.setValues(fDoctypePublicId, fDoctypeSystemId, null, null);
XMLInputSource xmlInputSource = null ;
StaxXMLInputSource staxInputSource = fEntityManager.resolveEntityAsPerStax(resourceIdentifier);
+
+ // Check access permission. If the source is resolved by a resolver, the check is skipped.
+ if (!staxInputSource.hasResolver()) {
+ String accessError = checkAccess(fDoctypeSystemId, fAccessExternalDTD);
+ if (accessError != null) {
+ reportFatalError("AccessExternalDTD", new Object[]{ SecuritySupport.sanitizePath(fDoctypeSystemId), accessError });
+ }
+ }
xmlInputSource = staxInputSource.getXMLInputSource();
fDTDScanner.setInputSource(xmlInputSource);
- setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
+ if (fEntityScanner.fCurrentEntity != null) {
+ setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
+ } else {
+ setScannerState(SCANNER_STATE_PROLOG);
+ }
again = true;
break;
}
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
index b761fc41974..ee6ff0a6b2e 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -20,51 +20,37 @@
package com.sun.org.apache.xerces.internal.impl ;
+import com.sun.org.apache.xerces.internal.impl.Constants;
+import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
+import com.sun.org.apache.xerces.internal.impl.io.UCSReader;
+import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader;
+import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
+import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler;
+import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
+import com.sun.org.apache.xerces.internal.util.*;
+import com.sun.org.apache.xerces.internal.util.SecurityManager;
+import com.sun.org.apache.xerces.internal.util.URI;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
+import com.sun.org.apache.xerces.internal.xni.Augmentations;
+import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
+import com.sun.org.apache.xerces.internal.xni.XNIException;
+import com.sun.org.apache.xerces.internal.xni.parser.*;
+import com.sun.xml.internal.stream.Entity;
import com.sun.xml.internal.stream.StaxEntityResolverWrapper;
import com.sun.xml.internal.stream.StaxXMLInputSource;
import com.sun.xml.internal.stream.XMLEntityStorage;
import java.io.*;
-import java.io.BufferedReader;
-import java.util.*;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringReader;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
+import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
-import java.net.URISyntaxException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Stack;
-
-
-import com.sun.org.apache.xerces.internal.impl.io.*;
-import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
-import com.sun.org.apache.xerces.internal.util.*;
-import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
-import com.sun.org.apache.xerces.internal.xni.XNIException;
-import com.sun.org.apache.xerces.internal.xni.parser.*;
-import com.sun.org.apache.xerces.internal.impl.Constants;
-import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
-import com.sun.xml.internal.stream.Entity;
-import com.sun.org.apache.xerces.internal.xni.Augmentations;
-
-import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader;
-import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
-import com.sun.org.apache.xerces.internal.impl.io.UCSReader;
-import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler;
-import com.sun.org.apache.xerces.internal.util.HTTPInputSource;
-import com.sun.org.apache.xerces.internal.xinclude.XIncludeHandler;
-
-import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
-import com.sun.org.apache.xerces.internal.util.SecurityManager;
-import com.sun.org.apache.xerces.internal.util.URI;
+import javax.xml.XMLConstants;
/**
@@ -140,6 +126,10 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
protected static final String WARN_ON_DUPLICATE_ENTITYDEF =
Constants.XERCES_FEATURE_PREFIX +Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE;
+ /** Feature identifier: load external DTD. */
+ protected static final String LOAD_EXTERNAL_DTD =
+ Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE;
+
// property identifiers
/** Property identifier: symbol table. */
@@ -173,8 +163,16 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
protected static final String SECURITY_MANAGER =
Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
-protected static final String PARSER_SETTINGS =
+ protected static final String PARSER_SETTINGS =
Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS;
+
+ /** property identifier: access external dtd. */
+ protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+ /** access external dtd: file protocol */
+ static final String EXTERNAL_ACCESS_DEFAULT = Constants.EXTERNAL_ACCESS_DEFAULT;
+
+
// recognized features and properties
/** Recognized features. */
@@ -205,7 +203,7 @@ protected static final String PARSER_SETTINGS =
VALIDATION_MANAGER,
BUFFER_SIZE,
SECURITY_MANAGER,
-
+ ACCESS_EXTERNAL_DTD
};
/** Property defaults. */
@@ -215,7 +213,8 @@ protected static final String PARSER_SETTINGS =
null,
null,
new Integer(DEFAULT_BUFFER_SIZE),
- null
+ null,
+ EXTERNAL_ACCESS_DEFAULT
};
private static final String XMLEntity = "[xml]".intern();
@@ -274,6 +273,8 @@ protected static final String PARSER_SETTINGS =
*/
protected boolean fAllowJavaEncodings = true ;
+ /** Load external DTD. */
+ protected boolean fLoadExternalDTD = true;
// properties
@@ -302,7 +303,8 @@ protected static final String PARSER_SETTINGS =
/** Property Manager. This is used from Stax */
protected PropertyManager fPropertyManager ;
-
+ /** used to restrict external access */
+ protected String fAccessExternalDTD = EXTERNAL_ACCESS_DEFAULT;
// settings
/**
@@ -366,6 +368,9 @@ protected static final String PARSER_SETTINGS =
/** Current entity. */
protected Entity.ScannedEntity fCurrentEntity = null;
+ /** identify if the InputSource is created by a resolver */
+ boolean fISCreatedByResolver = false;
+
// shared context
protected XMLEntityStorage fEntityStorage ;
@@ -965,18 +970,25 @@ protected static final String PARSER_SETTINGS =
System.out.println("BEFORE Calling resolveEntity") ;
}
+ fISCreatedByResolver = false;
//either of Stax or Xerces would be null
if(fStaxEntityResolver != null){
staxInputSource = fStaxEntityResolver.resolveEntity(ri);
+ if(staxInputSource != null) {
+ fISCreatedByResolver = true;
+ }
}
if(fEntityResolver != null){
xmlInputSource = fEntityResolver.resolveEntity(ri);
+ if(xmlInputSource != null) {
+ fISCreatedByResolver = true;
+ }
}
if(xmlInputSource != null){
//wrap this XMLInputSource to StaxInputSource
- staxInputSource = new StaxXMLInputSource(xmlInputSource);
+ staxInputSource = new StaxXMLInputSource(xmlInputSource, fISCreatedByResolver);
}
// do default resolution
@@ -1108,7 +1120,13 @@ protected static final String PARSER_SETTINGS =
// should we skip external entities?
boolean external = entity.isExternal();
+ Entity.ExternalEntity externalEntity = null;
+ String extLitSysId = null, extBaseSysId = null, expandedSystemId = null;
if (external) {
+ externalEntity = (Entity.ExternalEntity)entity;
+ extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null);
+ extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null);
+ expandedSystemId = expandSystemId(extLitSysId, extBaseSysId);
boolean unparsed = entity.isUnparsed();
boolean parameter = entityName.startsWith("%");
boolean general = !parameter;
@@ -1118,13 +1136,6 @@ protected static final String PARSER_SETTINGS =
if (fEntityHandler != null) {
fResourceIdentifier.clear();
final String encoding = null;
- Entity.ExternalEntity externalEntity = (Entity.ExternalEntity)entity;
- //REVISIT: since we're storing expandedSystemId in the
- // externalEntity, how could this have got here if it wasn't already
- // expanded??? - neilg
- String extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null);
- String extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null);
- String expandedSystemId = expandSystemId(extLitSysId, extBaseSysId);
fResourceIdentifier.setValues(
(externalEntity.entityLocation != null ? externalEntity.entityLocation.getPublicId() : null),
extLitSysId, extBaseSysId, expandedSystemId);
@@ -1162,11 +1173,6 @@ protected static final String PARSER_SETTINGS =
fResourceIdentifier.clear();
final String encoding = null;
if (external) {
- Entity.ExternalEntity externalEntity = (Entity.ExternalEntity)entity;
- // REVISIT: for the same reason above...
- String extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null);
- String extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null);
- String expandedSystemId = expandSystemId(extLitSysId, extBaseSysId);
fResourceIdentifier.setValues(
(externalEntity.entityLocation != null ? externalEntity.entityLocation.getPublicId() : null),
extLitSysId, extBaseSysId, expandedSystemId);
@@ -1188,7 +1194,6 @@ protected static final String PARSER_SETTINGS =
XMLInputSource xmlInputSource = null ;
if (external) {
- Entity.ExternalEntity externalEntity = (Entity.ExternalEntity)entity;
staxInputSource = resolveEntityAsPerStax(externalEntity.entityLocation);
/** xxx: Waiting from the EG
* //simply return if there was entity resolver registered and application
@@ -1196,6 +1201,18 @@ protected static final String PARSER_SETTINGS =
* if(staxInputSource.hasXMLStreamOrXMLEventReader()) return ;
*/
xmlInputSource = staxInputSource.getXMLInputSource() ;
+ if (!fISCreatedByResolver) {
+ //let the not-LoadExternalDTD or not-SupportDTD process to handle the situation
+ if (fLoadExternalDTD) {
+ String accessError = SecuritySupport.checkAccess(expandedSystemId, fAccessExternalDTD, Constants.ACCESS_EXTERNAL_ALL);
+ if (accessError != null) {
+ fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN,
+ "AccessExternalEntity",
+ new Object[] { SecuritySupport.sanitizePath(expandedSystemId), accessError },
+ XMLErrorReporter.SEVERITY_FATAL_ERROR);
+ }
+ }
+ }
}
// wrap internal entity
else {
@@ -1400,6 +1417,12 @@ protected static final String PARSER_SETTINGS =
fStaxEntityResolver = null;
}
+ // Zephyr feature ignore-external-dtd is the opposite of Xerces' load-external-dtd
+ fLoadExternalDTD = !((Boolean)propertyManager.getProperty(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.IGNORE_EXTERNAL_DTD)).booleanValue();
+
+ // JAXP 1.5 feature
+ fAccessExternalDTD = (String) propertyManager.getProperty(ACCESS_EXTERNAL_DTD);
+
// initialize state
//fStandalone = false;
fEntities.clear();
@@ -1409,8 +1432,6 @@ protected static final String PARSER_SETTINGS =
fExternalGeneralEntities = true;
fExternalParameterEntities = true;
fAllowJavaEncodings = true ;
-
- //test();
}
/**
@@ -1453,6 +1474,7 @@ protected static final String PARSER_SETTINGS =
fAllowJavaEncodings = componentManager.getFeature(ALLOW_JAVA_ENCODINGS, false);
fWarnDuplicateEntityDef = componentManager.getFeature(WARN_ON_DUPLICATE_ENTITYDEF, false);
fStrictURI = componentManager.getFeature(STANDARD_URI_CONFORMANT, false);
+ fLoadExternalDTD = componentManager.getFeature(LOAD_EXTERNAL_DTD, true);
// xerces properties
fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE);
@@ -1462,6 +1484,9 @@ protected static final String PARSER_SETTINGS =
fValidationManager = (ValidationManager)componentManager.getProperty(VALIDATION_MANAGER, null);
fSecurityManager = (SecurityManager)componentManager.getProperty(SECURITY_MANAGER, null);
+ // JAXP 1.5 feature
+ fAccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD, EXTERNAL_ACCESS_DEFAULT);
+
//reset general state
reset();
@@ -1554,6 +1579,11 @@ protected static final String PARSER_SETTINGS =
featureId.endsWith(Constants.ALLOW_JAVA_ENCODINGS_FEATURE)) {
fAllowJavaEncodings = state;
}
+ if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() &&
+ featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
+ fLoadExternalDTD = state;
+ return;
+ }
}
} // setFeature(String,boolean)
@@ -1610,7 +1640,15 @@ protected static final String PARSER_SETTINGS =
}
}
+ //JAXP 1.5 properties
+ if (propertyId.startsWith(Constants.JAXPAPI_PROPERTY_PREFIX)) {
+ if (propertyId.equals(ACCESS_EXTERNAL_DTD))
+ {
+ fAccessExternalDTD = (String)value;
+ }
+ }
}
+
/**
* Returns a list of property identifiers that are recognized by
* this component. This method may return null if no properties
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/AbstractDateTimeDV.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/AbstractDateTimeDV.java
index e69c9e56a8a..d9d6587379b 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/AbstractDateTimeDV.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/AbstractDateTimeDV.java
@@ -51,456 +51,471 @@ import com.sun.org.apache.xerces.internal.xs.datatypes.XSDateTime;
*/
public abstract class AbstractDateTimeDV extends TypeValidator {
- //debugging
- private static final boolean DEBUG=false;
-
- //define shared variables for date/time
-
-
- //define constants to be used in assigning default values for
- //all date/time excluding duration
- protected final static int YEAR=2000;
- protected final static int MONTH=01;
- protected final static int DAY = 01;
-
+ //debugging
+ private static final boolean DEBUG = false;
+ //define shared variables for date/time
+ //define constants to be used in assigning default values for
+ //all date/time excluding duration
+ protected final static int YEAR = 2000;
+ protected final static int MONTH = 01;
+ protected final static int DAY = 01;
protected static final DatatypeFactory datatypeFactory = new DatatypeFactoryImpl();
- public short getAllowedFacets(){
- return ( XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION |XSSimpleTypeDecl.FACET_MAXINCLUSIVE |XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE );
- }//getAllowedFacets()
-
-
- // distinguishes between identity and equality for date/time values
- // ie: two values representing the same "moment in time" but with different
- // remembered timezones are now equal but not identical.
- public boolean isIdentical (Object value1, Object value2) {
- if (!(value1 instanceof DateTimeData) || !(value2 instanceof DateTimeData)) {
- return false;
- }
-
- DateTimeData v1 = (DateTimeData)value1;
- DateTimeData v2 = (DateTimeData)value2;
-
- // original timezones must be the same in addition to date/time values
- // being 'equal'
- if ((v1.timezoneHr == v2.timezoneHr) && (v1.timezoneMin == v2.timezoneMin)) {
- return v1.equals(v2);
- }
-
- return false;
- }//isIdentical()
-
- // the parameters are in compiled form (from getActualValue)
- public int compare (Object value1, Object value2) {
- return compareDates(((DateTimeData)value1),
- ((DateTimeData)value2), true);
- }//compare()
-
- /**
- * Compare algorithm described in dateDime (3.2.7).
- * Duration datatype overwrites this method
- *
- * @param date1 normalized date representation of the first value
- * @param date2 normalized date representation of the second value
- * @param strict
- * @return less, greater, less_equal, greater_equal, equal
- */
- protected short compareDates(DateTimeData date1, DateTimeData date2, boolean strict) {
- if (date1.utc == date2.utc) {
- return compareOrder(date1, date2);
- }
- short c1, c2;
-
- DateTimeData tempDate = new DateTimeData(null, this);
-
- if ( date1.utc=='Z' ) {
-
- //compare date1<=date1<=(date2 with time zone -14)
- //
- cloneDate(date2, tempDate); //clones date1 value to global temporary storage: fTempDate
- tempDate.timezoneHr=14;
- tempDate.timezoneMin = 0;
- tempDate.utc='+';
- normalize(tempDate);
- c1 = compareOrder(date1, tempDate);
- if (c1 == LESS_THAN)
- return c1;
-
- //compare date1>=(date2 with time zone +14)
- //
- cloneDate(date2, tempDate); //clones date1 value to global temporary storage: tempDate
- tempDate.timezoneHr = -14;
- tempDate.timezoneMin = 0;
- tempDate.utc='-';
- normalize(tempDate);
- c2 = compareOrder(date1, tempDate);
- if (c2 == GREATER_THAN)
- return c2;
-
- return INDETERMINATE;
- }
- else if ( date2.utc=='Z' ) {
-
- //compare (date1 with time zone -14)<=date2
- //
- cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate
- tempDate.timezoneHr = -14;
- tempDate.timezoneMin = 0;
- tempDate.utc='-';
- if (DEBUG) {
- System.out.println("tempDate=" + dateToString(tempDate));
- }
- normalize(tempDate);
- c1 = compareOrder(tempDate, date2);
- if (DEBUG) {
- System.out.println("date=" + dateToString(date2));
- System.out.println("tempDate=" + dateToString(tempDate));
- }
- if (c1 == LESS_THAN)
- return c1;
-
- //compare (date1 with time zone +14)<=date2
- //
- cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate
- tempDate.timezoneHr = 14;
- tempDate.timezoneMin = 0;
- tempDate.utc='+';
- normalize(tempDate);
- c2 = compareOrder(tempDate, date2);
- if (DEBUG) {
- System.out.println("tempDate=" + dateToString(tempDate));
- }
- if (c2 == GREATER_THAN)
- return c2;
-
- return INDETERMINATE;
- }
- return INDETERMINATE;
+ @Override
+ public short getAllowedFacets() {
+ return (XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION | XSSimpleTypeDecl.FACET_MAXINCLUSIVE | XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE);
+ }//getAllowedFacets()
+ // distinguishes between identity and equality for date/time values
+ // ie: two values representing the same "moment in time" but with different
+ // remembered timezones are now equal but not identical.
+ @Override
+ public boolean isIdentical(Object value1, Object value2) {
+ if (!(value1 instanceof DateTimeData) || !(value2 instanceof DateTimeData)) {
+ return false;
}
- /**
- * Given normalized values, determines order-relation
- * between give date/time objects.
- *
- * @param date1 date/time object
- * @param date2 date/time object
- * @return 0 if date1 and date2 are equal, a value less than 0 if date1 is less than date2, a value greater than 0 if date1 is greater than date2
- */
- protected short compareOrder(DateTimeData date1, DateTimeData date2) {
- if(date1.position < 1) {
- if (date1.year < date2.year)
- return -1;
- if (date1.year > date2.year)
- return 1;
- }
- if(date1.position < 2) {
- if (date1.month < date2.month)
- return -1;
- if (date1.month > date2.month)
- return 1;
- }
- if (date1.day < date2.day)
- return -1;
- if (date1.day > date2.day)
- return 1;
- if (date1.hour < date2.hour)
- return -1;
- if (date1.hour > date2.hour)
- return 1;
- if (date1.minute < date2.minute)
- return -1;
- if (date1.minute > date2.minute)
- return 1;
- if (date1.second < date2.second)
- return -1;
- if (date1.second > date2.second)
- return 1;
- if (date1.utc < date2.utc)
- return -1;
- if (date1.utc > date2.utc)
- return 1;
- return 0;
+ DateTimeData v1 = (DateTimeData) value1;
+ DateTimeData v2 = (DateTimeData) value2;
+
+ // original timezones must be the same in addition to date/time values
+ // being 'equal'
+ if ((v1.timezoneHr == v2.timezoneHr) && (v1.timezoneMin == v2.timezoneMin)) {
+ return v1.equals(v2);
}
- /**
- * Parses time hh:mm:ss.sss and time zone if any
- *
- * @param start
- * @param end
- * @param data
- * @exception RuntimeException
- */
- protected void getTime (String buffer, int start, int end, DateTimeData data) throws RuntimeException{
+ return false;
+ }//isIdentical()
- int stop = start+2;
-
- //get hours (hh)
- data.hour=parseInt(buffer, start,stop);
-
- //get minutes (mm)
-
- if (buffer.charAt(stop++)!=':') {
- throw new RuntimeException("Error in parsing time zone" );
- }
- start = stop;
- stop = stop+2;
- data.minute=parseInt(buffer, start,stop);
-
- //get seconds (ss)
- if (buffer.charAt(stop++)!=':') {
- throw new RuntimeException("Error in parsing time zone" );
- }
-
- //find UTC sign if any
- int sign = findUTCSign(buffer, start, end);
-
- //get seconds (ms)
- start = stop;
- stop = sign < 0 ? end : sign;
- data.second = parseSecond(buffer, start, stop);
-
- //parse UTC time zone (hh:mm)
- if (sign > 0) {
- getTimeZone(buffer, data, sign, end);
- }
- }
-
- /**
- * Parses date CCYY-MM-DD
- *
- * @param buffer
- * @param start start position
- * @param end end position
- * @param date
- * @exception RuntimeException
- */
- protected int getDate (String buffer, int start, int end, DateTimeData date) throws RuntimeException{
-
- start = getYearMonth(buffer, start, end, date);
-
- if (buffer.charAt(start++) !='-') {
- throw new RuntimeException("CCYY-MM must be followed by '-' sign");
- }
- int stop = start + 2;
- date.day=parseInt(buffer, start, stop);
- return stop;
- }
-
- /**
- * Parses date CCYY-MM
- *
- * @param buffer
- * @param start start position
- * @param end end position
- * @param date
- * @exception RuntimeException
- */
- protected int getYearMonth (String buffer, int start, int end, DateTimeData date) throws RuntimeException{
-
- if ( buffer.charAt(0)=='-' ) {
- // REVISIT: date starts with preceding '-' sign
- // do we have to do anything with it?
- //
- start++;
- }
- int i = indexOf(buffer, start, end, '-');
- if ( i==-1 ) throw new RuntimeException("Year separator is missing or misplaced");
- int length = i-start;
- if (length<4) {
- throw new RuntimeException("Year must have 'CCYY' format");
- }
- else if (length > 4 && buffer.charAt(start)=='0'){
- throw new RuntimeException("Leading zeros are required if the year value would otherwise have fewer than four digits; otherwise they are forbidden");
- }
- date.year= parseIntYear(buffer, i);
- if (buffer.charAt(i)!='-') {
- throw new RuntimeException("CCYY must be followed by '-' sign");
- }
- start = ++i;
- i = start +2;
- date.month=parseInt(buffer, start, i);
- return i; //fStart points right after the MONTH
- }
-
- /**
- * Shared code from Date and YearMonth datatypes.
- * Finds if time zone sign is present
- *
- * @param end
- * @param date
- * @exception RuntimeException
- */
- protected void parseTimeZone (String buffer, int start, int end, DateTimeData date) throws RuntimeException{
-
- //fStart points right after the date
-
- if ( start < end ) {
- if (!isNextCharUTCSign(buffer, start, end)) {
- throw new RuntimeException ("Error in month parsing");
- }
- else {
- getTimeZone(buffer, date, start, end);
- }
- }
- }
-
- /**
- * Parses time zone: 'Z' or {+,-} followed by hh:mm
- *
- * @param data
- * @param sign
- * @exception RuntimeException
- */
- protected void getTimeZone (String buffer, DateTimeData data, int sign, int end) throws RuntimeException{
- data.utc=buffer.charAt(sign);
-
- if ( buffer.charAt(sign) == 'Z' ) {
- if (end>(++sign)) {
- throw new RuntimeException("Error in parsing time zone");
- }
- return;
- }
- if ( sign<=(end-6) ) {
-
- int negate = buffer.charAt(sign) == '-'?-1:1;
- //parse hr
- int stop = ++sign+2;
- data.timezoneHr = negate*parseInt(buffer, sign, stop);
- if (buffer.charAt(stop++)!=':') {
- throw new RuntimeException("Error in parsing time zone" );
- }
-
- //parse min
- data.timezoneMin = negate*parseInt(buffer, stop, stop+2);
-
- if ( stop+2!=end ) {
- throw new RuntimeException("Error in parsing time zone");
- }
- if(data.timezoneHr != 0 || data.timezoneMin != 0)
- data.normalized = false;
- }
- else {
- throw new RuntimeException("Error in parsing time zone");
- }
- if ( DEBUG ) {
- System.out.println("time[hh]="+data.timezoneHr + " time[mm]=" +data.timezoneMin);
- }
- }
-
- /**
- * Computes index of given char within StringBuffer
- *
- * @param start
- * @param end
- * @param ch character to look for in StringBuffer
- * @return index of ch within StringBuffer
- */
- protected int indexOf (String buffer, int start, int end, char ch) {
- for ( int i=start;i12 ) {
- throw new RuntimeException("The month must have values 1 to 12");
-
- }
-
- //validate days
- if ( data.day>maxDayInMonthFor(data.year, data.month) || data.day<1 ) {
- throw new RuntimeException("The day must have values 1 to 31");
- }
-
- //validate hours
- if ( data.hour>23 || data.hour<0 ) {
- if (data.hour == 24 && data.minute == 0 && data.second == 0) {
- data.hour = 0;
- if (++data.day > maxDayInMonthFor(data.year, data.month)) {
- data.day = 1;
- if (++data.month > 12) {
- data.month = 1;
- if (Constants.SCHEMA_1_1_SUPPORT) {
- ++data.year;
- }
- else if (++data.year == 0) {
- data.year = 1;
- }
- }
- }
- }
- else {
- throw new RuntimeException("Hour must have values 0-23, unless 24:00:00");
- }
- }
-
- //validate
- if ( data.minute>59 || data.minute<0 ) {
- throw new RuntimeException("Minute must have values 0-59");
- }
-
- //validate
- if ( data.second>=60 || data.second<0 ) {
- throw new RuntimeException("Second must have values 0-59");
-
- }
-
- //validate
- if ( data.timezoneHr>14 || data.timezoneHr<-14 ) {
- throw new RuntimeException("Time zone should have range -14:00 to +14:00");
- }
- else {
- if((data.timezoneHr == 14 || data.timezoneHr == -14) && data.timezoneMin != 0)
- throw new RuntimeException("Time zone should have range -14:00 to +14:00");
- else if(data.timezoneMin > 59 || data.timezoneMin < -59)
- throw new RuntimeException("Minute must have values 0-59");
- }
-
- }
-
- /**
- * Return index of UTC char: 'Z', '+', '-'
- *
- * @param start
- * @param end
- * @return index of the UTC character that was found
- */
- protected int findUTCSign (String buffer, int start, int end) {
- int c;
- for ( int i=start;itrue if the character at start is 'Z', '+' or '-'.
+ * Compare algorithm described in dateDime (3.2.7). Duration datatype
+ * overwrites this method
+ *
+ * @param date1 normalized date representation of the first value
+ * @param date2 normalized date representation of the second value
+ * @param strict
+ * @return less, greater, less_equal, greater_equal, equal
+ */
+ protected short compareDates(DateTimeData date1, DateTimeData date2, boolean strict) {
+ if (date1.utc == date2.utc) {
+ return compareOrder(date1, date2);
+ }
+ short c1, c2;
+
+ DateTimeData tempDate = new DateTimeData(null, this);
+
+ if (date1.utc == 'Z') {
+
+ //compare date1<=date1<=(date2 with time zone -14)
+ //
+ cloneDate(date2, tempDate); //clones date1 value to global temporary storage: fTempDate
+ tempDate.timezoneHr = 14;
+ tempDate.timezoneMin = 0;
+ tempDate.utc = '+';
+ normalize(tempDate);
+ c1 = compareOrder(date1, tempDate);
+ if (c1 == LESS_THAN) {
+ return c1;
+ }
+
+ //compare date1>=(date2 with time zone +14)
+ //
+ cloneDate(date2, tempDate); //clones date1 value to global temporary storage: tempDate
+ tempDate.timezoneHr = -14;
+ tempDate.timezoneMin = 0;
+ tempDate.utc = '-';
+ normalize(tempDate);
+ c2 = compareOrder(date1, tempDate);
+ if (c2 == GREATER_THAN) {
+ return c2;
+ }
+
+ return INDETERMINATE;
+ } else if (date2.utc == 'Z') {
+
+ //compare (date1 with time zone -14)<=date2
+ //
+ cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate
+ tempDate.timezoneHr = -14;
+ tempDate.timezoneMin = 0;
+ tempDate.utc = '-';
+ if (DEBUG) {
+ System.out.println("tempDate=" + dateToString(tempDate));
+ }
+ normalize(tempDate);
+ c1 = compareOrder(tempDate, date2);
+ if (DEBUG) {
+ System.out.println("date=" + dateToString(date2));
+ System.out.println("tempDate=" + dateToString(tempDate));
+ }
+ if (c1 == LESS_THAN) {
+ return c1;
+ }
+
+ //compare (date1 with time zone +14)<=date2
+ //
+ cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate
+ tempDate.timezoneHr = 14;
+ tempDate.timezoneMin = 0;
+ tempDate.utc = '+';
+ normalize(tempDate);
+ c2 = compareOrder(tempDate, date2);
+ if (DEBUG) {
+ System.out.println("tempDate=" + dateToString(tempDate));
+ }
+ if (c2 == GREATER_THAN) {
+ return c2;
+ }
+
+ return INDETERMINATE;
+ }
+ return INDETERMINATE;
+
+ }
+
+ /**
+ * Given normalized values, determines order-relation between give date/time
+ * objects.
+ *
+ * @param date1 date/time object
+ * @param date2 date/time object
+ * @return 0 if date1 and date2 are equal, a value less than 0 if date1 is
+ * less than date2, a value greater than 0 if date1 is greater than date2
+ */
+ protected short compareOrder(DateTimeData date1, DateTimeData date2) {
+ if (date1.position < 1) {
+ if (date1.year < date2.year) {
+ return -1;
+ }
+ if (date1.year > date2.year) {
+ return 1;
+ }
+ }
+ if (date1.position < 2) {
+ if (date1.month < date2.month) {
+ return -1;
+ }
+ if (date1.month > date2.month) {
+ return 1;
+ }
+ }
+ if (date1.day < date2.day) {
+ return -1;
+ }
+ if (date1.day > date2.day) {
+ return 1;
+ }
+ if (date1.hour < date2.hour) {
+ return -1;
+ }
+ if (date1.hour > date2.hour) {
+ return 1;
+ }
+ if (date1.minute < date2.minute) {
+ return -1;
+ }
+ if (date1.minute > date2.minute) {
+ return 1;
+ }
+ if (date1.second < date2.second) {
+ return -1;
+ }
+ if (date1.second > date2.second) {
+ return 1;
+ }
+ if (date1.utc < date2.utc) {
+ return -1;
+ }
+ if (date1.utc > date2.utc) {
+ return 1;
+ }
+ return 0;
+ }
+
+ /**
+ * Parses time hh:mm:ss.sss and time zone if any
+ *
+ * @param start
+ * @param end
+ * @param data
+ * @exception RuntimeException
+ */
+ protected void getTime(String buffer, int start, int end, DateTimeData data) throws RuntimeException {
+
+ int stop = start + 2;
+
+ //get hours (hh)
+ data.hour = parseInt(buffer, start, stop);
+
+ //get minutes (mm)
+
+ if (buffer.charAt(stop++) != ':') {
+ throw new RuntimeException("Error in parsing time zone");
+ }
+ start = stop;
+ stop = stop + 2;
+ data.minute = parseInt(buffer, start, stop);
+
+ //get seconds (ss)
+ if (buffer.charAt(stop++) != ':') {
+ throw new RuntimeException("Error in parsing time zone");
+ }
+
+ //find UTC sign if any
+ int sign = findUTCSign(buffer, start, end);
+
+ //get seconds (ms)
+ start = stop;
+ stop = sign < 0 ? end : sign;
+ data.second = parseSecond(buffer, start, stop);
+
+ //parse UTC time zone (hh:mm)
+ if (sign > 0) {
+ getTimeZone(buffer, data, sign, end);
+ }
+ }
+
+ /**
+ * Parses date CCYY-MM-DD
+ *
+ * @param buffer
+ * @param start start position
+ * @param end end position
+ * @param date
+ * @exception RuntimeException
+ */
+ protected int getDate(String buffer, int start, int end, DateTimeData date) throws RuntimeException {
+
+ start = getYearMonth(buffer, start, end, date);
+
+ if (buffer.charAt(start++) != '-') {
+ throw new RuntimeException("CCYY-MM must be followed by '-' sign");
+ }
+ int stop = start + 2;
+ date.day = parseInt(buffer, start, stop);
+ return stop;
+ }
+
+ /**
+ * Parses date CCYY-MM
+ *
+ * @param buffer
+ * @param start start position
+ * @param end end position
+ * @param date
+ * @exception RuntimeException
+ */
+ protected int getYearMonth(String buffer, int start, int end, DateTimeData date) throws RuntimeException {
+
+ if (buffer.charAt(0) == '-') {
+ // REVISIT: date starts with preceding '-' sign
+ // do we have to do anything with it?
+ //
+ start++;
+ }
+ int i = indexOf(buffer, start, end, '-');
+ if (i == -1) {
+ throw new RuntimeException("Year separator is missing or misplaced");
+ }
+ int length = i - start;
+ if (length < 4) {
+ throw new RuntimeException("Year must have 'CCYY' format");
+ } else if (length > 4 && buffer.charAt(start) == '0') {
+ throw new RuntimeException("Leading zeros are required if the year value would otherwise have fewer than four digits; otherwise they are forbidden");
+ }
+ date.year = parseIntYear(buffer, i);
+ if (buffer.charAt(i) != '-') {
+ throw new RuntimeException("CCYY must be followed by '-' sign");
+ }
+ start = ++i;
+ i = start + 2;
+ date.month = parseInt(buffer, start, i);
+ return i; //fStart points right after the MONTH
+ }
+
+ /**
+ * Shared code from Date and YearMonth datatypes. Finds if time zone sign is
+ * present
+ *
+ * @param end
+ * @param date
+ * @exception RuntimeException
+ */
+ protected void parseTimeZone(String buffer, int start, int end, DateTimeData date) throws RuntimeException {
+
+ //fStart points right after the date
+
+ if (start < end) {
+ if (!isNextCharUTCSign(buffer, start, end)) {
+ throw new RuntimeException("Error in month parsing");
+ } else {
+ getTimeZone(buffer, date, start, end);
+ }
+ }
+ }
+
+ /**
+ * Parses time zone: 'Z' or {+,-} followed by hh:mm
+ *
+ * @param data
+ * @param sign
+ * @exception RuntimeException
+ */
+ protected void getTimeZone(String buffer, DateTimeData data, int sign, int end) throws RuntimeException {
+ data.utc = buffer.charAt(sign);
+
+ if (buffer.charAt(sign) == 'Z') {
+ if (end > (++sign)) {
+ throw new RuntimeException("Error in parsing time zone");
+ }
+ return;
+ }
+ if (sign <= (end - 6)) {
+
+ int negate = buffer.charAt(sign) == '-' ? -1 : 1;
+ //parse hr
+ int stop = ++sign + 2;
+ data.timezoneHr = negate * parseInt(buffer, sign, stop);
+ if (buffer.charAt(stop++) != ':') {
+ throw new RuntimeException("Error in parsing time zone");
+ }
+
+ //parse min
+ data.timezoneMin = negate * parseInt(buffer, stop, stop + 2);
+
+ if (stop + 2 != end) {
+ throw new RuntimeException("Error in parsing time zone");
+ }
+ if (data.timezoneHr != 0 || data.timezoneMin != 0) {
+ data.normalized = false;
+ }
+ } else {
+ throw new RuntimeException("Error in parsing time zone");
+ }
+ if (DEBUG) {
+ System.out.println("time[hh]=" + data.timezoneHr + " time[mm]=" + data.timezoneMin);
+ }
+ }
+
+ /**
+ * Computes index of given char within StringBuffer
+ *
+ * @param start
+ * @param end
+ * @param ch character to look for in StringBuffer
+ * @return index of ch within StringBuffer
+ */
+ protected int indexOf(String buffer, int start, int end, char ch) {
+ for (int i = start; i < end; i++) {
+ if (buffer.charAt(i) == ch) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Validates given date/time object accoring to W3C PR Schema [D.1 ISO 8601
+ * Conventions]
+ *
+ * @param data
+ */
+ protected void validateDateTime(DateTimeData data) {
+
+ //REVISIT: should we throw an exception for not valid dates
+ // or reporting an error message should be sufficient?
+
+ /**
+ * XML Schema 1.1 - RQ-123: Allow year 0000 in date related types.
+ */
+ if (!Constants.SCHEMA_1_1_SUPPORT && data.year == 0) {
+ throw new RuntimeException("The year \"0000\" is an illegal year value");
+
+ }
+
+ if (data.month < 1 || data.month > 12) {
+ throw new RuntimeException("The month must have values 1 to 12");
+
+ }
+
+ //validate days
+ if (data.day > maxDayInMonthFor(data.year, data.month) || data.day < 1) {
+ throw new RuntimeException("The day must have values 1 to 31");
+ }
+
+ //validate hours
+ if (data.hour > 23 || data.hour < 0) {
+ if (data.hour == 24 && data.minute == 0 && data.second == 0) {
+ data.hour = 0;
+ if (++data.day > maxDayInMonthFor(data.year, data.month)) {
+ data.day = 1;
+ if (++data.month > 12) {
+ data.month = 1;
+ if (Constants.SCHEMA_1_1_SUPPORT) {
+ ++data.year;
+ } else if (++data.year == 0) {
+ data.year = 1;
+ }
+ }
+ }
+ } else {
+ throw new RuntimeException("Hour must have values 0-23, unless 24:00:00");
+ }
+ }
+
+ //validate
+ if (data.minute > 59 || data.minute < 0) {
+ throw new RuntimeException("Minute must have values 0-59");
+ }
+
+ //validate
+ if (data.second >= 60 || data.second < 0) {
+ throw new RuntimeException("Second must have values 0-59");
+
+ }
+
+ //validate
+ if (data.timezoneHr > 14 || data.timezoneHr < -14) {
+ throw new RuntimeException("Time zone should have range -14:00 to +14:00");
+ } else {
+ if ((data.timezoneHr == 14 || data.timezoneHr == -14) && data.timezoneMin != 0) {
+ throw new RuntimeException("Time zone should have range -14:00 to +14:00");
+ } else if (data.timezoneMin > 59 || data.timezoneMin < -59) {
+ throw new RuntimeException("Minute must have values 0-59");
+ }
+ }
+
+ }
+
+ /**
+ * Return index of UTC char: 'Z', '+', '-'
+ *
+ * @param start
+ * @param end
+ * @return index of the UTC character that was found
+ */
+ protected int findUTCSign(String buffer, int start, int end) {
+ int c;
+ for (int i = start; i < end; i++) {
+ c = buffer.charAt(i);
+ if (c == 'Z' || c == '+' || c == '-') {
+ return i;
+ }
+
+ }
+ return -1;
+ }
+
+ /**
+ * Returns
+ * true if the character at start is 'Z', '+' or '-'.
*/
protected final boolean isNextCharUTCSign(String buffer, int start, int end) {
if (start < end) {
@@ -510,135 +525,145 @@ public abstract class AbstractDateTimeDV extends TypeValidator {
return false;
}
- /**
- * Given start and end position, parses string value
- *
- * @param buffer string to parse
- * @param start start position
- * @param end end position
- * @return return integer representation of characters
- */
- protected int parseInt (String buffer, int start, int end)
- throws NumberFormatException{
- //REVISIT: more testing on this parsing needs to be done.
- int radix=10;
- int result = 0;
- int digit=0;
- int limit = -Integer.MAX_VALUE;
- int multmin = limit / radix;
- int i = start;
- do {
- digit = getDigit(buffer.charAt(i));
- if ( digit < 0 ) throw new NumberFormatException("'" + buffer + "' has wrong format");
- if ( result < multmin ) throw new NumberFormatException("'" + buffer + "' has wrong format");
- result *= radix;
- if ( result < limit + digit ) throw new NumberFormatException("'" + buffer + "' has wrong format");
- result -= digit;
-
- }while ( ++i < end );
- return -result;
- }
-
- // parse Year differently to support negative value.
- protected int parseIntYear (String buffer, int end){
- int radix=10;
- int result = 0;
- boolean negative = false;
- int i=0;
- int limit;
- int multmin;
- int digit=0;
-
- if (buffer.charAt(0) == '-'){
- negative = true;
- limit = Integer.MIN_VALUE;
- i++;
-
- }
- else{
- limit = -Integer.MAX_VALUE;
- }
- multmin = limit / radix;
- while (i < end)
- {
- digit = getDigit(buffer.charAt(i++));
- if (digit < 0) throw new NumberFormatException("'" + buffer + "' has wrong format");
- if (result < multmin) throw new NumberFormatException("'" + buffer + "' has wrong format");
- result *= radix;
- if (result < limit + digit) throw new NumberFormatException("'" + buffer + "' has wrong format");
- result -= digit;
- }
-
- if (negative)
- {
- if (i > 1) return result;
- else throw new NumberFormatException("'" + buffer + "' has wrong format");
- }
- return -result;
-
- }
-
- /**
- * If timezone present - normalize dateTime [E Adding durations to dateTimes]
- *
- * @param date CCYY-MM-DDThh:mm:ss+03
- */
- protected void normalize(DateTimeData date) {
-
- // REVISIT: we have common code in addDuration() for durations
- // should consider reorganizing it.
- //
-
- //add minutes (from time zone)
- int negate = -1;
-
- if ( DEBUG ) {
- System.out.println("==>date.minute"+date.minute);
- System.out.println("==>date.timezoneMin" +date.timezoneMin);
- }
- int temp = date.minute + negate * date.timezoneMin;
- int carry = fQuotient (temp, 60);
- date.minute= mod(temp, 60, carry);
-
- if ( DEBUG ) {
- System.out.println("==>carry: " + carry);
- }
- //add hours
- temp = date.hour + negate * date.timezoneHr + carry;
- carry = fQuotient(temp, 24);
- date.hour=mod(temp, 24, carry);
- if ( DEBUG ) {
- System.out.println("==>date.hour"+date.hour);
- System.out.println("==>carry: " + carry);
- }
-
- date.day=date.day+carry;
-
- while ( true ) {
- temp=maxDayInMonthFor(date.year, date.month);
- if (date.day<1) {
- date.day = date.day + maxDayInMonthFor(date.year, date.month-1);
- carry=-1;
- }
- else if ( date.day>temp ) {
- date.day=date.day-temp;
- carry=1;
- }
- else {
- break;
- }
- temp=date.month+carry;
- date.month=modulo(temp, 1, 13);
- date.year=date.year+fQuotient(temp, 1, 13);
- if(date.year == 0 && !Constants.SCHEMA_1_1_SUPPORT) {
- date.year = (date.timezoneHr < 0 || date.timezoneMin < 0)?1:-1;
+ /**
+ * Given start and end position, parses string value
+ *
+ * @param buffer string to parse
+ * @param start start position
+ * @param end end position
+ * @return return integer representation of characters
+ */
+ protected int parseInt(String buffer, int start, int end)
+ throws NumberFormatException {
+ //REVISIT: more testing on this parsing needs to be done.
+ int radix = 10;
+ int result = 0;
+ int digit = 0;
+ int limit = -Integer.MAX_VALUE;
+ int multmin = limit / radix;
+ int i = start;
+ do {
+ digit = getDigit(buffer.charAt(i));
+ if (digit < 0) {
+ throw new NumberFormatException("'" + buffer + "' has wrong format");
}
- }
- date.utc='Z';
+ if (result < multmin) {
+ throw new NumberFormatException("'" + buffer + "' has wrong format");
+ }
+ result *= radix;
+ if (result < limit + digit) {
+ throw new NumberFormatException("'" + buffer + "' has wrong format");
+ }
+ result -= digit;
+
+ } while (++i < end);
+ return -result;
+ }
+
+ // parse Year differently to support negative value.
+ protected int parseIntYear(String buffer, int end) {
+ int radix = 10;
+ int result = 0;
+ boolean negative = false;
+ int i = 0;
+ int limit;
+ int multmin;
+ int digit = 0;
+
+ if (buffer.charAt(0) == '-') {
+ negative = true;
+ limit = Integer.MIN_VALUE;
+ i++;
+
+ } else {
+ limit = -Integer.MAX_VALUE;
+ }
+ multmin = limit / radix;
+ while (i < end) {
+ digit = getDigit(buffer.charAt(i++));
+ if (digit < 0) {
+ throw new NumberFormatException("'" + buffer + "' has wrong format");
+ }
+ if (result < multmin) {
+ throw new NumberFormatException("'" + buffer + "' has wrong format");
+ }
+ result *= radix;
+ if (result < limit + digit) {
+ throw new NumberFormatException("'" + buffer + "' has wrong format");
+ }
+ result -= digit;
}
+ if (negative) {
+ if (i > 1) {
+ return result;
+ } else {
+ throw new NumberFormatException("'" + buffer + "' has wrong format");
+ }
+ }
+ return -result;
- /**
+ }
+
+ /**
+ * If timezone present - normalize dateTime [E Adding durations to
+ * dateTimes]
+ *
+ * @param date CCYY-MM-DDThh:mm:ss+03
+ */
+ protected void normalize(DateTimeData date) {
+
+ // REVISIT: we have common code in addDuration() for durations
+ // should consider reorganizing it.
+ //
+
+ //add minutes (from time zone)
+ int negate = -1;
+
+ if (DEBUG) {
+ System.out.println("==>date.minute" + date.minute);
+ System.out.println("==>date.timezoneMin" + date.timezoneMin);
+ }
+ int temp = date.minute + negate * date.timezoneMin;
+ int carry = fQuotient(temp, 60);
+ date.minute = mod(temp, 60, carry);
+
+ if (DEBUG) {
+ System.out.println("==>carry: " + carry);
+ }
+ //add hours
+ temp = date.hour + negate * date.timezoneHr + carry;
+ carry = fQuotient(temp, 24);
+ date.hour = mod(temp, 24, carry);
+ if (DEBUG) {
+ System.out.println("==>date.hour" + date.hour);
+ System.out.println("==>carry: " + carry);
+ }
+
+ date.day = date.day + carry;
+
+ while (true) {
+ temp = maxDayInMonthFor(date.year, date.month);
+ if (date.day < 1) {
+ date.day = date.day + maxDayInMonthFor(date.year, date.month - 1);
+ carry = -1;
+ } else if (date.day > temp) {
+ date.day = date.day - temp;
+ carry = 1;
+ } else {
+ break;
+ }
+ temp = date.month + carry;
+ date.month = modulo(temp, 1, 13);
+ date.year = date.year + fQuotient(temp, 1, 13);
+ if (date.year == 0 && !Constants.SCHEMA_1_1_SUPPORT) {
+ date.year = (date.timezoneHr < 0 || date.timezoneMin < 0) ? 1 : -1;
+ }
+ }
+ date.utc = 'Z';
+ }
+
+ /**
* @param date
*/
protected void saveUnnormalized(DateTimeData date) {
@@ -651,154 +676,149 @@ public abstract class AbstractDateTimeDV extends TypeValidator {
}
/**
- * Resets object representation of date/time
- *
- * @param data date/time object
- */
- protected void resetDateObj(DateTimeData data) {
- data.year = 0;
- data.month = 0;
- data.day = 0;
- data.hour = 0;
- data.minute = 0;
- data.second = 0;
- data.utc = 0;
- data.timezoneHr = 0;
- data.timezoneMin = 0;
+ * Resets object representation of date/time
+ *
+ * @param data date/time object
+ */
+ protected void resetDateObj(DateTimeData data) {
+ data.year = 0;
+ data.month = 0;
+ data.day = 0;
+ data.hour = 0;
+ data.minute = 0;
+ data.second = 0;
+ data.utc = 0;
+ data.timezoneHr = 0;
+ data.timezoneMin = 0;
+ }
+
+ /**
+ * Given {year,month} computes maximum number of days for given month
+ *
+ * @param year
+ * @param month
+ * @return integer containg the number of days in a given month
+ */
+ protected int maxDayInMonthFor(int year, int month) {
+ //validate days
+ if (month == 4 || month == 6 || month == 9 || month == 11) {
+ return 30;
+ } else if (month == 2) {
+ if (isLeapYear(year)) {
+ return 29;
+ } else {
+ return 28;
+ }
+ } else {
+ return 31;
}
+ }
- /**
- * Given {year,month} computes maximum
- * number of days for given month
- *
- * @param year
- * @param month
- * @return integer containg the number of days in a given month
- */
- protected int maxDayInMonthFor(int year, int month) {
- //validate days
- if ( month==4 || month==6 || month==9 || month==11 ) {
- return 30;
- }
- else if ( month==2 ) {
- if ( isLeapYear(year) ) {
- return 29;
- }
- else {
- return 28;
- }
- }
- else {
- return 31;
- }
- }
+ private boolean isLeapYear(int year) {
- private boolean isLeapYear(int year) {
+ //REVISIT: should we take care about Julian calendar?
+ return ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)));
+ }
- //REVISIT: should we take care about Julian calendar?
- return((year%4 == 0) && ((year%100 != 0) || (year%400 == 0)));
- }
+ //
+ // help function described in W3C PR Schema [E Adding durations to dateTimes]
+ //
+ protected int mod(int a, int b, int quotient) {
+ //modulo(a, b) = a - fQuotient(a,b)*b
+ return (a - quotient * b);
+ }
- //
- // help function described in W3C PR Schema [E Adding durations to dateTimes]
- //
- protected int mod (int a, int b, int quotient) {
- //modulo(a, b) = a - fQuotient(a,b)*b
- return (a - quotient*b) ;
- }
+ //
+ // help function described in W3C PR Schema [E Adding durations to dateTimes]
+ //
+ protected int fQuotient(int a, int b) {
- //
- // help function described in W3C PR Schema [E Adding durations to dateTimes]
- //
- protected int fQuotient (int a, int b) {
+ //fQuotient(a, b) = the greatest integer less than or equal to a/b
+ return (int) Math.floor((float) a / b);
+ }
- //fQuotient(a, b) = the greatest integer less than or equal to a/b
- return (int)Math.floor((float)a/b);
- }
+ //
+ // help function described in W3C PR Schema [E Adding durations to dateTimes]
+ //
+ protected int modulo(int temp, int low, int high) {
+ //modulo(a - low, high - low) + low
+ int a = temp - low;
+ int b = high - low;
+ return (mod(a, b, fQuotient(a, b)) + low);
+ }
- //
- // help function described in W3C PR Schema [E Adding durations to dateTimes]
- //
- protected int modulo (int temp, int low, int high) {
- //modulo(a - low, high - low) + low
- int a = temp - low;
- int b = high - low;
- return (mod (a, b, fQuotient(a, b)) + low) ;
- }
+ //
+ // help function described in W3C PR Schema [E Adding durations to dateTimes]
+ //
+ protected int fQuotient(int temp, int low, int high) {
+ //fQuotient(a - low, high - low)
- //
- // help function described in W3C PR Schema [E Adding durations to dateTimes]
- //
- protected int fQuotient (int temp, int low, int high) {
- //fQuotient(a - low, high - low)
+ return fQuotient(temp - low, high - low);
+ }
- return fQuotient(temp - low, high - low);
- }
+ protected String dateToString(DateTimeData date) {
+ StringBuffer message = new StringBuffer(25);
+ append(message, date.year, 4);
+ message.append('-');
+ append(message, date.month, 2);
+ message.append('-');
+ append(message, date.day, 2);
+ message.append('T');
+ append(message, date.hour, 2);
+ message.append(':');
+ append(message, date.minute, 2);
+ message.append(':');
+ append(message, date.second);
+ append(message, (char) date.utc, 0);
+ return message.toString();
+ }
-
- protected String dateToString(DateTimeData date) {
- StringBuffer message = new StringBuffer(25);
- append(message, date.year, 4);
- message.append('-');
- append(message, date.month, 2);
- message.append('-');
- append(message, date.day, 2);
- message.append('T');
- append(message, date.hour, 2);
- message.append(':');
- append(message, date.minute, 2);
- message.append(':');
- append(message, date.second);
- append(message, (char)date.utc, 0);
- return message.toString();
- }
-
- protected final void append(StringBuffer message, int value, int nch) {
+ protected final void append(StringBuffer message, int value, int nch) {
if (value == Integer.MIN_VALUE) {
message.append(value);
return;
}
- if (value < 0) {
- message.append('-');
- value = -value;
- }
- if (nch == 4) {
- if (value < 10)
- message.append("000");
- else if (value < 100)
- message.append("00");
- else if (value < 1000)
- message.append('0');
- message.append(value);
- }
- else if (nch == 2) {
- if (value < 10)
- message.append('0');
- message.append(value);
- }
- else {
- if (value != 0)
- message.append((char)value);
- }
+ if (value < 0) {
+ message.append('-');
+ value = -value;
}
-
- protected final void append(StringBuffer message, double value) {
- if (value < 0) {
- message.append('-');
- value = -value;
+ if (nch == 4) {
+ if (value < 10) {
+ message.append("000");
+ } else if (value < 100) {
+ message.append("00");
+ } else if (value < 1000) {
+ message.append('0');
}
+ message.append(value);
+ } else if (nch == 2) {
if (value < 10) {
message.append('0');
}
- append2(message, value);
+ message.append(value);
+ } else {
+ if (value != 0) {
+ message.append((char) value);
+ }
}
+ }
+
+ protected final void append(StringBuffer message, double value) {
+ if (value < 0) {
+ message.append('-');
+ value = -value;
+ }
+ if (value < 10) {
+ message.append('0');
+ }
+ append2(message, value);
+ }
protected final void append2(StringBuffer message, double value) {
final int intValue = (int) value;
if (value == intValue) {
message.append(intValue);
- }
- else {
+ } else {
append3(message, value);
}
}
@@ -815,9 +835,8 @@ public abstract class AbstractDateTimeDV extends TypeValidator {
// Need to convert from scientific notation of the form
// n.nnn...E-N (N >= 4) to a normal decimal value.
try {
- exp = parseInt(d, eIndex+2, d.length());
- }
- // This should never happen.
+ exp = parseInt(d, eIndex + 2, d.length());
+ } // This should never happen.
// It's only possible if String.valueOf(double) is broken.
catch (Exception e) {
message.append(d);
@@ -843,14 +862,12 @@ public abstract class AbstractDateTimeDV extends TypeValidator {
message.append(c);
}
}
- }
- else {
+ } else {
// Need to convert from scientific notation of the form
// n.nnn...EN (N >= 7) to a normal decimal value.
try {
- exp = parseInt(d, eIndex+1, d.length());
- }
- // This should never happen.
+ exp = parseInt(d, eIndex + 1, d.length());
+ } // This should never happen.
// It's only possible if String.valueOf(double) is broken.
catch (Exception e) {
message.append(d);
@@ -873,174 +890,220 @@ public abstract class AbstractDateTimeDV extends TypeValidator {
}
}
- protected double parseSecond(String buffer, int start, int end)
- throws NumberFormatException {
- int dot = -1;
- for (int i = start; i < end; i++) {
- char ch = buffer.charAt(i);
- if (ch == '.')
- dot = i;
- else if (ch > '9' || ch < '0')
- throw new NumberFormatException("'" + buffer + "' has wrong format");
- }
- if (dot == -1) {
- if (start+2 != end)
- throw new NumberFormatException("'" + buffer + "' has wrong format");
- }
- else if (start+2 != dot || dot+1 == end) {
- throw new NumberFormatException("'" + buffer + "' has wrong format");
- }
- return Double.parseDouble(buffer.substring(start, end));
+ protected double parseSecond(String buffer, int start, int end)
+ throws NumberFormatException {
+ int dot = -1;
+ for (int i = start; i < end; i++) {
+ char ch = buffer.charAt(i);
+ if (ch == '.') {
+ dot = i;
+ } else if (ch > '9' || ch < '0') {
+ throw new NumberFormatException("'" + buffer + "' has wrong format");
+ }
}
-
- //
- //Private help functions
- //
-
- private void cloneDate (DateTimeData finalValue, DateTimeData tempDate) {
- tempDate.year = finalValue.year;
- tempDate.month = finalValue.month;
- tempDate.day = finalValue.day;
- tempDate.hour = finalValue.hour;
- tempDate.minute = finalValue.minute;
- tempDate.second = finalValue.second;
- tempDate.utc = finalValue.utc;
- tempDate.timezoneHr = finalValue.timezoneHr;
- tempDate.timezoneMin = finalValue.timezoneMin;
+ if (dot == -1) {
+ if (start + 2 != end) {
+ throw new NumberFormatException("'" + buffer + "' has wrong format");
+ }
+ } else if (start + 2 != dot || dot + 1 == end) {
+ throw new NumberFormatException("'" + buffer + "' has wrong format");
}
+ return Double.parseDouble(buffer.substring(start, end));
+ }
- /**
- * Represents date time data
- */
- static final class DateTimeData implements XSDateTime {
- int year, month, day, hour, minute, utc;
- double second;
- int timezoneHr, timezoneMin;
+ //
+ //Private help functions
+ //
+ private void cloneDate(DateTimeData finalValue, DateTimeData tempDate) {
+ tempDate.year = finalValue.year;
+ tempDate.month = finalValue.month;
+ tempDate.day = finalValue.day;
+ tempDate.hour = finalValue.hour;
+ tempDate.minute = finalValue.minute;
+ tempDate.second = finalValue.second;
+ tempDate.utc = finalValue.utc;
+ tempDate.timezoneHr = finalValue.timezoneHr;
+ tempDate.timezoneMin = finalValue.timezoneMin;
+ }
+
+ /**
+ * Represents date time data
+ */
+ static final class DateTimeData implements XSDateTime {
+
+ int year, month, day, hour, minute, utc;
+ double second;
+ int timezoneHr, timezoneMin;
private String originalValue;
boolean normalized = true;
-
int unNormYear;
int unNormMonth;
int unNormDay;
int unNormHour;
int unNormMinute;
double unNormSecond;
+ // used for comparisons - to decide the 'interesting' portions of
+ // a date/time based data type.
+ int position;
+ // a pointer to the type that was used go generate this data
+ // note that this is not the actual simple type, but one of the
+ // statically created XXXDV objects, so this won't cause any GC problem.
+ final AbstractDateTimeDV type;
+ private volatile String canonical;
- // used for comparisons - to decide the 'interesting' portions of
- // a date/time based data type.
- int position;
- // a pointer to the type that was used go generate this data
- // note that this is not the actual simple type, but one of the
- // statically created XXXDV objects, so this won't cause any GC problem.
- final AbstractDateTimeDV type;
- private String canonical;
- public DateTimeData(String originalValue, AbstractDateTimeDV type) {
+ public DateTimeData(String originalValue, AbstractDateTimeDV type) {
this.originalValue = originalValue;
- this.type = type;
- }
- public DateTimeData(int year, int month, int day, int hour, int minute,
- double second, int utc, String originalValue, boolean normalized, AbstractDateTimeDV type) {
- this.year = year;
- this.month = month;
- this.day = day;
- this.hour = hour;
- this.minute = minute;
- this.second = second;
- this.utc = utc;
- this.type = type;
+ this.type = type;
+ }
+
+ public DateTimeData(int year, int month, int day, int hour, int minute,
+ double second, int utc, String originalValue, boolean normalized, AbstractDateTimeDV type) {
+ this.year = year;
+ this.month = month;
+ this.day = day;
+ this.hour = hour;
+ this.minute = minute;
+ this.second = second;
+ this.utc = utc;
+ this.type = type;
this.originalValue = originalValue;
- }
- public boolean equals(Object obj) {
- if (!(obj instanceof DateTimeData))
- return false;
- return type.compareDates(this, (DateTimeData)obj, true)==0;
- }
- public synchronized String toString() {
- if (canonical == null) {
- canonical = type.dateToString(this);
- }
- return canonical;
- }
- /* (non-Javadoc)
- * @see org.apache.xerces.xs.datatypes.XSDateTime#getYear()
- */
- public int getYears() {
- if(type instanceof DurationDV)
- return 0;
- return normalized?year:unNormYear;
- }
- /* (non-Javadoc)
- * @see org.apache.xerces.xs.datatypes.XSDateTime#getMonth()
- */
- public int getMonths() {
- if(type instanceof DurationDV) {
- return year*12 + month;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof DateTimeData)) {
+ return false;
}
- return normalized?month:unNormMonth;
- }
- /* (non-Javadoc)
- * @see org.apache.xerces.xs.datatypes.XSDateTime#getDay()
- */
- public int getDays() {
- if(type instanceof DurationDV)
- return 0;
- return normalized?day:unNormDay;
- }
- /* (non-Javadoc)
- * @see org.apache.xerces.xs.datatypes.XSDateTime#getHour()
- */
- public int getHours() {
- if(type instanceof DurationDV)
- return 0;
- return normalized?hour:unNormHour;
- }
- /* (non-Javadoc)
- * @see org.apache.xerces.xs.datatypes.XSDateTime#getMinutes()
- */
- public int getMinutes() {
- if(type instanceof DurationDV)
- return 0;
- return normalized?minute:unNormMinute;
- }
- /* (non-Javadoc)
- * @see org.apache.xerces.xs.datatypes.XSDateTime#getSeconds()
- */
- public double getSeconds() {
- if(type instanceof DurationDV) {
- return day*24*60*60 + hour*60*60 + minute*60 + second;
+ return type.compareDates(this, (DateTimeData) obj, true) == 0;
+ }
+
+ // If two DateTimeData are equals - then they should have the same
+ // hashcode. This means we need to convert the date to UTC before
+ // we return its hashcode.
+ // The DateTimeData is unfortunately mutable - so we cannot
+ // cache the result of the conversion...
+ //
+ @Override
+ public int hashCode() {
+ final DateTimeData tempDate = new DateTimeData(null, type);
+ type.cloneDate(this, tempDate);
+ type.normalize(tempDate);
+ return type.dateToString(tempDate).hashCode();
+ }
+
+ @Override
+ public String toString() {
+ if (canonical == null) {
+ canonical = type.dateToString(this);
}
- return normalized?second:unNormSecond;
- }
- /* (non-Javadoc)
- * @see org.apache.xerces.xs.datatypes.XSDateTime#hasTimeZone()
- */
- public boolean hasTimeZone() {
- return utc != 0;
- }
- /* (non-Javadoc)
- * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneHours()
- */
- public int getTimeZoneHours() {
- return timezoneHr;
- }
- /* (non-Javadoc)
- * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneMinutes()
- */
- public int getTimeZoneMinutes() {
- return timezoneMin;
- }
+ return canonical;
+ }
+ /* (non-Javadoc)
+ * @see org.apache.xerces.xs.datatypes.XSDateTime#getYear()
+ */
+
+ @Override
+ public int getYears() {
+ if (type instanceof DurationDV) {
+ return 0;
+ }
+ return normalized ? year : unNormYear;
+ }
+ /* (non-Javadoc)
+ * @see org.apache.xerces.xs.datatypes.XSDateTime#getMonth()
+ */
+
+ @Override
+ public int getMonths() {
+ if (type instanceof DurationDV) {
+ return year * 12 + month;
+ }
+ return normalized ? month : unNormMonth;
+ }
+ /* (non-Javadoc)
+ * @see org.apache.xerces.xs.datatypes.XSDateTime#getDay()
+ */
+
+ @Override
+ public int getDays() {
+ if (type instanceof DurationDV) {
+ return 0;
+ }
+ return normalized ? day : unNormDay;
+ }
+ /* (non-Javadoc)
+ * @see org.apache.xerces.xs.datatypes.XSDateTime#getHour()
+ */
+
+ @Override
+ public int getHours() {
+ if (type instanceof DurationDV) {
+ return 0;
+ }
+ return normalized ? hour : unNormHour;
+ }
+ /* (non-Javadoc)
+ * @see org.apache.xerces.xs.datatypes.XSDateTime#getMinutes()
+ */
+
+ @Override
+ public int getMinutes() {
+ if (type instanceof DurationDV) {
+ return 0;
+ }
+ return normalized ? minute : unNormMinute;
+ }
+ /* (non-Javadoc)
+ * @see org.apache.xerces.xs.datatypes.XSDateTime#getSeconds()
+ */
+
+ @Override
+ public double getSeconds() {
+ if (type instanceof DurationDV) {
+ return day * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 + second;
+ }
+ return normalized ? second : unNormSecond;
+ }
+ /* (non-Javadoc)
+ * @see org.apache.xerces.xs.datatypes.XSDateTime#hasTimeZone()
+ */
+
+ @Override
+ public boolean hasTimeZone() {
+ return utc != 0;
+ }
+ /* (non-Javadoc)
+ * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneHours()
+ */
+
+ @Override
+ public int getTimeZoneHours() {
+ return timezoneHr;
+ }
+ /* (non-Javadoc)
+ * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneMinutes()
+ */
+
+ @Override
+ public int getTimeZoneMinutes() {
+ return timezoneMin;
+ }
/* (non-Javadoc)
* @see org.apache.xerces.xs.datatypes.XSDateTime#getLexicalValue()
*/
+
+ @Override
public String getLexicalValue() {
return originalValue;
}
/* (non-Javadoc)
* @see org.apache.xerces.xs.datatypes.XSDateTime#normalize()
*/
+
+ @Override
public XSDateTime normalize() {
- if(!normalized) {
- DateTimeData dt = (DateTimeData)this.clone();
+ if (!normalized) {
+ DateTimeData dt = (DateTimeData) this.clone();
dt.normalized = true;
return dt;
}
@@ -1049,13 +1112,16 @@ public abstract class AbstractDateTimeDV extends TypeValidator {
/* (non-Javadoc)
* @see org.apache.xerces.xs.datatypes.XSDateTime#isNormalized()
*/
+
+ @Override
public boolean isNormalized() {
return normalized;
}
+ @Override
public Object clone() {
DateTimeData dt = new DateTimeData(this.year, this.month, this.day, this.hour,
- this.minute, this.second, this.utc, this.originalValue, this.normalized, this.type);
+ this.minute, this.second, this.utc, this.originalValue, this.normalized, this.type);
dt.canonical = this.canonical;
dt.position = position;
dt.timezoneHr = this.timezoneHr;
@@ -1072,16 +1138,19 @@ public abstract class AbstractDateTimeDV extends TypeValidator {
/* (non-Javadoc)
* @see org.apache.xerces.xs.datatypes.XSDateTime#getXMLGregorianCalendar()
*/
+ @Override
public XMLGregorianCalendar getXMLGregorianCalendar() {
return type.getXMLGregorianCalendar(this);
}
/* (non-Javadoc)
* @see org.apache.xerces.xs.datatypes.XSDateTime#getDuration()
*/
+
+ @Override
public Duration getDuration() {
return type.getDuration(this);
}
- }
+ }
protected XMLGregorianCalendar getXMLGregorianCalendar(DateTimeData data) {
return null;
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/DecimalDV.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/DecimalDV.java
index ce616113c04..622042b37cf 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/DecimalDV.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/DecimalDV.java
@@ -26,6 +26,7 @@ import java.math.BigInteger;
import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
import com.sun.org.apache.xerces.internal.impl.dv.ValidationContext;
import com.sun.org.apache.xerces.internal.xs.datatypes.XSDecimal;
+import java.util.Objects;
/**
* Represent the schema type "decimal"
@@ -38,10 +39,12 @@ import com.sun.org.apache.xerces.internal.xs.datatypes.XSDecimal;
*/
public class DecimalDV extends TypeValidator {
+ @Override
public final short getAllowedFacets(){
return ( XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION |XSSimpleTypeDecl.FACET_MAXINCLUSIVE |XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE | XSSimpleTypeDecl.FACET_TOTALDIGITS | XSSimpleTypeDecl.FACET_FRACTIONDIGITS);
}
+ @Override
public Object getActualValue(String content, ValidationContext context) throws InvalidDatatypeValueException {
try {
return new XDecimal(content);
@@ -50,20 +53,23 @@ public class DecimalDV extends TypeValidator {
}
}
+ @Override
public final int compare(Object value1, Object value2){
return ((XDecimal)value1).compareTo((XDecimal)value2);
}
+ @Override
public final int getTotalDigits(Object value){
return ((XDecimal)value).totalDigits;
}
+ @Override
public final int getFractionDigits(Object value){
return ((XDecimal)value).fracDigits;
}
// Avoid using the heavy-weight java.math.BigDecimal
- static class XDecimal implements XSDecimal {
+ static final class XDecimal implements XSDecimal {
// sign: 0 for vlaue 0; 1 for positive values; -1 for negative values
int sign = 1;
// total digits. >= 1
@@ -216,6 +222,8 @@ public class DecimalDV extends TypeValidator {
integer = true;
}
+
+ @Override
public boolean equals(Object val) {
if (val == this)
return true;
@@ -232,6 +240,19 @@ public class DecimalDV extends TypeValidator {
return intDigits == oval.intDigits && fracDigits == oval.fracDigits &&
ivalue.equals(oval.ivalue) && fvalue.equals(oval.fvalue);
}
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 17 * hash + this.sign;
+ if (this.sign == 0) return hash;
+ hash = 17 * hash + this.intDigits;
+ hash = 17 * hash + this.fracDigits;
+ hash = 17 * hash + Objects.hashCode(this.ivalue);
+ hash = 17 * hash + Objects.hashCode(this.fvalue);
+ return hash;
+ }
+
public int compareTo(XDecimal val) {
if (sign != val.sign)
return sign > val.sign ? 1 : -1;
@@ -248,7 +269,9 @@ public class DecimalDV extends TypeValidator {
ret = fvalue.compareTo(val.fvalue);
return ret == 0 ? 0 : (ret > 0 ? 1 : -1);
}
+
private String canonical;
+ @Override
public synchronized String toString() {
if (canonical == null) {
makeCanonical();
@@ -269,7 +292,7 @@ public class DecimalDV extends TypeValidator {
return;
}
// for -0.1, total digits is 1, so we need 3 extra spots
- StringBuffer buffer = new StringBuffer(totalDigits+3);
+ final StringBuilder buffer = new StringBuilder(totalDigits+3);
if (sign == -1)
buffer.append('-');
if (intDigits != 0)
@@ -288,6 +311,7 @@ public class DecimalDV extends TypeValidator {
canonical = buffer.toString();
}
+ @Override
public BigDecimal getBigDecimal() {
if (sign == 0) {
return new BigDecimal(BigInteger.ZERO);
@@ -295,6 +319,7 @@ public class DecimalDV extends TypeValidator {
return new BigDecimal(toString());
}
+ @Override
public BigInteger getBigInteger() throws NumberFormatException {
if (fracDigits != 0) {
throw new NumberFormatException();
@@ -308,6 +333,7 @@ public class DecimalDV extends TypeValidator {
return new BigInteger("-" + ivalue);
}
+ @Override
public long getLong() throws NumberFormatException {
if (fracDigits != 0) {
throw new NumberFormatException();
@@ -321,6 +347,7 @@ public class DecimalDV extends TypeValidator {
return Long.parseLong("-" + ivalue);
}
+ @Override
public int getInt() throws NumberFormatException {
if (fracDigits != 0) {
throw new NumberFormatException();
@@ -334,6 +361,7 @@ public class DecimalDV extends TypeValidator {
return Integer.parseInt("-" + ivalue);
}
+ @Override
public short getShort() throws NumberFormatException {
if (fracDigits != 0) {
throw new NumberFormatException();
@@ -347,6 +375,7 @@ public class DecimalDV extends TypeValidator {
return Short.parseShort("-" + ivalue);
}
+ @Override
public byte getByte() throws NumberFormatException {
if (fracDigits != 0) {
throw new NumberFormatException();
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/PrecisionDecimalDV.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/PrecisionDecimalDV.java
index af8d8d499dc..a75f03a03ea 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/PrecisionDecimalDV.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/PrecisionDecimalDV.java
@@ -32,7 +32,7 @@ import com.sun.org.apache.xerces.internal.impl.dv.ValidationContext;
*/
class PrecisionDecimalDV extends TypeValidator {
- static class XPrecisionDecimal {
+ static final class XPrecisionDecimal {
// sign: 0 for absent; 1 for positive values; -1 for negative values (except in case of INF, -INF)
int sign = 1;
@@ -144,7 +144,71 @@ class PrecisionDecimalDV extends TypeValidator {
totalDigits = intDigits + fracDigits;
}
+ // Construct a canonical String representation of this number
+ // for the purpose of deriving a hashCode value compliant with
+ // equals.
+ // The toString representation will be:
+ // NaN for NaN, INF for +infinity, -INF for -infinity, 0 for zero,
+ // and [1-9].[0-9]*[1-9]?(E[1-9][0-9]*)? for other numbers.
+ private static String canonicalToStringForHashCode(String ivalue, String fvalue, int sign, int pvalue) {
+ if ("NaN".equals(ivalue)) {
+ return "NaN";
+ }
+ if ("INF".equals(ivalue)) {
+ return sign < 0 ? "-INF" : "INF";
+ }
+ final StringBuilder builder = new StringBuilder();
+ final int ilen = ivalue.length();
+ final int flen0 = fvalue.length();
+ int lastNonZero;
+ for (lastNonZero = flen0; lastNonZero > 0 ; lastNonZero--) {
+ if (fvalue.charAt(lastNonZero -1 ) != '0') break;
+ }
+ final int flen = lastNonZero;
+ int iStart;
+ int exponent = pvalue;
+ for (iStart = 0; iStart < ilen; iStart++) {
+ if (ivalue.charAt(iStart) != '0') break;
+ }
+ int fStart = 0;
+ if (iStart < ivalue.length()) {
+ builder.append(sign == -1 ? "-" : "");
+ builder.append(ivalue.charAt(iStart));
+ iStart++;
+ } else {
+ if (flen > 0) {
+ for (fStart = 0; fStart < flen; fStart++) {
+ if (fvalue.charAt(fStart) != '0') break;
+ }
+ if (fStart < flen) {
+ builder.append(sign == -1 ? "-" : "");
+ builder.append(fvalue.charAt(fStart));
+ exponent -= ++fStart;
+ } else {
+ return "0";
+ }
+ } else {
+ return "0";
+ }
+ }
+ if (iStart < ilen || fStart < flen) {
+ builder.append('.');
+ }
+ while (iStart < ilen) {
+ builder.append(ivalue.charAt(iStart++));
+ exponent++;
+ }
+ while (fStart < flen) {
+ builder.append(fvalue.charAt(fStart++));
+ }
+ if (exponent != 0) {
+ builder.append("E").append(exponent);
+ }
+ return builder.toString();
+ }
+
+ @Override
public boolean equals(Object val) {
if (val == this)
return true;
@@ -156,6 +220,20 @@ class PrecisionDecimalDV extends TypeValidator {
return this.compareTo(oval) == EQUAL;
}
+ @Override
+ public int hashCode() {
+ // There's nothing else we can use easily, because equals could
+ // return true for widely different representation of the
+ // same number - and we don't have any canonical representation.
+ // The problem here is that we must ensure that if two numbers
+ // are equals then their hash code must also be equals.
+ // hashCode for 1.01E1 should be the same as hashCode for 0.101E2
+ // So we call cannonicalToStringForHashCode - which implements an
+ // algorithm that invents a normalized string representation
+ // for this number, and we return a hash for that.
+ return canonicalToStringForHashCode(ivalue, fvalue, sign, pvalue).hashCode();
+ }
+
/**
* @return
*/
@@ -295,6 +373,7 @@ class PrecisionDecimalDV extends TypeValidator {
private String canonical;
+ @Override
public synchronized String toString() {
if (canonical == null) {
makeCanonical();
@@ -325,6 +404,7 @@ class PrecisionDecimalDV extends TypeValidator {
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.impl.dv.xs.TypeValidator#getAllowedFacets()
*/
+ @Override
public short getAllowedFacets() {
return ( XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION |XSSimpleTypeDecl.FACET_MAXINCLUSIVE |XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE | XSSimpleTypeDecl.FACET_TOTALDIGITS | XSSimpleTypeDecl.FACET_FRACTIONDIGITS);
}
@@ -332,6 +412,7 @@ class PrecisionDecimalDV extends TypeValidator {
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.impl.dv.xs.TypeValidator#getActualValue(java.lang.String, com.sun.org.apache.xerces.internal.impl.dv.ValidationContext)
*/
+ @Override
public Object getActualValue(String content, ValidationContext context)
throws InvalidDatatypeValueException {
try {
@@ -341,18 +422,22 @@ class PrecisionDecimalDV extends TypeValidator {
}
}
+ @Override
public int compare(Object value1, Object value2) {
return ((XPrecisionDecimal)value1).compareTo((XPrecisionDecimal)value2);
}
+ @Override
public int getFractionDigits(Object value) {
return ((XPrecisionDecimal)value).fracDigits;
}
+ @Override
public int getTotalDigits(Object value) {
return ((XPrecisionDecimal)value).totalDigits;
}
+ @Override
public boolean isIdentical(Object value1, Object value2) {
if(!(value2 instanceof XPrecisionDecimal) || !(value1 instanceof XPrecisionDecimal))
return false;
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages.properties
index 5a06fa07fed..ea35c9e8377 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages.properties
@@ -11,7 +11,7 @@ FallbackChild = Elements from namespace ''http://www.w3.org/2001/XInclude'', oth
HrefMissing = The 'href' attribute of an 'include' element is missing.
RecursiveInclude = Recursive include detected. Document ''{0}'' was already processed.
InvalidParseValue = Invalid value for ''parse'' attribute on ''include'' element: ''{0}''.
-XMLParseError = Error attempting to parse XML file (href=''{0}'').
+XMLParseError = Error attempting to parse XML file (href=''{0}''). Reason: {1}
XMLResourceError = Include operation failed, reverting to fallback. Resource error reading file as XML (href=''{0}''). Reason: {1}
TextResourceError = Include operation failed, reverting to fallback. Resource error reading file as text (href=''{0}''). Reason: {1}
NO_XPointerSchema = Schema for \"{0}\" is not supported by default. Define your own schema for {0}.See http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_de.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_de.properties
index 5a05972a6d9..58c045b8d32 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_de.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_de.properties
@@ -39,7 +39,7 @@ FallbackChild = Andere Elemente aus Namespace "http://www.w3.org/2001/XInclude"
HrefMissing = "href"-Attribut eines "include"-Elements fehlt.
RecursiveInclude = Rekursives "include" ermittelt. Dokument "{0}" wurde bereits verarbeitet.
InvalidParseValue = Ung\u00FCltiger Wert f\u00FCr "parse"-Attribut bei "include"-Element: "{0}".
-XMLParseError = Fehler beim Versuch, XML-Datei zu parsen (href="{0}").
+XMLParseError = Fehler beim Versuch, XML-Datei zu parsen (href="{0}"). Grund: {1}
XMLResourceError = Include-Vorgang nicht erfolgreich. Zur\u00FCck zu Fallback. Ressourcenfehler beim Lesen der Datei als XML (href="{0}"). Grund: {1}
TextResourceError = Include-Vorgang nicht erfolgreich. Zur\u00FCck zu Fallback. Ressourcenfehler beim Lesen der Datei als Text (href="{0}"). Grund: {1}
NO_XPointerSchema = Schema f\u00FCr \"{0}\" wird standardm\u00E4\u00DFig nicht unterst\u00FCtzt. Definieren Sie Ihr eigenes Schema f\u00FCr {0}. Siehe http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_es.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_es.properties
index 59b669f997f..2bf1f2b47b0 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_es.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_es.properties
@@ -39,7 +39,7 @@ FallbackChild = No se permite que los elementos del espacio de nombres ''http://
HrefMissing = Falta el atributo 'href' de un elemento 'include'.
RecursiveInclude = Se ha detectado un elemento include recursivo. El documento ''{0}'' ya se ha procesado.
InvalidParseValue = Valor no v\u00E1lido para el atributo ''parse'' en el elemento ''include'': ''{0}''.
-XMLParseError = Error al intentar analizar el archivo XML (href=''{0}'').
+XMLParseError = Error al intentar analizar el archivo XML (href=''{0}''). Motivo: {1}
XMLResourceError = Fallo de la operaci\u00F3n include, conversi\u00F3n a fallback. Error del recurso al leer el archivo como XML (href=''{0}''). Motivo: {1}
TextResourceError = Fallo de la operaci\u00F3n include, conversi\u00F3n a fallback. Error del recurso al leer el archivo como texto (href=''{0}''). Motivo: {1}
NO_XPointerSchema = El esquema para \"{0}\" no est\u00E1 soportado por defecto. Defina su propio esquema para {0}. Consulte http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_fr.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_fr.properties
index c5f36660a2a..9a22cb4e2f2 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_fr.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_fr.properties
@@ -39,7 +39,7 @@ FallbackChild = Les \u00E9l\u00E9ments de l''espace de noms ''http://www.w3.org/
HrefMissing = L'attribut 'href' d'un \u00E9l\u00E9ment 'include' est manquant.
RecursiveInclude = El\u00E9ment "include" r\u00E9cursif d\u00E9tect\u00E9. Le document ''{0}'' a d\u00E9j\u00E0 \u00E9t\u00E9 trait\u00E9.
InvalidParseValue = Valeur non valide pour l''attribut ''parse'' sur l''\u00E9l\u00E9ment ''include'' : ''{0}''.
-XMLParseError = Erreur lors de la tentative d''analyse du fichier XML (href=''{0}'').
+XMLParseError = Erreur lors de la tentative d''analyse du fichier XML (href=''{0}''). Raison : {1}
XMLResourceError = Echec de l''op\u00E9ration Include, r\u00E9tablissement de l''\u00E9l\u00E9ment fallback. Erreur de ressource lors de la lecture du fichier en tant que XML (href=''{0}''). Raison : {1}
TextResourceError = Echec de l''op\u00E9ration Include, r\u00E9tablissement de l''\u00E9l\u00E9ment fallback. Erreur de ressource lors de la lecture du fichier en tant que texte (href=''{0}''). Raison : {1}
NO_XPointerSchema = Par d\u00E9faut, le sch\u00E9ma pour \"{0}\" n''est pas pris en charge. D\u00E9finissez votre propre sch\u00E9ma pour {0}. Reportez-vous \u00E0 l''adresse http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_it.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_it.properties
index d0ca4e0414f..1cdc5442130 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_it.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_it.properties
@@ -39,7 +39,7 @@ FallbackChild = Gli elementi dello spazio di nomi ''http://www.w3.org/2001/XIncl
HrefMissing = Manca l'attributo 'href' di un elemento 'include'.
RecursiveInclude = Inclusione ricorsiva rilevata. Il documento ''{0}'' \u00E8 gi\u00E0 stato elaborato.
InvalidParseValue = Valore non valido per l''attributo ''parse'' nell''elemento ''include'': ''{0}''.
-XMLParseError = Errore nel tentativo di analizzare il file XML (href=''{0}'').
+XMLParseError = Errore nel tentativo di analizzare il file XML (href=''{0}''). Motivo: {1}
XMLResourceError = Operazione di inclusione non riuscita. Verr\u00E0 ripristinato il fallback. Errore di risorsa durante la lettura del file come XML (href=''{0}''). Motivo: {1}
TextResourceError = Operazione di inclusione non riuscita. Verr\u00E0 ripristinato il fallback. Errore di risorsa durante la lettura del file come testo (href=''{0}''). Motivo: {1}
NO_XPointerSchema = Lo schema per \"{0}\" non \u00E8 supportato per impostazione predefinita. Definire il proprio schema per {0}. Vedere http://apache.org/xml/properties/xpointer-schema.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ja.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ja.properties
index d17b8dbbefd..6b88fe82e05 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ja.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ja.properties
@@ -39,7 +39,7 @@ FallbackChild = \u30CD\u30FC\u30E0\u30B9\u30DA\u30FC\u30B9''http://www.w3.org/20
HrefMissing = 'include'\u8981\u7D20\u306E'href'\u5C5E\u6027\u304C\u3042\u308A\u307E\u305B\u3093\u3002
RecursiveInclude = \u518D\u5E30\u7684\u306Ainclude\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F\u3002\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8''{0}''\u306F\u3059\u3067\u306B\u51E6\u7406\u3055\u308C\u3066\u3044\u307E\u3059\u3002
InvalidParseValue = ''include''\u8981\u7D20\u306E''parse''\u5C5E\u6027\u306E\u5024\u304C\u7121\u52B9\u3067\u3059: ''{0}''\u3002
-XMLParseError = XML\u30D5\u30A1\u30A4\u30EB\u306E\u89E3\u6790\u8A66\u884C\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F(href=''{0}'')\u3002
+XMLParseError = XML\u30D5\u30A1\u30A4\u30EB\u306E\u89E3\u6790\u8A66\u884C\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F(href=''{0}'')\u3002\u7406\u7531: {1}
XMLResourceError = \u30A4\u30F3\u30AF\u30EB\u30FC\u30C9\u64CD\u4F5C\u304C\u5931\u6557\u3057\u3001\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u306B\u623B\u308A\u307E\u3059\u3002\u30D5\u30A1\u30A4\u30EB\u3092XML\u3068\u3057\u3066\u8AAD\u53D6\u308A\u4E2D\u306B\u30EA\u30BD\u30FC\u30B9\u30FB\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F(href=''{0}'')\u3002\u7406\u7531: {1}
TextResourceError = \u30A4\u30F3\u30AF\u30EB\u30FC\u30C9\u64CD\u4F5C\u304C\u5931\u6557\u3057\u3001\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u306B\u623B\u308A\u307E\u3059\u3002\u30D5\u30A1\u30A4\u30EB\u3092\u30C6\u30AD\u30B9\u30C8\u3068\u3057\u3066\u8AAD\u53D6\u308A\u4E2D\u306B\u30EA\u30BD\u30FC\u30B9\u30FB\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F(href=''{0}'')\u3002\u7406\u7531: {1}
NO_XPointerSchema = \u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\"{0}\"\u306E\u30B9\u30AD\u30FC\u30DE\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002{0}\u306B\u5BFE\u3057\u3066\u72EC\u81EA\u306E\u30B9\u30AD\u30FC\u30DE\u3092\u5B9A\u7FA9\u3057\u3066\u304F\u3060\u3055\u3044\u3002http://apache.org/xml/properties/xpointer-schema\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ko.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ko.properties
index 430d6603d4a..570b7a7d583 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ko.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ko.properties
@@ -39,7 +39,7 @@ FallbackChild = ''include'' \uC678\uC5D0 \uB2E4\uB978 ''http://www.w3.org/2001/X
HrefMissing = 'include' \uC694\uC18C\uC758 'href' \uC18D\uC131\uC774 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
RecursiveInclude = \uC21C\uD658 include\uAC00 \uAC10\uC9C0\uB418\uC5C8\uC2B5\uB2C8\uB2E4. ''{0}'' \uBB38\uC11C\uAC00 \uC774\uBBF8 \uCC98\uB9AC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
InvalidParseValue = ''include'' \uC694\uC18C\uC5D0 ''parse'' \uC18D\uC131\uC5D0 \uB300\uD574 \uBD80\uC801\uD569\uD55C \uAC12\uC774 \uC788\uC74C: ''{0}''.
-XMLParseError = XML \uD30C\uC77C(href=''{0}'')\uC758 \uAD6C\uBB38\uC744 \uBD84\uC11D\uD558\uB824\uACE0 \uC2DC\uB3C4\uD558\uB294 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.
+XMLParseError = XML \uD30C\uC77C(href=''{0}'')\uC758 \uAD6C\uBB38\uC744 \uBD84\uC11D\uD558\uB824\uACE0 \uC2DC\uB3C4\uD558\uB294 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.\uC6D0\uC778: {1}
XMLResourceError = Include \uC791\uC5C5\uC744 \uC2E4\uD328\uD558\uC5EC fallback\uC73C\uB85C \uBCF5\uC6D0\uD558\uB294 \uC911\uC785\uB2C8\uB2E4. \uD30C\uC77C\uC744 XML(href=''{0}'')\uB85C \uC77D\uB294 \uC911 \uB9AC\uC18C\uC2A4 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. \uC6D0\uC778: {1}
TextResourceError = Include \uC791\uC5C5\uC744 \uC2E4\uD328\uD558\uC5EC fallback\uC73C\uB85C \uBCF5\uC6D0\uD558\uB294 \uC911\uC785\uB2C8\uB2E4. \uD30C\uC77C\uC744 \uD14D\uC2A4\uD2B8(href=''{0}'')\uB85C \uC77D\uB294 \uC911 \uB9AC\uC18C\uC2A4 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. \uC6D0\uC778: {1}
NO_XPointerSchema = \uAE30\uBCF8\uC801\uC73C\uB85C \"{0}\"\uC5D0 \uB300\uD55C \uC2A4\uD0A4\uB9C8\uB294 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. {0}\uC5D0 \uB300\uD574 \uACE0\uC720\uD55C \uC2A4\uD0A4\uB9C8\uB97C \uC815\uC758\uD558\uC2ED\uC2DC\uC624. http://apache.org/xml/properties/xpointer-schema\uB97C \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_pt_BR.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_pt_BR.properties
index 8d5b021af0b..5abd8266549 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_pt_BR.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_pt_BR.properties
@@ -39,7 +39,7 @@ FallbackChild = Elementos do namespace ''http://www.w3.org/2001/XInclude'', dife
HrefMissing = O atributo 'href' de um elemento 'include' n\u00E3o foi encontrado.
RecursiveInclude = Inclus\u00E3o recursiva detectada. O documento ''{0}'' j\u00E1 foi processado.
InvalidParseValue = Valor inv\u00E1lido para o atributo ''parse'' no elemento ''include'': ''{0}''.
-XMLParseError = Erro ao tentar fazer parse do arquivo XML (href=''{0}'').
+XMLParseError = Erro ao tentar fazer parse do arquivo XML (href=''{0}''). Motivo: {1}
XMLResourceError = Falha na opera\u00E7\u00E3o de inclus\u00E3o; revertendo para fallback. Erro do recurso ao ler o arquivo como XML (href=''{0}''). Motivo: {1}
TextResourceError = Falha na opera\u00E7\u00E3o de inclus\u00E3o; revertendo para fallback. Erro do recurso ao ler o arquivo como texto (href=''{0}''). Motivo: {1}
NO_XPointerSchema = Por default, o esquema para \"{0}\" n\u00E3o \u00E9 suportado. Defina seu pr\u00F3prio esquema para {0}. Consulte http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_sv.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_sv.properties
index 6f0d1f39054..426a5fa82bd 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_sv.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_sv.properties
@@ -39,7 +39,7 @@ FallbackChild = Element fr\u00E5n namnrymd ''http://www.w3.org/2001/XInclude'',
HrefMissing = Ett 'href'-attribut i ett 'include'-element saknas.
RecursiveInclude = Rekursiv inkludering uppt\u00E4cktes. Dokumentet ''{0}'' har redan bearbetats.
InvalidParseValue = Ogiltigt v\u00E4rde f\u00F6r ''parse''-attribut i ''include''-element: ''{0}''.
-XMLParseError = Fel vid f\u00F6rs\u00F6k att tolka XML-fil (href=''{0}'').
+XMLParseError = Fel vid f\u00F6rs\u00F6k att tolka XML-fil (href=''{0}''). Orsak: {1}
XMLResourceError = Inkluderings\u00E5tg\u00E4rden utf\u00F6rdes inte, \u00E5terst\u00E4ller genom att \u00E5terskapa. Resursfel vid l\u00E4sning av fil som XML (href=''{0}''). Orsak: {1}
TextResourceError = Inkluderings\u00E5tg\u00E4rden utf\u00F6rdes inte, \u00E5terst\u00E4ller genom att \u00E5terskapa. Resursfel vid l\u00E4sning av fil som text (href=''{0}''). Orsak: {1}
NO_XPointerSchema = Schema f\u00F6r \"{0}\" st\u00F6ds inte som standard. Definiera ett eget schema f\u00F6r {0}.Se http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_CN.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_CN.properties
index 3a36b4b243f..bcbb3aa3f70 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_CN.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_CN.properties
@@ -39,7 +39,7 @@ FallbackChild = \u4E0D\u5141\u8BB8\u5C06\u540D\u79F0\u7A7A\u95F4 ''http://www.w3
HrefMissing = \u7F3A\u5C11 'include' \u5143\u7D20\u7684 'href' \u5C5E\u6027\u3002
RecursiveInclude = \u68C0\u6D4B\u5230\u9012\u5F52 include\u3002\u5DF2\u5904\u7406\u6587\u6863 ''{0}''\u3002
InvalidParseValue = ''include'' \u5143\u7D20\u7684 ''parse'' \u5C5E\u6027\u7684\u503C\u65E0\u6548: ''{0}''\u3002
-XMLParseError = \u5C1D\u8BD5\u5BF9 XML \u6587\u4EF6 (href=''{0}'') \u8FDB\u884C\u8BED\u6CD5\u5206\u6790\u65F6\u51FA\u9519\u3002
+XMLParseError = \u5C1D\u8BD5\u5BF9 XML \u6587\u4EF6 (href=''{0}'') \u8FDB\u884C\u8BED\u6CD5\u5206\u6790\u65F6\u51FA\u9519\u3002\u539F\u56E0: {1}
XMLResourceError = Include \u64CD\u4F5C\u5931\u8D25, \u5E76\u8FD8\u539F\u4E3A fallback\u3002\u4EE5 XML (href=''{0}'') \u683C\u5F0F\u8BFB\u53D6\u6587\u4EF6\u65F6\u51FA\u73B0\u8D44\u6E90\u9519\u8BEF\u3002\u539F\u56E0: {1}
TextResourceError = Include \u64CD\u4F5C\u5931\u8D25, \u5E76\u8FD8\u539F\u4E3A fallback\u3002\u4EE5\u6587\u672C (href=''{0}'') \u683C\u5F0F\u8BFB\u53D6\u6587\u4EF6\u65F6\u51FA\u73B0\u8D44\u6E90\u9519\u8BEF\u3002\u539F\u56E0: {1}
NO_XPointerSchema = \u9ED8\u8BA4\u60C5\u51B5\u4E0B, \u4E0D\u652F\u6301 \"{0}\" \u7684\u65B9\u6848\u3002\u8BF7\u4E3A{0}\u5B9A\u4E49\u60A8\u81EA\u5DF1\u7684\u65B9\u6848\u3002\u8BF7\u8BBF\u95EE http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_TW.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_TW.properties
index 33948e31c01..11cff31525e 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_TW.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_TW.properties
@@ -39,7 +39,7 @@ FallbackChild = \u4F86\u81EA\u547D\u540D\u7A7A\u9593 ''http://www.w3.org/2001/XI
HrefMissing = \u907A\u6F0F 'include' \u5143\u7D20\u7684 'href' \u5C6C\u6027\u3002
RecursiveInclude = \u5075\u6E2C\u5230\u905E\u8FF4\u5305\u542B\u3002\u5DF2\u7D93\u8655\u7406\u6587\u4EF6 ''{0}''\u3002
InvalidParseValue = ''include'' \u5143\u7D20\u4E0A ''parse'' \u5C6C\u6027\u7684\u7121\u6548\u503C: ''{0}''\u3002
-XMLParseError = \u5617\u8A66\u5256\u6790 XML \u6A94\u6848\u6642\u767C\u751F\u932F\u8AA4 (href=''{0}'')\u3002
+XMLParseError = \u5617\u8A66\u5256\u6790 XML \u6A94\u6848\u6642\u767C\u751F\u932F\u8AA4 (href=''{0}'')\u3002\u539F\u56E0: {1}
XMLResourceError = \u5305\u542B\u4F5C\u696D\u5931\u6557\uFF0C\u56DE\u5FA9\u81F3\u5F8C\u63F4\u3002\u4EE5 XML (href=''{0}'') \u65B9\u5F0F\u8B80\u53D6\u6A94\u6848\u6642\u767C\u751F\u8CC7\u6E90\u932F\u8AA4\u3002\u539F\u56E0: {1}
TextResourceError = \u5305\u542B\u4F5C\u696D\u5931\u6557\uFF0C\u56DE\u5FA9\u81F3\u5F8C\u63F4\u3002\u4EE5\u6587\u5B57 (href=''{0}'') \u65B9\u5F0F\u8B80\u53D6\u6A94\u6848\u6642\u767C\u751F\u8CC7\u6E90\u932F\u8AA4\u3002\u539F\u56E0: {1}
NO_XPointerSchema = \u9810\u8A2D\u4E0D\u652F\u63F4 \"{0}\" \u7684\u7DB1\u8981\u3002\u8ACB\u70BA {0} \u5B9A\u7FA9\u60A8\u81EA\u5DF1\u7684\u7DB1\u8981\u3002\u8ACB\u53C3\u95B1 http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
index 133f4282020..3bf9ebdc987 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
@@ -261,6 +261,9 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = The external entity reference \"&{0};\" is not permitted in an attribute value.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
# 4.1 Character and Entity References
EntityNotDeclared = The entity \"{0}\" was referenced, but not declared.
ReferenceToUnparsedEntity = The unparsed entity reference \"&{0};\" is not permitted.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties
index 29bbccfb142..3cf21e56482 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties
@@ -289,6 +289,9 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = Externe Entit\u00E4tsreferenz \"&{0};\" ist in einem Attributwert nicht zul\u00E4ssig.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
# 4.1 Character and Entity References
EntityNotDeclared = Entit\u00E4t \"{0}\" wurde referenziert aber nicht deklariert.
ReferenceToUnparsedEntity = Nicht geparste Entit\u00E4tsreferenz \"&{0};\" ist nicht zul\u00E4ssig.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties
index f8227e2ce47..5ebfaf0eb2a 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties
@@ -289,6 +289,9 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = La referencia de entidad externa \"&{0};\" no est\u00E1 permitida en un valor de atributo.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
# 4.1 Character and Entity References
EntityNotDeclared = Se hizo referencia a la entidad \"{0}\", pero no se declar\u00F3.
ReferenceToUnparsedEntity = La referencia de entidad no analizada \"&{0};\" no est\u00E1 permitida.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties
index cc0c6bfff75..f60b07301ee 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties
@@ -289,6 +289,9 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = La r\u00E9f\u00E9rence d''entit\u00E9 externe \"&{0};\" n''est pas autoris\u00E9e dans une valeur d''attribut.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
# 4.1 Character and Entity References
EntityNotDeclared = L''entit\u00E9 \"{0}\" \u00E9tait r\u00E9f\u00E9renc\u00E9e, mais pas d\u00E9clar\u00E9e.
ReferenceToUnparsedEntity = La r\u00E9f\u00E9rence d''entit\u00E9 non analys\u00E9e \"&{0};\" n''est pas autoris\u00E9e.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties
index 03f8ce2fa42..e525777850b 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties
@@ -289,6 +289,9 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = Il riferimento di entit\u00E0 esterna \"&{0};\" non \u00E8 consentito in un valore di attributo.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
# 4.1 Character and Entity References
EntityNotDeclared = L''entit\u00E0 \"{0}\" \u00E8 indicata da un riferimento, ma non \u00E8 dichiarata.
ReferenceToUnparsedEntity = Il riferimento di entit\u00E0 non analizzata \"&{0};\" non \u00E8 consentito.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties
index e837075d8a1..ed548694ec4 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties
@@ -289,6 +289,9 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = \u5916\u90E8\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u53C2\u7167\"&{0};\"\u306F\u3001\u5C5E\u6027\u5024\u3067\u306F\u8A31\u53EF\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
# 4.1 Character and Entity References
EntityNotDeclared = \u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\"{0}\"\u304C\u53C2\u7167\u3055\u308C\u3066\u3044\u307E\u3059\u304C\u3001\u5BA3\u8A00\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
ReferenceToUnparsedEntity = \u672A\u89E3\u6790\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u53C2\u7167\"&{0};\"\u306F\u8A31\u53EF\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties
index 8262f88a9e4..882f8085758 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties
@@ -289,6 +289,9 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = \uC18D\uC131\uAC12\uC5D0\uC11C\uB294 \uC678\uBD80 \uC5D4\uD2F0\uD2F0 \uCC38\uC870 \"&{0};\"\uC774 \uD5C8\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
# 4.1 Character and Entity References
EntityNotDeclared = \"{0}\" \uC5D4\uD2F0\uD2F0\uAC00 \uCC38\uC870\uB418\uC5C8\uC9C0\uB9CC \uC120\uC5B8\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
ReferenceToUnparsedEntity = \uAD6C\uBB38\uC774 \uBD84\uC11D\uB418\uC9C0 \uC54A\uC740 \uC5D4\uD2F0\uD2F0 \uCC38\uC870 \"&{0};\"\uC740(\uB294) \uD5C8\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties
index 94eebc6d80a..57770dcde09 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties
@@ -289,6 +289,9 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = A refer\u00EAncia da entidade externa \"&{0};\" n\u00E3o \u00E9 permitida em um valor do atributo.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
# 4.1 Character and Entity References
EntityNotDeclared = A entidade \"{0}\" foi referenciada, mas n\u00E3o declarada.
ReferenceToUnparsedEntity = A refer\u00EAncia da entidade n\u00E3o submetida a parse \"&{0};\" n\u00E3o \u00E9 permitida.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties
index 6777adb5ed6..8c0bb0f0f8d 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties
@@ -289,6 +289,9 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = Den externa enhetsreferensen \"&{0};\" till\u00E5ts inte i ett attributv\u00E4rde.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
# 4.1 Character and Entity References
EntityNotDeclared = Enheten \"{0}\" har refererats, men \u00E4r inte deklarerad.
ReferenceToUnparsedEntity = Den otolkade enhetsreferensen \"&{0};\" \u00E4r inte till\u00E5ten.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties
index 959f147b130..74a7a061c2b 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties
@@ -289,6 +289,9 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = \u5C5E\u6027\u503C\u4E2D\u4E0D\u5141\u8BB8\u91C7\u7528\u5916\u90E8\u5B9E\u4F53\u5F15\u7528 \"&{0};\"\u3002
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
# 4.1 Character and Entity References
EntityNotDeclared = \u5F15\u7528\u4E86\u5B9E\u4F53 \"{0}\", \u4F46\u672A\u58F0\u660E\u5B83\u3002
ReferenceToUnparsedEntity = \u4E0D\u5141\u8BB8\u4F7F\u7528\u672A\u8FDB\u884C\u8BED\u6CD5\u5206\u6790\u7684\u5B9E\u4F53\u5F15\u7528 \"&{0};\"\u3002
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties
index 7495d31bfb4..1a953819503 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties
@@ -289,6 +289,9 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = \u5C6C\u6027\u503C\u4E0D\u5141\u8A31\u53C3\u7167\u5916\u90E8\u500B\u9AD4 \"&{0};\"\u3002
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
# 4.1 Character and Entity References
EntityNotDeclared = \u53C3\u7167\u4E86\u500B\u9AD4 \"{0}\"\uFF0C\u4F46\u662F\u672A\u5BA3\u544A\u3002
ReferenceToUnparsedEntity = \u4E0D\u5141\u8A31\u672A\u5256\u6790\u7684\u500B\u9AD4\u53C3\u7167 \"&{0};\"\u3002
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties
index d2e847199ec..23234a4bf61 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties
@@ -86,6 +86,7 @@
#schema valid (3.X.3)
+ schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
schema_reference.4 = schema_reference.4: Failed to read schema document ''{0}'', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not .
src-annotation = src-annotation: elements can only contain and elements, but ''{0}'' was found.
src-attribute.1 = src-attribute.1: The properties ''default'' and ''fixed'' cannot both be present in attribute declaration ''{0}''. Use only one of them.
@@ -289,6 +290,3 @@
TargetNamespace.2 = TargetNamespace.2: Expecting no namespace, but the schema document has a target namespace of ''{1}''.
UndeclaredEntity = UndeclaredEntity: Entity ''{0}'' is not declared.
UndeclaredPrefix = UndeclaredPrefix: Cannot resolve ''{0}'' as a QName: the prefix ''{1}'' is not declared.
-null
-null
-null
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_de.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_de.properties
index 755985e04c0..eed78fb7577 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_de.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_de.properties
@@ -114,6 +114,7 @@
#schema valid (3.X.3)
+ schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
schema_reference.4 = schema_reference.4: Schemadokument "{0}" konnte nicht gelesen werden, da 1) das Dokument nicht gefunden werden konnte; 2) das Dokument nicht gelesen werden konnte; 3) das Root-Element des Dokuments nicht ist.
src-annotation = src-annotation: -Elemente k\u00F6nnen nur - und -Elemente enthalten, aber es wurde "{0}" gefunden.
src-attribute.1 = src-attribute.1: Die Eigenschaften "default" und "fixed" k\u00F6nnen nicht beide in der Attributdeklaration "{0}" vorhanden sein. Verwenden Sie nur eine dieser Eigenschaften.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_es.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_es.properties
index 3a4e15cfd97..b5e6560e957 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_es.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_es.properties
@@ -114,6 +114,7 @@
#schema valid (3.X.3)
+ schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
schema_reference.4 = schema_reference.4: Fallo al leer el documento de esquema ''{0}'', porque 1) no se ha encontrado el documento; 2) no se ha podido leer el documento; 3) el elemento ra\u00EDz del documento no es .
src-annotation = src-annotation: Los elementos de s\u00F3lo pueden contener elementos de y , pero se ha encontrado ''{0}''.
src-attribute.1 = src-attribute.1: Las propiedades ''default'' y ''fixed'' no pueden estar presentes de forma simult\u00E1nea en la declaraci\u00F3n de atributo ''{0}''. Utilice s\u00F3lo una de ellas.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_fr.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_fr.properties
index 24e910cbe83..f3c3156d7c3 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_fr.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_fr.properties
@@ -114,6 +114,7 @@
#schema valid (3.X.3)
+ schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
schema_reference.4 = schema_reference.4 : Echec de la lecture du document de sch\u00E9ma ''{0}'' pour les raisons suivantes : 1) Le document est introuvable ; 2) Le document n''a pas pu \u00EAtre lu ; 3) L''\u00E9l\u00E9ment racine du document n''est pas .
src-annotation = src-annotation : Les \u00E9l\u00E9ments ne peuvent contenir que des \u00E9l\u00E9ments et , mais ''{0}'' a \u00E9t\u00E9 trouv\u00E9.
src-attribute.1 = src-attribute.1 : Les propri\u00E9t\u00E9s ''default'' et ''fixed'' ne peuvent pas figurer simultan\u00E9ment dans la d\u00E9claration d''attribut ''{0}''. Utilisez uniquement l''une d''entre elles.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_it.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_it.properties
index 638d40001e2..4153c6d2219 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_it.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_it.properties
@@ -114,6 +114,7 @@
#schema valid (3.X.3)
+ schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
schema_reference.4 = schema_reference.4: lettura del documento di schema "{0}" non riuscita perch\u00E9 1) non \u00E8 stato possibile trovare il documento; 2) non \u00E8 stato possibile leggere il documento; 3) l''elemento radice del documento non \u00E8 .
src-annotation = src-annotation: possono essere contenuti soltanto elementi e , ma \u00E8 stato trovato ''{0}''.
src-attribute.1 = src-attribute.1: le propriet\u00E0 ''default'' e ''fixed'' non possono essere entrambi presenti nella dichiarazione di attributo ''{0}''. Utilizzarne solo una.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ja.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ja.properties
index 536f78c9693..9fe30e2e67d 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ja.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ja.properties
@@ -114,6 +114,7 @@
#schema valid (3.X.3)
+ schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
schema_reference.4 = schema_reference.4: 1)\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u304C\u898B\u3064\u304B\u3089\u306A\u304B\u3063\u305F\u30012)\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u8AAD\u307F\u53D6\u308C\u306A\u304B\u3063\u305F\u30013)\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30EB\u30FC\u30C8\u8981\u7D20\u304C\u3067\u306F\u306A\u304B\u3063\u305F\u305F\u3081\u3001\u30B9\u30AD\u30FC\u30DE\u30FB\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8''{0}''\u306E\u8AAD\u53D6\u308A\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
src-annotation = src-annotation: \u8981\u7D20\u306B\u542B\u3081\u308B\u3053\u3068\u304C\u3067\u304D\u308B\u306E\u306F\u8981\u7D20\u304A\u3088\u3073\u8981\u7D20\u306E\u307F\u3067\u3059\u304C\u3001''{0}''\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F\u3002
src-attribute.1 = src-attribute.1: ''default''\u3068''fixed''\u306E\u4E21\u65B9\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u5C5E\u6027\u5BA3\u8A00''{0}''\u306B\u542B\u3081\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002\u3044\u305A\u308C\u304B\u4E00\u65B9\u306E\u307F\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ko.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ko.properties
index 102466bd5af..a6a77f32186 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ko.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ko.properties
@@ -114,6 +114,7 @@
#schema valid (3.X.3)
+ schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
schema_reference.4 = schema_reference.4: \uC2A4\uD0A4\uB9C8 \uBB38\uC11C ''{0}'' \uC77D\uAE30\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uC6D0\uC778: 1) \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. 2) \uBB38\uC11C\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. 3) \uBB38\uC11C\uC758 \uB8E8\uD2B8 \uC694\uC18C\uAC00 \uAC00 \uC544\uB2D9\uB2C8\uB2E4.
src-annotation = src-annotation: \uC694\uC18C\uC5D0\uB294 \uBC0F \uC694\uC18C\uB9CC \uD3EC\uD568\uB420 \uC218 \uC788\uC9C0\uB9CC ''{0}''\uC774(\uAC00) \uBC1C\uACAC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
src-attribute.1 = src-attribute.1: ''default'' \uBC0F ''fixed'' \uC18D\uC131\uC740 \uC18D\uC131 \uC120\uC5B8 ''{0}''\uC5D0 \uD568\uAED8 \uC874\uC7AC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uD558\uB098\uB9CC \uC0AC\uC6A9\uD558\uC2ED\uC2DC\uC624.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_pt_BR.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_pt_BR.properties
index e3bee291978..163fc6d2b4a 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_pt_BR.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_pt_BR.properties
@@ -114,6 +114,7 @@
#schema valid (3.X.3)
+ schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
schema_reference.4 = schema_reference.4: Falha ao ler o documento do esquema ''{0}'' porque 1) n\u00E3o foi poss\u00EDvel encontrar o documento; 2) n\u00E3o foi poss\u00EDvel ler o documento; 3) o elemento-raiz do documento n\u00E3o \u00E9 .
src-annotation = src-annotation: os elementos de podem conter somente os elementos e , mas foi encontrado ''{0}''.
src-attribute.1 = src-attribute.1: As propriedades ''default'' e ''fixed'' n\u00E3o podem estar presentes na declara\u00E7\u00E3o do atributo ''{0}''. Use somente uma delas.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_sv.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_sv.properties
index 0332f512fee..4cc42ca5eb5 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_sv.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_sv.properties
@@ -114,6 +114,7 @@
#schema valid (3.X.3)
+ schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
schema_reference.4 = schema_reference.4: L\u00E4sning av schemadokument ''{0}'' utf\u00F6rdes inte p\u00E5 grund av 1) det g\u00E5r inte att hitta dokumentet; 2) det g\u00E5r inte att l\u00E4sa dokumentet; 3) dokumentets rotelement \u00E4r inte .
src-annotation = src-annotation: element f\u00F6r f\u00E5r endast inneh\u00E5lla element f\u00F6r och , men ''{0}'' hittades.
src-attribute.1 = src-attribute.1: B\u00E5da egenskaperna ''default'' och ''fixed'' kan inte samtidigt ing\u00E5 i attributdeklarationen ''{0}''. Anv\u00E4nd en av dem.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_CN.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_CN.properties
index ef0338ab8e7..f517a72a2cd 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_CN.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_CN.properties
@@ -114,6 +114,7 @@
#schema valid (3.X.3)
+ schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
schema_reference.4 = schema_reference.4: \u65E0\u6CD5\u8BFB\u53D6\u65B9\u6848\u6587\u6863 ''{0}'', \u539F\u56E0\u4E3A 1) \u65E0\u6CD5\u627E\u5230\u6587\u6863; 2) \u65E0\u6CD5\u8BFB\u53D6\u6587\u6863; 3) \u6587\u6863\u7684\u6839\u5143\u7D20\u4E0D\u662F \u3002
src-annotation = src-annotation: \u5143\u7D20\u53EA\u80FD\u5305\u542B \u548C \u5143\u7D20, \u4F46\u53D1\u73B0\u4E86 ''{0}''\u3002
src-attribute.1 = src-attribute.1: \u5C5E\u6027\u58F0\u660E ''{0}'' \u4E2D\u4E0D\u80FD\u540C\u65F6\u5B58\u5728\u7279\u6027 ''default'' \u548C ''fixed''\u3002\u5E94\u53EA\u4F7F\u7528\u5176\u4E2D\u4E00\u4E2A\u3002
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_TW.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_TW.properties
index a61dc7cecb1..8661de47c74 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_TW.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_TW.properties
@@ -114,6 +114,7 @@
#schema valid (3.X.3)
+ schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
schema_reference.4 = schema_reference.4: \u7121\u6CD5\u8B80\u53D6\u7DB1\u8981\u6587\u4EF6 ''{0}''\uFF0C\u56E0\u70BA 1) \u627E\u4E0D\u5230\u6587\u4EF6; 2) \u7121\u6CD5\u8B80\u53D6\u6587\u4EF6; 3) \u6587\u4EF6\u7684\u6839\u5143\u7D20\u4E0D\u662F \u3002
src-annotation = src-annotation: \u5143\u7D20\u50C5\u80FD\u5305\u542B \u8207 \u5143\u7D20\uFF0C\u4F46\u627E\u5230 ''{0}''\u3002
src-attribute.1 = src-attribute.1: \u5C6C\u6027 ''default'' \u8207 ''fixed'' \u4E0D\u53EF\u540C\u6642\u51FA\u73FE\u5728\u5C6C\u6027\u5BA3\u544A ''{0}'' \u4E2D\u3002\u8ACB\u53EA\u4F7F\u7528\u5176\u4E2D\u4E00\u500B\u3002
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java
index 4b7ba136685..3fbe23475d7 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java
@@ -53,6 +53,7 @@ import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings;
import com.sun.org.apache.xerces.internal.util.Status;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
import com.sun.org.apache.xerces.internal.util.XMLSymbols;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
@@ -71,6 +72,7 @@ import com.sun.org.apache.xerces.internal.xs.XSLoader;
import com.sun.org.apache.xerces.internal.xs.XSModel;
import java.util.HashMap;
import java.util.Map;
+import javax.xml.XMLConstants;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMError;
import org.w3c.dom.DOMErrorHandler;
@@ -216,6 +218,12 @@ XSLoader, DOMConfiguration {
protected static final String ENTITY_MANAGER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
+ /** Property identifier: access to external dtd */
+ public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+ /** Property identifier: access to external schema */
+ public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
// recognized properties
private static final String [] RECOGNIZED_PROPERTIES = {
ENTITY_MANAGER,
@@ -229,7 +237,9 @@ XSLoader, DOMConfiguration {
JAXP_SCHEMA_SOURCE,
SECURITY_MANAGER,
LOCALE,
- SCHEMA_DV_FACTORY
+ SCHEMA_DV_FACTORY,
+ ACCESS_EXTERNAL_DTD,
+ ACCESS_EXTERNAL_SCHEMA
};
// Data
@@ -260,6 +270,8 @@ XSLoader, DOMConfiguration {
private final CMNodeFactory fNodeFactory = new CMNodeFactory(); //component mgr will be set later
private CMBuilder fCMBuilder;
private XSDDescription fXSDDescription = new XSDDescription();
+ private String faccessExternalDTD = Constants.EXTERNAL_ACCESS_DEFAULT;
+ private String faccessExternalSchema = Constants.EXTERNAL_ACCESS_DEFAULT;
private Map fJAXPCache;
private Locale fLocale = Locale.getDefault();
@@ -454,6 +466,12 @@ XSLoader, DOMConfiguration {
fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, new XSMessageFormatter());
}
}
+ else if (propertyId.equals(ACCESS_EXTERNAL_DTD)) {
+ faccessExternalDTD = (String) state;
+ }
+ else if (propertyId.equals(ACCESS_EXTERNAL_SCHEMA)) {
+ faccessExternalSchema = (String) state;
+ }
} // setProperty(String, Object)
/**
@@ -585,6 +603,15 @@ XSLoader, DOMConfiguration {
if(!fJAXPProcessed) {
processJAXPSchemaSource(locationPairs);
}
+
+ if (desc.isExternal()) {
+ String accessError = SecuritySupport.checkAccess(desc.getExpandedSystemId(), faccessExternalSchema, Constants.ACCESS_EXTERNAL_ALL);
+ if (accessError != null) {
+ throw new XNIException(fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
+ "schema_reference.access",
+ new Object[] { SecuritySupport.sanitizePath(desc.getExpandedSystemId()), accessError }, XMLErrorReporter.SEVERITY_ERROR));
+ }
+ }
SchemaGrammar grammar = fSchemaHandler.parseSchema(source, desc, locationPairs);
return grammar;
@@ -1038,6 +1065,9 @@ XSLoader, DOMConfiguration {
// get generate-synthetic-annotations feature
fSchemaHandler.setGenerateSyntheticAnnotations(componentManager.getFeature(GENERATE_SYNTHETIC_ANNOTATIONS, false));
fSchemaHandler.reset(componentManager);
+
+ faccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD);
+ faccessExternalSchema = (String) componentManager.getProperty(ACCESS_EXTERNAL_SCHEMA);
}
private void initGrammarBucket(){
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java
index c14673ec26a..170601cb46a 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java
@@ -29,7 +29,7 @@ import java.util.Map;
import java.util.Stack;
import java.util.Vector;
import java.util.ArrayList;
-
+import javax.xml.XMLConstants;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.RevalidationHandler;
import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
@@ -233,6 +233,12 @@ public class XMLSchemaValidator
protected static final String SCHEMA_DV_FACTORY =
Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY;
+ /** property identifier: access external dtd. */
+ private static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+ /** Property identifier: access to external schema */
+ private static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
protected static final String USE_SERVICE_MECHANISM = Constants.ORACLE_FEATURE_SERVICE_MECHANISM;
// recognized features and properties
@@ -291,11 +297,13 @@ public class XMLSchemaValidator
JAXP_SCHEMA_SOURCE,
JAXP_SCHEMA_LANGUAGE,
SCHEMA_DV_FACTORY,
+ ACCESS_EXTERNAL_DTD,
+ ACCESS_EXTERNAL_SCHEMA
};
/** Property defaults. */
private static final Object[] PROPERTY_DEFAULTS =
- { null, null, null, null, null, null, null, null, null, null, null};
+ { null, null, null, null, null, null, null, null, null, null, null, null, null};
// this is the number of valuestores of each kind
// we expect an element to have. It's almost
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XSDDescription.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XSDDescription.java
index 8e09b9f80d8..c35baa8667a 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XSDDescription.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XSDDescription.java
@@ -34,6 +34,7 @@ import com.sun.org.apache.xerces.internal.xni.grammars.XMLSchemaDescription;
* @author Neil Graham, IBM
* @author Neeraj Bajaj, SUN Microsystems.
*
+ * @version $Id: XSDDescription.java,v 1.6 2010-11-01 04:39:55 joehw Exp $
*/
public class XSDDescription extends XMLResourceIdentifierImpl
implements XMLSchemaDescription {
@@ -180,6 +181,17 @@ public class XSDDescription extends XMLResourceIdentifierImpl
fContextType == CONTEXT_XSITYPE;
}
+ /**
+ * @return true is the schema is external
+ */
+ public boolean isExternal() {
+ return fContextType == CONTEXT_INCLUDE ||
+ fContextType == CONTEXT_REDEFINE ||
+ fContextType == CONTEXT_IMPORT ||
+ fContextType == CONTEXT_ELEMENT ||
+ fContextType == CONTEXT_ATTRIBUTE ||
+ fContextType == CONTEXT_XSITYPE;
+ }
/**
* Compares this grammar with the given grammar. Currently, we compare
* the target namespaces.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java
index 7c9974e4a17..eba1ac0de20 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java
@@ -77,6 +77,7 @@ import com.sun.org.apache.xerces.internal.util.SymbolHash;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
import com.sun.org.apache.xerces.internal.util.XMLSymbols;
import com.sun.org.apache.xerces.internal.util.URI.MalformedURIException;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
import com.sun.org.apache.xerces.internal.xni.QName;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
@@ -105,6 +106,7 @@ import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition;
import com.sun.org.apache.xerces.internal.xs.XSTerm;
import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
import com.sun.org.apache.xerces.internal.xs.datatypes.ObjectList;
+import javax.xml.XMLConstants;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -221,6 +223,12 @@ public class XSDHandler {
protected static final String LOCALE =
Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY;
+ /** property identifier: access external dtd. */
+ public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+ /** Property identifier: access to external schema */
+ public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
protected static final boolean DEBUG_NODE_POOL = false;
// Data
@@ -251,6 +259,8 @@ public class XSDHandler {
*/
protected SecurityManager fSecureProcessing = null;
+ private String fAccessExternalSchema;
+
// These tables correspond to the symbol spaces defined in the
// spec.
// They are keyed with a QName (that is, String("URI,localpart) and
@@ -2150,6 +2160,15 @@ public class XSDHandler {
fLastSchemaWasDuplicate = true;
return schemaElement;
}
+ if (referType == XSDDescription.CONTEXT_IMPORT || referType == XSDDescription.CONTEXT_INCLUDE
+ || referType == XSDDescription.CONTEXT_REDEFINE) {
+ String accessError = SecuritySupport.checkAccess(schemaId, fAccessExternalSchema, Constants.ACCESS_EXTERNAL_ALL);
+ if (accessError != null) {
+ reportSchemaFatalError("schema_reference.access",
+ new Object[] { SecuritySupport.sanitizePath(schemaId), accessError },
+ referElement);
+ }
+ }
}
fSchemaParser.parse(schemaSource);
@@ -3561,6 +3580,11 @@ public class XSDHandler {
} catch (XMLConfigurationException e) {
}
+ //For Schema validation, the secure feature is set to true by default
+ fSchemaParser.setProperty(ACCESS_EXTERNAL_DTD,
+ componentManager.getProperty(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT));
+ fAccessExternalSchema = (String) componentManager.getProperty(
+ ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT);
} // reset(XMLComponentManager)
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java
index af14049cf50..aea63c2eb16 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java
@@ -37,7 +37,7 @@ import org.xml.sax.SAXNotSupportedException;
/**
* @author Rajiv Mordani
* @author Edwin Goei
- * @version $Id: DocumentBuilderFactoryImpl.java,v 1.6 2009/07/28 23:48:32 joehw Exp $
+ * @version $Id: DocumentBuilderFactoryImpl.java,v 1.8 2010-11-01 04:40:06 joehw Exp $
*/
public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory {
/** These are DocumentBuilderFactory attributes not DOM attributes */
@@ -191,6 +191,9 @@ public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory {
public void setFeature(String name, boolean value)
throws ParserConfigurationException {
+ if (features == null) {
+ features = new Hashtable();
+ }
// If this is the secure processing feature, save it then return.
if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
if (System.getSecurityManager() != null && (!value)) {
@@ -199,11 +202,10 @@ public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory {
"jaxp-secureprocessing-feature", null));
}
fSecureProcess = value;
+ features.put(name, value ? Boolean.TRUE : Boolean.FALSE);
return;
}
- if (features == null) {
- features = new Hashtable();
- }
+
features.put(name, value ? Boolean.TRUE : Boolean.FALSE);
// Test the feature by possibly throwing SAX exceptions
try {
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java
index 84bab42cbc5..39112a61f64 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java
@@ -27,6 +27,7 @@ import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.validation.Schema;
+import javax.xml.XMLConstants;
import com.sun.org.apache.xerces.internal.dom.DOMImplementationImpl;
import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter;
@@ -42,6 +43,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
+import javax.xml.XMLConstants;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.xml.sax.EntityResolver;
@@ -95,6 +97,12 @@ public class DocumentBuilderImpl extends DocumentBuilder
private static final String SECURITY_MANAGER =
Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
+ /** property identifier: access external dtd. */
+ public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+ /** Property identifier: access to external schema */
+ public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
private final DOMParser domParser;
private final Schema grammar;
@@ -155,6 +163,23 @@ public class DocumentBuilderImpl extends DocumentBuilder
// If the secure processing feature is on set a security manager.
if (secureProcessing) {
domParser.setProperty(SECURITY_MANAGER, new SecurityManager());
+
+ /**
+ * By default, secure processing is set, no external access is allowed.
+ * However, we need to check if it is actively set on the factory since we
+ * allow the use of the System Property or jaxp.properties to override
+ * the default value
+ */
+ if (features != null) {
+ Object temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING);
+ if (temp != null) {
+ boolean value = ((Boolean) temp).booleanValue();
+ if (value) {
+ domParser.setProperty(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
+ domParser.setProperty(ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
+ }
+ }
+ }
}
this.grammar = dbf.getSchema();
@@ -211,6 +236,10 @@ public class DocumentBuilderImpl extends DocumentBuilder
String feature = (String) entry.getKey();
boolean value = ((Boolean) entry.getValue()).booleanValue();
domParser.setFeature(feature, value);
+ if (feature.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
+ domParser.setProperty(ACCESS_EXTERNAL_DTD, "");
+ domParser.setProperty(ACCESS_EXTERNAL_SCHEMA, "");
+ }
}
}
}
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserFactoryImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserFactoryImpl.java
index eecdc100344..ae9d99509d9 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserFactoryImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserFactoryImpl.java
@@ -43,7 +43,7 @@ import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter;
* @author Rajiv Mordani
* @author Edwin Goei
*
- * @version $Id: SAXParserFactoryImpl.java,v 1.7 2009/07/28 23:48:32 joehw Exp $
+ * @version $Id: SAXParserFactoryImpl.java,v 1.9 2010-11-01 04:40:06 joehw Exp $
*/
public class SAXParserFactoryImpl extends SAXParserFactory {
@@ -124,6 +124,7 @@ public class SAXParserFactoryImpl extends SAXParserFactory {
"jaxp-secureprocessing-feature", null));
}
fSecureProcess = value;
+ putInFeatures(name, value);
return;
}
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java
index 58d7d165d88..bbb609e9e28 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java
@@ -92,6 +92,12 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser
private static final String SECURITY_MANAGER =
Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
+ /** property identifier: access external dtd. */
+ public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+ /** Property identifier: access to external schema */
+ public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
private final JAXPSAXParser xmlReader;
private String schemaLanguage = null; // null means DTD
private final Schema grammar;
@@ -146,6 +152,22 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser
// If the secure processing feature is on set a security manager.
if (secureProcessing) {
xmlReader.setProperty0(SECURITY_MANAGER, new SecurityManager());
+ /**
+ * By default, secure processing is set, no external access is allowed.
+ * However, we need to check if it is actively set on the factory since we
+ * allow the use of the System Property or jaxp.properties to override
+ * the default value
+ */
+ if (features != null) {
+ Object temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING);
+ if (temp != null) {
+ boolean value = ((Boolean) temp).booleanValue();
+ if (value) {
+ xmlReader.setProperty0(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
+ xmlReader.setProperty0(ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
+ }
+ }
+ }
}
// Set application's features, followed by validation features.
@@ -220,6 +242,10 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser
String feature = (String) entry.getKey();
boolean value = ((Boolean) entry.getValue()).booleanValue();
xmlReader.setFeature0(feature, value);
+ if (feature.equals(XMLConstants.FEATURE_SECURE_PROCESSING) && value) {
+ xmlReader.setProperty0(ACCESS_EXTERNAL_DTD, "");
+ xmlReader.setProperty0(ACCESS_EXTERNAL_SCHEMA, "");
+ }
}
}
}
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/AbstractXMLSchema.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/AbstractXMLSchema.java
index 696dd9e1bf6..25e13a7a5ce 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/AbstractXMLSchema.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/AbstractXMLSchema.java
@@ -41,8 +41,15 @@ abstract class AbstractXMLSchema extends Schema implements
*/
private final HashMap fFeatures;
+ /**
+ * Map containing the initial values of properties for
+ * validators created using this grammar pool container.
+ */
+ private final HashMap fProperties;
+
public AbstractXMLSchema() {
fFeatures = new HashMap();
+ fProperties = new HashMap();
}
/*
@@ -77,11 +84,26 @@ abstract class AbstractXMLSchema extends Schema implements
}
/*
- * Other methods
+ * Set a feature on the schema
*/
-
- final void setFeature(String featureId, boolean state) {
+ public final void setFeature(String featureId, boolean state) {
fFeatures.put(featureId, state ? Boolean.TRUE : Boolean.FALSE);
}
+ /**
+ * Returns the initial value of a property for validators created
+ * using this grammar pool container or null if the validators
+ * should use the default value.
+ */
+ public final Object getProperty(String propertyId) {
+ return fProperties.get(propertyId);
+ }
+
+ /*
+ * Set a property on the schema
+ */
+ public final void setProperty(String propertyId, Object state) {
+ fProperties.put(propertyId, state);
+ }
+
} // AbstractXMLSchema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java
index 3919c0ca80f..1b4f6875611 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java
@@ -32,6 +32,7 @@ import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.XMLConstants;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
@@ -176,6 +177,8 @@ final class StreamValidatorHelper implements ValidatorHelper {
}
config.setProperty(SYMBOL_TABLE, fComponentManager.getProperty(SYMBOL_TABLE));
config.setProperty(VALIDATION_MANAGER, fComponentManager.getProperty(VALIDATION_MANAGER));
+ config.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
+ fComponentManager.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
config.setDocumentHandler(fSchemaValidator);
config.setDTDHandler(null);
config.setDTDContentModelHandler(null);
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java
index 2d9f2807910..e53118b2d4f 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java
@@ -675,6 +675,8 @@ final class ValidatorHandlerImpl extends ValidatorHandler implements
spf.setNamespaceAware(true);
try {
reader = spf.newSAXParser().getXMLReader();
+ reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
+ fComponentManager.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
// If this is a Xerces SAX parser, set the security manager if there is one
if (reader instanceof com.sun.org.apache.xerces.internal.parsers.SAXParser) {
SecurityManager securityManager = (SecurityManager) fComponentManager.getProperty(SECURITY_MANAGER);
@@ -685,6 +687,8 @@ final class ValidatorHandlerImpl extends ValidatorHandler implements
// Ignore the exception if the security manager cannot be set.
catch (SAXException exc) {}
}
+ reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
+ fComponentManager.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
}
} catch( Exception e ) {
// this is impossible, but better safe than sorry
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java
index fece15d7697..4cac487362f 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java
@@ -45,6 +45,7 @@ import com.sun.org.apache.xerces.internal.util.SecurityManager;
import com.sun.org.apache.xerces.internal.util.StAXInputSource;
import com.sun.org.apache.xerces.internal.util.Status;
import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
@@ -82,6 +83,12 @@ public final class XMLSchemaFactory extends SchemaFactory {
private static final String SECURITY_MANAGER =
Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
+ /** property identifier: access external dtd. */
+ public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+ /** Property identifier: access to external schema */
+ public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
//
// Data
//
@@ -132,6 +139,14 @@ public final class XMLSchemaFactory extends SchemaFactory {
// Enable secure processing feature by default
fSecurityManager = new SecurityManager();
fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager);
+
+ //by default, the secure feature is set to true, otherwise the default would have been 'file'
+ String accessExternal = SecuritySupport.getDefaultAccessProperty(
+ Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT);
+ fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_DTD, accessExternal);
+ accessExternal = SecuritySupport.getDefaultAccessProperty(
+ Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT);
+ fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_SCHEMA, accessExternal);
}
/**
@@ -274,6 +289,7 @@ public final class XMLSchemaFactory extends SchemaFactory {
// Use a Schema that uses the system id as the equality source.
AbstractXMLSchema schema = new WeakReferenceXMLSchema();
propagateFeatures(schema);
+ propagateProperties(schema);
return schema;
}
@@ -350,6 +366,8 @@ public final class XMLSchemaFactory extends SchemaFactory {
}
fSecurityManager = value ? new SecurityManager() : null;
fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager);
+ fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
+ fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
return;
} else if (name.equals(Constants.ORACLE_FEATURE_SERVICE_MECHANISM)) {
//in secure mode, let _useServicesMechanism be determined by the constructor
@@ -418,6 +436,15 @@ public final class XMLSchemaFactory extends SchemaFactory {
}
}
+ private void propagateProperties(AbstractXMLSchema schema) {
+ String[] properties = fXMLSchemaLoader.getRecognizedProperties();
+ for (int i = 0; i < properties.length; ++i) {
+ Object state = fXMLSchemaLoader.getProperty(properties[i]);
+ schema.setProperty(properties[i], state);
+ }
+ }
+
+
/**
* Extension of XMLGrammarPoolImpl which exposes the number of
* grammars stored in the grammar pool.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java
index bc4bdefb413..241d02cbf85 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java
@@ -123,6 +123,12 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin
private static final String LOCALE =
Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY;
+ /** property identifier: access external dtd. */
+ private static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+ /** Property identifier: access to external schema */
+ private static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
//
// Data
//
@@ -243,6 +249,9 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin
}
fComponents.put(SECURITY_MANAGER, fInitSecurityManager);
+ //pass on properties set on SchemaFactory
+ setProperty(ACCESS_EXTERNAL_DTD, grammarContainer.getProperty(ACCESS_EXTERNAL_DTD));
+ setProperty(ACCESS_EXTERNAL_SCHEMA, grammarContainer.getProperty(ACCESS_EXTERNAL_SCHEMA));
}
/**
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XSGrammarPoolContainer.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XSGrammarPoolContainer.java
index 0246f37380c..79ef5593b06 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XSGrammarPoolContainer.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XSGrammarPoolContainer.java
@@ -55,4 +55,21 @@ public interface XSGrammarPoolContainer {
*/
public Boolean getFeature(String featureId);
+ /*
+ * Set a feature on the schema
+ */
+ public void setFeature(String featureId, boolean state);
+
+ /**
+ * Returns the initial value of a property for validators created
+ * using this grammar pool container or null if the validators
+ * should use the default value.
+ */
+ public Object getProperty(String propertyId);
+
+ /*
+ * Set a property on the schema
+ */
+ public void setProperty(String propertyId, Object state);
+
}
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java
index 72acd0a20f8..32ac6a86d78 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java
@@ -20,10 +20,13 @@
package com.sun.org.apache.xerces.internal.parsers;
+import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
+import java.util.Properties;
+import javax.xml.XMLConstants;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.XML11DTDScannerImpl;
@@ -52,6 +55,7 @@ import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings;
import com.sun.org.apache.xerces.internal.util.PropertyState;
import com.sun.org.apache.xerces.internal.util.Status;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
@@ -274,6 +278,12 @@ public class XML11Configuration extends ParserConfigurationSettings
protected static final String SCHEMA_DV_FACTORY =
Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY;
+ /** Property identifier: access to external dtd */
+ protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+ /** Property identifier: access to external schema */
+ protected static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
// debugging
/** Set to true and recompile to print exception stack trace. */
@@ -475,7 +485,8 @@ public class XML11Configuration extends ParserConfigurationSettings
XMLSCHEMA_VALIDATION, XMLSCHEMA_FULL_CHECKING,
EXTERNAL_GENERAL_ENTITIES,
EXTERNAL_PARAMETER_ENTITIES,
- PARSER_SETTINGS
+ PARSER_SETTINGS,
+ XMLConstants.FEATURE_SECURE_PROCESSING
};
addRecognizedFeatures(recognizedFeatures);
// set state for default features
@@ -488,30 +499,31 @@ public class XML11Configuration extends ParserConfigurationSettings
fFeatures.put(SCHEMA_ELEMENT_DEFAULT, Boolean.TRUE);
fFeatures.put(NORMALIZE_DATA, Boolean.TRUE);
fFeatures.put(SCHEMA_AUGMENT_PSVI, Boolean.TRUE);
- fFeatures.put(GENERATE_SYNTHETIC_ANNOTATIONS, Boolean.FALSE);
- fFeatures.put(VALIDATE_ANNOTATIONS, Boolean.FALSE);
- fFeatures.put(HONOUR_ALL_SCHEMALOCATIONS, Boolean.FALSE);
- fFeatures.put(NAMESPACE_GROWTH, Boolean.FALSE);
- fFeatures.put(TOLERATE_DUPLICATES, Boolean.FALSE);
- fFeatures.put(USE_GRAMMAR_POOL_ONLY, Boolean.FALSE);
+ fFeatures.put(GENERATE_SYNTHETIC_ANNOTATIONS, Boolean.FALSE);
+ fFeatures.put(VALIDATE_ANNOTATIONS, Boolean.FALSE);
+ fFeatures.put(HONOUR_ALL_SCHEMALOCATIONS, Boolean.FALSE);
+ fFeatures.put(NAMESPACE_GROWTH, Boolean.FALSE);
+ fFeatures.put(TOLERATE_DUPLICATES, Boolean.FALSE);
+ fFeatures.put(USE_GRAMMAR_POOL_ONLY, Boolean.FALSE);
fFeatures.put(PARSER_SETTINGS, Boolean.TRUE);
+ fFeatures.put(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
// add default recognized properties
final String[] recognizedProperties =
{
- SYMBOL_TABLE,
- ERROR_HANDLER,
- ENTITY_RESOLVER,
+ SYMBOL_TABLE,
+ ERROR_HANDLER,
+ ENTITY_RESOLVER,
ERROR_REPORTER,
ENTITY_MANAGER,
DOCUMENT_SCANNER,
DTD_SCANNER,
DTD_PROCESSOR,
DTD_VALIDATOR,
- DATATYPE_VALIDATOR_FACTORY,
- VALIDATION_MANAGER,
- SCHEMA_VALIDATOR,
- XML_STRING,
+ DATATYPE_VALIDATOR_FACTORY,
+ VALIDATION_MANAGER,
+ SCHEMA_VALIDATOR,
+ XML_STRING,
XMLGRAMMAR_POOL,
JAXP_SCHEMA_SOURCE,
JAXP_SCHEMA_LANGUAGE,
@@ -523,18 +535,20 @@ public class XML11Configuration extends ParserConfigurationSettings
SCHEMA_NONS_LOCATION,
LOCALE,
SCHEMA_DV_FACTORY,
+ ACCESS_EXTERNAL_DTD,
+ ACCESS_EXTERNAL_SCHEMA
};
addRecognizedProperties(recognizedProperties);
- if (symbolTable == null) {
- symbolTable = new SymbolTable();
- }
- fSymbolTable = symbolTable;
- fProperties.put(SYMBOL_TABLE, fSymbolTable);
+ if (symbolTable == null) {
+ symbolTable = new SymbolTable();
+ }
+ fSymbolTable = symbolTable;
+ fProperties.put(SYMBOL_TABLE, fSymbolTable);
fGrammarPool = grammarPool;
if (fGrammarPool != null) {
- fProperties.put(XMLGRAMMAR_POOL, fGrammarPool);
+ fProperties.put(XMLGRAMMAR_POOL, fGrammarPool);
}
fEntityManager = new XMLEntityManager();
@@ -570,6 +584,15 @@ public class XML11Configuration extends ParserConfigurationSettings
fVersionDetector = new XMLVersionDetector();
+ //FEATURE_SECURE_PROCESSING is true, see the feature above
+ String accessExternal = SecuritySupport.getDefaultAccessProperty(
+ Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT);
+ fProperties.put(ACCESS_EXTERNAL_DTD, accessExternal);
+
+ accessExternal = SecuritySupport.getDefaultAccessProperty(
+ Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT);
+ fProperties.put(ACCESS_EXTERNAL_SCHEMA, accessExternal);
+
// add message formatters
if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
XMLMessageFormatter xmft = new XMLMessageFormatter();
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/util/URI.java b/jaxp/src/com/sun/org/apache/xerces/internal/util/URI.java
index 0f35b8ec665..e420f2616b6 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/util/URI.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/util/URI.java
@@ -22,6 +22,7 @@ package com.sun.org.apache.xerces.internal.util;
import java.io.IOException;
import java.io.Serializable;
+import java.util.Objects;
/**********************************************************************
* A class to represent a Uniform Resource Identifier (URI). This class
@@ -1212,7 +1213,7 @@ import java.io.Serializable;
* @return the scheme-specific part for this URI
*/
public String getSchemeSpecificPart() {
- StringBuffer schemespec = new StringBuffer();
+ final StringBuilder schemespec = new StringBuilder();
if (m_host != null || m_regAuthority != null) {
schemespec.append("//");
@@ -1297,7 +1298,7 @@ import java.io.Serializable;
* @return the authority
*/
public String getAuthority() {
- StringBuffer authority = new StringBuffer();
+ final StringBuilder authority = new StringBuilder();
if (m_host != null || m_regAuthority != null) {
authority.append("//");
@@ -1340,7 +1341,7 @@ import java.io.Serializable;
*/
public String getPath(boolean p_includeQueryString,
boolean p_includeFragment) {
- StringBuffer pathString = new StringBuffer(m_path);
+ final StringBuilder pathString = new StringBuilder(m_path);
if (p_includeQueryString && m_queryString != null) {
pathString.append('?');
@@ -1683,6 +1684,7 @@ import java.io.Serializable;
* @return true if p_test is a URI with all values equal to this
* URI, false otherwise
*/
+ @Override
public boolean equals(Object p_test) {
if (p_test instanceof URI) {
URI testURI = (URI) p_test;
@@ -1711,13 +1713,27 @@ import java.io.Serializable;
return false;
}
+ @Override
+ public int hashCode() {
+ int hash = 5;
+ hash = 47 * hash + Objects.hashCode(this.m_scheme);
+ hash = 47 * hash + Objects.hashCode(this.m_userinfo);
+ hash = 47 * hash + Objects.hashCode(this.m_host);
+ hash = 47 * hash + this.m_port;
+ hash = 47 * hash + Objects.hashCode(this.m_path);
+ hash = 47 * hash + Objects.hashCode(this.m_queryString);
+ hash = 47 * hash + Objects.hashCode(this.m_fragment);
+ return hash;
+ }
+
/**
* Get the URI as a string specification. See RFC 2396 Section 5.2.
*
* @return the URI string specification
*/
+ @Override
public String toString() {
- StringBuffer uriSpecString = new StringBuffer();
+ final StringBuilder uriSpecString = new StringBuilder();
if (m_scheme != null) {
uriSpecString.append(m_scheme);
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java
index b1d9d870412..7b6d1d553d8 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java
@@ -23,14 +23,16 @@ package com.sun.org.apache.xerces.internal.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.io.InputStream;
-
+import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Locale;
import java.util.MissingResourceException;
+import java.util.Properties;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
@@ -195,5 +197,141 @@ public final class SecuritySupport {
})).longValue();
}
+ /**
+ * Strip off path from an URI
+ *
+ * @param uri an URI with full path
+ * @return the file name only
+ */
+ public static String sanitizePath(String uri) {
+ if (uri == null) {
+ return "";
+ }
+ int i = uri.lastIndexOf("/");
+ if (i > 0) {
+ return uri.substring(i+1, uri.length());
+ }
+ return "";
+ }
+
+ /**
+ * Check the protocol used in the systemId against allowed protocols
+ *
+ * @param systemId the Id of the URI
+ * @param allowedProtocols a list of allowed protocols separated by comma
+ * @param accessAny keyword to indicate allowing any protocol
+ * @return the name of the protocol if rejected, null otherwise
+ */
+ public static String checkAccess(String systemId, String allowedProtocols, String accessAny) throws IOException {
+ if (systemId == null || allowedProtocols.equalsIgnoreCase(accessAny)) {
+ return null;
+ }
+
+ String protocol;
+ if (systemId.indexOf(":")==-1) {
+ protocol = "file";
+ } else {
+ URL url = new URL(systemId);
+ protocol = url.getProtocol();
+ if (protocol.equalsIgnoreCase("jar")) {
+ String path = url.getPath();
+ protocol = path.substring(0, path.indexOf(":"));
+ }
+ }
+
+ if (isProtocolAllowed(protocol, allowedProtocols)) {
+ //access allowed
+ return null;
+ } else {
+ return protocol;
+ }
+ }
+
+ /**
+ * Check if the protocol is in the allowed list of protocols. The check
+ * is case-insensitive while ignoring whitespaces.
+ *
+ * @param protocol a protocol
+ * @param allowedProtocols a list of allowed protocols
+ * @return true if the protocol is in the list
+ */
+ private static boolean isProtocolAllowed(String protocol, String allowedProtocols) {
+ String temp[] = allowedProtocols.split(",");
+ for (String t : temp) {
+ t = t.trim();
+ if (t.equalsIgnoreCase(protocol)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Read from $java.home/lib/jaxp.properties for the specified property
+ *
+ * @param propertyId the Id of the property
+ * @return the value of the property
+ */
+ public static String getDefaultAccessProperty(String sysPropertyId, String defaultVal) {
+ String accessExternal = SecuritySupport.getSystemProperty(sysPropertyId);
+ if (accessExternal == null) {
+ accessExternal = readJAXPProperty(sysPropertyId);
+ if (accessExternal == null) {
+ accessExternal = defaultVal;
+ }
+ }
+ return accessExternal;
+ }
+
+ /**
+ * Read from $java.home/lib/jaxp.properties for the specified property
+ * The program
+ *
+ * @param propertyId the Id of the property
+ * @return the value of the property
+ */
+ static String readJAXPProperty(String propertyId) {
+ String value = null;
+ InputStream is = null;
+ try {
+ if (firstTime) {
+ synchronized (cacheProps) {
+ if (firstTime) {
+ String configFile = getSystemProperty("java.home") + File.separator +
+ "lib" + File.separator + "jaxp.properties";
+ File f = new File(configFile);
+ if (getFileExists(f)) {
+ is = getFileInputStream(f);
+ cacheProps.load(is);
+ }
+ firstTime = false;
+ }
+ }
+ }
+ value = cacheProps.getProperty(propertyId);
+
+ }
+ catch (Exception ex) {}
+ finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ex) {}
+ }
+ }
+
+ return value;
+ }
+
+ /**
+ * Cache for properties in java.home/lib/jaxp.properties
+ */
+ static final Properties cacheProps = new Properties();
+
+ /**
+ * Flag indicating if the program has tried reading java.home/lib/jaxp.properties
+ */
+ static volatile boolean firstTime = true;
+
private SecuritySupport () {}
}
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java b/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java
index 347ae24e446..ba7284609e1 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java
@@ -26,6 +26,7 @@ import java.util.Enumeration;
import java.util.Locale;
import java.util.Stack;
import java.util.StringTokenizer;
+import javax.xml.XMLConstants;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
@@ -67,6 +68,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
import com.sun.org.apache.xerces.internal.xpointer.XPointerHandler;
import com.sun.org.apache.xerces.internal.xpointer.XPointerProcessor;
import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
+import java.util.Objects;
/**
*
@@ -229,6 +231,14 @@ public class XIncludeHandler
protected static final String PARSER_SETTINGS =
Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS;
+ /** property identifier: access external dtd. */
+ protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+ /** access external dtd: file protocol
+ * For DOM/SAX, the secure feature is set to true by default
+ */
+ final static String EXTERNAL_ACCESS_DEFAULT = Constants.EXTERNAL_ACCESS_DEFAULT;
+
/** Recognized features. */
private static final String[] RECOGNIZED_FEATURES =
{ ALLOW_UE_AND_NOTATION_EVENTS, XINCLUDE_FIXUP_BASE_URIS, XINCLUDE_FIXUP_LANGUAGE };
@@ -283,6 +293,12 @@ public class XIncludeHandler
protected XMLErrorReporter fErrorReporter;
protected XMLEntityResolver fEntityResolver;
protected SecurityManager fSecurityManager;
+ /**
+ * comma-delimited list of protocols that are allowed for the purpose
+ * of accessing external dtd or entity references
+ */
+ protected String fAccessExternalDTD = EXTERNAL_ACCESS_DEFAULT;
+
// these are needed for text include processing
protected XIncludeTextReader fXInclude10TextReader;
@@ -375,6 +391,7 @@ public class XIncludeHandler
// XMLComponent methods
+ @Override
public void reset(XMLComponentManager componentManager)
throws XNIException {
fNamespaceContext = null;
@@ -523,6 +540,8 @@ public class XIncludeHandler
fSecurityManager = null;
}
+ fAccessExternalDTD = (String)componentManager.getProperty(ACCESS_EXTERNAL_DTD);
+
// Get buffer size.
try {
Integer value =
@@ -580,6 +599,7 @@ public class XIncludeHandler
* this component. This method may return null if no features
* are recognized by this component.
*/
+ @Override
public String[] getRecognizedFeatures() {
return (String[])(RECOGNIZED_FEATURES.clone());
} // getRecognizedFeatures():String[]
@@ -599,6 +619,7 @@ public class XIncludeHandler
* @throws SAXNotSupportedException The component should not throw
* this exception.
*/
+ @Override
public void setFeature(String featureId, boolean state)
throws XMLConfigurationException {
if (featureId.equals(ALLOW_UE_AND_NOTATION_EVENTS)) {
@@ -615,6 +636,7 @@ public class XIncludeHandler
* this component. This method may return null if no properties
* are recognized by this component.
*/
+ @Override
public String[] getRecognizedProperties() {
return (String[])(RECOGNIZED_PROPERTIES.clone());
} // getRecognizedProperties():String[]
@@ -634,6 +656,7 @@ public class XIncludeHandler
* @throws SAXNotSupportedException The component should not throw
* this exception.
*/
+ @Override
public void setProperty(String propertyId, Object value)
throws XMLConfigurationException {
if (propertyId.equals(SYMBOL_TABLE)) {
@@ -664,6 +687,14 @@ public class XIncludeHandler
}
return;
}
+ if (propertyId.equals(ACCESS_EXTERNAL_DTD)) {
+ fAccessExternalDTD = (String)value;
+ if (fChildConfig != null) {
+ fChildConfig.setProperty(propertyId, value);
+ }
+ return;
+ }
+
if (propertyId.equals(BUFFER_SIZE)) {
Integer bufferSize = (Integer) value;
if (fChildConfig != null) {
@@ -694,6 +725,7 @@ public class XIncludeHandler
*
* @since Xerces 2.2.0
*/
+ @Override
public Boolean getFeatureDefault(String featureId) {
for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
if (RECOGNIZED_FEATURES[i].equals(featureId)) {
@@ -712,6 +744,7 @@ public class XIncludeHandler
*
* @since Xerces 2.2.0
*/
+ @Override
public Object getPropertyDefault(String propertyId) {
for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
@@ -721,10 +754,12 @@ public class XIncludeHandler
return null;
} // getPropertyDefault(String):Object
+ @Override
public void setDocumentHandler(XMLDocumentHandler handler) {
fDocumentHandler = handler;
}
+ @Override
public XMLDocumentHandler getDocumentHandler() {
return fDocumentHandler;
}
@@ -739,6 +774,7 @@ public class XIncludeHandler
*
* This event is only passed on to the document handler if this is the root document.
*/
+ @Override
public void startDocument(
XMLLocator locator,
String encoding,
@@ -786,6 +822,7 @@ public class XIncludeHandler
}
}
+ @Override
public void xmlDecl(
String version,
String encoding,
@@ -798,6 +835,7 @@ public class XIncludeHandler
}
}
+ @Override
public void doctypeDecl(
String rootElement,
String publicId,
@@ -809,6 +847,7 @@ public class XIncludeHandler
}
}
+ @Override
public void comment(XMLString text, Augmentations augs)
throws XNIException {
if (!fInDTD) {
@@ -825,6 +864,7 @@ public class XIncludeHandler
}
}
+ @Override
public void processingInstruction(
String target,
XMLString data,
@@ -845,6 +885,7 @@ public class XIncludeHandler
}
}
+ @Override
public void startElement(
QName element,
XMLAttributes attributes,
@@ -915,6 +956,7 @@ public class XIncludeHandler
}
}
+ @Override
public void emptyElement(
QName element,
XMLAttributes attributes,
@@ -996,6 +1038,7 @@ public class XIncludeHandler
fDepth--;
}
+ @Override
public void endElement(QName element, Augmentations augs)
throws XNIException {
@@ -1041,6 +1084,7 @@ public class XIncludeHandler
fDepth--;
}
+ @Override
public void startGeneralEntity(
String name,
XMLResourceIdentifier resId,
@@ -1059,6 +1103,7 @@ public class XIncludeHandler
}
}
+ @Override
public void textDecl(String version, String encoding, Augmentations augs)
throws XNIException {
if (fDocumentHandler != null
@@ -1067,6 +1112,7 @@ public class XIncludeHandler
}
}
+ @Override
public void endGeneralEntity(String name, Augmentations augs)
throws XNIException {
if (fDocumentHandler != null
@@ -1076,6 +1122,7 @@ public class XIncludeHandler
}
}
+ @Override
public void characters(XMLString text, Augmentations augs)
throws XNIException {
if (getState() == STATE_NORMAL_PROCESSING) {
@@ -1092,6 +1139,7 @@ public class XIncludeHandler
}
}
+ @Override
public void ignorableWhitespace(XMLString text, Augmentations augs)
throws XNIException {
if (fDocumentHandler != null
@@ -1101,6 +1149,7 @@ public class XIncludeHandler
}
}
+ @Override
public void startCDATA(Augmentations augs) throws XNIException {
if (fDocumentHandler != null
&& getState() == STATE_NORMAL_PROCESSING
@@ -1109,6 +1158,7 @@ public class XIncludeHandler
}
}
+ @Override
public void endCDATA(Augmentations augs) throws XNIException {
if (fDocumentHandler != null
&& getState() == STATE_NORMAL_PROCESSING
@@ -1117,6 +1167,7 @@ public class XIncludeHandler
}
}
+ @Override
public void endDocument(Augmentations augs) throws XNIException {
if (isRootDocument()) {
if (!fSeenRootElement) {
@@ -1128,10 +1179,12 @@ public class XIncludeHandler
}
}
+ @Override
public void setDocumentSource(XMLDocumentSource source) {
fDocumentSource = source;
}
+ @Override
public XMLDocumentSource getDocumentSource() {
return fDocumentSource;
}
@@ -1143,6 +1196,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#attributeDecl(java.lang.String, java.lang.String, java.lang.String, java.lang.String[], java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void attributeDecl(
String elementName,
String attributeName,
@@ -1169,6 +1223,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#elementDecl(java.lang.String, java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void elementDecl(
String name,
String contentModel,
@@ -1182,6 +1237,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endAttlist(com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void endAttlist(Augmentations augmentations) throws XNIException {
if (fDTDHandler != null) {
fDTDHandler.endAttlist(augmentations);
@@ -1191,6 +1247,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endConditional(com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void endConditional(Augmentations augmentations)
throws XNIException {
if (fDTDHandler != null) {
@@ -1201,6 +1258,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endDTD(com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void endDTD(Augmentations augmentations) throws XNIException {
if (fDTDHandler != null) {
fDTDHandler.endDTD(augmentations);
@@ -1211,6 +1269,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endExternalSubset(com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void endExternalSubset(Augmentations augmentations)
throws XNIException {
if (fDTDHandler != null) {
@@ -1221,6 +1280,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endParameterEntity(java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void endParameterEntity(String name, Augmentations augmentations)
throws XNIException {
if (fDTDHandler != null) {
@@ -1231,6 +1291,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#externalEntityDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void externalEntityDecl(
String name,
XMLResourceIdentifier identifier,
@@ -1244,6 +1305,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#getDTDSource()
*/
+ @Override
public XMLDTDSource getDTDSource() {
return fDTDSource;
}
@@ -1251,6 +1313,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#ignoredCharacters(com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void ignoredCharacters(XMLString text, Augmentations augmentations)
throws XNIException {
if (fDTDHandler != null) {
@@ -1261,6 +1324,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#internalEntityDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void internalEntityDecl(
String name,
XMLString text,
@@ -1279,6 +1343,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#notationDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void notationDecl(
String name,
XMLResourceIdentifier identifier,
@@ -1293,6 +1358,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#setDTDSource(com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource)
*/
+ @Override
public void setDTDSource(XMLDTDSource source) {
fDTDSource = source;
}
@@ -1300,6 +1366,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startAttlist(java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void startAttlist(String elementName, Augmentations augmentations)
throws XNIException {
if (fDTDHandler != null) {
@@ -1310,6 +1377,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startConditional(short, com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void startConditional(short type, Augmentations augmentations)
throws XNIException {
if (fDTDHandler != null) {
@@ -1320,6 +1388,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startDTD(com.sun.org.apache.xerces.internal.xni.XMLLocator, com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void startDTD(XMLLocator locator, Augmentations augmentations)
throws XNIException {
fInDTD = true;
@@ -1331,6 +1400,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startExternalSubset(com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void startExternalSubset(
XMLResourceIdentifier identifier,
Augmentations augmentations)
@@ -1343,6 +1413,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startParameterEntity(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void startParameterEntity(
String name,
XMLResourceIdentifier identifier,
@@ -1361,6 +1432,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#unparsedEntityDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
*/
+ @Override
public void unparsedEntityDecl(
String name,
XMLResourceIdentifier identifier,
@@ -1380,6 +1452,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource#getDTDHandler()
*/
+ @Override
public XMLDTDHandler getDTDHandler() {
return fDTDHandler;
}
@@ -1387,6 +1460,7 @@ public class XIncludeHandler
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource#setDTDHandler(com.sun.org.apache.xerces.internal.xni.XMLDTDHandler)
*/
+ @Override
public void setDTDHandler(XMLDTDHandler handler) {
fDTDHandler = handler;
}
@@ -1578,6 +1652,7 @@ public class XIncludeHandler
if (fErrorReporter != null) fChildConfig.setProperty(ERROR_REPORTER, fErrorReporter);
if (fEntityResolver != null) fChildConfig.setProperty(ENTITY_RESOLVER, fEntityResolver);
fChildConfig.setProperty(SECURITY_MANAGER, fSecurityManager);
+ fChildConfig.setProperty(ACCESS_EXTERNAL_DTD, fAccessExternalDTD);
fChildConfig.setProperty(BUFFER_SIZE, new Integer(fBufferSize));
// features must be copied to child configuration
@@ -1615,11 +1690,10 @@ public class XIncludeHandler
fNamespaceContext);
((XPointerHandler)fXPtrProcessor).setProperty(XINCLUDE_FIXUP_BASE_URIS,
- new Boolean(fFixupBaseURIs));
+ fFixupBaseURIs);
((XPointerHandler)fXPtrProcessor).setProperty(
- XINCLUDE_FIXUP_LANGUAGE,
- new Boolean (fFixupLanguage));
+ XINCLUDE_FIXUP_LANGUAGE, fFixupLanguage);
if (fErrorReporter != null)
((XPointerHandler)fXPtrProcessor).setProperty(ERROR_REPORTER, fErrorReporter);
@@ -1691,7 +1765,7 @@ public class XIncludeHandler
if (fErrorReporter != null) {
fErrorReporter.setDocumentLocator(fDocLocation);
}
- reportFatalError("XMLParseError", new Object[] { href });
+ reportFatalError("XMLParseError", new Object[] { href, e.getMessage() });
}
catch (IOException e) {
// necessary to make sure proper location is reported in errors
@@ -2093,14 +2167,14 @@ public class XIncludeHandler
/** Check whether the scheme components are equal. */
final String baseScheme = base.getScheme();
final String literalScheme = uri.getScheme();
- if (!isEqual(baseScheme, literalScheme)) {
+ if (!Objects.equals(baseScheme, literalScheme)) {
return relativeURI;
}
/** Check whether the authority components are equal. */
final String baseAuthority = base.getAuthority();
final String literalAuthority = uri.getAuthority();
- if (!isEqual(baseAuthority, literalAuthority)) {
+ if (!Objects.equals(baseAuthority, literalAuthority)) {
return uri.getSchemeSpecificPart();
}
@@ -2113,7 +2187,7 @@ public class XIncludeHandler
final String literalQuery = uri.getQueryString();
final String literalFragment = uri.getFragment();
if (literalQuery != null || literalFragment != null) {
- StringBuffer buffer = new StringBuffer();
+ final StringBuilder buffer = new StringBuilder();
if (literalPath != null) {
buffer.append(literalPath);
}
@@ -2624,15 +2698,15 @@ public class XIncludeHandler
// equals() returns true if two Notations have the same name.
// Useful for searching Vectors for notations with the same name
+ @Override
public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (obj instanceof Notation) {
- Notation other = (Notation)obj;
- return name.equals(other.name);
- }
- return false;
+ return obj == this || obj instanceof Notation
+ && Objects.equals(name, ((Notation)obj).name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(name);
}
// from 4.5.2
@@ -2645,16 +2719,12 @@ public class XIncludeHandler
public boolean isDuplicate(Object obj) {
if (obj != null && obj instanceof Notation) {
Notation other = (Notation)obj;
- return name.equals(other.name)
- && isEqual(publicId, other.publicId)
- && isEqual(expandedSystemId, other.expandedSystemId);
+ return Objects.equals(name, other.name)
+ && Objects.equals(publicId, other.publicId)
+ && Objects.equals(expandedSystemId, other.expandedSystemId);
}
return false;
}
-
- private boolean isEqual(String one, String two) {
- return (one == two || (one != null && one.equals(two)));
- }
}
// This is a storage class to hold information about the unparsed entities.
@@ -2670,15 +2740,15 @@ public class XIncludeHandler
// equals() returns true if two UnparsedEntities have the same name.
// Useful for searching Vectors for entities with the same name
+ @Override
public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (obj instanceof UnparsedEntity) {
- UnparsedEntity other = (UnparsedEntity)obj;
- return name.equals(other.name);
- }
- return false;
+ return obj == this || obj instanceof UnparsedEntity
+ && Objects.equals(name, ((UnparsedEntity)obj).name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(name);
}
// from 4.5.1:
@@ -2691,17 +2761,13 @@ public class XIncludeHandler
public boolean isDuplicate(Object obj) {
if (obj != null && obj instanceof UnparsedEntity) {
UnparsedEntity other = (UnparsedEntity)obj;
- return name.equals(other.name)
- && isEqual(publicId, other.publicId)
- && isEqual(expandedSystemId, other.expandedSystemId)
- && isEqual(notation, other.notation);
+ return Objects.equals(name, other.name)
+ && Objects.equals(publicId, other.publicId)
+ && Objects.equals(expandedSystemId, other.expandedSystemId)
+ && Objects.equals(notation, other.notation);
}
return false;
}
-
- private boolean isEqual(String one, String two) {
- return (one == two || (one != null && one.equals(two)));
- }
}
// The following methods are used for XML Base processing
@@ -2891,17 +2957,13 @@ public class XIncludeHandler
return httpSource;
}
- private boolean isEqual(String one, String two) {
- return (one == two || (one != null && one.equals(two)));
- }
-
// which ASCII characters need to be escaped
- private static boolean gNeedEscaping[] = new boolean[128];
+ private static final boolean gNeedEscaping[] = new boolean[128];
// the first hex character if a character needs to be escaped
- private static char gAfterEscaping1[] = new char[128];
+ private static final char gAfterEscaping1[] = new char[128];
// the second hex character if a character needs to be escaped
- private static char gAfterEscaping2[] = new char[128];
- private static char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
+ private static final char gAfterEscaping2[] = new char[128];
+ private static final char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
// initialize the above 3 arrays
static {
@@ -2931,7 +2993,7 @@ public class XIncludeHandler
private String escapeHref(String href) {
int len = href.length();
int ch;
- StringBuffer buffer = new StringBuffer(len*3);
+ final StringBuilder buffer = new StringBuilder(len*3);
// for each character in the href
int i = 0;
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/dtm/ref/DTMNodeProxy.java b/jaxp/src/com/sun/org/apache/xml/internal/dtm/ref/DTMNodeProxy.java
index fa86b06fc3e..d9ca5b010f5 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/dtm/ref/DTMNodeProxy.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/dtm/ref/DTMNodeProxy.java
@@ -27,6 +27,7 @@ import java.util.Vector;
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xml.internal.dtm.DTMDOMException;
import com.sun.org.apache.xpath.internal.NodeSet;
+import java.util.Objects;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
@@ -141,21 +142,21 @@ public class DTMNodeProxy
*
* @return true if the given node has the same handle as this node.
*/
+ @Override
public final boolean equals(Object node)
{
-
- try
- {
-
// DTMNodeProxy dtmp = (DTMNodeProxy)node;
// return (dtmp.node == this.node);
// Patch attributed to Gary L Peskin
- return equals((Node) node);
- }
- catch (ClassCastException cce)
- {
- return false;
- }
+ return node instanceof Node && equals((Node) node);
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 29 * hash + Objects.hashCode(this.dtm);
+ hash = 29 * hash + this.node;
+ return hash;
}
/**
@@ -181,6 +182,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Node
*/
+ @Override
public final String getNodeName()
{
return dtm.getNodeName(node);
@@ -199,6 +201,7 @@ public class DTMNodeProxy
*
*
*/
+ @Override
public final String getTarget()
{
return dtm.getNodeName(node);
@@ -209,6 +212,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Node as of DOM Level 2
*/
+ @Override
public final String getLocalName()
{
return dtm.getLocalName(node);
@@ -218,6 +222,7 @@ public class DTMNodeProxy
* @return The prefix for this node.
* @see org.w3c.dom.Node as of DOM Level 2
*/
+ @Override
public final String getPrefix()
{
return dtm.getPrefix(node);
@@ -230,6 +235,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Node as of DOM Level 2 -- DTMNodeProxy is read-only
*/
+ @Override
public final void setPrefix(String prefix) throws DOMException
{
throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
@@ -240,6 +246,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Node as of DOM Level 2
*/
+ @Override
public final String getNamespaceURI()
{
return dtm.getNamespaceURI(node);
@@ -277,6 +284,7 @@ public class DTMNodeProxy
* @return false
* @see org.w3c.dom.Node as of DOM Level 2
*/
+ @Override
public final boolean isSupported(String feature, String version)
{
return implementation.hasFeature(feature,version);
@@ -290,6 +298,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Node
*/
+ @Override
public final String getNodeValue() throws DOMException
{
return dtm.getNodeValue(node);
@@ -312,6 +321,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Node -- DTMNodeProxy is read-only
*/
+ @Override
public final void setNodeValue(String nodeValue) throws DOMException
{
throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
@@ -322,6 +332,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Node
*/
+ @Override
public final short getNodeType()
{
return (short) dtm.getNodeType(node);
@@ -332,6 +343,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Node
*/
+ @Override
public final Node getParentNode()
{
@@ -361,6 +373,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Node
*/
+ @Override
public final NodeList getChildNodes()
{
@@ -377,6 +390,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Node
*/
+ @Override
public final Node getFirstChild()
{
@@ -390,6 +404,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Node
*/
+ @Override
public final Node getLastChild()
{
@@ -403,6 +418,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Node
*/
+ @Override
public final Node getPreviousSibling()
{
@@ -416,6 +432,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Node
*/
+ @Override
public final Node getNextSibling()
{
@@ -435,6 +452,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Node
*/
+ @Override
public final NamedNodeMap getAttributes()
{
@@ -448,6 +466,7 @@ public class DTMNodeProxy
* @param name
*
*/
+ @Override
public boolean hasAttribute(String name)
{
return DTM.NULL != dtm.getAttributeNode(node,null,name);
@@ -462,6 +481,7 @@ public class DTMNodeProxy
*
*
*/
+ @Override
public boolean hasAttributeNS(String namespaceURI, String localName)
{
return DTM.NULL != dtm.getAttributeNode(node,namespaceURI,localName);
@@ -472,6 +492,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Node
*/
+ @Override
public final Document getOwnerDocument()
{
// Note that this uses the DOM-compatable version of the call
@@ -488,6 +509,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Node -- DTMNodeProxy is read-only
*/
+ @Override
public final Node insertBefore(Node newChild, Node refChild)
throws DOMException
{
@@ -504,6 +526,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Node -- DTMNodeProxy is read-only
*/
+ @Override
public final Node replaceChild(Node newChild, Node oldChild)
throws DOMException
{
@@ -519,6 +542,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Node -- DTMNodeProxy is read-only
*/
+ @Override
public final Node removeChild(Node oldChild) throws DOMException
{
throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
@@ -533,6 +557,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Node -- DTMNodeProxy is read-only
*/
+ @Override
public final Node appendChild(Node newChild) throws DOMException
{
throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
@@ -543,6 +568,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Node
*/
+ @Override
public final boolean hasChildNodes()
{
return (DTM.NULL != dtm.getFirstChild(node));
@@ -555,6 +581,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Node -- DTMNodeProxy is read-only
*/
+ @Override
public final Node cloneNode(boolean deep)
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -565,6 +592,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Document
*/
+ @Override
public final DocumentType getDoctype()
{
return null;
@@ -575,6 +603,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Document
*/
+ @Override
public final DOMImplementation getImplementation()
{
return implementation;
@@ -587,6 +616,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Document
*/
+ @Override
public final Element getDocumentElement()
{
int dochandle=dtm.getDocument();
@@ -634,6 +664,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Document
*/
+ @Override
public final Element createElement(String tagName) throws DOMException
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -644,6 +675,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Document
*/
+ @Override
public final DocumentFragment createDocumentFragment()
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -656,6 +688,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Document
*/
+ @Override
public final Text createTextNode(String data)
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -668,6 +701,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Document
*/
+ @Override
public final Comment createComment(String data)
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -682,6 +716,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Document
*/
+ @Override
public final CDATASection createCDATASection(String data)
throws DOMException
{
@@ -698,8 +733,9 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Document
*/
+ @Override
public final ProcessingInstruction createProcessingInstruction(
- String target, String data) throws DOMException
+ String target, String data) throws DOMException
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
}
@@ -713,6 +749,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Document
*/
+ @Override
public final Attr createAttribute(String name) throws DOMException
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -727,6 +764,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Document
*/
+ @Override
public final EntityReference createEntityReference(String name)
throws DOMException
{
@@ -739,6 +777,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Document
*/
+ @Override
public final NodeList getElementsByTagName(String tagname)
{
Vector listVector = new Vector();
@@ -819,6 +858,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Document as of DOM Level 2 -- DTMNodeProxy is read-only
*/
+ @Override
public final Node importNode(Node importedNode, boolean deep)
throws DOMException
{
@@ -835,8 +875,9 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Document as of DOM Level 2
*/
+ @Override
public final Element createElementNS(
- String namespaceURI, String qualifiedName) throws DOMException
+ String namespaceURI, String qualifiedName) throws DOMException
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
}
@@ -851,8 +892,9 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Document as of DOM Level 2
*/
+ @Override
public final Attr createAttributeNS(
- String namespaceURI, String qualifiedName) throws DOMException
+ String namespaceURI, String qualifiedName) throws DOMException
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
}
@@ -865,6 +907,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Document as of DOM Level 2
*/
+ @Override
public final NodeList getElementsByTagNameNS(String namespaceURI,
String localName)
{
@@ -952,6 +995,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Document as of DOM Level 2
*/
+ @Override
public final Element getElementById(String elementId)
{
return (Element) dtm.getNode(dtm.getElementById(elementId));
@@ -966,6 +1010,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Text
*/
+ @Override
public final Text splitText(int offset) throws DOMException
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -978,6 +1023,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.CharacterData
*/
+ @Override
public final String getData() throws DOMException
{
return dtm.getNodeValue(node);
@@ -990,6 +1036,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.CharacterData
*/
+ @Override
public final void setData(String data) throws DOMException
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1000,6 +1047,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.CharacterData
*/
+ @Override
public final int getLength()
{
// %OPT% This should do something smarter?
@@ -1016,6 +1064,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.CharacterData
*/
+ @Override
public final String substringData(int offset, int count) throws DOMException
{
return getData().substring(offset,offset+count);
@@ -1028,6 +1077,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.CharacterData
*/
+ @Override
public final void appendData(String arg) throws DOMException
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1041,6 +1091,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.CharacterData
*/
+ @Override
public final void insertData(int offset, String arg) throws DOMException
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1054,6 +1105,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.CharacterData
*/
+ @Override
public final void deleteData(int offset, int count) throws DOMException
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1068,6 +1120,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.CharacterData
*/
+ @Override
public final void replaceData(int offset, int count, String arg)
throws DOMException
{
@@ -1079,6 +1132,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Element
*/
+ @Override
public final String getTagName()
{
return dtm.getNodeName(node);
@@ -1091,12 +1145,13 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Element
*/
+ @Override
public final String getAttribute(String name)
{
-
DTMNamedNodeMap map = new DTMNamedNodeMap(dtm, node);
- Node node = map.getNamedItem(name);
- return (null == node) ? EMPTYSTRING : node.getNodeValue(); }
+ Node n = map.getNamedItem(name);
+ return (null == n) ? EMPTYSTRING : n.getNodeValue();
+ }
/**
*
@@ -1106,6 +1161,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Element
*/
+ @Override
public final void setAttribute(String name, String value)
throws DOMException
{
@@ -1119,6 +1175,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Element
*/
+ @Override
public final void removeAttribute(String name) throws DOMException
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1131,9 +1188,9 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Element
*/
+ @Override
public final Attr getAttributeNode(String name)
{
-
DTMNamedNodeMap map = new DTMNamedNodeMap(dtm, node);
return (Attr)map.getNamedItem(name);
}
@@ -1147,6 +1204,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Element
*/
+ @Override
public final Attr setAttributeNode(Attr newAttr) throws DOMException
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1161,6 +1219,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Element
*/
+ @Override
public final Attr removeAttributeNode(Attr oldAttr) throws DOMException
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1171,12 +1230,14 @@ public class DTMNodeProxy
*
*
*/
+ @Override
public boolean hasAttributes()
{
return DTM.NULL != dtm.getFirstAttribute(node);
}
/** @see org.w3c.dom.Element */
+ @Override
public final void normalize()
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1190,6 +1251,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Element
*/
+ @Override
public final String getAttributeNS(String namespaceURI, String localName)
{
Node retNode = null;
@@ -1208,6 +1270,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Element
*/
+ @Override
public final void setAttributeNS(
String namespaceURI, String qualifiedName, String value)
throws DOMException
@@ -1223,6 +1286,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Element
*/
+ @Override
public final void removeAttributeNS(String namespaceURI, String localName)
throws DOMException
{
@@ -1237,6 +1301,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Element
*/
+ @Override
public final Attr getAttributeNodeNS(String namespaceURI, String localName)
{
Attr retAttr = null;
@@ -1256,6 +1321,7 @@ public class DTMNodeProxy
* @throws DOMException
* @see org.w3c.dom.Element
*/
+ @Override
public final Attr setAttributeNodeNS(Attr newAttr) throws DOMException
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1266,6 +1332,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Attr
*/
+ @Override
public final String getName()
{
return dtm.getNodeName(node);
@@ -1276,6 +1343,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Attr
*/
+ @Override
public final boolean getSpecified()
{
// We really don't know which attributes might have come from the
@@ -1290,6 +1358,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Attr
*/
+ @Override
public final String getValue()
{
return dtm.getNodeValue(node);
@@ -1300,6 +1369,7 @@ public class DTMNodeProxy
* @param value
* @see org.w3c.dom.Attr
*/
+ @Override
public final void setValue(String value)
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1311,6 +1381,7 @@ public class DTMNodeProxy
*
* @see org.w3c.dom.Attr as of DOM Level 2
*/
+ @Override
public final Element getOwnerElement()
{
if (getNodeType() != Node.ATTRIBUTE_NODE)
@@ -1331,9 +1402,9 @@ public class DTMNodeProxy
*
* @throws DOMException
*/
+ @Override
public Node adoptNode(Node source) throws DOMException
{
-
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
}
@@ -1348,9 +1419,9 @@ public class DTMNodeProxy
*
* NEEDSDOC ($objectName$) @return
*/
+ @Override
public String getInputEncoding()
{
-
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
}
@@ -1383,7 +1454,6 @@ public class DTMNodeProxy
*/
public boolean getStandalone()
{
-
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
}
@@ -1418,9 +1488,9 @@ public class DTMNodeProxy
*
* NEEDSDOC ($objectName$) @return
*/
+ @Override
public boolean getStrictErrorChecking()
{
-
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
}
@@ -1439,6 +1509,7 @@ public class DTMNodeProxy
*
* NEEDSDOC @param strictErrorChecking
*/
+ @Override
public void setStrictErrorChecking(boolean strictErrorChecking)
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1457,7 +1528,6 @@ public class DTMNodeProxy
*/
public String getVersion()
{
-
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
}
@@ -1482,10 +1552,12 @@ public class DTMNodeProxy
*/
static class DTMNodeProxyImplementation implements DOMImplementation
{
+ @Override
public DocumentType createDocumentType(String qualifiedName,String publicId, String systemId)
{
throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
}
+ @Override
public Document createDocument(String namespaceURI,String qualfiedName,DocumentType doctype)
{
// Could create a DTM... but why, when it'd have to be permanantly empty?
@@ -1500,6 +1572,7 @@ public class DTMNodeProxy
* methods we can't support. I'm not sure which would be more useful
* to the caller.
*/
+ @Override
public boolean hasFeature(String feature,String version)
{
if( ("CORE".equals(feature.toUpperCase()) || "XML".equals(feature.toUpperCase()))
@@ -1530,6 +1603,7 @@ public class DTMNodeProxy
* childNodes, etc.
* @since DOM Level 3
*/
+ @Override
public Object getFeature(String feature, String version) {
// we don't have any alternate node, either this node does the job
// or we don't have anything that does
@@ -1542,6 +1616,7 @@ public class DTMNodeProxy
//RAMESH : Pending proper implementation of DOM Level 3
+ @Override
public Object setUserData(String key,
Object data,
UserDataHandler handler) {
@@ -1557,6 +1632,7 @@ public class DTMNodeProxy
* on this node, or null if there was none.
* @since DOM Level 3
*/
+ @Override
public Object getUserData(String key) {
return getOwnerDocument().getUserData( key);
}
@@ -1581,6 +1657,7 @@ public class DTMNodeProxy
* childNodes, etc.
* @since DOM Level 3
*/
+ @Override
public Object getFeature(String feature, String version) {
// we don't have any alternate node, either this node does the job
// or we don't have anything that does
@@ -1629,6 +1706,7 @@ public class DTMNodeProxy
* true otherwise false.
* @since DOM Level 3
*/
+ @Override
public boolean isEqualNode(Node arg) {
if (arg == this) {
return true;
@@ -1705,6 +1783,7 @@ public class DTMNodeProxy
* @return th URI for the namespace
* @since DOM Level 3
*/
+ @Override
public String lookupNamespaceURI(String specifiedPrefix) {
short type = this.getNodeType();
switch (type) {
@@ -1797,6 +1876,7 @@ public class DTMNodeProxy
* is the default namespace, false otherwise.
* @since DOM Level 3
*/
+ @Override
public boolean isDefaultNamespace(String namespaceURI){
/*
// REVISIT: remove casts when DOM L3 becomes REC.
@@ -1871,6 +1951,7 @@ public class DTMNodeProxy
* @param namespaceURI
* @return the prefix for the namespace
*/
+ @Override
public String lookupPrefix(String namespaceURI){
// REVISIT: When Namespaces 1.1 comes out this may not be true
@@ -1932,6 +2013,7 @@ public class DTMNodeProxy
* false otherwise.
* @since DOM Level 3
*/
+ @Override
public boolean isSameNode(Node other) {
// we do not use any wrapper so the answer is obvious
return this == other;
@@ -1980,8 +2062,9 @@ public class DTMNodeProxy
* DOMSTRING_SIZE_ERR: Raised when it would return more characters than
* fit in a DOMString variable on the implementation
* platform.
- * @since DOM Level 3
+ * @since DOM Level 3
*/
+ @Override
public void setTextContent(String textContent)
throws DOMException {
setNodeValue(textContent);
@@ -2031,6 +2114,7 @@ public class DTMNodeProxy
* platform.
* @since DOM Level 3
*/
+ @Override
public String getTextContent() throws DOMException {
return getNodeValue(); // overriden in some subclasses
}
@@ -2043,6 +2127,7 @@ public class DTMNodeProxy
* node.
* @since DOM Level 3
*/
+ @Override
public short compareDocumentPosition(Node other) throws DOMException {
return 0;
}
@@ -2071,14 +2156,16 @@ public class DTMNodeProxy
* Yes. (F2F 26 Sep 2001)
* @since DOM Level 3
*/
+ @Override
public String getBaseURI() {
return null;
}
- /**
+ /**
* DOM Level 3
* Renaming node
*/
+ @Override
public Node renameNode(Node n,
String namespaceURI,
String name)
@@ -2091,14 +2178,16 @@ public class DTMNodeProxy
* DOM Level 3
* Normalize document.
*/
+ @Override
public void normalizeDocument(){
}
/**
- * The configuration used when Document.normalizeDocument is
+ * The configuration used when Document.normalizeDocument is
* invoked.
* @since DOM Level 3
*/
+ @Override
public DOMConfiguration getDomConfig(){
return null;
}
@@ -2110,8 +2199,8 @@ public class DTMNodeProxy
/**
* DOM Level 3
*/
+ @Override
public void setDocumentURI(String documentURI){
-
fDocumentURI= documentURI;
}
@@ -2123,6 +2212,7 @@ public class DTMNodeProxy
* over this attribute.
* @since DOM Level 3
*/
+ @Override
public String getDocumentURI(){
return fDocumentURI;
}
@@ -2154,9 +2244,10 @@ public class DTMNodeProxy
actualEncoding = value;
}
- /**
+ /**
* DOM Level 3
*/
+ @Override
public Text replaceWholeText(String content)
throws DOMException{
/*
@@ -2210,6 +2301,7 @@ public class DTMNodeProxy
* nodes to this node, concatenated in document order.
* @since DOM Level 3
*/
+ @Override
public String getWholeText(){
/*
@@ -2235,13 +2327,11 @@ public class DTMNodeProxy
* Returns whether this text node contains whitespace in element content,
* often abusively called "ignorable whitespace".
*/
+ @Override
public boolean isElementContentWhitespace(){
return false;
}
-
-
-
/**
* NON-DOM: set the type of this attribute to be ID type.
*
@@ -2254,6 +2344,7 @@ public class DTMNodeProxy
/**
* DOM Level 3: register the given attribute node as an ID attribute
*/
+ @Override
public void setIdAttribute(String name, boolean makeId) {
//PENDING
}
@@ -2262,6 +2353,7 @@ public class DTMNodeProxy
/**
* DOM Level 3: register the given attribute node as an ID attribute
*/
+ @Override
public void setIdAttributeNode(Attr at, boolean makeId) {
//PENDING
}
@@ -2269,6 +2361,7 @@ public class DTMNodeProxy
/**
* DOM Level 3: register the given attribute node as an ID attribute
*/
+ @Override
public void setIdAttributeNS(String namespaceURI, String localName,
boolean makeId) {
//PENDING
@@ -2277,16 +2370,19 @@ public class DTMNodeProxy
* Method getSchemaTypeInfo.
* @return TypeInfo
*/
+ @Override
public TypeInfo getSchemaTypeInfo(){
return null; //PENDING
}
+ @Override
public boolean isId() {
return false; //PENDING
}
private String xmlEncoding;
+ @Override
public String getXmlEncoding( ) {
return xmlEncoding;
}
@@ -2295,23 +2391,25 @@ public class DTMNodeProxy
}
private boolean xmlStandalone;
+ @Override
public boolean getXmlStandalone() {
return xmlStandalone;
}
+ @Override
public void setXmlStandalone(boolean xmlStandalone) throws DOMException {
this.xmlStandalone = xmlStandalone;
}
private String xmlVersion;
+ @Override
public String getXmlVersion() {
return xmlVersion;
}
+ @Override
public void setXmlVersion(String xmlVersion) throws DOMException {
this.xmlVersion = xmlVersion;
}
-
-
}
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/serializer/Encodings.java b/jaxp/src/com/sun/org/apache/xml/internal/serializer/Encodings.java
index 35845697a32..d4d95ff8cf2 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/Encodings.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/Encodings.java
@@ -33,6 +33,14 @@ import java.util.Enumeration;
import java.util.HashMap;
import java.util.Properties;
import java.util.StringTokenizer;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Map.Entry;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
@@ -79,36 +87,17 @@ public final class Encodings extends Object
throws UnsupportedEncodingException
{
- for (int i = 0; i < _encodings.length; ++i)
- {
- if (_encodings[i].name.equalsIgnoreCase(encoding))
- {
- try
- {
- return new BufferedWriter(new OutputStreamWriter(
- output,
- _encodings[i].javaName));
- }
- catch (java.lang.IllegalArgumentException iae) // java 1.1.8
- {
- // keep trying
- }
- catch (UnsupportedEncodingException usee)
- {
-
- // keep trying
- }
+ final EncodingInfo ei = _encodingInfos.findEncoding(toUpperCaseFast(encoding));
+ if (ei != null) {
+ try {
+ return new BufferedWriter(new OutputStreamWriter(
+ output, ei.javaName));
+ } catch (UnsupportedEncodingException usee) {
+ // keep trying
}
}
- try
- {
- return new BufferedWriter(new OutputStreamWriter(output, encoding));
- }
- catch (java.lang.IllegalArgumentException iae) // java 1.1.8
- {
- throw new UnsupportedEncodingException(encoding);
- }
+ return new BufferedWriter(new OutputStreamWriter(output, encoding));
}
@@ -141,12 +130,24 @@ public final class Encodings extends Object
EncodingInfo ei;
String normalizedEncoding = toUpperCaseFast(encoding);
- ei = (EncodingInfo) _encodingTableKeyJava.get(normalizedEncoding);
- if (ei == null)
- ei = (EncodingInfo) _encodingTableKeyMime.get(normalizedEncoding);
+ ei = _encodingInfos.findEncoding(normalizedEncoding);
if (ei == null) {
// We shouldn't have to do this, but just in case.
- ei = new EncodingInfo(null,null);
+ try {
+ // This may happen if the caller tries to use
+ // an encoding that wasn't registered in the
+ // (java name)->(preferred mime name) mapping file.
+ // In that case we attempt to load the charset for the
+ // given encoding, and if that succeeds - we create a new
+ // EncodingInfo instance - assuming the canonical name
+ // of the charset can be used as the mime name.
+ final Charset c = Charset.forName(encoding);
+ final String name = c.name();
+ ei = new EncodingInfo(name, name);
+ _encodingInfos.putEncoding(normalizedEncoding, ei);
+ } catch (IllegalCharsetNameException | UnsupportedCharsetException x) {
+ ei = new EncodingInfo(null,null);
+ }
}
return ei;
@@ -269,8 +270,8 @@ public final class Encodings extends Object
*/
private static String convertJava2MimeEncoding(String encoding)
{
- EncodingInfo enc =
- (EncodingInfo) _encodingTableKeyJava.get(encoding.toUpperCase());
+ final EncodingInfo enc =
+ _encodingInfos.getEncodingFromJavaKey(toUpperCaseFast(encoding));
if (null != enc)
return enc.name;
return encoding;
@@ -285,38 +286,37 @@ public final class Encodings extends Object
*/
public static String convertMime2JavaEncoding(String encoding)
{
-
- for (int i = 0; i < _encodings.length; ++i)
- {
- if (_encodings[i].name.equalsIgnoreCase(encoding))
- {
- return _encodings[i].javaName;
- }
- }
-
- return encoding;
+ final EncodingInfo info = _encodingInfos.findEncoding(toUpperCaseFast(encoding));
+ return info != null ? info.javaName : encoding;
}
- /**
- * Load a list of all the supported encodings.
- *
- * System property "encodings" formatted using URL syntax may define an
- * external encodings list. Thanks to Sergey Ushakov for the code
- * contribution!
- */
- private static EncodingInfo[] loadEncodingInfo()
- {
- try
- {
+ // Using an inner static class here prevent initialization races
+ // where the hash maps could be used before they were populated.
+ //
+ private final static class EncodingInfos {
+ // These maps are final and not modified after initialization.
+ private final Map _encodingTableKeyJava = new HashMap<>();
+ private final Map _encodingTableKeyMime = new HashMap<>();
+ // This map will be added to after initialization: make sure it's
+ // thread-safe. This map should not be used frequently - only in cases
+ // where the mapping requested was not declared in the Encodings.properties
+ // file.
+ private final Map _encodingDynamicTable =
+ Collections.synchronizedMap(new HashMap());
+
+ private EncodingInfos() {
+ loadEncodingInfo();
+ }
+
+ // Opens the file/resource containing java charset name -> preferred mime
+ // name mapping and returns it as an InputStream.
+ private InputStream openEncodingsFileStream() throws MalformedURLException, IOException {
String urlString = null;
InputStream is = null;
- try
- {
+ try {
urlString = SecuritySupport.getSystemProperty(ENCODINGS_PROP, "");
- }
- catch (SecurityException e)
- {
+ } catch (SecurityException e) {
}
if (urlString != null && urlString.length() > 0) {
@@ -327,84 +327,188 @@ public final class Encodings extends Object
if (is == null) {
is = SecuritySupport.getResourceAsStream(ENCODINGS_FILE);
}
+ return is;
+ }
+ // Loads the Properties resource containing the mapping:
+ // java charset name -> preferred mime name
+ // and returns it.
+ private Properties loadProperties() throws MalformedURLException, IOException {
Properties props = new Properties();
- if (is != null) {
- props.load(is);
- is.close();
- } else {
- // Seems to be no real need to force failure here, let the
- // system do its best... The issue is not really very critical,
- // and the output will be in any case _correct_ though maybe not
- // always human-friendly... :)
- // But maybe report/log the resource problem?
- // Any standard ways to report/log errors (in static context)?
- }
-
- int totalEntries = props.size();
- int totalMimeNames = 0;
- Enumeration keys = props.keys();
- for (int i = 0; i < totalEntries; ++i)
- {
- String javaName = (String) keys.nextElement();
- String val = props.getProperty(javaName);
- totalMimeNames++;
- int pos = val.indexOf(' ');
- for (int j = 0; j < pos; ++j)
- if (val.charAt(j) == ',')
- totalMimeNames++;
- }
- EncodingInfo[] ret = new EncodingInfo[totalMimeNames];
- int j = 0;
- keys = props.keys();
- for (int i = 0; i < totalEntries; ++i)
- {
- String javaName = (String) keys.nextElement();
- String val = props.getProperty(javaName);
- int pos = val.indexOf(' ');
- String mimeName;
- //int lastPrintable;
- if (pos < 0)
- {
- // Maybe report/log this problem?
- // "Last printable character not defined for encoding " +
- // mimeName + " (" + val + ")" ...
- mimeName = val;
- //lastPrintable = 0x00FF;
+ try (InputStream is = openEncodingsFileStream()) {
+ if (is != null) {
+ props.load(is);
+ } else {
+ // Seems to be no real need to force failure here, let the
+ // system do its best... The issue is not really very critical,
+ // and the output will be in any case _correct_ though maybe not
+ // always human-friendly... :)
+ // But maybe report/log the resource problem?
+ // Any standard ways to report/log errors (in static context)?
}
- else
- {
- //lastPrintable =
- // Integer.decode(val.substring(pos).trim()).intValue();
- StringTokenizer st =
- new StringTokenizer(val.substring(0, pos), ",");
- for (boolean first = true;
- st.hasMoreTokens();
- first = false)
- {
- mimeName = st.nextToken();
- ret[j] =
- new EncodingInfo(mimeName, javaName);
- _encodingTableKeyMime.put(
- mimeName.toUpperCase(),
- ret[j]);
- if (first)
- _encodingTableKeyJava.put(
- javaName.toUpperCase(),
- ret[j]);
- j++;
+ }
+ return props;
+ }
+
+ // Parses the mime list associated to a java charset name.
+ // The first mime name in the list is supposed to be the preferred
+ // mime name.
+ private String[] parseMimeTypes(String val) {
+ int pos = val.indexOf(' ');
+ //int lastPrintable;
+ if (pos < 0) {
+ // Maybe report/log this problem?
+ // "Last printable character not defined for encoding " +
+ // mimeName + " (" + val + ")" ...
+ return new String[] { val };
+ //lastPrintable = 0x00FF;
+ }
+ //lastPrintable =
+ // Integer.decode(val.substring(pos).trim()).intValue();
+ StringTokenizer st =
+ new StringTokenizer(val.substring(0, pos), ",");
+ String[] values = new String[st.countTokens()];
+ for (int i=0; st.hasMoreTokens(); i++) {
+ values[i] = st.nextToken();
+ }
+ return values;
+ }
+
+ // This method here attempts to find the canonical charset name for the
+ // the given name - which is supposed to be either a java name or a mime
+ // name.
+ // For that, it attempts to load the charset using the given name, and
+ // then returns the charset's canonical name.
+ // If the charset could not be loaded from the given name,
+ // the method returns null.
+ private String findCharsetNameFor(String name) {
+ try {
+ return Charset.forName(name).name();
+ } catch (Exception x) {
+ return null;
+ }
+ }
+
+ // This method here attempts to find the canonical charset name for the
+ // the set javaName+mimeNames - which are supposed to all refer to the
+ // same charset.
+ // For that it attempts to load the charset using the javaName, and if
+ // not found, attempts again using each of the mime names in turn.
+ // If the charset could be loaded from the javaName, then the javaName
+ // itself is returned as charset name. Otherwise, each of the mime names
+ // is tried in turn, until a charset can be loaded from one of the names,
+ // and the loaded charset's canonical name is returned.
+ // If no charset can be loaded from either the javaName or one of the
+ // mime names, then null is returned.
+ //
+ // Note that the returned name is the 'java' name that will be used in
+ // instances of EncodingInfo.
+ // This is important because EncodingInfo uses that 'java name' later on
+ // in calls to String.getBytes(javaName).
+ // As it happens, sometimes only one element of the set mime names/javaName
+ // is known by Charset: sometimes only one of the mime names is known,
+ // sometime only the javaName is known, sometimes all are known.
+ //
+ // By using this method here, we fix the problem where one of the mime
+ // names is known but the javaName is unknown, by associating the charset
+ // loaded from one of the mime names with the unrecognized javaName.
+ //
+ // When none of the mime names or javaName are known - there's not much we can
+ // do... It can mean that this encoding is not supported for this
+ // OS. If such a charset is ever use it will result in having all characters
+ // escaped.
+ //
+ private String findCharsetNameFor(String javaName, String[] mimes) {
+ String cs = findCharsetNameFor(javaName);
+ if (cs != null) return javaName;
+ for (String m : mimes) {
+ cs = findCharsetNameFor(m);
+ if (cs != null) break;
+ }
+ return cs;
+ }
+
+ /**
+ * Loads a list of all the supported encodings.
+ *
+ * System property "encodings" formatted using URL syntax may define an
+ * external encodings list. Thanks to Sergey Ushakov for the code
+ * contribution!
+ */
+ private void loadEncodingInfo() {
+ try {
+ // load (java name)->(preferred mime name) mapping.
+ final Properties props = loadProperties();
+
+ // create instances of EncodingInfo from the loaded mapping
+ Enumeration keys = props.keys();
+ Map canonicals = new HashMap<>();
+ while (keys.hasMoreElements()) {
+ final String javaName = (String) keys.nextElement();
+ final String[] mimes = parseMimeTypes(props.getProperty(javaName));
+
+ final String charsetName = findCharsetNameFor(javaName, mimes);
+ if (charsetName != null) {
+ final String kj = toUpperCaseFast(javaName);
+ final String kc = toUpperCaseFast(charsetName);
+ for (int i = 0; i < mimes.length; ++i) {
+ final String mimeName = mimes[i];
+ final String km = toUpperCaseFast(mimeName);
+ EncodingInfo info = new EncodingInfo(mimeName, charsetName);
+ _encodingTableKeyMime.put(km, info);
+ if (!canonicals.containsKey(kc)) {
+ // canonicals will map the charset name to
+ // the info containing the prefered mime name
+ // (the preferred mime name is the first mime
+ // name in the list).
+ canonicals.put(kc, info);
+ _encodingTableKeyJava.put(kc, info);
+ }
+ _encodingTableKeyJava.put(kj, info);
+ }
+ } else {
+ // None of the java or mime names on the line were
+ // recognized => this charset is not supported?
}
}
+
+ // Fix up the _encodingTableKeyJava so that the info mapped to
+ // the java name contains the preferred mime name.
+ // (a given java name can correspond to several mime name,
+ // but we want the _encodingTableKeyJava to point to the
+ // preferred mime name).
+ for (Entry e : _encodingTableKeyJava.entrySet()) {
+ e.setValue(canonicals.get(toUpperCaseFast(e.getValue().javaName)));
+ }
+
+ } catch (java.net.MalformedURLException mue) {
+ throw new com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException(mue);
+ } catch (java.io.IOException ioe) {
+ throw new com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException(ioe);
}
- return ret;
}
- catch (java.net.MalformedURLException mue)
- {
- throw new com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException(mue);
+
+ EncodingInfo findEncoding(String normalizedEncoding) {
+ EncodingInfo info = _encodingTableKeyJava.get(normalizedEncoding);
+ if (info == null) {
+ info = _encodingTableKeyMime.get(normalizedEncoding);
+ }
+ if (info == null) {
+ info = _encodingDynamicTable.get(normalizedEncoding);
+ }
+ return info;
}
- catch (java.io.IOException ioe)
- {
- throw new com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException(ioe);
+
+ EncodingInfo getEncodingFromMimeKey(String normalizedMimeName) {
+ return _encodingTableKeyMime.get(normalizedMimeName);
+ }
+
+ EncodingInfo getEncodingFromJavaKey(String normalizedJavaName) {
+ return _encodingTableKeyJava.get(normalizedJavaName);
+ }
+
+ void putEncoding(String key, EncodingInfo info) {
+ _encodingDynamicTable.put(key, info);
}
}
@@ -457,7 +561,6 @@ public final class Encodings extends Object
return codePoint;
}
- private static final HashMap _encodingTableKeyJava = new HashMap();
- private static final HashMap _encodingTableKeyMime = new HashMap();
- private static final EncodingInfo[] _encodings = loadEncodingInfo();
+ private final static EncodingInfos _encodingInfos = new EncodingInfos();
+
}
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/serializer/utils/URI.java b/jaxp/src/com/sun/org/apache/xml/internal/serializer/utils/URI.java
index 8af2fd8a1b4..4d5375a59c8 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/utils/URI.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/utils/URI.java
@@ -23,7 +23,7 @@
package com.sun.org.apache.xml.internal.serializer.utils;
import java.io.IOException;
-import java.io.Serializable;
+import java.util.Objects;
/**
@@ -863,7 +863,7 @@ final class URI
public String getSchemeSpecificPart()
{
- StringBuffer schemespec = new StringBuffer();
+ final StringBuilder schemespec = new StringBuilder();
if (m_userinfo != null || m_host != null || m_port != -1)
{
@@ -955,7 +955,7 @@ final class URI
boolean p_includeFragment)
{
- StringBuffer pathString = new StringBuffer(m_path);
+ final StringBuilder pathString = new StringBuilder(m_path);
if (p_includeQueryString && m_queryString != null)
{
@@ -1321,6 +1321,7 @@ final class URI
* @return true if p_test is a URI with all values equal to this
* URI, false otherwise
*/
+ @Override
public boolean equals(Object p_test)
{
@@ -1343,15 +1344,29 @@ final class URI
return false;
}
+ @Override
+ public int hashCode() {
+ int hash = 5;
+ hash = 41 * hash + Objects.hashCode(this.m_scheme);
+ hash = 41 * hash + Objects.hashCode(this.m_userinfo);
+ hash = 41 * hash + Objects.hashCode(this.m_host);
+ hash = 41 * hash + this.m_port;
+ hash = 41 * hash + Objects.hashCode(this.m_path);
+ hash = 41 * hash + Objects.hashCode(this.m_queryString);
+ hash = 41 * hash + Objects.hashCode(this.m_fragment);
+ return hash;
+ }
+
/**
* Get the URI as a string specification. See RFC 2396 Section 5.2.
*
* @return the URI string specification
*/
+ @Override
public String toString()
{
- StringBuffer uriSpecString = new StringBuffer();
+ final StringBuilder uriSpecString = new StringBuilder();
if (m_scheme != null)
{
@@ -1543,7 +1558,7 @@ final class URI
*
*
* @param p_char the character to check
- * @return true if the char is betweeen '0' and '9', 'a' and 'f'
+ * @return true if the char is between '0' and '9', 'a' and 'f'
* or 'A' and 'F', false otherwise
*/
private static boolean isHex(char p_char)
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/utils/URI.java b/jaxp/src/com/sun/org/apache/xml/internal/utils/URI.java
index b2606a7134e..f9e67ab663c 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/utils/URI.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/utils/URI.java
@@ -27,6 +27,7 @@ import java.io.Serializable;
import com.sun.org.apache.xml.internal.res.XMLErrorResources;
import com.sun.org.apache.xml.internal.res.XMLMessages;
+import java.util.Objects;
/**
* A class to represent a Uniform Resource Identifier (URI). This class
@@ -883,7 +884,7 @@ public class URI implements Serializable
public String getSchemeSpecificPart()
{
- StringBuffer schemespec = new StringBuffer();
+ final StringBuilder schemespec = new StringBuilder();
if (m_userinfo != null || m_host != null || m_port != -1)
{
@@ -975,7 +976,7 @@ public class URI implements Serializable
boolean p_includeFragment)
{
- StringBuffer pathString = new StringBuffer(m_path);
+ final StringBuilder pathString = new StringBuilder(m_path);
if (p_includeQueryString && m_queryString != null)
{
@@ -1341,6 +1342,7 @@ public class URI implements Serializable
* @return true if p_test is a URI with all values equal to this
* URI, false otherwise
*/
+ @Override
public boolean equals(Object p_test)
{
@@ -1363,15 +1365,29 @@ public class URI implements Serializable
return false;
}
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 59 * hash + Objects.hashCode(this.m_scheme);
+ hash = 59 * hash + Objects.hashCode(this.m_userinfo);
+ hash = 59 * hash + Objects.hashCode(this.m_host);
+ hash = 59 * hash + this.m_port;
+ hash = 59 * hash + Objects.hashCode(this.m_path);
+ hash = 59 * hash + Objects.hashCode(this.m_queryString);
+ hash = 59 * hash + Objects.hashCode(this.m_fragment);
+ return hash;
+ }
+
/**
* Get the URI as a string specification. See RFC 2396 Section 5.2.
*
* @return the URI string specification
*/
+ @Override
public String toString()
{
- StringBuffer uriSpecString = new StringBuffer();
+ final StringBuilder uriSpecString = new StringBuilder();
if (m_scheme != null)
{
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java
index 20ed918f909..8f79f869cb2 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java
@@ -22,17 +22,17 @@
*/
package com.sun.org.apache.xml.internal.utils;
-import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
+import com.sun.org.apache.xalan.internal.XalanConstants;
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
+import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
import java.util.HashMap;
-
+import javax.xml.XMLConstants;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
-
+import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
-import org.xml.sax.SAXException;
/**
* Creates XMLReader objects and caches them for re-use.
@@ -63,6 +63,11 @@ public class XMLReaderManager {
private HashMap m_inUse;
private boolean m_useServicesMechanism = true;
+ /**
+ * protocols allowed for external DTD references in source file and/or stylesheet.
+ */
+ private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+
/**
* Hidden constructor
*/
@@ -131,6 +136,7 @@ public class XMLReaderManager {
try {
reader.setFeature(NAMESPACES_FEATURE, true);
reader.setFeature(NAMESPACE_PREFIXES_FEATURE, false);
+ reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
} catch (SAXException se) {
// Try to carry on if we've got a parser that
// doesn't know about namespace prefixes.
@@ -181,4 +187,22 @@ public class XMLReaderManager {
m_useServicesMechanism = flag;
}
+ /**
+ * Get property value
+ */
+ public String getProperty(String name) {
+ if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
+ return _accessExternalDTD;
+ }
+ return null;
+ }
+
+ /**
+ * Set property.
+ */
+ public void setProperty(String name, String value) {
+ if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
+ _accessExternalDTD = (String)value;
+ }
+ }
}
diff --git a/jaxp/src/com/sun/org/apache/xpath/internal/Arg.java b/jaxp/src/com/sun/org/apache/xpath/internal/Arg.java
index bc3d13a3d58..311d07efca2 100644
--- a/jaxp/src/com/sun/org/apache/xpath/internal/Arg.java
+++ b/jaxp/src/com/sun/org/apache/xpath/internal/Arg.java
@@ -24,6 +24,7 @@ package com.sun.org.apache.xpath.internal;
import com.sun.org.apache.xml.internal.utils.QName;
import com.sun.org.apache.xpath.internal.objects.XObject;
+import java.util.Objects;
/**
* This class holds an instance of an argument on
@@ -182,7 +183,7 @@ public class Arg
{
m_qname = new QName("");
- ; // so that string compares can be done.
+ // so that string compares can be done.
m_val = null;
m_expression = null;
m_isVisible = true;
@@ -223,6 +224,11 @@ public class Arg
m_expression = null;
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.m_qname);
+ }
+
/**
* Equality function specialized for the variable name. If the argument
* is not a qname, it will deligate to the super class.
@@ -231,6 +237,7 @@ public class Arg
* @return true if this object is the same as the obj
* argument; false otherwise.
*/
+ @Override
public boolean equals(Object obj)
{
if(obj instanceof QName)
diff --git a/jaxp/src/com/sun/xml/internal/stream/StaxXMLInputSource.java b/jaxp/src/com/sun/xml/internal/stream/StaxXMLInputSource.java
index 351693f1472..106f9f9d227 100644
--- a/jaxp/src/com/sun/xml/internal/stream/StaxXMLInputSource.java
+++ b/jaxp/src/com/sun/xml/internal/stream/StaxXMLInputSource.java
@@ -43,6 +43,9 @@ public class StaxXMLInputSource {
XMLEventReader fEventReader ;
XMLInputSource fInputSource ;
+ //indicate if the source is resolved by a resolver
+ boolean fHasResolver = false;
+
/** Creates a new instance of StaxXMLInputSource */
public StaxXMLInputSource(XMLStreamReader streamReader) {
fStreamReader = streamReader ;
@@ -57,6 +60,12 @@ public class StaxXMLInputSource {
fInputSource = inputSource ;
}
+
+ public StaxXMLInputSource(XMLInputSource inputSource, boolean hasResolver){
+ fInputSource = inputSource ;
+ fHasResolver = hasResolver;
+ }
+
public XMLStreamReader getXMLStreamReader(){
return fStreamReader ;
}
@@ -72,4 +81,8 @@ public class StaxXMLInputSource {
public boolean hasXMLStreamOrXMLEventReader(){
return (fStreamReader == null) && (fEventReader == null) ? false : true ;
}
+
+ public boolean hasResolver() {
+ return fHasResolver;
+ }
}
diff --git a/jaxp/src/javax/xml/XMLConstants.java b/jaxp/src/javax/xml/XMLConstants.java
index 2e570f1de7b..b923a6cbf02 100644
--- a/jaxp/src/javax/xml/XMLConstants.java
+++ b/jaxp/src/javax/xml/XMLConstants.java
@@ -73,7 +73,7 @@ public final class XMLConstants {
* The official XML Namespace name URI.
*
* Defined by the XML specification to be
- * "http://www.w3.org/XML/1998/namespace".
+ * "{@code http://www.w3.org/XML/1998/namespace}".
*
* @see
@@ -85,7 +85,7 @@ public final class XMLConstants {
/**
* The official XML Namespace prefix.
*
- * Defined by the XML specification to be "xml".
+ * Defined by the XML specification to be "{@code xml}".
*
* @see
@@ -99,7 +99,7 @@ public final class XMLConstants {
* XMLConstants.XMLNS_ATTRIBUTE}, Namespace name URI.
*
* Defined by the XML specification to be
- * "http://www.w3.org/2000/xmlns/".
+ * "{@code http://www.w3.org/2000/xmlns/}".
*
* @see
@@ -117,7 +117,7 @@ public final class XMLConstants {
*
* It is NOT valid to use as a
* prefix. Defined by the XML specification to be
- * "xmlns".
+ * "{@code xmlns}".
*
* @see
@@ -128,7 +128,7 @@ public final class XMLConstants {
/**
* W3C XML Schema Namespace URI.
*
- * Defined to be "http://www.w3.org/2001/XMLSchema".
+ *
Defined to be "{@code http://www.w3.org/2001/XMLSchema}".
*
* @see
@@ -141,7 +141,7 @@ public final class XMLConstants {
/**
* W3C XML Schema Instance Namespace URI.
*
- * Defined to be "http://www.w3.org/2001/XMLSchema-instance".
+ * Defined to be "{@code http://www.w3.org/2001/XMLSchema-instance}".
*
* @see
@@ -154,7 +154,7 @@ public final class XMLConstants {
/**
* W3C XPath Datatype Namespace URI.
*
- * Defined to be "http://www.w3.org/2003/11/xpath-datatypes".
+ * Defined to be "{@code http://www.w3.org/2003/11/xpath-datatypes}".
*
* @see XQuery 1.0 and XPath 2.0 Data Model
*/
@@ -163,14 +163,14 @@ public final class XMLConstants {
/**
*
XML Document Type Declaration Namespace URI as an arbitrary value.
*
- * Since not formally defined by any existing standard, arbitrarily define to be "http://www.w3.org/TR/REC-xml".
+ *
Since not formally defined by any existing standard, arbitrarily define to be "{@code http://www.w3.org/TR/REC-xml}".
*/
public static final String XML_DTD_NS_URI = "http://www.w3.org/TR/REC-xml";
/**
*
RELAX NG Namespace URI.
*
- * Defined to be "http://relaxng.org/ns/structure/1.0".
+ * Defined to be "{@code http://relaxng.org/ns/structure/1.0}".
*
* @see RELAX NG Specification
*/
@@ -181,14 +181,212 @@ public final class XMLConstants {
*
*
* -
- *
true instructs the implementation to process XML securely.
+ * {@code true} instructs the implementation to process XML securely.
* This may set limits on XML constructs to avoid conditions such as denial of service attacks.
*
* -
- *
false instructs the implementation to process XML acording the letter of the XML specifications
- * ingoring security issues such as limits on XML constructs to avoid conditions such as denial of service attacks.
+ * {@code false} instructs the implementation to process XML in accordance with the XML specifications
+ * ignoring security issues such as limits on XML constructs to avoid conditions such as denial of service attacks.
*
*
*/
public static final String FEATURE_SECURE_PROCESSING = "http://javax.xml.XMLConstants/feature/secure-processing";
+
+
+ /**
+ * Property: accessExternalDTD
+ *
+ *
+ * Restrict access to external DTDs and external Entity References to the protocols specified.
+ * If access is denied due to the restriction of this property, a runtime exception that
+ * is specific to the context is thrown. In the case of {@link javax.xml.parsers.SAXParser}
+ * for example, {@link org.xml.sax.SAXException} is thrown.
+ *
+ *
+ *
+ * Value: a list of protocols separated by comma. A protocol is the scheme portion of a
+ * {@link java.net.URI}, or in the case of the JAR protocol, "jar" plus the scheme portion
+ * separated by colon.
+ * A scheme is defined as:
+ *
+ *
+ * scheme = alpha *( alpha | digit | "+" | "-" | "." )
+ * where alpha = a-z and A-Z.
+ *
+ * And the JAR protocol:
+ *
+ * jar[:scheme]
+ *
+ * Protocols including the keyword "jar" are case-insensitive. Any whitespaces as defined by
+ * {@link java.lang.Character#isSpaceChar } in the value will be ignored.
+ * Examples of protocols are file, http, jar:file.
+ *
+ *
+ *
+ *
+ *
+ * Default value: The default value is implementation specific and therefore not specified.
+ * The following options are provided for consideration:
+ *
+ *
+ * - an empty string to deny all access to external references;
+ * - a specific protocol, such as file, to give permission to only the protocol;
+ * - the keyword "all" to grant permission to all protocols.
+ *
+ * When FEATURE_SECURE_PROCESSING is enabled, it is recommended that implementations
+ * restrict external connections by default, though this may cause problems for applications
+ * that process XML/XSD/XSL with external references.
+ *
+ *
+ *
+ *
+ * Granting all access: the keyword "all" grants permission to all protocols.
+ *
+ *
+ * System Property: The value of this property can be set or overridden by
+ * system property {@code javax.xml.accessExternalDTD}.
+ *
+ *
+ *
+ * ${JAVA_HOME}/lib/jaxp.properties: This configuration file is in standard
+ * {@link java.util.Properties} format. If the file exists and the system property is specified,
+ * its value will be used to override the default of the property.
+ *
+ *
+ *
+ *
+ *
+ * @since 1.7
+ */
+ public static final String ACCESS_EXTERNAL_DTD = "http://javax.xml.XMLConstants/property/accessExternalDTD";
+
+ /**
+ * Property: accessExternalSchema
+ *
+ *
+ * Restrict access to the protocols specified for external reference set by the
+ * schemaLocation attribute, Import and Include element. If access is denied
+ * due to the restriction of this property, a runtime exception that is specific
+ * to the context is thrown. In the case of {@link javax.xml.validation.SchemaFactory}
+ * for example, org.xml.sax.SAXException is thrown.
+ *
+ *
+ * Value: a list of protocols separated by comma. A protocol is the scheme portion of a
+ * {@link java.net.URI}, or in the case of the JAR protocol, "jar" plus the scheme portion
+ * separated by colon.
+ * A scheme is defined as:
+ *
+ *
+ * scheme = alpha *( alpha | digit | "+" | "-" | "." )
+ * where alpha = a-z and A-Z.
+ *
+ * And the JAR protocol:
+ *
+ * jar[:scheme]
+ *
+ * Protocols including the keyword "jar" are case-insensitive. Any whitespaces as defined by
+ * {@link java.lang.Character#isSpaceChar } in the value will be ignored.
+ * Examples of protocols are file, http, jar:file.
+ *
+ *
+ *
+ *
+ *
+ * Default value: The default value is implementation specific and therefore not specified.
+ * The following options are provided for consideration:
+ *
+ *
+ * - an empty string to deny all access to external references;
+ * - a specific protocol, such as file, to give permission to only the protocol;
+ * - the keyword "all" to grant permission to all protocols.
+ *
+ * When FEATURE_SECURE_PROCESSING is enabled, it is recommended that implementations
+ * restrict external connections by default, though this may cause problems for applications
+ * that process XML/XSD/XSL with external references.
+ *
+ *
+ *
+ * Granting all access: the keyword "all" grants permission to all protocols.
+ *
+ *
+ *
+ * System Property: The value of this property can be set or overridden by
+ * system property {@code javax.xml.accessExternalSchema}
+ *
+ *
+ *
+ * ${JAVA_HOME}/lib/jaxp.properties: This configuration file is in standard
+ * java.util.Properties format. If the file exists and the system property is specified,
+ * its value will be used to override the default of the property.
+ *
+ * @since 1.7
+ *
+ */
+ public static final String ACCESS_EXTERNAL_SCHEMA = "http://javax.xml.XMLConstants/property/accessExternalSchema";
+
+ /**
+ * Property: accessExternalStylesheet
+ *
+ *
+ * Restrict access to the protocols specified for external references set by the
+ * stylesheet processing instruction, Import and Include element, and document function.
+ * If access is denied due to the restriction of this property, a runtime exception
+ * that is specific to the context is thrown. In the case of constructing new
+ * {@link javax.xml.transform.Transformer} for example,
+ * {@link javax.xml.transform.TransformerConfigurationException}
+ * will be thrown by the {@link javax.xml.transform.TransformerFactory}.
+ *
+ *
+ * Value: a list of protocols separated by comma. A protocol is the scheme portion of a
+ * {@link java.net.URI}, or in the case of the JAR protocol, "jar" plus the scheme portion
+ * separated by colon.
+ * A scheme is defined as:
+ *
+ *
+ * scheme = alpha *( alpha | digit | "+" | "-" | "." )
+ * where alpha = a-z and A-Z.
+ *
+ * And the JAR protocol:
+ *
+ * jar[:scheme]
+ *
+ * Protocols including the keyword "jar" are case-insensitive. Any whitespaces as defined by
+ * {@link java.lang.Character#isSpaceChar } in the value will be ignored.
+ * Examples of protocols are file, http, jar:file.
+ *
+ *
+ *
+ *
+ *
+ * Default value: The default value is implementation specific and therefore not specified.
+ * The following options are provided for consideration:
+ *
+ *
+ * - an empty string to deny all access to external references;
+ * - a specific protocol, such as file, to give permission to only the protocol;
+ * - the keyword "all" to grant permission to all protocols.
+ *
+ * When FEATURE_SECURE_PROCESSING is enabled, it is recommended that implementations
+ * restrict external connections by default, though this may cause problems for applications
+ * that process XML/XSD/XSL with external references.
+ *
+ *
+ *
+ * Granting all access: the keyword "all" grants permission to all protocols.
+ *
+ *
+ *
+ * System Property: The value of this property can be set or overridden by
+ * system property {@code javax.xml.accessExternalStylesheet}
+ *
+ *
+ *
+ * ${JAVA_HOME}/lib/jaxp.properties: This configuration file is in standard
+ * java.util.Properties format. If the file exists and the system property is specified,
+ * its value will be used to override the default of the property.
+ *
+ * @since 1.7
+ */
+ public static final String ACCESS_EXTERNAL_STYLESHEET = "http://javax.xml.XMLConstants/property/accessExternalStylesheet";
+
}
diff --git a/jaxp/src/javax/xml/parsers/DocumentBuilderFactory.java b/jaxp/src/javax/xml/parsers/DocumentBuilderFactory.java
index 0ef1c13cecb..748a1636f0a 100644
--- a/jaxp/src/javax/xml/parsers/DocumentBuilderFactory.java
+++ b/jaxp/src/javax/xml/parsers/DocumentBuilderFactory.java
@@ -351,6 +351,31 @@ public abstract class DocumentBuilderFactory {
/**
* Allows the user to set specific attributes on the underlying
* implementation.
+ *
+ * All implementations that implement JAXP 1.5 or newer are required to
+ * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and
+ * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties.
+ *
+ *
+ * -
+ *
+ * Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property
+ * restricts the access to external DTDs, external Entity References to the
+ * protocols specified by the property.
+ * If access is denied during parsing due to the restriction of this property,
+ * {@link org.xml.sax.SAXException} will be thrown by the parse methods defined by
+ * {@link javax.xml.parsers.DocumentBuilder}.
+ *
+ *
+ * Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property
+ * restricts the access to external Schema set by the schemaLocation attribute to
+ * the protocols specified by the property. If access is denied during parsing
+ * due to the restriction of this property, {@link org.xml.sax.SAXException}
+ * will be thrown by the parse methods defined by
+ * {@link javax.xml.parsers.DocumentBuilder}.
+ *
+ *
+ *
*
* @param name The name of the attribute.
* @param value The value of the attribute.
diff --git a/jaxp/src/javax/xml/parsers/SAXParser.java b/jaxp/src/javax/xml/parsers/SAXParser.java
index ef7b2e942c3..5461413eb41 100644
--- a/jaxp/src/javax/xml/parsers/SAXParser.java
+++ b/jaxp/src/javax/xml/parsers/SAXParser.java
@@ -441,6 +441,29 @@ public abstract class SAXParser {
* A list of the core features and properties can be found at
*
* http://sax.sourceforge.net/?selected=get-set.
+ *
+ * All implementations that implement JAXP 1.5 or newer are required to
+ * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and
+ * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties.
+ *
+ *
+ * -
+ *
+ * Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property
+ * restricts the access to external DTDs, external Entity References to
+ * the protocols specified by the property. If access is denied during parsing
+ * due to the restriction of this property, {@link org.xml.sax.SAXException}
+ * will be thrown by the parse methods defined by {@link javax.xml.parsers.SAXParser}.
+ *
+ *
+ * Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property
+ * restricts the access to external Schema set by the schemaLocation attribute to
+ * the protocols specified by the property. If access is denied during parsing
+ * due to the restriction of this property, {@link org.xml.sax.SAXException}
+ * will be thrown by the parse methods defined by the {@link javax.xml.parsers.SAXParser}.
+ *
+ *
+ *
*
* @param name The name of the property to be set.
* @param value The value of the property to be set.
diff --git a/jaxp/src/javax/xml/stream/XMLInputFactory.java b/jaxp/src/javax/xml/stream/XMLInputFactory.java
index 2bfbad5d461..d894893eb6d 100644
--- a/jaxp/src/javax/xml/stream/XMLInputFactory.java
+++ b/jaxp/src/javax/xml/stream/XMLInputFactory.java
@@ -433,9 +433,26 @@ public abstract class XMLInputFactory {
public abstract void setXMLReporter(XMLReporter reporter);
/**
- * Allows the user to set specific feature/property on the underlying implementation. The underlying implementation
- * is not required to support every setting of every property in the specification and may use IllegalArgumentException
- * to signal that an unsupported property may not be set with the specified value.
+ * Allows the user to set specific feature/property on the underlying
+ * implementation. The underlying implementation is not required to support
+ * every setting of every property in the specification and may use
+ * IllegalArgumentException to signal that an unsupported property may not be
+ * set with the specified value.
+ *
+ * All implementations that implement JAXP 1.5 or newer are required to
+ * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property.
+ *
+ *
+ * -
+ *
+ * Access to external DTDs, external Entity References is restricted to the
+ * protocols specified by the property. If access is denied during parsing
+ * due to the restriction of this property, {@link javax.xml.stream.XMLStreamException}
+ * will be thrown by the {@link javax.xml.stream.XMLStreamReader#next()} or
+ * {@link javax.xml.stream.XMLEventReader#nextEvent()} method.
+ *
+ *
+ *
* @param name The name of the property (may not be null)
* @param value The value of the property
* @throws java.lang.IllegalArgumentException if the property is not supported
diff --git a/jaxp/src/javax/xml/transform/TransformerFactory.java b/jaxp/src/javax/xml/transform/TransformerFactory.java
index 61528855be6..9c4a076549d 100644
--- a/jaxp/src/javax/xml/transform/TransformerFactory.java
+++ b/jaxp/src/javax/xml/transform/TransformerFactory.java
@@ -325,6 +325,46 @@ public abstract class TransformerFactory {
* be an option that the implementation provides.
* An IllegalArgumentException is thrown if the underlying
* implementation doesn't recognize the attribute.
+ *
+ * All implementations that implement JAXP 1.5 or newer are required to
+ * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and
+ * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_STYLESHEET} properties.
+ *
+ *
+ * -
+ *
+ * Access to external DTDs in the source file is restricted to the protocols
+ * specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property.
+ * If access is denied during transformation due to the restriction of this property,
+ * {@link javax.xml.transform.TransformerException} will be thrown by
+ * {@link javax.xml.transform.Transformer#transform(Source, Result)}.
+ *
+ *
+ * Access to external DTDs in the stylesheet is restricted to the protocols
+ * specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property.
+ * If access is denied during the creation of a new transformer due to the
+ * restriction of this property,
+ * {@link javax.xml.transform.TransformerConfigurationException} will be thrown
+ * by the {@link #newTransformer(Source)} method.
+ *
+ *
+ * Access to external reference set by the stylesheet processing instruction,
+ * Import and Include element is restricted to the protocols specified by the
+ * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_STYLESHEET} property.
+ * If access is denied during the creation of a new transformer due to the
+ * restriction of this property,
+ * {@link javax.xml.transform.TransformerConfigurationException} will be thrown
+ * by the {@link #newTransformer(Source)} method.
+ *
+ *
+ * Access to external document through XSLT document function is restricted
+ * to the protocols specified by the property. If access is denied during
+ * the transformation due to the restriction of this property,
+ * {@link javax.xml.transform.TransformerException} will be thrown by the
+ * {@link javax.xml.transform.Transformer#transform(Source, Result)} method.
+ *
+ *
+ *
*
* @param name The name of the attribute.
* @param value The value of the attribute.
diff --git a/jaxp/src/javax/xml/validation/SchemaFactory.java b/jaxp/src/javax/xml/validation/SchemaFactory.java
index 6f156af0ff5..d99f45011f7 100644
--- a/jaxp/src/javax/xml/validation/SchemaFactory.java
+++ b/jaxp/src/javax/xml/validation/SchemaFactory.java
@@ -390,8 +390,44 @@ public abstract class SchemaFactory {
* possible for a {@link SchemaFactory} to recognize a property name but
* to be unable to change the current value.
*
- * {@link SchemaFactory}s are not required to recognize setting
- * any specific property names.
+ *
+ * All implementations that implement JAXP 1.5 or newer are required to
+ * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and
+ * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties.
+ *
+ *
+ * -
+ *
Access to external DTDs in Schema files is restricted to the protocols
+ * specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property.
+ * If access is denied during the creation of new Schema due to the restriction
+ * of this property, {@link org.xml.sax.SAXException} will be thrown by the
+ * {@link #newSchema(Source)} or {@link #newSchema(File)}
+ * or {@link #newSchema(URL)} or or {@link #newSchema(Source[])} method.
+ *
+ * Access to external DTDs in xml source files is restricted to the protocols
+ * specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property.
+ * If access is denied during validation due to the restriction
+ * of this property, {@link org.xml.sax.SAXException} will be thrown by the
+ * {@link javax.xml.validation.Validator#validate(Source)} or
+ * {@link javax.xml.validation.Validator#validate(Source, Result)} method.
+ *
+ * Access to external reference set by the schemaLocation attribute is
+ * restricted to the protocols specified by the
+ * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property.
+ * If access is denied during validation due to the restriction of this property,
+ * {@link org.xml.sax.SAXException} will be thrown by the
+ * {@link javax.xml.validation.Validator#validate(Source)} or
+ * {@link javax.xml.validation.Validator#validate(Source, Result)} method.
+ *
+ * Access to external reference set by the Import
+ * and Include element is restricted to the protocols specified by the
+ * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property.
+ * If access is denied during the creation of new Schema due to the restriction
+ * of this property, {@link org.xml.sax.SAXException} will be thrown by the
+ * {@link #newSchema(Source)} or {@link #newSchema(File)}
+ * or {@link #newSchema(URL)} or {@link #newSchema(Source[])} method.
+ *
+ *
*
* @param name The property name, which is a non-null fully-qualified URI.
* @param object The requested value for the property.
diff --git a/jaxp/src/javax/xml/validation/Validator.java b/jaxp/src/javax/xml/validation/Validator.java
index ee66a6d1f45..fad7c5ac4f0 100644
--- a/jaxp/src/javax/xml/validation/Validator.java
+++ b/jaxp/src/javax/xml/validation/Validator.java
@@ -440,8 +440,27 @@ public abstract class Validator {
* in specific contexts, such as before, during, or after
* a validation.
*
- * {@link Validator}s are not required to recognize setting
- * any specific property names.
+ *
+ * All implementations that implement JAXP 1.5 or newer are required to
+ * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and
+ * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties.
+ *
+ *
+ * -
+ *
Access to external DTDs in source or Schema file is restricted to
+ * the protocols specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD}
+ * property. If access is denied during validation due to the restriction
+ * of this property, {@link org.xml.sax.SAXException} will be thrown by the
+ * {@link #validate(Source)} method.
+ *
+ * Access to external reference set by the schemaLocation attribute is
+ * restricted to the protocols specified by the
+ * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property.
+ * If access is denied during validation due to the restriction of this property,
+ * {@link org.xml.sax.SAXException} will be thrown by the
+ * {@link #validate(Source)} method.
+ *
+ *
*
* @param name The property name, which is a non-null fully-qualified URI.
* @param object The requested value for the property.
diff --git a/jaxws/.hgtags b/jaxws/.hgtags
index 6ba47546a48..088ec3da462 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -211,3 +211,5 @@ a5e7c2f093c9996ab3419db1565094a07b059e9c jdk8-b86
72e03566f0a61282cc48ebc869803b256cccd66c jdk8-b87
24fa5452e5d4e9df8b85196283275a6ca4b4adb4 jdk8-b88
88838e08e4ef6a254867c8126070a1975683108d jdk8-b89
+3e5b9ea5ac35ea7096da484e24a863cf4552179f jdk8-b90
+0bb1a9fa56b037d072efdaae5f5b73a0f23c966c jdk8-b91
diff --git a/jdk/.hgtags b/jdk/.hgtags
index 7be0eb3751c..08ec69310ef 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -212,3 +212,5 @@ d5228e624826a10ccc5b05f30ad8d839b58fe48d jdk8-b87
8dbb4b159e04de3c447c9242c70505e71f8624c7 jdk8-b88
845025546e35519fbb8970e79fc2a834063a5e19 jdk8-b89
c63eda8f63008a4398d2c22ac8d72f7fef6f9238 jdk8-b90
+169451cf0cc53bde5af24f9820ea3f35ec4b4df4 jdk8-b91
+a2a2a91075ad85becbe10a39d7fd04ef9bea8df5 jdk8-b92
diff --git a/jdk/makefiles/CompileLaunchers.gmk b/jdk/makefiles/CompileLaunchers.gmk
index 7ecad956fbb..0621f4ce38b 100644
--- a/jdk/makefiles/CompileLaunchers.gmk
+++ b/jdk/makefiles/CompileLaunchers.gmk
@@ -472,6 +472,7 @@ $(eval $(call SetupNativeCompilation,BUILD_UNPACKEXE,\
-D "JDK_FNAME=unpack200.exe" \
-D "JDK_INTERNAL_NAME=unpack200" \
-D "JDK_FTYPE=0x1L",\
+ DEBUG_SYMBOLS:=true,\
MANIFEST:=$(JDK_TOPDIR)/src/windows/resource/unpack200_proto.exe.manifest))
ifeq ($(OPENJDK_TARGET_OS),windows)
@@ -555,6 +556,7 @@ ifneq ($(BUILD_JEXEC_SRC),)
$(call SET_SHARED_LIBRARY_NAME,$(LIBRARY_PREFIX)$(SHARED_LIBRARY_SUFFIX)), \
OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/jexec_obj,\
OUTPUT_DIR:=$(BUILD_JEXEC_DST_DIR),\
+ DEBUG_SYMBOLS:=true,\
PROGRAM:=jexec))
BUILD_LAUNCHERS += $(BUILD_JEXEC)
diff --git a/jdk/makefiles/GensrcSwing.gmk b/jdk/makefiles/GensrcSwing.gmk
index f5741ae5f46..5350c143b73 100644
--- a/jdk/makefiles/GensrcSwing.gmk
+++ b/jdk/makefiles/GensrcSwing.gmk
@@ -68,10 +68,17 @@ BEANS_SRC = $(BEANS:%=$(JDK_TOPDIR)/src/share/classes/javax/swing/%.java) \
# Dummy variable so far, in the old build system it was false by default
SWINGBEAN_DEBUG_FLAG = false
# GenDocletBeanInfo is compiled in Tools.gmk and picks up from $(JDK_OUTPUTDIR)/btclasses
-$(JDK_OUTPUTDIR)/gensrc_no_srczip/_the.generated_beaninfo: $(BEANS_SRC) $(JDK_OUTPUTDIR)/gensrc_no_srczip/javax/swing/SwingBeanInfoBase.java $(JDK_OUTPUTDIR)/gensrc/sun/swing/BeanInfoUtils.java $(BUILD_TOOLS)
+# LocaleDataMetaInfo needs to be generated before running this to avoid confusing errors
+# in the build log.
+$(JDK_OUTPUTDIR)/gensrc_no_srczip/_the.generated_beaninfo: $(BEANS_SRC) \
+ $(JDK_OUTPUTDIR)/gensrc_no_srczip/javax/swing/SwingBeanInfoBase.java \
+ $(JDK_OUTPUTDIR)/gensrc/sun/swing/BeanInfoUtils.java $(BUILD_TOOLS) \
+ | $(GENSRC_LOCALEDATAMETAINFO)
$(ECHO) Generating beaninfo
$(MKDIR) -p $(JDK_OUTPUTDIR)/gensrc_no_srczip/javax/swing
- $(JAVA) -Djava.awt.headless=true $(NEW_JAVADOC) -doclet GenDocletBeanInfo \
+ $(JAVA) -Djava.awt.headless=true $(NEW_JAVADOC) \
+ -sourcepath "$(JDK_TOPDIR)/src/share/classes$(PATH_SEP)$(JDK_OUTPUTDIR)/gensrc" \
+ -doclet GenDocletBeanInfo \
-x $(SWINGBEAN_DEBUG_FLAG) -d $(JDK_OUTPUTDIR)/gensrc_no_srczip/javax/swing \
-t $(DOCLETSRC_DIR)/SwingBeanInfo.template -docletpath $(JDK_OUTPUTDIR)/btclasses \
-XDignore.symbol.file=true \
diff --git a/jdk/makefiles/Images.gmk b/jdk/makefiles/Images.gmk
index fb74b2dc74b..a1db8b9a148 100644
--- a/jdk/makefiles/Images.gmk
+++ b/jdk/makefiles/Images.gmk
@@ -352,11 +352,8 @@ ifneq ($(OPENJDK_TARGET_OS),windows)
JDK_MAN_PAGES += jvisualvm.1
endif
- ifndef OPENJDK
- MAN_SRC_BASEDIR:=$(JDK_TOPDIR)/src/closed
- else
- MAN_SRC_BASEDIR:=$(JDK_TOPDIR)/src
- endif
+ # This variable is potentially overridden in the closed makefile.
+ MAN_SRC_BASEDIR ?= $(JDK_TOPDIR)/src
ifeq ($(OPENJDK_TARGET_OS), linux)
MAN_SRC_DIR:=$(MAN_SRC_BASEDIR)/linux/doc
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/FillableStringTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/FillableStringTest.java
index 5c8a65a50f3..565d668c79c 100644
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/FillableStringTest.java
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/FillableStringTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/MapTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/MapTest.java
index 53c7ab1c7dc..b0e33edd919 100644
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/MapTest.java
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/MapTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestInstanceMethod.java b/jdk/test/jdk/lambda/MethodReferenceTestInstanceMethod.java
index b000d648fd1..40a64aaf38e 100644
--- a/jdk/test/jdk/lambda/MethodReferenceTestInstanceMethod.java
+++ b/jdk/test/jdk/lambda/MethodReferenceTestInstanceMethod.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestKinds.java b/jdk/test/jdk/lambda/MethodReferenceTestKinds.java
index 356b3d603d2..8f11bc28f58 100644
--- a/jdk/test/jdk/lambda/MethodReferenceTestKinds.java
+++ b/jdk/test/jdk/lambda/MethodReferenceTestKinds.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestSueCase1.java b/jdk/test/jdk/lambda/MethodReferenceTestSueCase1.java
index 89bb988f7db..b6bbfa68d63 100644
--- a/jdk/test/jdk/lambda/MethodReferenceTestSueCase1.java
+++ b/jdk/test/jdk/lambda/MethodReferenceTestSueCase1.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestSueCase2.java b/jdk/test/jdk/lambda/MethodReferenceTestSueCase2.java
index f967f9d3eeb..dcb2a69e8ee 100644
--- a/jdk/test/jdk/lambda/MethodReferenceTestSueCase2.java
+++ b/jdk/test/jdk/lambda/MethodReferenceTestSueCase2.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestSueCase4.java b/jdk/test/jdk/lambda/MethodReferenceTestSueCase4.java
index c14b31f82c8..eb54df6a75d 100644
--- a/jdk/test/jdk/lambda/MethodReferenceTestSueCase4.java
+++ b/jdk/test/jdk/lambda/MethodReferenceTestSueCase4.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/separate/AttributeInjector.java b/jdk/test/jdk/lambda/separate/AttributeInjector.java
index 6ea11154c9f..52e3f76e31b 100644
--- a/jdk/test/jdk/lambda/separate/AttributeInjector.java
+++ b/jdk/test/jdk/lambda/separate/AttributeInjector.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/separate/ClassFile.java b/jdk/test/jdk/lambda/separate/ClassFile.java
index 7da140b8177..919df1a1a9d 100644
--- a/jdk/test/jdk/lambda/separate/ClassFile.java
+++ b/jdk/test/jdk/lambda/separate/ClassFile.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/separate/ClassFilePreprocessor.java b/jdk/test/jdk/lambda/separate/ClassFilePreprocessor.java
index e40434cc3cb..bb91746d5f7 100644
--- a/jdk/test/jdk/lambda/separate/ClassFilePreprocessor.java
+++ b/jdk/test/jdk/lambda/separate/ClassFilePreprocessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/separate/ClassToInterfaceConverter.java b/jdk/test/jdk/lambda/separate/ClassToInterfaceConverter.java
index 48c0e8dcbb3..8da05ac4e81 100644
--- a/jdk/test/jdk/lambda/separate/ClassToInterfaceConverter.java
+++ b/jdk/test/jdk/lambda/separate/ClassToInterfaceConverter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/separate/Compiler.java b/jdk/test/jdk/lambda/separate/Compiler.java
index 9ba81d65890..cbee5764b8b 100644
--- a/jdk/test/jdk/lambda/separate/Compiler.java
+++ b/jdk/test/jdk/lambda/separate/Compiler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/separate/DirectedClassLoader.java b/jdk/test/jdk/lambda/separate/DirectedClassLoader.java
index 6da38668378..726edabf38f 100644
--- a/jdk/test/jdk/lambda/separate/DirectedClassLoader.java
+++ b/jdk/test/jdk/lambda/separate/DirectedClassLoader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/separate/SourceModel.java b/jdk/test/jdk/lambda/separate/SourceModel.java
index 6cef02fb170..1fe3e9edb7e 100644
--- a/jdk/test/jdk/lambda/separate/SourceModel.java
+++ b/jdk/test/jdk/lambda/separate/SourceModel.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/separate/TestHarness.java b/jdk/test/jdk/lambda/separate/TestHarness.java
index d5ba449a3c9..801fa485b33 100644
--- a/jdk/test/jdk/lambda/separate/TestHarness.java
+++ b/jdk/test/jdk/lambda/separate/TestHarness.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/vm/DefaultMethodRegressionTests.java b/jdk/test/jdk/lambda/vm/DefaultMethodRegressionTests.java
index 538d26d9b5a..fc206d2614f 100644
--- a/jdk/test/jdk/lambda/vm/DefaultMethodRegressionTests.java
+++ b/jdk/test/jdk/lambda/vm/DefaultMethodRegressionTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/vm/DefaultMethodsTest.java b/jdk/test/jdk/lambda/vm/DefaultMethodsTest.java
index 76ae86cd6fc..a02ce752540 100644
--- a/jdk/test/jdk/lambda/vm/DefaultMethodsTest.java
+++ b/jdk/test/jdk/lambda/vm/DefaultMethodsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/jdk/test/jdk/lambda/vm/InterfaceAccessFlagsTest.java b/jdk/test/jdk/lambda/vm/InterfaceAccessFlagsTest.java
index b08e67c7a09..b33ea3e657c 100644
--- a/jdk/test/jdk/lambda/vm/InterfaceAccessFlagsTest.java
+++ b/jdk/test/jdk/lambda/vm/InterfaceAccessFlagsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * 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
diff --git a/langtools/.hgtags b/langtools/.hgtags
index fae56863926..1c4ad707352 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -211,3 +211,5 @@ cfb65ca92082b2412aed66c8422c2466bde544ef jdk8-b84
1329f9c38d93c8caf339d7687df8371d06fe9e56 jdk8-b87
a1e10f3adc47c8602a72e43a41403a642e73e0b1 jdk8-b88
ec434cfd2752a7742c875c2fe7d556d8b81c0f3a jdk8-b89
+e19283cd30a43fca94d8f7639c73ef66db493b1e jdk8-b90
+997c0fae2b12108959387862be54b78ca0ae3fca jdk8-b91
diff --git a/langtools/make/tools/genstubs/GenStubs.java b/langtools/make/tools/genstubs/GenStubs.java
index 5ff9f35789b..0ff475c9473 100644
--- a/langtools/make/tools/genstubs/GenStubs.java
+++ b/langtools/make/tools/genstubs/GenStubs.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@ import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCIdent;
@@ -204,6 +205,21 @@ public class GenStubs {
tree.docComments = null;
}
+ /**
+ * methods: remove method bodies, make methods native
+ */
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ long prevClassMods = currClassMods;
+ currClassMods = tree.mods.flags;
+ try {
+ super.visitClassDef(tree);;
+ } finally {
+ currClassMods = prevClassMods;
+ }
+ }
+ private long currClassMods = 0;
+
/**
* methods: remove method bodies, make methods native
*/
@@ -215,7 +231,11 @@ public class GenStubs {
tree.params = translateVarDefs(tree.params);
tree.thrown = translate(tree.thrown);
if (tree.restype != null && tree.body != null) {
- tree.mods.flags |= Flags.NATIVE;
+ if ((currClassMods & Flags.INTERFACE) != 0) {
+ tree.mods.flags &= ~Flags.DEFAULT;
+ } else {
+ tree.mods.flags |= Flags.NATIVE;
+ }
tree.body = null;
}
result = tree;
diff --git a/langtools/makefiles/BuildLangtools.gmk b/langtools/makefiles/BuildLangtools.gmk
index cd96a601e00..57d216b2bf9 100644
--- a/langtools/makefiles/BuildLangtools.gmk
+++ b/langtools/makefiles/BuildLangtools.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -56,7 +56,7 @@ $(eval $(call SetupJavaCompilation,BUILD_TOOLS,\
# The compileprops tools compiles a properties file into a resource bundle.
TOOL_COMPILEPROPS_CMD:=$(JAVA) -cp $(LANGTOOLS_OUTPUTDIR)/btclasses compileproperties.CompileProperties -quiet
# Lookup the properties that need to be compiled into resource bundles.
-PROPSOURCES:=$(shell find $(LANGTOOLS_TOPDIR)/src/share/classes -name "*.properties")
+PROPSOURCES:=$(shell $(FIND) $(LANGTOOLS_TOPDIR)/src/share/classes -name "*.properties")
# Strip away prefix and suffix, leaving for example only: "com/sun/tools/javac/resources/javac_zh_CN"
PROPPATHS:=$(patsubst $(LANGTOOLS_TOPDIR)/src/share/classes/%.properties,%,$(PROPSOURCES))
# Generate the list of java files to be created.
@@ -70,13 +70,13 @@ PROPCMDLINE:=$(subst _SPACE_,$(SPACE),$(join $(addprefix -compile_SPACE_,$(PROPS
# Now setup the rule for the generation of the resource bundles.
$(LANGTOOLS_OUTPUTDIR)/gensrc/_the_props.d : $(PROPSOURCES) $(BUILD_TOOLS)
- rm -rf $(@D)/*
- mkdir -p $(@D) $(PROPDIRS)
- printf "jdk=$(JDK_VERSION)\nfull=$(FULL_VERSION)\nrelease=$(RELEASE)\n" > $(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/javah/resources/version.properties
- printf "jdk=$(JDK_VERSION)\nfull=$(FULL_VERSION)\nrelease=$(RELEASE)\n" > $(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/javap/resources/version.properties
- printf "jdk=$(JDK_VERSION)\nfull=$(FULL_VERSION)\nrelease=$(RELEASE)\n" > $(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/javac/resources/version.properties
- printf "jdk=$(JDK_VERSION)\nfull=$(FULL_VERSION)\nrelease=$(RELEASE)\n" > $(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/jdeps/resources/version.properties
- echo Compiling $(words $(PROPSOURCES) v1 v2 v3) properties into resource bundles
+ $(RM) -r $(@D)/*
+ $(MKDIR) -p $(@D) $(PROPDIRS)
+ $(PRINTF) "jdk=$(JDK_VERSION)\nfull=$(FULL_VERSION)\nrelease=$(RELEASE)\n" > $(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/javah/resources/version.properties
+ $(PRINTF) "jdk=$(JDK_VERSION)\nfull=$(FULL_VERSION)\nrelease=$(RELEASE)\n" > $(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/javap/resources/version.properties
+ $(PRINTF) "jdk=$(JDK_VERSION)\nfull=$(FULL_VERSION)\nrelease=$(RELEASE)\n" > $(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/javac/resources/version.properties
+ $(PRINTF) "jdk=$(JDK_VERSION)\nfull=$(FULL_VERSION)\nrelease=$(RELEASE)\n" > $(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/jdeps/resources/version.properties
+ $(ECHO) Compiling $(words $(PROPSOURCES) v1 v2 v3) properties into resource bundles
$(TOOL_COMPILEPROPS_CMD) $(PROPCMDLINE) \
-compile $(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/javah/resources/version.properties \
$(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/javah/resources/version.java \
@@ -90,7 +90,7 @@ $(LANGTOOLS_OUTPUTDIR)/gensrc/_the_props.d : $(PROPSOURCES) $(BUILD_TOOLS)
-compile $(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/jdeps/resources/version.properties \
$(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/jdeps/resources/version.java \
java.util.ListResourceBundle
- echo PROPS_ARE_CREATED=yes > $@
+ $(ECHO) PROPS_ARE_CREATED=yes > $@
# Trigger the generation of the resource bundles. After the resource bundles have
# been compiled, then the makefile will restart and the newly created java files
@@ -123,10 +123,10 @@ ifeq ($(PROPS_ARE_CREATED),yes)
genstubs.GenStubs
# We fetch source from the JDK...
JDKS=$(JDK_TOPDIR)/src/share/classes
- # Build the list of classes to generate stubs from. java/util/Objects.java isn't
+ # Build the list of classes to generate stubs from. java/util/function/Predicate.java isn't
# currently needed, but is used as a demo for now.
STUBSOURCES:=$(shell $(FIND) $(JDKS) -name "*.java" | $(GREP) \
- -e "$(JDKS)/java/util/Objects.java")
+ -e "$(JDKS)/java/util/function/Predicate.java")
# Rewrite the file names into class names because the GenStubs tool require this.
STUBCLASSES:=$(subst /,.,$(patsubst $(JDKS)/%.java,%,$(STUBSOURCES)))
@@ -134,19 +134,19 @@ ifeq ($(PROPS_ARE_CREATED),yes)
$(LANGTOOLS_OUTPUTDIR)/genstubs/_the_stubs.d : $(STUBSOURCES) $(BUILD_TOOLS) \
$(LANGTOOLS_OUTPUTDIR)/dist/bootstrap/lib/javac.jar \
$(LANGTOOLS_OUTPUTDIR)/gensrc/_the_props.d
- mkdir -p $(@D)
- mkdir -p $(LANGTOOLS_OUTPUTDIR)/tmpstubs
- echo $(LOG_INFO) Generating stubs from JDK sources.
- ($(TOOL_GENSTUBS_CMD) -s $(LANGTOOLS_OUTPUTDIR)/tmpstubs -sourcepath $(JDKS) $(STUBCLASSES) && echo STUBS_ARE_CREATED=yes > $@)
+ $(MKDIR) -p $(@D)
+ $(MKDIR) -p $(LANGTOOLS_OUTPUTDIR)/tmpstubs
+ $(ECHO) $(LOG_INFO) Generating stubs from JDK sources.
+ ($(TOOL_GENSTUBS_CMD) -s $(LANGTOOLS_OUTPUTDIR)/tmpstubs -sourcepath $(JDKS) $(STUBCLASSES) && $(ECHO) STUBS_ARE_CREATED=yes > $@)
if $(DIFF) -x "_the*" -rq $(LANGTOOLS_OUTPUTDIR)/tmpstubs $(LANGTOOLS_OUTPUTDIR)/genstubs > /dev/null 2>&1; then \
- echo $(LOG_INFO) No changes in the stubs!; \
- rm -rf $(LANGTOOLS_OUTPUTDIR)/tmpstubs; \
+ $(ECHO) $(LOG_INFO) No changes in the stubs!; \
+ $(RM) -r $(LANGTOOLS_OUTPUTDIR)/tmpstubs; \
else \
- echo $(LOG_INFO) Changes in stubs detected!; \
- rm -rf $(@D); \
- mv $(LANGTOOLS_OUTPUTDIR)/tmpstubs $(@D); \
+ $(ECHO) $(LOG_INFO) Changes in stubs detected!; \
+ $(RM) -r $(@D); \
+ $(MV) $(LANGTOOLS_OUTPUTDIR)/tmpstubs $(@D); \
fi
- echo STUBS_ARE_CREATED=yes > $@
+ $(ECHO) STUBS_ARE_CREATED=yes > $@
# Trigger a generation of the genstubs java source code and a restart
# of the makefile to make sure that the following build setup use the
diff --git a/langtools/src/share/classes/com/sun/source/tree/VariableTree.java b/langtools/src/share/classes/com/sun/source/tree/VariableTree.java
index 7fba7df2b58..86fce994cb9 100644
--- a/langtools/src/share/classes/com/sun/source/tree/VariableTree.java
+++ b/langtools/src/share/classes/com/sun/source/tree/VariableTree.java
@@ -33,6 +33,7 @@ import javax.lang.model.element.Name;
* For example:
*
* modifiers type name initializer ;
+ * modifiers type qualified-name.this
*
*
* @jls sections 8.3 and 14.4
@@ -45,6 +46,7 @@ import javax.lang.model.element.Name;
public interface VariableTree extends StatementTree {
ModifiersTree getModifiers();
Name getName();
+ ExpressionTree getNameExpression();
Tree getType();
ExpressionTree getInitializer();
}
diff --git a/langtools/src/share/classes/com/sun/source/util/DocTreePath.java b/langtools/src/share/classes/com/sun/source/util/DocTreePath.java
new file mode 100644
index 00000000000..07206301298
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/source/util/DocTreePath.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.util;
+
+import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.doctree.DocTree;
+import java.util.Iterator;
+
+/**
+ * A path of tree nodes, typically used to represent the sequence of ancestor
+ * nodes of a tree node up to the top level DocCommentTree node.
+ *
+ * @since 1.8
+ */
+@jdk.Supported
+public class DocTreePath implements Iterable {
+ /**
+ * Gets a documentation tree path for a tree node within a compilation unit.
+ * @return null if the node is not found
+ */
+ public static DocTreePath getPath(TreePath treePath, DocCommentTree doc, DocTree target) {
+ return getPath(new DocTreePath(treePath, doc), target);
+ }
+
+ /**
+ * Gets a documentation tree path for a tree node within a subtree identified by a DocTreePath object.
+ * @return null if the node is not found
+ */
+ public static DocTreePath getPath(DocTreePath path, DocTree target) {
+ path.getClass();
+ target.getClass();
+
+ class Result extends Error {
+ static final long serialVersionUID = -5942088234594905625L;
+ DocTreePath path;
+ Result(DocTreePath path) {
+ this.path = path;
+ }
+ }
+
+ class PathFinder extends DocTreePathScanner {
+ public DocTreePath scan(DocTree tree, DocTree target) {
+ if (tree == target) {
+ throw new Result(new DocTreePath(getCurrentPath(), target));
+ }
+ return super.scan(tree, target);
+ }
+ }
+
+ if (path.getLeaf() == target) {
+ return path;
+ }
+
+ try {
+ new PathFinder().scan(path, target);
+ } catch (Result result) {
+ return result.path;
+ }
+ return null;
+ }
+
+ /**
+ * Creates a DocTreePath for a root node.
+ *
+ * @param treePath the TreePath from which the root node was created.
+ * @param t the DocCommentTree to create the path for.
+ */
+ public DocTreePath(TreePath treePath, DocCommentTree t) {
+ treePath.getClass();
+ t.getClass();
+
+ this.treePath = treePath;
+ this.docComment = t;
+ this.parent = null;
+ this.leaf = t;
+ }
+
+ /**
+ * Creates a DocTreePath for a child node.
+ */
+ public DocTreePath(DocTreePath p, DocTree t) {
+ if (t.getKind() == DocTree.Kind.DOC_COMMENT) {
+ throw new IllegalArgumentException("Use DocTreePath(TreePath, DocCommentTree) to construct DocTreePath for a DocCommentTree.");
+ } else {
+ treePath = p.treePath;
+ docComment = p.docComment;
+ parent = p;
+ }
+ leaf = t;
+ }
+
+ /**
+ * Get the TreePath associated with this path.
+ * @return TreePath for this DocTreePath
+ */
+ public TreePath getTreePath() {
+ return treePath;
+ }
+
+ /**
+ * Get the DocCommentTree associated with this path.
+ * @return DocCommentTree for this DocTreePath
+ */
+ public DocCommentTree getDocComment() {
+ return docComment;
+ }
+
+ /**
+ * Get the leaf node for this path.
+ * @return DocTree for this DocTreePath
+ */
+ public DocTree getLeaf() {
+ return leaf;
+ }
+
+ /**
+ * Get the path for the enclosing node, or null if there is no enclosing node.
+ * @return DocTreePath of parent
+ */
+ public DocTreePath getParentPath() {
+ return parent;
+ }
+
+ public Iterator iterator() {
+ return new Iterator() {
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ public DocTree next() {
+ DocTree t = next.leaf;
+ next = next.parent;
+ return t;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ private DocTreePath next = DocTreePath.this;
+ };
+ }
+
+ private final TreePath treePath;
+ private final DocCommentTree docComment;
+ private final DocTree leaf;
+ private final DocTreePath parent;
+}
diff --git a/langtools/src/share/classes/com/sun/source/util/DocTreePathScanner.java b/langtools/src/share/classes/com/sun/source/util/DocTreePathScanner.java
new file mode 100644
index 00000000000..326c1554e36
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/source/util/DocTreePathScanner.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.source.util;
+
+import com.sun.source.doctree.DocTree;
+
+/**
+ * A DocTreeVisitor that visits all the child tree nodes, and provides
+ * support for maintaining a path for the parent nodes.
+ * To visit nodes of a particular type, just override the
+ * corresponding visitorXYZ method.
+ * Inside your method, call super.visitXYZ to visit descendant
+ * nodes.
+ *
+ * @since 1.8
+ */
+@jdk.Supported
+public class DocTreePathScanner extends DocTreeScanner {
+ /**
+ * Scan a tree from a position identified by a TreePath.
+ */
+ public R scan(DocTreePath path, P p) {
+ this.path = path;
+ try {
+ return path.getLeaf().accept(this, p);
+ } finally {
+ this.path = null;
+ }
+ }
+
+ /**
+ * Scan a single node.
+ * The current path is updated for the duration of the scan.
+ */
+ @Override
+ public R scan(DocTree tree, P p) {
+ if (tree == null)
+ return null;
+
+ DocTreePath prev = path;
+ path = new DocTreePath(path, tree);
+ try {
+ return tree.accept(this, p);
+ } finally {
+ path = prev;
+ }
+ }
+
+ /**
+ * Get the current path for the node, as built up by the currently
+ * active set of scan calls.
+ */
+ public DocTreePath getCurrentPath() {
+ return path;
+ }
+
+ private DocTreePath path;
+}
diff --git a/langtools/src/share/classes/com/sun/source/util/DocTrees.java b/langtools/src/share/classes/com/sun/source/util/DocTrees.java
index 94f68bbd4a7..affc5f3a16d 100644
--- a/langtools/src/share/classes/com/sun/source/util/DocTrees.java
+++ b/langtools/src/share/classes/com/sun/source/util/DocTrees.java
@@ -67,10 +67,10 @@ public abstract class DocTrees extends Trees {
public abstract DocCommentTree getDocCommentTree(TreePath path);
/**
- * Gets the language model element referred to by a ReferenceTree that
- * appears on the declaration identified by the given path.
+ * Gets the language model element referred to by the leaf node of the given
+ * {@link DocTreePath}, or null if unknown.
*/
- public abstract Element getElement(TreePath path, ReferenceTree reference);
+ public abstract Element getElement(DocTreePath path);
public abstract DocSourcePositions getSourcePositions();
diff --git a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java
index ee05b228b32..a6d0466a729 100644
--- a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java
+++ b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java
@@ -149,6 +149,7 @@ public class TreeScanner implements TreeVisitor {
public R visitVariable(VariableTree node, P p) {
R r = scan(node.getModifiers(), p);
r = scanAndReduce(node.getType(), p, r);
+ r = scanAndReduce(node.getNameExpression(), p, r);
r = scanAndReduce(node.getInitializer(), p, r);
return r;
}
diff --git a/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java
index be6d5282c69..17c21c81b37 100644
--- a/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java
@@ -751,7 +751,7 @@ public class ClassWriter {
break;
// exception parameter
case EXCEPTION_PARAMETER:
- out.writeByte(p.exception_index);
+ out.writeShort(p.exception_index);
break;
// method receiver
case METHOD_RECEIVER:
@@ -770,11 +770,11 @@ public class ClassWriter {
break;
// class extends or implements clause
case CLASS_EXTENDS:
- out.writeByte(p.type_index);
+ out.writeShort(p.type_index);
break;
// throws
case THROWS:
- out.writeByte(p.type_index);
+ out.writeShort(p.type_index);
break;
// method parameter
case METHOD_FORMAL_PARAMETER:
diff --git a/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java b/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java
index ec842d0e3c1..1369069a9eb 100644
--- a/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java
+++ b/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java
@@ -111,7 +111,7 @@ public class TypeAnnotation {
break;
// exception parameter
case EXCEPTION_PARAMETER:
- position.exception_index = cr.readUnsignedByte();
+ position.exception_index = cr.readUnsignedShort();
break;
// method receiver
case METHOD_RECEIVER:
@@ -198,7 +198,7 @@ public class TypeAnnotation {
break;
// exception parameter
case EXCEPTION_PARAMETER:
- n += 1; // exception_index
+ n += 2; // exception_index
break;
// method receiver
case METHOD_RECEIVER:
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java
index 4ec8af0c426..0468a8e9134 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java
@@ -60,17 +60,24 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
* @param htmltree the content tree to which the parameters will be added.
* @return the display length required to write this information.
*/
- protected int addTypeParameters(ExecutableMemberDoc member, Content htmltree) {
- LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_MEMBER_TYPE_PARAMS, member, false);
- String typeParameters = writer.getTypeParameterLinks(linkInfo);
- if (linkInfo.displayLength > 0) {
- Content linkContent = new RawHtml(typeParameters);
- htmltree.addContent(linkContent);
+ protected void addTypeParameters(ExecutableMemberDoc member, Content htmltree) {
+ Content typeParameters = getTypeParameters(member);
+ if (!typeParameters.isEmpty()) {
+ htmltree.addContent(typeParameters);
htmltree.addContent(writer.getSpace());
- writer.displayLength += linkInfo.displayLength + 1;
}
- return linkInfo.displayLength;
+ }
+
+ /**
+ * Get the type parameters for the executable member.
+ *
+ * @param member the member for which to get the type parameters.
+ * @return the type parameters.
+ */
+ protected Content getTypeParameters(ExecutableMemberDoc member) {
+ LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.MEMBER_TYPE_PARAMS, member);
+ return writer.getTypeParameterLinks(linkInfo);
}
/**
@@ -78,7 +85,7 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
*/
protected Content getDeprecatedLink(ProgramElementDoc member) {
ExecutableMemberDoc emd = (ExecutableMemberDoc)member;
- return writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER, (MemberDoc) emd,
+ return writer.getDocLink(LinkInfoImpl.Kind.MEMBER, (MemberDoc) emd,
emd.qualifiedName() + emd.flatSignature());
}
@@ -90,16 +97,15 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
* @param member the member being linked to
* @param tdSummary the content tree to which the link will be added
*/
- protected void addSummaryLink(int context, ClassDoc cd, ProgramElementDoc member,
+ protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member,
Content tdSummary) {
ExecutableMemberDoc emd = (ExecutableMemberDoc)member;
String name = emd.name();
- Content strong = HtmlTree.STRONG(new RawHtml(
+ Content strong = HtmlTree.STRONG(
writer.getDocLink(context, cd, (MemberDoc) emd,
- name, false)));
+ name, false));
Content code = HtmlTree.CODE(strong);
- writer.displayLength = name.length();
- addParameters(emd, false, code);
+ addParameters(emd, false, code, name.length() - 1);
tdSummary.addContent(code);
}
@@ -112,9 +118,9 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
*/
protected void addInheritedSummaryLink(ClassDoc cd,
ProgramElementDoc member, Content linksTree) {
- linksTree.addContent(new RawHtml(
- writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER, cd, (MemberDoc) member,
- member.name(), false)));
+ linksTree.addContent(
+ writer.getDocLink(LinkInfoImpl.Kind.MEMBER, cd, (MemberDoc) member,
+ member.name(), false));
}
/**
@@ -126,11 +132,11 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
* @param tree the content tree to which the parameter information will be added.
*/
protected void addParam(ExecutableMemberDoc member, Parameter param,
- boolean isVarArg, Content tree) {
+ boolean isVarArg, Content tree) {
if (param.type() != null) {
- Content link = new RawHtml(writer.getLink(new LinkInfoImpl(
- configuration, LinkInfoImpl.CONTEXT_EXECUTABLE_MEMBER_PARAM,
- param.type(), isVarArg)));
+ Content link = writer.getLink(new LinkInfoImpl(
+ configuration, LinkInfoImpl.Kind.EXECUTABLE_MEMBER_PARAM,
+ param.type()).varargs(isVarArg));
tree.addContent(link);
}
if(param.name().length() > 0) {
@@ -153,8 +159,8 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
tree.addContent(writer.getSpace());
tree.addContent(rcvrType.typeName());
LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CLASS_SIGNATURE, rcvrType);
- tree.addContent(new RawHtml(writer.getTypeParameterLinks(linkInfo)));
+ LinkInfoImpl.Kind.CLASS_SIGNATURE, rcvrType);
+ tree.addContent(writer.getTypeParameterLinks(linkInfo));
tree.addContent(writer.getSpace());
tree.addContent("this");
}
@@ -166,8 +172,8 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
* @param member the member to write parameters for.
* @param htmltree the content tree to which the parameters information will be added.
*/
- protected void addParameters(ExecutableMemberDoc member, Content htmltree) {
- addParameters(member, true, htmltree);
+ protected void addParameters(ExecutableMemberDoc member, Content htmltree, int indentSize) {
+ addParameters(member, true, htmltree, indentSize);
}
/**
@@ -178,15 +184,11 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
* @param htmltree the content tree to which the parameters information will be added.
*/
protected void addParameters(ExecutableMemberDoc member,
- boolean includeAnnotations, Content htmltree) {
+ boolean includeAnnotations, Content htmltree, int indentSize) {
htmltree.addContent("(");
String sep = "";
Parameter[] params = member.parameters();
- String indent = makeSpace(writer.displayLength);
- if (configuration.linksource) {
- //add spaces to offset indentation changes caused by link.
- indent+= makeSpace(member.name().length());
- }
+ String indent = makeSpace(indentSize + 1);
Type rcvrType = member.receiverType();
if (includeAnnotations && rcvrType instanceof AnnotatedType) {
AnnotationDesc[] descList = rcvrType.asAnnotatedType().annotations();
@@ -240,53 +242,30 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
* @param member the member to write exceptions for.
* @param htmltree the content tree to which the exceptions information will be added.
*/
- protected void addExceptions(ExecutableMemberDoc member, Content htmltree) {
+ protected void addExceptions(ExecutableMemberDoc member, Content htmltree, int indentSize) {
Type[] exceptions = member.thrownExceptionTypes();
- if(exceptions.length > 0) {
+ if (exceptions.length > 0) {
LinkInfoImpl memberTypeParam = new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_MEMBER, member, false);
- int retlen = getReturnTypeLength(member);
- writer.getTypeParameterLinks(memberTypeParam);
- retlen += memberTypeParam.displayLength == 0 ?
- 0 : memberTypeParam.displayLength + 1;
- String indent = makeSpace(modifierString(member).length() +
- member.name().length() + retlen - 4);
+ LinkInfoImpl.Kind.MEMBER, member);
+ String indent = makeSpace(indentSize + 1 - 7);
htmltree.addContent(DocletConstants.NL);
htmltree.addContent(indent);
htmltree.addContent("throws ");
- indent += " ";
- Content link = new RawHtml(writer.getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_MEMBER, exceptions[0])));
+ indent = makeSpace(indentSize + 1);
+ Content link = writer.getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.MEMBER, exceptions[0]));
htmltree.addContent(link);
for(int i = 1; i < exceptions.length; i++) {
htmltree.addContent(",");
htmltree.addContent(DocletConstants.NL);
htmltree.addContent(indent);
- Content exceptionLink = new RawHtml(writer.getLink(new LinkInfoImpl(
- configuration, LinkInfoImpl.CONTEXT_MEMBER, exceptions[i])));
+ Content exceptionLink = writer.getLink(new LinkInfoImpl(
+ configuration, LinkInfoImpl.Kind.MEMBER, exceptions[i]));
htmltree.addContent(exceptionLink);
}
}
}
- protected int getReturnTypeLength(ExecutableMemberDoc member) {
- if (member instanceof MethodDoc) {
- MethodDoc method = (MethodDoc)member;
- Type rettype = method.returnType();
- if (rettype.isPrimitive()) {
- return rettype.typeName().length() +
- rettype.dimension().length();
- } else {
- LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_MEMBER, rettype);
- writer.getLink(linkInfo);
- return linkInfo.displayLength;
- }
- } else { // it's a constructordoc
- return -1;
- }
- }
-
protected ClassDoc implementsMethodInIntfac(MethodDoc method,
ClassDoc[] intfacs) {
for (int i = 0; i < intfacs.length; i++) {
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java
index 62dabe3ec17..87a5bce3367 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -139,9 +139,8 @@ public class AbstractIndexWriter extends HtmlDocletWriter {
* @param dlTree the content tree to which the description will be added
*/
protected void addDescription(ClassDoc cd, Content dlTree) {
- Content link = new RawHtml(
- getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_INDEX, cd, true)));
+ Content link = getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.INDEX, cd).strong(true));
Content dt = HtmlTree.DT(link);
dt.addContent(" - ");
addClassInfo(cd, dt);
@@ -152,7 +151,7 @@ public class AbstractIndexWriter extends HtmlDocletWriter {
}
/**
- * Add the classkind(class, interface, exception, error of the class
+ * Add the classkind (class, interface, exception), error of the class
* passed.
*
* @param cd the class being documented
@@ -161,8 +160,9 @@ public class AbstractIndexWriter extends HtmlDocletWriter {
protected void addClassInfo(ClassDoc cd, Content contentTree) {
contentTree.addContent(getResource("doclet.in",
Util.getTypeName(configuration, cd, false),
- getPackageLinkString(cd.containingPackage(),
- Util.getPackageName(cd.containingPackage()), false)));
+ getPackageLink(cd.containingPackage(),
+ Util.getPackageName(cd.containingPackage()))
+ ));
}
/**
@@ -175,11 +175,8 @@ public class AbstractIndexWriter extends HtmlDocletWriter {
String name = (member instanceof ExecutableMemberDoc)?
member.name() + ((ExecutableMemberDoc)member).flatSignature() :
member.name();
- if (name.indexOf("<") != -1 || name.indexOf(">") != -1) {
- name = Util.escapeHtmlChars(name);
- }
Content span = HtmlTree.SPAN(HtmlStyle.strong,
- getDocLink(LinkInfoImpl.CONTEXT_INDEX, member, name));
+ getDocLink(LinkInfoImpl.Kind.INDEX, member, name));
Content dt = HtmlTree.DT(span);
dt.addContent(" - ");
addMemberDesc(member, dt);
@@ -253,7 +250,7 @@ public class AbstractIndexWriter extends HtmlDocletWriter {
getResource("doclet.Method_in", classdesc));
}
}
- addPreQualifiedClassLink(LinkInfoImpl.CONTEXT_INDEX, containing,
+ addPreQualifiedClassLink(LinkInfoImpl.Kind.INDEX, containing,
false, contentTree);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java
index b8b03545380..8ca56915294 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -91,7 +91,7 @@ public abstract class AbstractMemberWriter {
*
* @return a string for the table caption
*/
- public abstract String getCaption();
+ public abstract Content getCaption();
/**
* Get the summary table header for the member.
@@ -143,7 +143,7 @@ public abstract class AbstractMemberWriter {
*/
protected void addSummaryLink(ClassDoc cd, ProgramElementDoc member,
Content tdSummary) {
- addSummaryLink(LinkInfoImpl.CONTEXT_MEMBER, cd, member, tdSummary);
+ addSummaryLink(LinkInfoImpl.Kind.MEMBER, cd, member, tdSummary);
}
/**
@@ -154,7 +154,7 @@ public abstract class AbstractMemberWriter {
* @param member the member to be documented
* @param tdSummary the content tree to which the summary link will be added
*/
- protected abstract void addSummaryLink(int context,
+ protected abstract void addSummaryLink(LinkInfoImpl.Kind context,
ClassDoc cd, ProgramElementDoc member, Content tdSummary);
/**
@@ -193,14 +193,13 @@ public abstract class AbstractMemberWriter {
protected abstract void addNavDetailLink(boolean link, Content liNav);
/**
- * Add the member name to the content tree and modifies the display length.
+ * Add the member name to the content tree.
*
* @param name the member name to be added to the content tree.
* @param htmltree the content tree to which the name will be added.
*/
protected void addName(String name, Content htmltree) {
htmltree.addContent(name);
- writer.displayLength += name.length();
}
/**
@@ -259,7 +258,7 @@ public abstract class AbstractMemberWriter {
return "";
}
StringBuilder sb = new StringBuilder(len);
- for(int i = 0; i < len; i++) {
+ for (int i = 0; i < len; i++) {
sb.append(' ');
}
return sb.toString();
@@ -286,19 +285,22 @@ public abstract class AbstractMemberWriter {
} else {
if (member instanceof ExecutableMemberDoc &&
((ExecutableMemberDoc) member).typeParameters().length > 0) {
+ Content typeParameters = ((AbstractExecutableMemberWriter) this).getTypeParameters(
+ (ExecutableMemberDoc) member);
+ code.addContent(typeParameters);
//Code to avoid ugly wrapping in member summary table.
- int displayLength = ((AbstractExecutableMemberWriter) this).addTypeParameters(
- (ExecutableMemberDoc) member, code);
- if (displayLength > 10) {
+ if (typeParameters.charCount() > 10) {
code.addContent(new HtmlTree(HtmlTag.BR));
+ } else {
+ code.addContent(writer.getSpace());
}
- code.addContent(new RawHtml(
+ code.addContent(
writer.getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_SUMMARY_RETURN_TYPE, type))));
+ LinkInfoImpl.Kind.SUMMARY_RETURN_TYPE, type)));
} else {
- code.addContent(new RawHtml(
+ code.addContent(
writer.getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_SUMMARY_RETURN_TYPE, type))));
+ LinkInfoImpl.Kind.SUMMARY_RETURN_TYPE, type)));
}
}
@@ -346,10 +348,10 @@ public abstract class AbstractMemberWriter {
* @param contentTree the content tree to which the deprecated information will be added.
*/
protected void addDeprecatedInfo(ProgramElementDoc member, Content contentTree) {
- String output = (new DeprecatedTaglet()).getTagletOutput(member,
- writer.getTagletWriterInstance(false)).toString().trim();
+ Content output = (new DeprecatedTaglet()).getTagletOutput(member,
+ writer.getTagletWriterInstance(false));
if (!output.isEmpty()) {
- Content deprecatedContent = new RawHtml(output);
+ Content deprecatedContent = output;
Content div = HtmlTree.DIV(HtmlStyle.block, deprecatedContent);
contentTree.addContent(div);
}
@@ -378,7 +380,7 @@ public abstract class AbstractMemberWriter {
* @return a header content for the section.
*/
protected Content getHead(MemberDoc member) {
- Content memberContent = new RawHtml(member.name());
+ Content memberContent = new StringContent(member.name());
Content heading = HtmlTree.HEADING(HtmlConstants.MEMBER_HEADING, memberContent);
return heading;
}
@@ -412,7 +414,7 @@ public abstract class AbstractMemberWriter {
String tableSummary, String[] tableHeader, Content contentTree) {
if (deprmembers.size() > 0) {
Content table = HtmlTree.TABLE(0, 3, 0, tableSummary,
- writer.getTableCaption(configuration.getText(headingKey)));
+ writer.getTableCaption(configuration.getResource(headingKey)));
table.addContent(writer.getSummaryTableHeader(tableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
for (int i = 0; i < deprmembers.size(); i++) {
@@ -444,7 +446,7 @@ public abstract class AbstractMemberWriter {
* @param contentTree the content tree to which the use information will be added
*/
protected void addUseInfo(List extends ProgramElementDoc> mems,
- String heading, String tableSummary, Content contentTree) {
+ Content heading, String tableSummary, Content contentTree) {
if (mems == null) {
return;
}
@@ -483,7 +485,7 @@ public abstract class AbstractMemberWriter {
tdLast.addContent(name);
}
addSummaryLink(pgmdoc instanceof ClassDoc ?
- LinkInfoImpl.CONTEXT_CLASS_USE : LinkInfoImpl.CONTEXT_MEMBER,
+ LinkInfoImpl.Kind.CLASS_USE : LinkInfoImpl.Kind.MEMBER,
cd, pgmdoc, tdLast);
writer.addSummaryLinkComment(this, pgmdoc, tdLast);
tr.addContent(tdLast);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java
index 7ccee48c2ef..95cd4a44d08 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java
@@ -158,10 +158,10 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
}
body.addContent(div);
if (configuration.showProfiles) {
- String profileSummary = configuration.getText("doclet.Profiles");
- String profilesTableSummary = configuration.getText("doclet.Member_Table_Summary",
- configuration.getText("doclet.Profile_Summary"),
- configuration.getText("doclet.profiles"));
+ Content profileSummary = configuration.getResource("doclet.Profiles");
+ Content profilesTableSummary = configuration.getResource("doclet.Member_Table_Summary",
+ configuration.getResource("doclet.Profile_Summary"),
+ configuration.getResource("doclet.profiles"));
addProfilesList(profileSummary, profilesTableSummary, body);
}
addPackagesList(packages, text, tableSummary, body);
@@ -217,7 +217,7 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
* @param profilesTableSummary the profiles table summary information
* @param body the content tree to which the profiles list will be added
*/
- protected void addProfilesList(String profileSummary, String profilesTableSummary,
+ protected void addProfilesList(Content profileSummary, Content profilesTableSummary,
Content body) {
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java
index 53af067c6c9..8cc0b61045a 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -152,7 +152,7 @@ public abstract class AbstractTreeWriter extends HtmlDocletWriter {
} else {
contentTree.addContent(", ");
}
- addPreQualifiedClassLink(LinkInfoImpl.CONTEXT_TREE,
+ addPreQualifiedClassLink(LinkInfoImpl.Kind.TREE,
interfaces[i], contentTree);
counter++;
}
@@ -170,7 +170,7 @@ public abstract class AbstractTreeWriter extends HtmlDocletWriter {
* @param contentTree the content tree to which the information will be added
*/
protected void addPartialInfo(ClassDoc cd, Content contentTree) {
- addPreQualifiedStrongClassLink(LinkInfoImpl.CONTEXT_TREE, cd, contentTree);
+ addPreQualifiedStrongClassLink(LinkInfoImpl.Kind.TREE, cd, contentTree);
}
/**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java
index 85b8ce9791c..0d6846ae387 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -156,14 +156,13 @@ public class AllClassesFrameWriter extends HtmlDocletWriter {
if (!Util.isCoreClass(cd)) {
continue;
}
- String label = italicsClassName(cd, false);
+ Content label = italicsClassName(cd, false);
Content linkContent;
- if(wantFrames){
- linkContent = new RawHtml(getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.ALL_CLASSES_FRAME, cd, label, "classFrame")));
+ if (wantFrames) {
+ linkContent = getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.ALL_CLASSES_FRAME, cd).label(label).target("classFrame"));
} else {
- linkContent = new RawHtml(getLink(new LinkInfoImpl(
- configuration, cd, label)));
+ linkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.DEFAULT, cd).label(label));
}
Content li = HtmlTree.LI(linkContent);
content.addContent(li);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java
index cf8fba180a7..ff8fc100f0a 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -111,8 +111,8 @@ public class AnnotationTypeOptionalMemberWriterImpl extends
/**
* {@inheritDoc}
*/
- public String getCaption() {
- return configuration.getText("doclet.Annotation_Type_Optional_Members");
+ public Content getCaption() {
+ return configuration.getResource("doclet.Annotation_Type_Optional_Members");
}
/**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java
index daee94e5bf9..6583b891809 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -105,9 +105,9 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter
Content pre = new HtmlTree(HtmlTag.PRE);
writer.addAnnotationInfo(member, pre);
addModifiers(member, pre);
- Content link = new RawHtml(
+ Content link =
writer.getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_MEMBER, getType(member))));
+ LinkInfoImpl.Kind.MEMBER, getType(member)));
pre.addContent(link);
pre.addContent(writer.getSpace());
if (configuration.linksource) {
@@ -183,8 +183,8 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter
/**
* {@inheritDoc}
*/
- public String getCaption() {
- return configuration.getText("doclet.Annotation_Type_Required_Members");
+ public Content getCaption() {
+ return configuration.getResource("doclet.Annotation_Type_Required_Members");
}
/**
@@ -223,10 +223,10 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter
/**
* {@inheritDoc}
*/
- protected void addSummaryLink(int context, ClassDoc cd, ProgramElementDoc member,
+ protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member,
Content tdSummary) {
- Content strong = HtmlTree.STRONG(new RawHtml(
- writer.getDocLink(context, (MemberDoc) member, member.name(), false)));
+ Content strong = HtmlTree.STRONG(
+ writer.getDocLink(context, (MemberDoc) member, member.name(), false));
Content code = HtmlTree.CODE(strong);
tdSummary.addContent(code);
}
@@ -251,7 +251,7 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter
* {@inheritDoc}
*/
protected Content getDeprecatedLink(ProgramElementDoc member) {
- return writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER,
+ return writer.getDocLink(LinkInfoImpl.Kind.MEMBER,
(MemberDoc) member, ((MemberDoc)member).qualifiedName());
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java
index a86312e7660..df4b5ea1ef8 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -116,9 +116,9 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
public Content getNavLinkPrevious() {
Content li;
if (prev != null) {
- Content prevLink = new RawHtml(getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CLASS, prev.asClassDoc(), "",
- configuration.getText("doclet.Prev_Class"), true)));
+ Content prevLink = getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.CLASS, prev.asClassDoc())
+ .label(configuration.getText("doclet.Prev_Class")).strong(true));
li = HtmlTree.LI(prevLink);
}
else
@@ -134,9 +134,9 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
public Content getNavLinkNext() {
Content li;
if (next != null) {
- Content nextLink = new RawHtml(getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CLASS, next.asClassDoc(), "",
- configuration.getText("doclet.Next_Class"), true)));
+ Content nextLink = getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.CLASS, next.asClassDoc())
+ .label(configuration.getText("doclet.Next_Class")).strong(true));
li = HtmlTree.LI(nextLink);
}
else
@@ -163,11 +163,11 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
div.addContent(pkgNameDiv);
}
LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CLASS_HEADER, annotationType, false);
+ LinkInfoImpl.Kind.CLASS_HEADER, annotationType);
Content headerContent = new StringContent(header);
Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING, true,
HtmlStyle.title, headerContent);
- heading.addContent(new RawHtml(getTypeParameterLinks(linkInfo)));
+ heading.addContent(getTypeParameterLinks(linkInfo));
div.addContent(heading);
bodyTree.addContent(div);
return bodyTree;
@@ -220,9 +220,9 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
addAnnotationInfo(annotationType, pre);
pre.addContent(modifiers);
LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CLASS_SIGNATURE, annotationType, false);
+ LinkInfoImpl.Kind.CLASS_SIGNATURE, annotationType);
Content annotationName = new StringContent(annotationType.name());
- Content parameterLinks = new RawHtml(getTypeParameterLinks(linkInfo));
+ Content parameterLinks = getTypeParameterLinks(linkInfo);
if (configuration.linksource) {
addSrcLink(annotationType, annotationName, pre);
pre.addContent(parameterLinks);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java
index 8e2e14fceb4..90da398c685 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -256,10 +256,10 @@ public class ClassUseWriter extends SubWriterHolderWriter {
*/
protected void addPackageList(Content contentTree) throws IOException {
Content table = HtmlTree.TABLE(0, 3, 0, useTableSummary,
- getTableCaption(configuration.getText(
+ getTableCaption(configuration.getResource(
"doclet.ClassUse_Packages.that.use.0",
- getLink(new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc,
- false)))));
+ getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc
+ )))));
table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
Iterator it = pkgSet.iterator();
@@ -291,10 +291,10 @@ public class ClassUseWriter extends SubWriterHolderWriter {
return;
}
Content table = HtmlTree.TABLE(0, 3, 0, useTableSummary,
- getTableCaption(configuration.getText(
+ getTableCaption(configuration.getResource(
"doclet.ClassUse_PackageAnnotation",
getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc, false)))));
+ LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc)))));
table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
Iterator it = pkgToPackageAnnotations.iterator();
@@ -331,11 +331,10 @@ public class ClassUseWriter extends SubWriterHolderWriter {
for (Iterator it = pkgSet.iterator(); it.hasNext();) {
PackageDoc pkg = it.next();
Content li = HtmlTree.LI(HtmlStyle.blockList, getMarkerAnchor(pkg.name()));
- Content link = new RawHtml(
- configuration.getText("doclet.ClassUse_Uses.of.0.in.1",
- getLink(new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_CLASS_USE_HEADER,
- classdoc, false)),
- getPackageLinkString(pkg, Util.getPackageName(pkg), false)));
+ Content link = getResource("doclet.ClassUse_Uses.of.0.in.1",
+ getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER,
+ classdoc)),
+ getPackageLink(pkg, Util.getPackageName(pkg)));
Content heading = HtmlTree.HEADING(HtmlConstants.SUMMARY_HEADING, link);
li.addContent(heading);
addClassUse(pkg, li);
@@ -368,71 +367,71 @@ public class ClassUseWriter extends SubWriterHolderWriter {
* @param contentTree the content tree to which the class use information will be added
*/
protected void addClassUse(PackageDoc pkg, Content contentTree) throws IOException {
- String classLink = getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc, false));
- String pkgLink = getPackageLinkString(pkg, Util.getPackageName(pkg), false);
+ Content classLink = getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc));
+ Content pkgLink = getPackageLink(pkg, Util.getPackageName(pkg));
classSubWriter.addUseInfo(pkgToClassAnnotations.get(pkg.name()),
- configuration.getText("doclet.ClassUse_Annotation", classLink,
+ configuration.getResource("doclet.ClassUse_Annotation", classLink,
pkgLink), classUseTableSummary, contentTree);
classSubWriter.addUseInfo(pkgToClassTypeParameter.get(pkg.name()),
- configuration.getText("doclet.ClassUse_TypeParameter", classLink,
+ configuration.getResource("doclet.ClassUse_TypeParameter", classLink,
pkgLink), classUseTableSummary, contentTree);
classSubWriter.addUseInfo(pkgToSubclass.get(pkg.name()),
- configuration.getText("doclet.ClassUse_Subclass", classLink,
+ configuration.getResource("doclet.ClassUse_Subclass", classLink,
pkgLink), subclassUseTableSummary, contentTree);
classSubWriter.addUseInfo(pkgToSubinterface.get(pkg.name()),
- configuration.getText("doclet.ClassUse_Subinterface", classLink,
+ configuration.getResource("doclet.ClassUse_Subinterface", classLink,
pkgLink), subinterfaceUseTableSummary, contentTree);
classSubWriter.addUseInfo(pkgToImplementingClass.get(pkg.name()),
- configuration.getText("doclet.ClassUse_ImplementingClass", classLink,
+ configuration.getResource("doclet.ClassUse_ImplementingClass", classLink,
pkgLink), classUseTableSummary, contentTree);
fieldSubWriter.addUseInfo(pkgToField.get(pkg.name()),
- configuration.getText("doclet.ClassUse_Field", classLink,
+ configuration.getResource("doclet.ClassUse_Field", classLink,
pkgLink), fieldUseTableSummary, contentTree);
fieldSubWriter.addUseInfo(pkgToFieldAnnotations.get(pkg.name()),
- configuration.getText("doclet.ClassUse_FieldAnnotations", classLink,
+ configuration.getResource("doclet.ClassUse_FieldAnnotations", classLink,
pkgLink), fieldUseTableSummary, contentTree);
fieldSubWriter.addUseInfo(pkgToFieldTypeParameter.get(pkg.name()),
- configuration.getText("doclet.ClassUse_FieldTypeParameter", classLink,
+ configuration.getResource("doclet.ClassUse_FieldTypeParameter", classLink,
pkgLink), fieldUseTableSummary, contentTree);
methodSubWriter.addUseInfo(pkgToMethodAnnotations.get(pkg.name()),
- configuration.getText("doclet.ClassUse_MethodAnnotations", classLink,
+ configuration.getResource("doclet.ClassUse_MethodAnnotations", classLink,
pkgLink), methodUseTableSummary, contentTree);
methodSubWriter.addUseInfo(pkgToMethodParameterAnnotations.get(pkg.name()),
- configuration.getText("doclet.ClassUse_MethodParameterAnnotations", classLink,
+ configuration.getResource("doclet.ClassUse_MethodParameterAnnotations", classLink,
pkgLink), methodUseTableSummary, contentTree);
methodSubWriter.addUseInfo(pkgToMethodTypeParameter.get(pkg.name()),
- configuration.getText("doclet.ClassUse_MethodTypeParameter", classLink,
+ configuration.getResource("doclet.ClassUse_MethodTypeParameter", classLink,
pkgLink), methodUseTableSummary, contentTree);
methodSubWriter.addUseInfo(pkgToMethodReturn.get(pkg.name()),
- configuration.getText("doclet.ClassUse_MethodReturn", classLink,
+ configuration.getResource("doclet.ClassUse_MethodReturn", classLink,
pkgLink), methodUseTableSummary, contentTree);
methodSubWriter.addUseInfo(pkgToMethodReturnTypeParameter.get(pkg.name()),
- configuration.getText("doclet.ClassUse_MethodReturnTypeParameter", classLink,
+ configuration.getResource("doclet.ClassUse_MethodReturnTypeParameter", classLink,
pkgLink), methodUseTableSummary, contentTree);
methodSubWriter.addUseInfo(pkgToMethodArgs.get(pkg.name()),
- configuration.getText("doclet.ClassUse_MethodArgs", classLink,
+ configuration.getResource("doclet.ClassUse_MethodArgs", classLink,
pkgLink), methodUseTableSummary, contentTree);
methodSubWriter.addUseInfo(pkgToMethodArgTypeParameter.get(pkg.name()),
- configuration.getText("doclet.ClassUse_MethodArgsTypeParameters", classLink,
+ configuration.getResource("doclet.ClassUse_MethodArgsTypeParameters", classLink,
pkgLink), methodUseTableSummary, contentTree);
methodSubWriter.addUseInfo(pkgToMethodThrows.get(pkg.name()),
- configuration.getText("doclet.ClassUse_MethodThrows", classLink,
+ configuration.getResource("doclet.ClassUse_MethodThrows", classLink,
pkgLink), methodUseTableSummary, contentTree);
constrSubWriter.addUseInfo(pkgToConstructorAnnotations.get(pkg.name()),
- configuration.getText("doclet.ClassUse_ConstructorAnnotations", classLink,
+ configuration.getResource("doclet.ClassUse_ConstructorAnnotations", classLink,
pkgLink), constructorUseTableSummary, contentTree);
constrSubWriter.addUseInfo(pkgToConstructorParameterAnnotations.get(pkg.name()),
- configuration.getText("doclet.ClassUse_ConstructorParameterAnnotations", classLink,
+ configuration.getResource("doclet.ClassUse_ConstructorParameterAnnotations", classLink,
pkgLink), constructorUseTableSummary, contentTree);
constrSubWriter.addUseInfo(pkgToConstructorArgs.get(pkg.name()),
- configuration.getText("doclet.ClassUse_ConstructorArgs", classLink,
+ configuration.getResource("doclet.ClassUse_ConstructorArgs", classLink,
pkgLink), constructorUseTableSummary, contentTree);
constrSubWriter.addUseInfo(pkgToConstructorArgTypeParameter.get(pkg.name()),
- configuration.getText("doclet.ClassUse_ConstructorArgsTypeParameters", classLink,
+ configuration.getResource("doclet.ClassUse_ConstructorArgsTypeParameters", classLink,
pkgLink), constructorUseTableSummary, contentTree);
constrSubWriter.addUseInfo(pkgToConstructorThrows.get(pkg.name()),
- configuration.getText("doclet.ClassUse_ConstructorThrows", classLink,
+ configuration.getResource("doclet.ClassUse_ConstructorThrows", classLink,
pkgLink), constructorUseTableSummary, contentTree);
}
@@ -450,7 +449,10 @@ public class ClassUseWriter extends SubWriterHolderWriter {
Content bodyTree = getBody(true, getWindowTitle(title));
addTop(bodyTree);
addNavLinks(true, bodyTree);
- Content headContent = getResource("doclet.ClassUse_Title", cltype, clname);
+ ContentBuilder headContent = new ContentBuilder();
+ headContent.addContent(getResource("doclet.ClassUse_Title", cltype));
+ headContent.addContent(new HtmlTree(HtmlTag.BR));
+ headContent.addContent(clname);
Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING,
true, HtmlStyle.title, headContent);
Content div = HtmlTree.DIV(HtmlStyle.header, heading);
@@ -476,9 +478,9 @@ public class ClassUseWriter extends SubWriterHolderWriter {
* @return a content tree for the class page link
*/
protected Content getNavLinkClass() {
- Content linkContent = new RawHtml(getLink(new LinkInfoImpl(
- configuration, LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc,
- "", configuration.getText("doclet.Class"), false)));
+ Content linkContent = getLink(new LinkInfoImpl(
+ configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc)
+ .label(configuration.getText("doclet.Class")));
Content li = HtmlTree.LI(linkContent);
return li;
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java
index 36df53150c8..47e9346a072 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java
@@ -124,9 +124,9 @@ public class ClassWriterImpl extends SubWriterHolderWriter
public Content getNavLinkPrevious() {
Content li;
if (prev != null) {
- Content prevLink = new RawHtml(getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CLASS, prev, "",
- configuration.getText("doclet.Prev_Class"), true)));
+ Content prevLink = getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.CLASS, prev)
+ .label(configuration.getText("doclet.Prev_Class")).strong(true));
li = HtmlTree.LI(prevLink);
}
else
@@ -142,9 +142,9 @@ public class ClassWriterImpl extends SubWriterHolderWriter
public Content getNavLinkNext() {
Content li;
if (next != null) {
- Content nextLink = new RawHtml(getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CLASS, next, "",
- configuration.getText("doclet.Next_Class"), true)));
+ Content nextLink = getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.CLASS, next)
+ .label(configuration.getText("doclet.Next_Class")).strong(true));
li = HtmlTree.LI(nextLink);
}
else
@@ -185,13 +185,13 @@ public class ClassWriterImpl extends SubWriterHolderWriter
div.addContent(pkgNameDiv);
}
LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CLASS_HEADER, classDoc, false);
+ LinkInfoImpl.Kind.CLASS_HEADER, classDoc);
//Let's not link to ourselves in the header.
linkInfo.linkToSelf = false;
Content headerContent = new StringContent(header);
Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING, true,
HtmlStyle.title, headerContent);
- heading.addContent(new RawHtml(getTypeParameterLinks(linkInfo)));
+ heading.addContent(getTypeParameterLinks(linkInfo));
div.addContent(heading);
bodyTree.addContent(div);
return bodyTree;
@@ -245,11 +245,11 @@ public class ClassWriterImpl extends SubWriterHolderWriter
addAnnotationInfo(classDoc, pre);
pre.addContent(modifiers);
LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CLASS_SIGNATURE, classDoc, false);
+ LinkInfoImpl.Kind.CLASS_SIGNATURE, classDoc);
//Let's not link to ourselves in the signature.
linkInfo.linkToSelf = false;
Content className = new StringContent(classDoc.name());
- Content parameterLinks = new RawHtml(getTypeParameterLinks(linkInfo));
+ Content parameterLinks = getTypeParameterLinks(linkInfo);
if (configuration.linksource) {
addSrcLink(classDoc, className, pre);
pre.addContent(parameterLinks);
@@ -264,9 +264,9 @@ public class ClassWriterImpl extends SubWriterHolderWriter
if (superclass != null) {
pre.addContent(DocletConstants.NL);
pre.addContent("extends ");
- Content link = new RawHtml(getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
- superclass)));
+ Content link = getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME,
+ superclass));
pre.addContent(link);
}
}
@@ -285,9 +285,9 @@ public class ClassWriterImpl extends SubWriterHolderWriter
} else {
pre.addContent(", ");
}
- Content link = new RawHtml(getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
- implIntfacs[i])));
+ Content link = getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME,
+ implIntfacs[i]));
pre.addContent(link);
counter++;
}
@@ -360,22 +360,21 @@ public class ClassWriterImpl extends SubWriterHolderWriter
private Content getTreeForClassHelper(Type type) {
Content li = new HtmlTree(HtmlTag.LI);
if (type.equals(classDoc)) {
- String typeParameters = getTypeParameterLinks(
- new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_TREE,
- classDoc, false));
+ Content typeParameters = getTypeParameterLinks(
+ new LinkInfoImpl(configuration, LinkInfoImpl.Kind.TREE,
+ classDoc));
if (configuration.shouldExcludeQualifier(
classDoc.containingPackage().name())) {
li.addContent(type.asClassDoc().name());
- li.addContent(new RawHtml(typeParameters));
+ li.addContent(typeParameters);
} else {
li.addContent(type.asClassDoc().qualifiedName());
- li.addContent(new RawHtml(typeParameters));
+ li.addContent(typeParameters);
}
} else {
- Content link = new RawHtml(getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CLASS_TREE_PARENT,
- type instanceof ClassDoc ? (ClassDoc) type : type,
- configuration.getClassName(type.asClassDoc()), false)));
+ Content link = getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.CLASS_TREE_PARENT, type)
+ .label(configuration.getClassName(type.asClassDoc())));
li.addContent(link);
}
return li;
@@ -396,9 +395,8 @@ public class ClassWriterImpl extends SubWriterHolderWriter
*/
public void addTypeParamInfo(Content classInfoTree) {
if (classDoc.typeParamTags().length > 0) {
- TagletOutput output = (new ParamTaglet()).getTagletOutput(classDoc,
+ Content typeParam = (new ParamTaglet()).getTagletOutput(classDoc,
getTagletWriterInstance(false));
- Content typeParam = new RawHtml(output.toString());
Content dl = HtmlTree.DL(typeParam);
classInfoTree.addContent(dl);
}
@@ -419,7 +417,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter
"doclet.Subclasses");
Content dt = HtmlTree.DT(label);
Content dl = HtmlTree.DL(dt);
- dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_SUBCLASSES,
+ dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUBCLASSES,
subclasses));
classInfoTree.addContent(dl);
}
@@ -437,7 +435,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter
"doclet.Subinterfaces");
Content dt = HtmlTree.DT(label);
Content dl = HtmlTree.DL(dt);
- dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_SUBINTERFACES,
+ dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUBINTERFACES,
subInterfaces));
classInfoTree.addContent(dl);
}
@@ -461,7 +459,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter
"doclet.Implementing_Classes");
Content dt = HtmlTree.DT(label);
Content dl = HtmlTree.DL(dt);
- dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_CLASSES,
+ dl.addContent(getClassLinks(LinkInfoImpl.Kind.IMPLEMENTED_CLASSES,
implcl));
classInfoTree.addContent(dl);
}
@@ -479,7 +477,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter
"doclet.All_Implemented_Interfaces");
Content dt = HtmlTree.DT(label);
Content dl = HtmlTree.DL(dt);
- dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_INTERFACES,
+ dl.addContent(getClassLinks(LinkInfoImpl.Kind.IMPLEMENTED_INTERFACES,
interfaceArray));
classInfoTree.addContent(dl);
}
@@ -497,7 +495,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter
"doclet.All_Superinterfaces");
Content dt = HtmlTree.DT(label);
Content dl = HtmlTree.DL(dt);
- dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_SUPER_INTERFACES,
+ dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUPER_INTERFACES,
interfaceArray));
classInfoTree.addContent(dl);
}
@@ -520,8 +518,8 @@ public class ClassWriterImpl extends SubWriterHolderWriter
Content dt = HtmlTree.DT(label);
Content dl = HtmlTree.DL(dt);
Content dd = new HtmlTree(HtmlTag.DD);
- dd.addContent(new RawHtml(getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CLASS, outerClass, false))));
+ dd.addContent(getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.CLASS, outerClass)));
dl.addContent(dd);
classInfoTree.addContent(dl);
}
@@ -569,7 +567,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter
* @param list the list of classes
* @return a content tree for the class list
*/
- private Content getClassLinks(int context, List> list) {
+ private Content getClassLinks(LinkInfoImpl.Kind context, List> list) {
Object[] typeList = list.toArray();
Content dd = new HtmlTree(HtmlTag.DD);
for (int i = 0; i < list.size(); i++) {
@@ -578,12 +576,12 @@ public class ClassWriterImpl extends SubWriterHolderWriter
dd.addContent(separator);
}
if (typeList[i] instanceof ClassDoc) {
- Content link = new RawHtml(getLink(
- new LinkInfoImpl(configuration, context, (ClassDoc)(typeList[i]))));
+ Content link = getLink(
+ new LinkInfoImpl(configuration, context, (ClassDoc)(typeList[i])));
dd.addContent(link);
} else {
- Content link = new RawHtml(getLink(
- new LinkInfoImpl(configuration, context, (Type)(typeList[i]))));
+ Content link = getLink(
+ new LinkInfoImpl(configuration, context, (Type)(typeList[i])));
dd.addContent(link);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java
index e74c73835d9..2b37dd66481 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java
@@ -31,6 +31,7 @@ import java.util.*;
import javax.tools.JavaFileManager;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.formats.html.markup.ContentBuilder;
import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.doclets.internal.toolkit.util.*;
import com.sun.tools.doclint.DocLint;
@@ -562,4 +563,9 @@ public class ConfigurationImpl extends Configuration {
}
return true;
}
+
+ @Override
+ public Content newContent() {
+ return new ContentBuilder();
+ }
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java
index afc0aeb2d6f..02dfdb3d7cc 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -184,13 +184,17 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter
*/
public Content getConstantMembersHeader(ClassDoc cd) {
//generate links backward only to public classes.
- String classlink = (cd.isPublic() || cd.isProtected()) ?
+ Content classlink = (cd.isPublic() || cd.isProtected()) ?
getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CONSTANT_SUMMARY, cd, false)) :
- cd.qualifiedName();
+ LinkInfoImpl.Kind.CONSTANT_SUMMARY, cd)) :
+ new StringContent(cd.qualifiedName());
String name = cd.containingPackage().name();
if (name.length() > 0) {
- return getClassName(name + "." + classlink);
+ Content cb = new ContentBuilder();
+ cb.addContent(name);
+ cb.addContent(".");
+ cb.addContent(classlink);
+ return getClassName(cb);
} else {
return getClassName(classlink);
}
@@ -202,7 +206,7 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter
* @param classStr the class name to print.
* @return the table caption and header
*/
- protected Content getClassName(String classStr) {
+ protected Content getClassName(Content classStr) {
Content table = HtmlTree.TABLE(0, 3, 0, constantsTableSummary,
getTableCaption(classStr));
table.addContent(getSummaryTableHeader(constantsTableHeader, "col"));
@@ -260,8 +264,8 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter
code.addContent(modifier);
code.addContent(getSpace());
}
- Content type = new RawHtml(getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_CONSTANT_SUMMARY, member.type())));
+ Content type = getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.CONSTANT_SUMMARY, member.type()));
code.addContent(type);
tdType.addContent(code);
return tdType;
@@ -274,8 +278,8 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter
* @return the name column of the constant table row
*/
private Content getNameColumn(FieldDoc member) {
- Content nameContent = new RawHtml(getDocLink(
- LinkInfoImpl.CONTEXT_CONSTANT_SUMMARY, member, member.name(), false));
+ Content nameContent = getDocLink(
+ LinkInfoImpl.Kind.CONSTANT_SUMMARY, member, member.name(), false);
Content code = HtmlTree.CODE(nameContent);
return HtmlTree.TD(code);
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java
index 85cd1c5beca..496737078dd 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java
@@ -126,7 +126,6 @@ public class ConstructorWriterImpl extends AbstractExecutableMemberWriter
* {@inheritDoc}
*/
public Content getSignature(ConstructorDoc constructor) {
- writer.displayLength = 0;
Content pre = new HtmlTree(HtmlTag.PRE);
writer.addAnnotationInfo(constructor, pre);
addModifiers(constructor, pre);
@@ -136,8 +135,9 @@ public class ConstructorWriterImpl extends AbstractExecutableMemberWriter
} else {
addName(constructor.name(), pre);
}
- addParameters(constructor, pre);
- addExceptions(constructor, pre);
+ int indent = pre.charCount();
+ addParameters(constructor, pre, indent);
+ addExceptions(constructor, pre, indent);
return pre;
}
@@ -225,8 +225,8 @@ public class ConstructorWriterImpl extends AbstractExecutableMemberWriter
/**
* {@inheritDoc}
*/
- public String getCaption() {
- return configuration.getText("doclet.Constructors");
+ public Content getCaption() {
+ return configuration.getResource("doclet.Constructors");
}
/**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java
index a37d8be9e5c..9643e878117 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -101,8 +101,8 @@ public class EnumConstantWriterImpl extends AbstractMemberWriter
Content pre = new HtmlTree(HtmlTag.PRE);
writer.addAnnotationInfo(enumConstant, pre);
addModifiers(enumConstant, pre);
- Content enumConstantLink = new RawHtml(writer.getLink(new LinkInfoImpl(
- configuration, LinkInfoImpl.CONTEXT_MEMBER, enumConstant.type())));
+ Content enumConstantLink = writer.getLink(new LinkInfoImpl(
+ configuration, LinkInfoImpl.Kind.MEMBER, enumConstant.type()));
pre.addContent(enumConstantLink);
pre.addContent(" ");
if (configuration.linksource) {
@@ -182,8 +182,8 @@ public class EnumConstantWriterImpl extends AbstractMemberWriter
/**
* {@inheritDoc}
*/
- public String getCaption() {
- return configuration.getText("doclet.Enum_Constants");
+ public Content getCaption() {
+ return configuration.getResource("doclet.Enum_Constants");
}
/**
@@ -220,10 +220,10 @@ public class EnumConstantWriterImpl extends AbstractMemberWriter
/**
* {@inheritDoc}
*/
- protected void addSummaryLink(int context, ClassDoc cd, ProgramElementDoc member,
+ protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member,
Content tdSummary) {
- Content strong = HtmlTree.STRONG(new RawHtml(
- writer.getDocLink(context, (MemberDoc) member, member.name(), false)));
+ Content strong = HtmlTree.STRONG(
+ writer.getDocLink(context, (MemberDoc) member, member.name(), false));
Content code = HtmlTree.CODE(strong);
tdSummary.addContent(code);
}
@@ -254,7 +254,7 @@ public class EnumConstantWriterImpl extends AbstractMemberWriter
* {@inheritDoc}
*/
protected Content getDeprecatedLink(ProgramElementDoc member) {
- return writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER,
+ return writer.getDocLink(LinkInfoImpl.Kind.MEMBER,
(MemberDoc) member, ((FieldDoc)member).qualifiedName());
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java
index dc5515882bc..4f1dbbd9bff 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -102,8 +102,8 @@ public class FieldWriterImpl extends AbstractMemberWriter
Content pre = new HtmlTree(HtmlTag.PRE);
writer.addAnnotationInfo(field, pre);
addModifiers(field, pre);
- Content fieldlink = new RawHtml(writer.getLink(new LinkInfoImpl(
- configuration, LinkInfoImpl.CONTEXT_MEMBER, field.type())));
+ Content fieldlink = writer.getLink(new LinkInfoImpl(
+ configuration, LinkInfoImpl.Kind.MEMBER, field.type()));
pre.addContent(fieldlink);
pre.addContent(" ");
if (configuration.linksource) {
@@ -132,12 +132,12 @@ public class FieldWriterImpl extends AbstractMemberWriter
(! (holder.isPublic() || Util.isLinkable(holder, configuration)))) {
writer.addInlineComment(field, fieldDocTree);
} else {
- Content link = new RawHtml(
- writer.getDocLink(LinkInfoImpl.CONTEXT_FIELD_DOC_COPY,
+ Content link =
+ writer.getDocLink(LinkInfoImpl.Kind.FIELD_DOC_COPY,
holder, field,
holder.isIncluded() ?
holder.typeName() : holder.qualifiedTypeName(),
- false));
+ false);
Content codeLink = HtmlTree.CODE(link);
Content strong = HtmlTree.STRONG(holder.isClass()?
writer.descfrmClassLabel : writer.descfrmInterfaceLabel);
@@ -203,8 +203,8 @@ public class FieldWriterImpl extends AbstractMemberWriter
/**
* {@inheritDoc}
*/
- public String getCaption() {
- return configuration.getText("doclet.Fields");
+ public Content getCaption() {
+ return configuration.getResource("doclet.Fields");
}
/**
@@ -239,8 +239,8 @@ public class FieldWriterImpl extends AbstractMemberWriter
* {@inheritDoc}
*/
public void addInheritedSummaryLabel(ClassDoc cd, Content inheritedTree) {
- Content classLink = new RawHtml(writer.getPreQualifiedClassLink(
- LinkInfoImpl.CONTEXT_MEMBER, cd, false));
+ Content classLink = writer.getPreQualifiedClassLink(
+ LinkInfoImpl.Kind.MEMBER, cd, false);
Content label = new StringContent(cd.isClass() ?
configuration.getText("doclet.Fields_Inherited_From_Class") :
configuration.getText("doclet.Fields_Inherited_From_Interface"));
@@ -254,10 +254,10 @@ public class FieldWriterImpl extends AbstractMemberWriter
/**
* {@inheritDoc}
*/
- protected void addSummaryLink(int context, ClassDoc cd, ProgramElementDoc member,
+ protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member,
Content tdSummary) {
- Content strong = HtmlTree.STRONG(new RawHtml(
- writer.getDocLink(context, cd , (MemberDoc) member, member.name(), false)));
+ Content strong = HtmlTree.STRONG(
+ writer.getDocLink(context, cd , (MemberDoc) member, member.name(), false));
Content code = HtmlTree.CODE(strong);
tdSummary.addContent(code);
}
@@ -267,9 +267,9 @@ public class FieldWriterImpl extends AbstractMemberWriter
*/
protected void addInheritedSummaryLink(ClassDoc cd,
ProgramElementDoc member, Content linksTree) {
- linksTree.addContent(new RawHtml(
- writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER, cd, (MemberDoc)member,
- member.name(), false)));
+ linksTree.addContent(
+ writer.getDocLink(LinkInfoImpl.Kind.MEMBER, cd, (MemberDoc)member,
+ member.name(), false));
}
/**
@@ -284,7 +284,7 @@ public class FieldWriterImpl extends AbstractMemberWriter
* {@inheritDoc}
*/
protected Content getDeprecatedLink(ProgramElementDoc member) {
- return writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER,
+ return writer.getDocLink(LinkInfoImpl.Kind.MEMBER,
(MemberDoc) member, ((FieldDoc)member).qualifiedName());
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java
index b853cea635d..3d483cdff0c 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java
@@ -121,7 +121,7 @@ public class FrameOutputWriter extends HtmlDocletWriter {
getResource("doclet.Frame_Alert"));
noframes.addContent(noframesHead);
Content p = HtmlTree.P(getResource("doclet.Frame_Warning_Message",
- getHyperLinkString(configuration.topFile,
+ getHyperLink(configuration.topFile,
configuration.getText("doclet.Non_Frame_Version"))));
noframes.addContent(p);
contentTree.addContent(noframes);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java
index 9d14671f3d2..2884d3b45bb 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -113,7 +113,7 @@ public class HelpWriter extends HtmlDocletWriter {
getResource("doclet.Overview"));
Content liOverview = HtmlTree.LI(HtmlStyle.blockList, overviewHeading);
Content line3 = getResource("doclet.Help_line_3",
- getHyperLinkString(DocPaths.OVERVIEW_SUMMARY,
+ getHyperLink(DocPaths.OVERVIEW_SUMMARY,
configuration.getText("doclet.Overview")));
Content overviewPara = HtmlTree.P(line3);
liOverview.addContent(overviewPara);
@@ -234,8 +234,9 @@ public class HelpWriter extends HtmlDocletWriter {
getResource("doclet.Help_line_16"));
Content liTree = HtmlTree.LI(HtmlStyle.blockList, treeHead);
Content line17 = getResource("doclet.Help_line_17_with_tree_link",
- getHyperLinkString(DocPaths.OVERVIEW_TREE,
- configuration.getText("doclet.Class_Hierarchy")));
+ getHyperLink(DocPaths.OVERVIEW_TREE,
+ configuration.getText("doclet.Class_Hierarchy")),
+ HtmlTree.CODE(new StringContent("java.lang.Object")));
Content treePara = HtmlTree.P(line17);
liTree.addContent(treePara);
HtmlTree tul = new HtmlTree(HtmlTag.UL);
@@ -252,19 +253,19 @@ public class HelpWriter extends HtmlDocletWriter {
getResource("doclet.Deprecated_API"));
Content liDeprecated = HtmlTree.LI(HtmlStyle.blockList, dHead);
Content line20 = getResource("doclet.Help_line_20_with_deprecated_api_link",
- getHyperLinkString(DocPaths.DEPRECATED_LIST,
+ getHyperLink(DocPaths.DEPRECATED_LIST,
configuration.getText("doclet.Deprecated_API")));
Content dPara = HtmlTree.P(line20);
liDeprecated.addContent(dPara);
ul.addContent(liDeprecated);
}
if (configuration.createindex) {
- String indexlink;
+ Content indexlink;
if (configuration.splitindex) {
- indexlink = getHyperLinkString(DocPaths.INDEX_FILES.resolve(DocPaths.indexN(1)),
+ indexlink = getHyperLink(DocPaths.INDEX_FILES.resolve(DocPaths.indexN(1)),
configuration.getText("doclet.Index"));
} else {
- indexlink = getHyperLinkString(DocPaths.INDEX_ALL,
+ indexlink = getHyperLink(DocPaths.INDEX_ALL,
configuration.getText("doclet.Index"));
}
Content indexHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
@@ -293,7 +294,7 @@ public class HelpWriter extends HtmlDocletWriter {
getResource("doclet.All_Classes"));
Content liAllClasses = HtmlTree.LI(HtmlStyle.blockList, allclassesHead);
Content line27 = getResource("doclet.Help_line_27",
- getHyperLinkString(DocPaths.ALLCLASSES_NOFRAME,
+ getHyperLink(DocPaths.ALLCLASSES_NOFRAME,
configuration.getText("doclet.All_Classes")));
Content allclassesPara = HtmlTree.P(line27);
liAllClasses.addContent(allclassesPara);
@@ -309,7 +310,7 @@ public class HelpWriter extends HtmlDocletWriter {
getResource("doclet.Constants_Summary"));
Content liConst = HtmlTree.LI(HtmlStyle.blockList, constHead);
Content line29 = getResource("doclet.Help_line_29",
- getHyperLinkString(DocPaths.CONSTANT_VALUES,
+ getHyperLink(DocPaths.CONSTANT_VALUES,
configuration.getText("doclet.Constants_Summary")));
Content constPara = HtmlTree.P(line29);
liConst.addContent(constPara);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
index d30e8044c75..ba62e7cccec 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
@@ -74,11 +74,6 @@ public class HtmlDocletWriter extends HtmlDocWriter {
*/
public final DocPath filename;
- /**
- * The display length used for indentation while generating the class page.
- */
- public int displayLength = 0;
-
/**
* The global configuration information for this run.
*/
@@ -251,15 +246,11 @@ public class HtmlDocletWriter extends HtmlDocWriter {
if (doc instanceof MethodDoc) {
addMethodInfo((MethodDoc) doc, dl);
}
- TagletOutputImpl output = new TagletOutputImpl("");
+ Content output = new ContentBuilder();
TagletWriter.genTagOuput(configuration.tagletManager, doc,
- configuration.tagletManager.getCustomTags(doc),
+ configuration.tagletManager.getCustomTaglets(doc),
getTagletWriterInstance(false), output);
- String outputString = output.toString().trim();
- if (!outputString.isEmpty()) {
- Content resultString = new RawHtml(outputString);
- dl.addContent(resultString);
- }
+ dl.addContent(output);
htmltree.addContent(dl);
}
@@ -271,11 +262,11 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @return true if there are tags to be printed else return false.
*/
protected boolean hasSerializationOverviewTags(FieldDoc field) {
- TagletOutputImpl output = new TagletOutputImpl("");
+ Content output = new ContentBuilder();
TagletWriter.genTagOuput(configuration.tagletManager, field,
- configuration.tagletManager.getCustomTags(field),
+ configuration.tagletManager.getCustomTaglets(field),
getTagletWriterInstance(false), output);
- return (!output.toString().trim().isEmpty());
+ return !output.isEmpty();
}
/**
@@ -359,7 +350,7 @@ public class HtmlDocletWriter extends HtmlDocWriter {
int profileValue) {
if(classes.length > 0) {
Arrays.sort(classes);
- Content caption = getTableCaption(label);
+ Content caption = getTableCaption(new RawHtml(label));
Content table = HtmlTree.TABLE(HtmlStyle.packageSummary, 0, 3, 0,
tableSummary, caption);
table.addContent(getSummaryTableHeader(tableHeader, "col"));
@@ -372,9 +363,8 @@ public class HtmlDocletWriter extends HtmlDocWriter {
!configuration.isGeneratedDoc(classes[i])) {
continue;
}
- Content classContent = new RawHtml(getLink(new LinkInfoImpl(
- configuration, LinkInfoImpl.CONTEXT_PACKAGE, classes[i],
- false)));
+ Content classContent = getLink(new LinkInfoImpl(
+ configuration, LinkInfoImpl.Kind.PACKAGE, classes[i]));
Content tdClass = HtmlTree.TD(HtmlStyle.colFirst, classContent);
HtmlTree tr = HtmlTree.TR(tdClass);
if (i%2 == 0)
@@ -879,8 +869,7 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @param rawText the caption for the table which could be raw Html
* @return a content tree for the caption
*/
- public Content getTableCaption(String rawText) {
- Content title = new RawHtml(rawText);
+ public Content getTableCaption(Content title) {
Content captionSpan = HtmlTree.SPAN(title);
Content space = getSpace();
Content tabSpan = HtmlTree.SPAN(HtmlStyle.tabEnd, space);
@@ -948,7 +937,7 @@ public class HtmlDocletWriter extends HtmlDocWriter {
String tableSummary, String[] tableHeader, Content contentTree) {
if (deprPkgs.size() > 0) {
Content table = HtmlTree.TABLE(0, 3, 0, tableSummary,
- getTableCaption(configuration.getText(headingKey)));
+ getTableCaption(configuration.getResource(headingKey)));
table.addContent(getSummaryTableHeader(tableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
for (int i = 0; i < deprPkgs.size(); i++) {
@@ -1001,46 +990,10 @@ public class HtmlDocletWriter extends HtmlDocWriter {
*
* @param pkg the package to link to.
* @param label the label for the link.
- * @param isStrong true if the label should be strong.
- * @return the link to the given package.
+ * @return a content tree for the package link.
*/
- public String getPackageLinkString(PackageDoc pkg, String label,
- boolean isStrong) {
- return getPackageLinkString(pkg, label, isStrong, "");
- }
-
- /**
- * Return the link to the given package.
- *
- * @param pkg the package to link to.
- * @param label the label for the link.
- * @param isStrong true if the label should be strong.
- * @param style the font of the package link label.
- * @return the link to the given package.
- */
- public String getPackageLinkString(PackageDoc pkg, String label, boolean isStrong,
- String style) {
- boolean included = pkg != null && pkg.isIncluded();
- if (! included) {
- PackageDoc[] packages = configuration.packages;
- for (int i = 0; i < packages.length; i++) {
- if (packages[i].equals(pkg)) {
- included = true;
- break;
- }
- }
- }
- if (included || pkg == null) {
- return getHyperLinkString(pathString(pkg, DocPaths.PACKAGE_SUMMARY),
- label, isStrong, style);
- } else {
- DocLink crossPkgLink = getCrossPackageLink(Util.getPackageName(pkg));
- if (crossPkgLink != null) {
- return getHyperLinkString(crossPkgLink, label, isStrong, style);
- } else {
- return label;
- }
- }
+ public Content getPackageLink(PackageDoc pkg, String label) {
+ return getPackageLink(pkg, new StringContent(label));
}
/**
@@ -1074,9 +1027,9 @@ public class HtmlDocletWriter extends HtmlDocWriter {
}
}
- public String italicsClassName(ClassDoc cd, boolean qual) {
- String name = (qual)? cd.qualifiedName(): cd.name();
- return (cd.isInterface())? italicsText(name): name;
+ public Content italicsClassName(ClassDoc cd, boolean qual) {
+ Content name = new StringContent((qual)? cd.qualifiedName(): cd.name());
+ return (cd.isInterface())? HtmlTree.I(name): name;
}
/**
@@ -1109,11 +1062,9 @@ public class HtmlDocletWriter extends HtmlDocWriter {
*
* @return the link for the given class.
*/
- public String getLink(LinkInfoImpl linkInfo) {
+ public Content getLink(LinkInfoImpl linkInfo) {
LinkFactoryImpl factory = new LinkFactoryImpl(this);
- String link = factory.getLinkOutput(linkInfo).toString();
- displayLength += linkInfo.displayLength;
- return link;
+ return factory.getLink(linkInfo);
}
/**
@@ -1122,9 +1073,9 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @param linkInfo the information about the link.
* @return the type for the given class.
*/
- public String getTypeParameterLinks(LinkInfoImpl linkInfo) {
+ public Content getTypeParameterLinks(LinkInfoImpl linkInfo) {
LinkFactoryImpl factory = new LinkFactoryImpl(this);
- return factory.getTypeParameterLinks(linkInfo, false).toString();
+ return factory.getTypeParameterLinks(linkInfo, false);
}
/*************************************************************
@@ -1141,8 +1092,8 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @param style the style of the link.
* @param code true if the label should be code font.
*/
- public String getCrossClassLink(String qualifiedClassName, String refMemName,
- String label, boolean strong, String style,
+ public Content getCrossClassLink(String qualifiedClassName, String refMemName,
+ Content label, boolean strong, String style,
boolean code) {
String className = "";
String packageName = qualifiedClassName == null ? "" : qualifiedClassName;
@@ -1150,7 +1101,9 @@ public class HtmlDocletWriter extends HtmlDocWriter {
while ((periodIndex = packageName.lastIndexOf('.')) != -1) {
className = packageName.substring(periodIndex + 1, packageName.length()) +
(className.length() > 0 ? "." + className : "");
- String defaultLabel = code ? codeText(className) : className;
+ Content defaultLabel = new StringContent(className);
+ if (code)
+ defaultLabel = HtmlTree.CODE(defaultLabel);
packageName = packageName.substring(0, periodIndex);
if (getCrossPackageLink(packageName) != null) {
//The package exists in external documentation, so link to the external
@@ -1160,10 +1113,8 @@ public class HtmlDocletWriter extends HtmlDocWriter {
//have to assume that it does.
DocLink link = configuration.extern.getExternalLink(packageName, pathToRoot,
className + ".html", refMemName);
- return getHyperLinkString(link,
- (label == null) || label.length() == 0 ? defaultLabel : label,
-
-
+ return getHyperLink(link,
+ (label == null) || label.isEmpty() ? defaultLabel : label,
strong, style,
configuration.getText("doclet.Href_Class_Or_Interface_Title", packageName),
"");
@@ -1191,9 +1142,9 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @param cd the class doc to link to
* @return a content tree for the link
*/
- public Content getQualifiedClassLink(int context, ClassDoc cd) {
- return new RawHtml(getLink(new LinkInfoImpl(configuration, context, cd,
- configuration.getClassName(cd), "")));
+ public Content getQualifiedClassLink(LinkInfoImpl.Kind context, ClassDoc cd) {
+ return getLink(new LinkInfoImpl(configuration, context, cd)
+ .label(configuration.getClassName(cd)));
}
/**
@@ -1203,7 +1154,7 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @param cd the class doc to link to
* @param contentTree the content tree to which the link will be added
*/
- public void addPreQualifiedClassLink(int context, ClassDoc cd, Content contentTree) {
+ public void addPreQualifiedClassLink(LinkInfoImpl.Kind context, ClassDoc cd, Content contentTree) {
addPreQualifiedClassLink(context, cd, false, contentTree);
}
@@ -1216,15 +1167,15 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @param isStrong true if the link should be strong.
* @return the link with the package portion of the label in plain text.
*/
- public String getPreQualifiedClassLink(int context,
+ public Content getPreQualifiedClassLink(LinkInfoImpl.Kind context,
ClassDoc cd, boolean isStrong) {
- String classlink = "";
+ ContentBuilder classlink = new ContentBuilder();
PackageDoc pd = cd.containingPackage();
- if(pd != null && ! configuration.shouldExcludeQualifier(pd.name())) {
- classlink = getPkgName(cd);
+ if (pd != null && ! configuration.shouldExcludeQualifier(pd.name())) {
+ classlink.addContent(getPkgName(cd));
}
- classlink += getLink(new LinkInfoImpl(configuration,
- context, cd, cd.name(), isStrong));
+ classlink.addContent(getLink(new LinkInfoImpl(configuration,
+ context, cd).label(cd.name()).strong(isStrong)));
return classlink;
}
@@ -1238,14 +1189,14 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @param isStrong true if the link should be strong
* @param contentTree the content tree to which the link with be added
*/
- public void addPreQualifiedClassLink(int context,
+ public void addPreQualifiedClassLink(LinkInfoImpl.Kind context,
ClassDoc cd, boolean isStrong, Content contentTree) {
PackageDoc pd = cd.containingPackage();
if(pd != null && ! configuration.shouldExcludeQualifier(pd.name())) {
contentTree.addContent(getPkgName(cd));
}
- contentTree.addContent(new RawHtml(getLink(new LinkInfoImpl(configuration,
- context, cd, cd.name(), isStrong))));
+ contentTree.addContent(getLink(new LinkInfoImpl(configuration,
+ context, cd).label(cd.name()).strong(isStrong)));
}
/**
@@ -1256,7 +1207,7 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @param cd the class to link to
* @param contentTree the content tree to which the link with be added
*/
- public void addPreQualifiedStrongClassLink(int context, ClassDoc cd, Content contentTree) {
+ public void addPreQualifiedStrongClassLink(LinkInfoImpl.Kind context, ClassDoc cd, Content contentTree) {
addPreQualifiedClassLink(context, cd, true, contentTree);
}
@@ -1268,8 +1219,9 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @param label the label for the link
* @return a content tree for the doc link
*/
- public Content getDocLink(int context, MemberDoc doc, String label) {
- return getDocLink(context, doc.containingClass(), doc, label);
+ public Content getDocLink(LinkInfoImpl.Kind context, MemberDoc doc, String label) {
+ return getDocLink(context, doc.containingClass(), doc,
+ new StringContent(label));
}
/**
@@ -1281,8 +1233,8 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @param strong true if the link should be strong.
* @return the link for the given member.
*/
- public String getDocLink(int context, MemberDoc doc, String label,
- boolean strong) {
+ public Content getDocLink(LinkInfoImpl.Kind context, MemberDoc doc, String label,
+ boolean strong) {
return getDocLink(context, doc.containingClass(), doc, label, strong);
}
@@ -1298,8 +1250,12 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @param strong true if the link should be strong.
* @return the link for the given member.
*/
- public String getDocLink(int context, ClassDoc classDoc, MemberDoc doc,
- String label, boolean strong) {
+ public Content getDocLink(LinkInfoImpl.Kind context, ClassDoc classDoc, MemberDoc doc,
+ String label, boolean strong) {
+ return getDocLink(context, classDoc, doc, label, strong, false);
+ }
+ public Content getDocLink(LinkInfoImpl.Kind context, ClassDoc classDoc, MemberDoc doc,
+ Content label, boolean strong) {
return getDocLink(context, classDoc, doc, label, strong, false);
}
@@ -1316,18 +1272,28 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @param isProperty true if the doc parameter is a JavaFX property.
* @return the link for the given member.
*/
- public String getDocLink(int context, ClassDoc classDoc, MemberDoc doc,
- String label, boolean strong, boolean isProperty) {
+ public Content getDocLink(LinkInfoImpl.Kind context, ClassDoc classDoc, MemberDoc doc,
+ String label, boolean strong, boolean isProperty) {
+ return getDocLink(context, classDoc, doc, new StringContent(check(label)), strong, isProperty);
+ }
+
+ String check(String s) {
+ if (s.matches(".*[&<>].*"))throw new IllegalArgumentException(s);
+ return s;
+ }
+
+ public Content getDocLink(LinkInfoImpl.Kind context, ClassDoc classDoc, MemberDoc doc,
+ Content label, boolean strong, boolean isProperty) {
if (! (doc.isIncluded() ||
Util.isLinkable(classDoc, configuration))) {
return label;
} else if (doc instanceof ExecutableMemberDoc) {
ExecutableMemberDoc emd = (ExecutableMemberDoc)doc;
- return getLink(new LinkInfoImpl(configuration, context, classDoc,
- getAnchor(emd, isProperty), label, strong));
+ return getLink(new LinkInfoImpl(configuration, context, classDoc)
+ .label(label).where(getAnchor(emd, isProperty)).strong(strong));
} else if (doc instanceof MemberDoc) {
- return getLink(new LinkInfoImpl(configuration, context, classDoc,
- doc.name(), label, strong));
+ return getLink(new LinkInfoImpl(configuration, context, classDoc)
+ .label(label).where(doc.name()).strong(strong));
} else {
return label;
}
@@ -1344,20 +1310,20 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @param label the label for the link
* @return the link for the given member
*/
- public Content getDocLink(int context, ClassDoc classDoc, MemberDoc doc,
- String label) {
+ public Content getDocLink(LinkInfoImpl.Kind context, ClassDoc classDoc, MemberDoc doc,
+ Content label) {
if (! (doc.isIncluded() ||
Util.isLinkable(classDoc, configuration))) {
- return new StringContent(label);
+ return label;
} else if (doc instanceof ExecutableMemberDoc) {
- ExecutableMemberDoc emd = (ExecutableMemberDoc)doc;
- return new RawHtml(getLink(new LinkInfoImpl(configuration, context, classDoc,
- getAnchor(emd), label, false)));
+ ExecutableMemberDoc emd = (ExecutableMemberDoc) doc;
+ return getLink(new LinkInfoImpl(configuration, context, classDoc)
+ .label(label).where(getAnchor(emd)));
} else if (doc instanceof MemberDoc) {
- return new RawHtml(getLink(new LinkInfoImpl(configuration, context, classDoc,
- doc.name(), label, false)));
+ return getLink(new LinkInfoImpl(configuration, context, classDoc)
+ .label(label).where(doc.name()));
} else {
- return new StringContent(label);
+ return label;
}
}
@@ -1385,24 +1351,24 @@ public class HtmlDocletWriter extends HtmlDocWriter {
return emd.name() + signatureParsed.toString();
}
- public String seeTagToString(SeeTag see) {
+ public Content seeTagToContent(SeeTag see) {
String tagName = see.name();
if (! (tagName.startsWith("@link") || tagName.equals("@see"))) {
- return "";
+ return new ContentBuilder();
}
String seetext = replaceDocRootDir(see.text());
//Check if @see is an href or "string"
if (seetext.startsWith("<") || seetext.startsWith("\"")) {
- return seetext;
+ return new RawHtml(seetext);
}
boolean plain = tagName.equalsIgnoreCase("@linkplain");
- String label = plainOrCodeText(plain, see.label());
+ Content label = plainOrCode(plain, new RawHtml(see.label()));
//The text from the @see tag. We will output this text when a label is not specified.
- String text = plainOrCodeText(plain, seetext);
+ Content text = plainOrCode(plain, new RawHtml(seetext));
ClassDoc refClass = see.referencedClass();
String refClassName = see.referencedClassName();
@@ -1415,16 +1381,16 @@ public class HtmlDocletWriter extends HtmlDocWriter {
if (refPackage != null && refPackage.isIncluded()) {
//@see is referencing an included package
if (label.isEmpty())
- label = plainOrCodeText(plain, refPackage.name());
- return getPackageLinkString(refPackage, label, false);
+ label = plainOrCode(plain, new StringContent(refPackage.name()));
+ return getPackageLink(refPackage, label);
} else {
//@see is not referencing an included class or package. Check for cross links.
- String classCrossLink;
+ Content classCrossLink;
DocLink packageCrossLink = getCrossPackageLink(refClassName);
if (packageCrossLink != null) {
//Package cross link found
- return getHyperLinkString(packageCrossLink,
- (label.isEmpty() ? text : label), false);
+ return getHyperLink(packageCrossLink,
+ (label.isEmpty() ? text : label));
} else if ((classCrossLink = getCrossClassLink(refClassName,
refMemName, label, false, "", !plain)) != null) {
//Class cross link found (possibly to a member in the class)
@@ -1439,9 +1405,10 @@ public class HtmlDocletWriter extends HtmlDocWriter {
} else if (refMemName == null) {
// Must be a class reference since refClass is not null and refMemName is null.
if (label.isEmpty()) {
- label = plainOrCodeText(plain, refClass.name());
+ label = plainOrCode(plain, new StringContent(refClass.name()));
}
- return getLink(new LinkInfoImpl(configuration, refClass, label));
+ return getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.DEFAULT, refClass)
+ .label(label));
} else if (refMem == null) {
// Must be a member reference since refClass is not null and refMemName is not null.
// However, refMem is null, so this referenced member does not exist.
@@ -1478,15 +1445,15 @@ public class HtmlDocletWriter extends HtmlDocWriter {
}
}
- text = plainOrCodeText(plain, Util.escapeHtmlChars(refMemName));
+ text = plainOrCode(plain, new StringContent(refMemName));
- return getDocLink(LinkInfoImpl.CONTEXT_SEE_TAG, containing,
+ return getDocLink(LinkInfoImpl.Kind.SEE_TAG, containing,
refMem, (label.isEmpty() ? text: label), false);
}
}
- private String plainOrCodeText(boolean plain, String text) {
- return (plain || text.isEmpty()) ? text : codeText(text);
+ private Content plainOrCode(boolean plain, Content body) {
+ return (plain || body.isEmpty()) ? body : HtmlTree.CODE(body);
}
/**
@@ -1497,7 +1464,7 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @param htmltree the content tree to which the comment will be added
*/
public void addInlineComment(Doc doc, Tag tag, Content htmltree) {
- addCommentTags(doc, tag.inlineTags(), false, false, htmltree);
+ addCommentTags(doc, tag, tag.inlineTags(), false, false, htmltree);
}
/**
@@ -1557,11 +1524,26 @@ public class HtmlDocletWriter extends HtmlDocWriter {
*/
private void addCommentTags(Doc doc, Tag[] tags, boolean depr,
boolean first, Content htmltree) {
+ addCommentTags(doc, null, tags, depr, first, htmltree);
+ }
+
+ /**
+ * Adds the comment tags.
+ *
+ * @param doc the doc for which the comment tags will be generated
+ * @param holderTag the block tag context for the inline tags
+ * @param tags the first sentence tags for the doc
+ * @param depr true if it is deprecated
+ * @param first true if the first sentence tags should be added
+ * @param htmltree the documentation tree to which the comment tags will be added
+ */
+ private void addCommentTags(Doc doc, Tag holderTag, Tag[] tags, boolean depr,
+ boolean first, Content htmltree) {
if(configuration.nocomment){
return;
}
Content div;
- Content result = new RawHtml(commentTagsToString(null, doc, tags, first));
+ Content result = commentTagsToContent(null, doc, tags, first);
if (depr) {
Content italic = HtmlTree.I(result);
div = HtmlTree.DIV(HtmlStyle.block, italic);
@@ -1588,9 +1570,9 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* present in the text of interest for this doc
* @param isFirstSentence true if text is first sentence
*/
- public String commentTagsToString(Tag holderTag, Doc doc, Tag[] tags,
+ public Content commentTagsToContent(Tag holderTag, Doc doc, Tag[] tags,
boolean isFirstSentence) {
- StringBuilder result = new StringBuilder();
+ Content result = new ContentBuilder();
boolean textTagChange = false;
// Array of all possible inline tags for this javadoc run
configuration.tagletManager.checkTags(doc, tags, true);
@@ -1598,14 +1580,15 @@ public class HtmlDocletWriter extends HtmlDocWriter {
Tag tagelem = tags[i];
String tagName = tagelem.name();
if (tagelem instanceof SeeTag) {
- result.append(seeTagToString((SeeTag)tagelem));
+ result.addContent(seeTagToContent((SeeTag) tagelem));
} else if (! tagName.equals("Text")) {
- int originalLength = result.length();
- TagletOutput output = TagletWriter.getInlineTagOuput(
+ boolean wasEmpty = result.isEmpty();
+ Content output = TagletWriter.getInlineTagOuput(
configuration.tagletManager, holderTag,
tagelem, getTagletWriterInstance(isFirstSentence));
- result.append(output == null ? "" : output.toString());
- if (originalLength == 0 && isFirstSentence && tagelem.name().equals("@inheritDoc") && result.length() > 0) {
+ if (output != null)
+ result.addContent(output);
+ if (wasEmpty && isFirstSentence && tagelem.name().equals("@inheritDoc") && !result.isEmpty()) {
break;
} else if (configuration.docrootparent.length() > 0 &&
tagelem.name().equals("@docRoot") &&
@@ -1637,17 +1620,11 @@ public class HtmlDocletWriter extends HtmlDocWriter {
if (isFirstSentence) {
text = removeNonInlineHtmlTags(text);
}
- StringTokenizer lines = new StringTokenizer(text, "\r\n", true);
- StringBuilder textBuff = new StringBuilder();
- while (lines.hasMoreTokens()) {
- StringBuilder line = new StringBuilder(lines.nextToken());
- Util.replaceTabs(configuration, line);
- textBuff.append(line.toString());
- }
- result.append(textBuff);
+ text = Util.replaceTabs(configuration, text);
+ result.addContent(new RawHtml(text));
}
}
- return result.toString();
+ return result;
}
/**
@@ -1749,60 +1726,55 @@ public class HtmlDocletWriter extends HtmlDocWriter {
return text;
}
- public String removeNonInlineHtmlTags(String text) {
- if (text.indexOf('<') < 0) {
- return text;
+ static final Set blockTags = new HashSet();
+ static {
+ for (HtmlTag t: HtmlTag.values()) {
+ if (t.blockType == HtmlTag.BlockType.BLOCK)
+ blockTags.add(t.value);
}
- String noninlinetags[] = { "", "", "
",
- "", "
", "",
- "", "
", "", " | ",
- "", " | ", "", "
",
- "", "", "", "",
- "", "", "", "",
- "", "
", "", "
",
- "", "
", "", "
",
- "", "
", "", "
",
- "", "
", "",
- "", "", "
",
- "", "
",
- "", "",
- "", "", "
",
- "", "
", "",
- "", "
", "", " | ",
- "", " | ", "", "
",
- "", "", "", "",
- "", "", "", "",
- "", "
", "", "
",
- "", "
", "", "
",
- "", "
", "", "
",
- "", "
", "",
- "", "", "
",
- "", "
",
- "", ""
- };
- for (int i = 0; i < noninlinetags.length; i++) {
- text = replace(text, noninlinetags[i], "");
- }
- return text;
}
- public String replace(String text, String tobe, String by) {
- while (true) {
- int startindex = text.indexOf(tobe);
- if (startindex < 0) {
- return text;
- }
- int endindex = startindex + tobe.length();
- StringBuilder replaced = new StringBuilder();
- if (startindex > 0) {
- replaced.append(text.substring(0, startindex));
- }
- replaced.append(by);
- if (text.length() > endindex) {
- replaced.append(text.substring(endindex));
- }
- text = replaced.toString();
+ public static String removeNonInlineHtmlTags(String text) {
+ final int len = text.length();
+
+ int startPos = 0; // start of text to copy
+ int lessThanPos = text.indexOf('<'); // position of latest '<'
+ if (lessThanPos < 0) {
+ return text;
}
+
+ StringBuilder result = new StringBuilder();
+ main: while (lessThanPos != -1) {
+ int currPos = lessThanPos + 1;
+ if (currPos == len)
+ break;
+ char ch = text.charAt(currPos);
+ if (ch == '/') {
+ if (++currPos == len)
+ break;
+ ch = text.charAt(currPos);
+ }
+ int tagPos = currPos;
+ while (isHtmlTagLetterOrDigit(ch)) {
+ if (++currPos == len)
+ break main;
+ ch = text.charAt(currPos);
+ }
+ if (ch == '>' && blockTags.contains(text.substring(tagPos, currPos).toLowerCase())) {
+ result.append(text, startPos, lessThanPos);
+ startPos = currPos + 1;
+ }
+ lessThanPos = text.indexOf('<', currPos);
+ }
+ result.append(text.substring(startPos));
+
+ return result.toString();
+ }
+
+ private static boolean isHtmlTagLetterOrDigit(char ch) {
+ return ('a' <= ch && ch <= 'z') ||
+ ('A' <= ch && ch <= 'Z') ||
+ ('1' <= ch && ch <= '6');
}
/**
@@ -1906,7 +1878,7 @@ public class HtmlDocletWriter extends HtmlDocWriter {
}
/**
- * Adds the annotatation types for the given doc.
+ * Adds the annotation types for the given doc.
*
* @param indent the number of extra spaces to indent the annotations.
* @param doc the doc to write annotations for.
@@ -1916,16 +1888,14 @@ public class HtmlDocletWriter extends HtmlDocWriter {
*/
private boolean addAnnotationInfo(int indent, Doc doc,
AnnotationDesc[] descList, boolean lineBreak, Content htmltree) {
- List annotations = getAnnotations(indent, descList, lineBreak);
+ List annotations = getAnnotations(indent, descList, lineBreak);
String sep ="";
- if (annotations.size() == 0) {
+ if (annotations.isEmpty()) {
return false;
}
- Content annotationContent;
- for (Iterator iter = annotations.iterator(); iter.hasNext();) {
+ for (Content annotation: annotations) {
htmltree.addContent(sep);
- annotationContent = new RawHtml(iter.next());
- htmltree.addContent(annotationContent);
+ htmltree.addContent(annotation);
sep = " ";
}
return true;
@@ -1941,7 +1911,7 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @return an array of strings representing the annotations being
* documented.
*/
- private List getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak) {
+ private List getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak) {
return getAnnotations(indent, descList, linkBreak, true);
}
@@ -1960,10 +1930,10 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @return an array of strings representing the annotations being
* documented.
*/
- public List getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak,
+ public List getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak,
boolean isJava5DeclarationLocation) {
- List results = new ArrayList();
- StringBuilder annotation;
+ List results = new ArrayList();
+ ContentBuilder annotation;
for (int i = 0; i < descList.length; i++) {
AnnotationTypeDoc annotationDoc = descList[i].annotationType();
// If an annotation is not documented, do not add it to the list. If
@@ -1980,10 +1950,10 @@ public class HtmlDocletWriter extends HtmlDocWriter {
if (Util.isDeclarationAnnotation(annotationDoc, isJava5DeclarationLocation)) {
continue;
}*/
- annotation = new StringBuilder();
+ annotation = new ContentBuilder();
isAnnotationDocumented = false;
LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_ANNOTATION, annotationDoc);
+ LinkInfoImpl.Kind.ANNOTATION, annotationDoc);
AnnotationDesc.ElementValuePair[] pairs = descList[i].elementValues();
// If the annotation is synthesized, do not print the container.
if (descList[i].isSynthesized()) {
@@ -1999,8 +1969,8 @@ public class HtmlDocletWriter extends HtmlDocWriter {
}
String sep = "";
for (AnnotationValue av : annotationTypeValues) {
- annotation.append(sep);
- annotation.append(annotationValueToString(av));
+ annotation.addContent(sep);
+ annotation.addContent(annotationValueToContent(av));
sep = " ";
}
}
@@ -2016,8 +1986,8 @@ public class HtmlDocletWriter extends HtmlDocWriter {
annotationTypeValues.addAll(Arrays.asList(annotationArray));
String sep = "";
for (AnnotationValue av : annotationTypeValues) {
- annotation.append(sep);
- annotation.append(annotationValueToString(av));
+ annotation.addContent(sep);
+ annotation.addContent(annotationValueToContent(av));
sep = " ";
}
}
@@ -2032,8 +2002,8 @@ public class HtmlDocletWriter extends HtmlDocWriter {
addAnnotations(annotationDoc, linkInfo, annotation, pairs,
indent, linkBreak);
}
- annotation.append(linkBreak ? DocletConstants.NL : "");
- results.add(annotation.toString());
+ annotation.addContent(linkBreak ? DocletConstants.NL : "");
+ results.add(annotation);
}
return results;
}
@@ -2049,26 +2019,26 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @param linkBreak if true, add new line between each member value
*/
private void addAnnotations(AnnotationTypeDoc annotationDoc, LinkInfoImpl linkInfo,
- StringBuilder annotation, AnnotationDesc.ElementValuePair[] pairs,
+ ContentBuilder annotation, AnnotationDesc.ElementValuePair[] pairs,
int indent, boolean linkBreak) {
- linkInfo.label = "@" + annotationDoc.name();
- annotation.append(getLink(linkInfo));
+ linkInfo.label = new StringContent("@" + annotationDoc.name());
+ annotation.addContent(getLink(linkInfo));
if (pairs.length > 0) {
- annotation.append('(');
+ annotation.addContent("(");
for (int j = 0; j < pairs.length; j++) {
if (j > 0) {
- annotation.append(",");
+ annotation.addContent(",");
if (linkBreak) {
- annotation.append(DocletConstants.NL);
+ annotation.addContent(DocletConstants.NL);
int spaces = annotationDoc.name().length() + 2;
for (int k = 0; k < (spaces + indent); k++) {
- annotation.append(' ');
+ annotation.addContent(" ");
}
}
}
- annotation.append(getDocLink(LinkInfoImpl.CONTEXT_ANNOTATION,
+ annotation.addContent(getDocLink(LinkInfoImpl.Kind.ANNOTATION,
pairs[j].element(), pairs[j].element().name(), false));
- annotation.append('=');
+ annotation.addContent("=");
AnnotationValue annotationValue = pairs[j].value();
List annotationTypeValues = new ArrayList();
if (annotationValue.value() instanceof AnnotationValue[]) {
@@ -2078,17 +2048,17 @@ public class HtmlDocletWriter extends HtmlDocWriter {
} else {
annotationTypeValues.add(annotationValue);
}
- annotation.append(annotationTypeValues.size() == 1 ? "" : "{");
+ annotation.addContent(annotationTypeValues.size() == 1 ? "" : "{");
String sep = "";
for (AnnotationValue av : annotationTypeValues) {
- annotation.append(sep);
- annotation.append(annotationValueToString(av));
+ annotation.addContent(sep);
+ annotation.addContent(annotationValueToContent(av));
sep = ",";
}
- annotation.append(annotationTypeValues.size() == 1 ? "" : "}");
+ annotation.addContent(annotationTypeValues.size() == 1 ? "" : "}");
isContainerDocumented = false;
}
- annotation.append(")");
+ annotation.addContent(")");
}
}
@@ -2123,34 +2093,34 @@ public class HtmlDocletWriter extends HtmlDocWriter {
return false;
}
- private String annotationValueToString(AnnotationValue annotationValue) {
+ private Content annotationValueToContent(AnnotationValue annotationValue) {
if (annotationValue.value() instanceof Type) {
Type type = (Type) annotationValue.value();
if (type.asClassDoc() != null) {
LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_ANNOTATION, type);
- linkInfo.label = (type.asClassDoc().isIncluded() ?
- type.typeName() :
- type.qualifiedTypeName()) + type.dimension() + ".class";
+ LinkInfoImpl.Kind.ANNOTATION, type);
+ linkInfo.label = new StringContent((type.asClassDoc().isIncluded() ?
+ type.typeName() :
+ type.qualifiedTypeName()) + type.dimension() + ".class");
return getLink(linkInfo);
} else {
- return type.typeName() + type.dimension() + ".class";
+ return new StringContent(type.typeName() + type.dimension() + ".class");
}
} else if (annotationValue.value() instanceof AnnotationDesc) {
- List list = getAnnotations(0,
+ List list = getAnnotations(0,
new AnnotationDesc[]{(AnnotationDesc) annotationValue.value()},
false);
- StringBuilder buf = new StringBuilder();
- for (String s: list) {
- buf.append(s);
+ ContentBuilder buf = new ContentBuilder();
+ for (Content c: list) {
+ buf.addContent(c);
}
- return buf.toString();
+ return buf;
} else if (annotationValue.value() instanceof MemberDoc) {
- return getDocLink(LinkInfoImpl.CONTEXT_ANNOTATION,
+ return getDocLink(LinkInfoImpl.Kind.ANNOTATION,
(MemberDoc) annotationValue.value(),
((MemberDoc) annotationValue.value()).name(), false);
} else {
- return annotationValue.toString();
+ return new StringContent(annotationValue.toString());
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java
index bc0e1deb68d..8918889a4c1 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,7 +46,7 @@ import com.sun.tools.doclets.internal.toolkit.taglets.*;
* @author Bhavesh Patel (Modified)
*/
public class HtmlSerialFieldWriter extends FieldWriterImpl
- implements SerializedFormWriter.SerialFieldWriter {
+ implements SerializedFormWriter.SerialFieldWriter {
ProgramElementDoc[] members = null;
private boolean printedOverallAnchor = false;
@@ -129,8 +129,8 @@ public class HtmlSerialFieldWriter extends FieldWriterImpl
if (fieldType == null) {
pre.addContent(fieldTypeStr);
} else {
- Content fieldContent = new RawHtml(writer.getLink(new LinkInfoImpl(
- configuration, LinkInfoImpl.CONTEXT_SERIAL_MEMBER, fieldType)));
+ Content fieldContent = writer.getLink(new LinkInfoImpl(
+ configuration, LinkInfoImpl.Kind.SERIAL_MEMBER, fieldType));
pre.addContent(fieldContent);
}
pre.addContent(fieldDimensions + " ");
@@ -186,17 +186,13 @@ public class HtmlSerialFieldWriter extends FieldWriterImpl
* @param contentTree the tree to which the member tags info will be added
*/
public void addMemberTags(FieldDoc field, Content contentTree) {
- TagletOutputImpl output = new TagletOutputImpl("");
+ Content tagContent = new ContentBuilder();
TagletWriter.genTagOuput(configuration.tagletManager, field,
- configuration.tagletManager.getCustomTags(field),
- writer.getTagletWriterInstance(false), output);
- String outputString = output.toString().trim();
+ configuration.tagletManager.getCustomTaglets(field),
+ writer.getTagletWriterInstance(false), tagContent);
Content dlTags = new HtmlTree(HtmlTag.DL);
- if (!outputString.isEmpty()) {
- Content tagContent = new RawHtml(outputString);
- dlTags.addContent(tagContent);
- }
- contentTree.addContent(dlTags);
+ dlTags.addContent(tagContent);
+ contentTree.addContent(dlTags); // TODO: what if empty?
}
/**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialMethodWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialMethodWriter.java
index d71b4370cc6..4e5da21fc7f 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialMethodWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialMethodWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -146,19 +146,15 @@ public class HtmlSerialMethodWriter extends MethodWriterImpl implements
* @param methodsContentTree the tree to which the member tags info will be added
*/
public void addMemberTags(MethodDoc member, Content methodsContentTree) {
- TagletOutputImpl output = new TagletOutputImpl("");
+ Content tagContent = new ContentBuilder();
TagletManager tagletManager =
configuration.tagletManager;
TagletWriter.genTagOuput(tagletManager, member,
- tagletManager.getSerializedFormTags(),
- writer.getTagletWriterInstance(false), output);
- String outputString = output.toString().trim();
+ tagletManager.getSerializedFormTaglets(),
+ writer.getTagletWriterInstance(false), tagContent);
Content dlTags = new HtmlTree(HtmlTag.DL);
- if (!outputString.isEmpty()) {
- Content tagContent = new RawHtml(outputString);
- dlTags.addContent(tagContent);
- }
- methodsContentTree.addContent(dlTags);
+ dlTags.addContent(tagContent);
+ methodsContentTree.addContent(dlTags); // TODO: what if empty?
MethodDoc method = member;
if (method.name().compareTo("writeExternal") == 0
&& method.tags("serialData").length == 0) {
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java
index e4346ead840..abad36dbf99 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java
@@ -28,6 +28,9 @@ package com.sun.tools.doclets.formats.html;
import java.util.List;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.formats.html.markup.ContentBuilder;
+import com.sun.tools.doclets.formats.html.markup.RawHtml;
+import com.sun.tools.doclets.formats.html.markup.StringContent;
import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.doclets.internal.toolkit.util.*;
import com.sun.tools.doclets.internal.toolkit.util.links.*;
@@ -54,16 +57,16 @@ public class LinkFactoryImpl extends LinkFactory {
/**
* {@inheritDoc}
*/
- protected LinkOutput getOutputInstance() {
- return new LinkOutputImpl();
+ protected Content newContent() {
+ return new ContentBuilder();
}
/**
* {@inheritDoc}
*/
- protected LinkOutput getClassLink(LinkInfo linkInfo) {
+ protected Content getClassLink(LinkInfo linkInfo) {
LinkInfoImpl classLinkInfo = (LinkInfoImpl) linkInfo;
- boolean noLabel = linkInfo.label == null || linkInfo.label.length() == 0;
+ boolean noLabel = linkInfo.label == null || linkInfo.label.isEmpty();
ClassDoc classDoc = classLinkInfo.classDoc;
//Create a tool tip if we are linking to a class or interface. Don't
//create one if we are linking to a member.
@@ -73,100 +76,94 @@ public class LinkFactoryImpl extends LinkFactory {
classLinkInfo.type != null &&
!classDoc.qualifiedTypeName().equals(classLinkInfo.type.qualifiedTypeName())) :
"";
- StringBuilder label = new StringBuilder(
- classLinkInfo.getClassLinkLabel(m_writer.configuration));
- classLinkInfo.displayLength += label.length();
+ Content label = classLinkInfo.getClassLinkLabel(m_writer.configuration);
Configuration configuration = m_writer.configuration;
- LinkOutputImpl linkOutput = new LinkOutputImpl();
+ Content link = new ContentBuilder();
if (classDoc.isIncluded()) {
if (configuration.isGeneratedDoc(classDoc)) {
DocPath filename = getPath(classLinkInfo);
if (linkInfo.linkToSelf ||
!(DocPath.forName(classDoc)).equals(m_writer.filename)) {
- linkOutput.append(m_writer.getHyperLinkString(
+ link.addContent(m_writer.getHyperLink(
filename.fragment(classLinkInfo.where),
- label.toString(),
+ label,
classLinkInfo.isStrong, classLinkInfo.styleName,
title, classLinkInfo.target));
if (noLabel && !classLinkInfo.excludeTypeParameterLinks) {
- linkOutput.append(getTypeParameterLinks(linkInfo).toString());
+ link.addContent(getTypeParameterLinks(linkInfo));
}
- return linkOutput;
+ return link;
}
}
} else {
- String crossLink = m_writer.getCrossClassLink(
+ Content crossLink = m_writer.getCrossClassLink(
classDoc.qualifiedName(), classLinkInfo.where,
- label.toString(), classLinkInfo.isStrong, classLinkInfo.styleName,
+ label, classLinkInfo.isStrong, classLinkInfo.styleName,
true);
if (crossLink != null) {
- linkOutput.append(crossLink);
+ link.addContent(crossLink);
if (noLabel && !classLinkInfo.excludeTypeParameterLinks) {
- linkOutput.append(getTypeParameterLinks(linkInfo).toString());
+ link.addContent(getTypeParameterLinks(linkInfo));
}
- return linkOutput;
+ return link;
}
}
// Can't link so just write label.
- linkOutput.append(label.toString());
+ link.addContent(label.toString());
if (noLabel && !classLinkInfo.excludeTypeParameterLinks) {
- linkOutput.append(getTypeParameterLinks(linkInfo).toString());
+ link.addContent(getTypeParameterLinks(linkInfo));
}
- return linkOutput;
+ return link;
}
/**
* {@inheritDoc}
*/
- protected LinkOutput getTypeParameterLink(LinkInfo linkInfo,
+ protected Content getTypeParameterLink(LinkInfo linkInfo,
Type typeParam) {
LinkInfoImpl typeLinkInfo = new LinkInfoImpl(m_writer.configuration,
- linkInfo.getContext(), typeParam);
+ ((LinkInfoImpl) linkInfo).getContext(), typeParam);
typeLinkInfo.excludeTypeBounds = linkInfo.excludeTypeBounds;
typeLinkInfo.excludeTypeParameterLinks = linkInfo.excludeTypeParameterLinks;
typeLinkInfo.linkToSelf = linkInfo.linkToSelf;
typeLinkInfo.isJava5DeclarationLocation = false;
- LinkOutput output = getLinkOutput(typeLinkInfo);
- ((LinkInfoImpl) linkInfo).displayLength += typeLinkInfo.displayLength;
- return output;
+ return getLink(typeLinkInfo);
}
- protected LinkOutput getTypeAnnotationLink(LinkInfo linkInfo,
+ protected Content getTypeAnnotationLink(LinkInfo linkInfo,
AnnotationDesc annotation) {
throw new RuntimeException("Not implemented yet!");
}
- public LinkOutput getTypeAnnotationLinks(LinkInfo linkInfo) {
- LinkOutput output = getOutputInstance();
+ public Content getTypeAnnotationLinks(LinkInfo linkInfo) {
+ ContentBuilder links = new ContentBuilder();
AnnotationDesc[] annotations;
if (linkInfo.type instanceof AnnotatedType) {
annotations = linkInfo.type.asAnnotatedType().annotations();
} else if (linkInfo.type instanceof TypeVariable) {
annotations = linkInfo.type.asTypeVariable().annotations();
} else {
- return output;
+ return links;
}
if (annotations.length == 0)
- return output;
+ return links;
- List annos = m_writer.getAnnotations(0, annotations, false, linkInfo.isJava5DeclarationLocation);
+ List annos = m_writer.getAnnotations(0, annotations, false, linkInfo.isJava5DeclarationLocation);
boolean isFirst = true;
- for (String anno : annos) {
+ for (Content anno : annos) {
if (!isFirst) {
- linkInfo.displayLength += 1;
- output.append(" ");
+ links.addContent(" ");
}
- output.append(anno);
+ links.addContent(anno);
isFirst = false;
}
if (!annos.isEmpty()) {
- linkInfo.displayLength += 1;
- output.append(" ");
+ links.addContent(" ");
}
- return output;
+ return links;
}
/**
@@ -204,7 +201,7 @@ public class LinkFactoryImpl extends LinkFactory {
* @param linkInfo the information about the link.
*/
private DocPath getPath(LinkInfoImpl linkInfo) {
- if (linkInfo.context == LinkInfoImpl.PACKAGE_FRAME) {
+ if (linkInfo.context == LinkInfoImpl.Kind.PACKAGE_FRAME) {
//Not really necessary to do this but we want to be consistent
//with 1.4.2 output.
return DocPath.forName(linkInfo.classDoc);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java
index ae64b75e0c4..7e3b6042a50 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java
@@ -27,6 +27,9 @@
package com.sun.tools.doclets.formats.html;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.formats.html.markup.ContentBuilder;
+import com.sun.tools.doclets.formats.html.markup.StringContent;
+import com.sun.tools.doclets.internal.toolkit.Content;
import com.sun.tools.doclets.internal.toolkit.util.*;
import com.sun.tools.doclets.internal.toolkit.util.links.*;
@@ -38,177 +41,181 @@ import com.sun.tools.doclets.internal.toolkit.util.links.*;
*/
public class LinkInfoImpl extends LinkInfo {
- /**
- * Indicate that the link appears in a class list.
- */
- public static final int ALL_CLASSES_FRAME = 1;
+ public enum Kind {
+ DEFAULT,
- /**
- * Indicate that the link appears in a class documentation.
- */
- public static final int CONTEXT_CLASS = 2;
+ /**
+ * Indicate that the link appears in a class list.
+ */
+ ALL_CLASSES_FRAME,
- /**
- * Indicate that the link appears in member documentation.
- */
- public static final int CONTEXT_MEMBER = 3;
+ /**
+ * Indicate that the link appears in a class documentation.
+ */
+ CLASS,
- /**
- * Indicate that the link appears in class use documentation.
- */
- public static final int CONTEXT_CLASS_USE = 4;
+ /**
+ * Indicate that the link appears in member documentation.
+ */
+ MEMBER,
- /**
- * Indicate that the link appears in index documentation.
- */
- public static final int CONTEXT_INDEX = 5;
+ /**
+ * Indicate that the link appears in class use documentation.
+ */
+ CLASS_USE,
- /**
- * Indicate that the link appears in constant value summary.
- */
- public static final int CONTEXT_CONSTANT_SUMMARY = 6;
+ /**
+ * Indicate that the link appears in index documentation.
+ */
+ INDEX,
- /**
- * Indicate that the link appears in serialized form documentation.
- */
- public static final int CONTEXT_SERIALIZED_FORM = 7;
+ /**
+ * Indicate that the link appears in constant value summary.
+ */
+ CONSTANT_SUMMARY,
- /**
- * Indicate that the link appears in serial member documentation.
- */
- public static final int CONTEXT_SERIAL_MEMBER = 8;
+ /**
+ * Indicate that the link appears in serialized form documentation.
+ */
+ SERIALIZED_FORM,
- /**
- * Indicate that the link appears in package documentation.
- */
- public static final int CONTEXT_PACKAGE = 9;
+ /**
+ * Indicate that the link appears in serial member documentation.
+ */
+ SERIAL_MEMBER,
- /**
- * Indicate that the link appears in see tag documentation.
- */
- public static final int CONTEXT_SEE_TAG = 10;
+ /**
+ * Indicate that the link appears in package documentation.
+ */
+ PACKAGE,
- /**
- * Indicate that the link appears in value tag documentation.
- */
- public static final int CONTEXT_VALUE_TAG = 11;
+ /**
+ * Indicate that the link appears in see tag documentation.
+ */
+ SEE_TAG,
- /**
- * Indicate that the link appears in tree documentation.
- */
- public static final int CONTEXT_TREE = 12;
+ /**
+ * Indicate that the link appears in value tag documentation.
+ */
+ VALUE_TAG,
- /**
- * Indicate that the link appears in a class list.
- */
- public static final int PACKAGE_FRAME = 13;
+ /**
+ * Indicate that the link appears in tree documentation.
+ */
+ TREE,
- /**
- * The header in the class documentation.
- */
- public static final int CONTEXT_CLASS_HEADER = 14;
+ /**
+ * Indicate that the link appears in a class list.
+ */
+ PACKAGE_FRAME,
- /**
- * The signature in the class documentation.
- */
- public static final int CONTEXT_CLASS_SIGNATURE = 15;
+ /**
+ * The header in the class documentation.
+ */
+ CLASS_HEADER,
- /**
- * The return type of a method.
- */
- public static final int CONTEXT_RETURN_TYPE = 16;
+ /**
+ * The signature in the class documentation.
+ */
+ CLASS_SIGNATURE,
- /**
- * The return type of a method in a member summary.
- */
- public static final int CONTEXT_SUMMARY_RETURN_TYPE = 17;
+ /**
+ * The return type of a method.
+ */
+ RETURN_TYPE,
- /**
- * The type of a method/constructor parameter.
- */
- public static final int CONTEXT_EXECUTABLE_MEMBER_PARAM = 18;
+ /**
+ * The return type of a method in a member summary.
+ */
+ SUMMARY_RETURN_TYPE,
- /**
- * Super interface links.
- */
- public static final int CONTEXT_SUPER_INTERFACES = 19;
+ /**
+ * The type of a method/constructor parameter.
+ */
+ EXECUTABLE_MEMBER_PARAM,
- /**
- * Implemented interface links.
- */
- public static final int CONTEXT_IMPLEMENTED_INTERFACES = 20;
+ /**
+ * Super interface links.
+ */
+ SUPER_INTERFACES,
- /**
- * Implemented class links.
- */
- public static final int CONTEXT_IMPLEMENTED_CLASSES = 21;
+ /**
+ * Implemented interface links.
+ */
+ IMPLEMENTED_INTERFACES,
- /**
- * Subinterface links.
- */
- public static final int CONTEXT_SUBINTERFACES = 22;
+ /**
+ * Implemented class links.
+ */
+ IMPLEMENTED_CLASSES,
- /**
- * Subclasses links.
- */
- public static final int CONTEXT_SUBCLASSES = 23;
+ /**
+ * Subinterface links.
+ */
+ SUBINTERFACES,
- /**
- * The signature in the class documentation (implements/extends portion).
- */
- public static final int CONTEXT_CLASS_SIGNATURE_PARENT_NAME = 24;
+ /**
+ * Subclasses links.
+ */
+ SUBCLASSES,
- /**
- * The header for method documentation copied from parent.
- */
- public static final int CONTEXT_METHOD_DOC_COPY = 26;
+ /**
+ * The signature in the class documentation (implements/extends portion).
+ */
+ CLASS_SIGNATURE_PARENT_NAME,
- /**
- * Method "specified by" link.
- */
- public static final int CONTEXT_METHOD_SPECIFIED_BY = 27;
+ /**
+ * The header for method documentation copied from parent.
+ */
+ METHOD_DOC_COPY,
- /**
- * Method "overrides" link.
- */
- public static final int CONTEXT_METHOD_OVERRIDES = 28;
+ /**
+ * Method "specified by" link.
+ */
+ METHOD_SPECIFIED_BY,
- /**
- * Annotation link.
- */
- public static final int CONTEXT_ANNOTATION = 29;
+ /**
+ * Method "overrides" link.
+ */
+ METHOD_OVERRIDES,
- /**
- * The header for field documentation copied from parent.
- */
- public static final int CONTEXT_FIELD_DOC_COPY = 30;
+ /**
+ * Annotation link.
+ */
+ ANNOTATION,
- /**
- * The parent nodes int the class tree.
- */
- public static final int CONTEXT_CLASS_TREE_PARENT = 31;
+ /**
+ * The header for field documentation copied from parent.
+ */
+ FIELD_DOC_COPY,
- /**
- * The type parameters of a method or constructor.
- */
- public static final int CONTEXT_MEMBER_TYPE_PARAMS = 32;
+ /**
+ * The parent nodes in the class tree.
+ */
+ CLASS_TREE_PARENT,
- /**
- * Indicate that the link appears in class use documentation.
- */
- public static final int CONTEXT_CLASS_USE_HEADER = 33;
+ /**
+ * The type parameters of a method or constructor.
+ */
+ MEMBER_TYPE_PARAMS,
- /**
- * The header for property documentation copied from parent.
- */
- public static final int CONTEXT_PROPERTY_DOC_COPY = 34;
+ /**
+ * Indicate that the link appears in class use documentation.
+ */
+ CLASS_USE_HEADER,
+
+ /**
+ * The header for property documentation copied from parent.
+ */
+ PROPERTY_DOC_COPY
+ }
public final ConfigurationImpl configuration;
/**
- * The integer indicating the location of the link.
+ * The location of the link.
*/
- public int context;
+ public Kind context = Kind.DEFAULT;
/**
* The value of the marker #.
@@ -218,7 +225,7 @@ public class LinkInfoImpl extends LinkInfo {
/**
* String style of text defined in style sheet.
*/
- public String styleName ="";
+ public String styleName = "";
/**
* The value of the target.
@@ -230,108 +237,34 @@ public class LinkInfoImpl extends LinkInfo {
*
* @param configuration the configuration data for the doclet
* @param context the context of the link.
- * @param classDoc the class to link to.
- * @param label the label for the link.
- * @param target the value of the target attribute.
- */
- public LinkInfoImpl(ConfigurationImpl configuration,
- int context, ClassDoc classDoc, String label, String target) {
- this.configuration = configuration;
- this.classDoc = classDoc;
- this.label = label;
- this.target = target;
- setContext(context);
- }
-
- /**
- * Construct a LinkInfo object.
- *
- * @param configuration the configuration data for the doclet
- * @param context the context of the link.
- * @param classDoc the class to link to.
- * @param where the value of the marker #.
- * @param label the label for the link.
- * @param isStrong true if the link should be strong.
- * @param styleName String style of text defined in style sheet.
- */
- public LinkInfoImpl(ConfigurationImpl configuration,
- int context, ClassDoc classDoc, String where, String label,
- boolean isStrong, String styleName) {
- this.configuration = configuration;
- this.classDoc = classDoc;
- this.where = where;
- this.label = label;
- this.isStrong = isStrong;
- this.styleName = styleName;
- setContext(context);
- }
-
- /**
- * Construct a LinkInfo object.
- *
- * @param configuration the configuration data for the doclet
- * @param context the context of the link.
- * @param classDoc the class to link to.
- * @param where the value of the marker #.
- * @param label the label for the link.
- * @param isStrong true if the link should be strong.
- */
- public LinkInfoImpl(ConfigurationImpl configuration,
- int context, ClassDoc classDoc, String where, String label,
- boolean isStrong) {
- this.configuration = configuration;
- this.classDoc = classDoc;
- this.where = where;
- this.label = label;
- this.isStrong = isStrong;
- setContext(context);
- }
-
- /**
- * Construct a LinkInfo object.
- *
- * @param configuration the configuration data for the doclet
- * @param classDoc the class to link to.
- * @param label the label for the link.
- */
- public LinkInfoImpl(ConfigurationImpl configuration,
- ClassDoc classDoc, String label) {
- this.configuration = configuration;
- this.classDoc = classDoc;
- this.label = label;
- setContext(context);
- }
-
- /**
- * Construct a LinkInfo object.
- *
- * @param configuration the configuration data for the doclet
* @param context the context of the link.
* @param executableMemberDoc the member to link to.
- * @param isStrong true if the link should be strong.
*/
public LinkInfoImpl(ConfigurationImpl configuration,
- int context, ExecutableMemberDoc executableMemberDoc,
- boolean isStrong) {
+ Kind context, ExecutableMemberDoc executableMemberDoc) {
this.configuration = configuration;
this.executableMemberDoc = executableMemberDoc;
- this.isStrong = isStrong;
setContext(context);
}
+ /**
+ * {@inherotDoc}
+ */
+ protected Content newContent() {
+ return new ContentBuilder();
+ }
+
/**
* Construct a LinkInfo object.
*
* @param configuration the configuration data for the doclet
* @param context the context of the link.
* @param classDoc the class to link to.
- * @param isStrong true if the link should be strong.
*/
public LinkInfoImpl(ConfigurationImpl configuration,
- int context, ClassDoc classDoc, boolean isStrong) {
+ Kind context, ClassDoc classDoc) {
this.configuration = configuration;
this.classDoc = classDoc;
- this.isStrong = isStrong;
setContext(context);
}
@@ -343,70 +276,76 @@ public class LinkInfoImpl extends LinkInfo {
* @param type the class to link to.
*/
public LinkInfoImpl(ConfigurationImpl configuration,
- int context, Type type) {
+ Kind context, Type type) {
this.configuration = configuration;
this.type = type;
setContext(context);
}
+
/**
- * Construct a LinkInfo object.
- *
- * @param configuration the configuration data for the doclet
- * @param context the context of the link.
- * @param type the class to link to.
- * @param isVarArg true if this is a link to a var arg.
+ * Set the label for the link.
+ * @param label plain-text label for the link
*/
- public LinkInfoImpl(ConfigurationImpl configuration,
- int context, Type type, boolean isVarArg) {
- this.configuration = configuration;
- this.type = type;
- this.isVarArg = isVarArg;
- setContext(context);
+ public LinkInfoImpl label(String label) {
+ this.label = new StringContent(label);
+ return this;
}
/**
- * Construct a LinkInfo object.
- *
- * @param configuration the configuration data for the doclet
- * @param context the context of the link.
- * @param type the class to link to.
- * @param label the label for the link.
- * @param isStrong true if the link should be strong.
+ * Set the label for the link.
*/
- public LinkInfoImpl(ConfigurationImpl configuration,
- int context, Type type, String label,
- boolean isStrong) {
- this.configuration = configuration;
- this.type = type;
+ public LinkInfoImpl label(Content label) {
this.label = label;
- this.isStrong = isStrong;
- setContext(context);
+ return this;
}
/**
- * Construct a LinkInfo object.
- *
- * @param configuration the configuration data for the doclet
- * @param context the context of the link.
- * @param classDoc the class to link to.
- * @param label the label for the link.
- * @param isStrong true if the link should be strong.
+ * Set whether or not the link should be strong.
*/
- public LinkInfoImpl(ConfigurationImpl configuration,
- int context, ClassDoc classDoc, String label,
- boolean isStrong) {
- this.configuration = configuration;
- this.classDoc = classDoc;
- this.label = label;
- this.isStrong = isStrong;
- setContext(context);
+ public LinkInfoImpl strong(boolean strong) {
+ this.isStrong = strong;
+ return this;
}
+ /**
+ * Set the style to be used for the link.
+ * @param styleName String style of text defined in style sheet.
+ */
+ public LinkInfoImpl styleName(String styleName) {
+ this.styleName = styleName;
+ return this;
+ }
+
+ /**
+ * Set the target to be used for the link.
+ * @param styleName String style of text defined in style sheet.
+ */
+ public LinkInfoImpl target(String target) {
+ this.target = target;
+ return this;
+ }
+
+ /**
+ * Set whether or not this is a link to a varargs parameter.
+ */
+ public LinkInfoImpl varargs(boolean varargs) {
+ this.isVarArg = varargs;
+ return this;
+ }
+
+ /**
+ * Set the fragment specifier for the link.
+ */
+ public LinkInfoImpl where(String where) {
+ this.where = where;
+ return this;
+ }
+
/**
* {@inheritDoc}
*/
- public int getContext() {
+ public Kind getContext() {
return context;
}
@@ -418,63 +357,63 @@ public class LinkInfoImpl extends LinkInfo {
*
* @param c the context id to set.
*/
- public void setContext(int c) {
+ public final void setContext(Kind c) {
//NOTE: Put context specific link code here.
switch (c) {
case ALL_CLASSES_FRAME:
case PACKAGE_FRAME:
- case CONTEXT_IMPLEMENTED_CLASSES:
- case CONTEXT_SUBCLASSES:
- case CONTEXT_METHOD_DOC_COPY:
- case CONTEXT_FIELD_DOC_COPY:
- case CONTEXT_PROPERTY_DOC_COPY:
- case CONTEXT_CLASS_USE_HEADER:
+ case IMPLEMENTED_CLASSES:
+ case SUBCLASSES:
+ case METHOD_DOC_COPY:
+ case FIELD_DOC_COPY:
+ case PROPERTY_DOC_COPY:
+ case CLASS_USE_HEADER:
includeTypeInClassLinkLabel = false;
break;
- case CONTEXT_ANNOTATION:
+ case ANNOTATION:
excludeTypeParameterLinks = true;
excludeTypeBounds = true;
break;
- case CONTEXT_IMPLEMENTED_INTERFACES:
- case CONTEXT_SUPER_INTERFACES:
- case CONTEXT_SUBINTERFACES:
- case CONTEXT_CLASS_TREE_PARENT:
- case CONTEXT_TREE:
- case CONTEXT_CLASS_SIGNATURE_PARENT_NAME:
+ case IMPLEMENTED_INTERFACES:
+ case SUPER_INTERFACES:
+ case SUBINTERFACES:
+ case CLASS_TREE_PARENT:
+ case TREE:
+ case CLASS_SIGNATURE_PARENT_NAME:
excludeTypeParameterLinks = true;
excludeTypeBounds = true;
includeTypeInClassLinkLabel = false;
includeTypeAsSepLink = true;
break;
- case CONTEXT_PACKAGE:
- case CONTEXT_CLASS_USE:
- case CONTEXT_CLASS_HEADER:
- case CONTEXT_CLASS_SIGNATURE:
+ case PACKAGE:
+ case CLASS_USE:
+ case CLASS_HEADER:
+ case CLASS_SIGNATURE:
excludeTypeParameterLinks = true;
includeTypeAsSepLink = true;
includeTypeInClassLinkLabel = false;
break;
- case CONTEXT_MEMBER_TYPE_PARAMS:
+ case MEMBER_TYPE_PARAMS:
includeTypeAsSepLink = true;
includeTypeInClassLinkLabel = false;
break;
- case CONTEXT_RETURN_TYPE:
- case CONTEXT_SUMMARY_RETURN_TYPE:
+ case RETURN_TYPE:
+ case SUMMARY_RETURN_TYPE:
excludeTypeBounds = true;
break;
- case CONTEXT_EXECUTABLE_MEMBER_PARAM:
+ case EXECUTABLE_MEMBER_PARAM:
excludeTypeBounds = true;
break;
}
context = c;
if (type != null &&
type.asTypeVariable()!= null &&
- type.asTypeVariable().owner() instanceof ExecutableMemberDoc){
+ type.asTypeVariable().owner() instanceof ExecutableMemberDoc) {
excludeTypeParameterLinks = true;
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java
index 0585a9ea7f4..235c913b913 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java
@@ -117,7 +117,6 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
* @return a content object for the signature
*/
public Content getSignature(MethodDoc method) {
- writer.displayLength = 0;
Content pre = new HtmlTree(HtmlTag.PRE);
writer.addAnnotationInfo(method, pre);
addModifiers(method, pre);
@@ -129,8 +128,9 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
} else {
addName(method.name(), pre);
}
- addParameters(method, pre);
- addExceptions(method, pre);
+ int indent = pre.charCount();
+ addParameters(method, pre, indent);
+ addExceptions(method, pre, indent);
return pre;
}
@@ -152,12 +152,12 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
Util.isLinkable(holderClassDoc, configuration)))) {
writer.addInlineComment(method, methodDocTree);
} else {
- Content link = new RawHtml(
- writer.getDocLink(LinkInfoImpl.CONTEXT_METHOD_DOC_COPY,
+ Content link =
+ writer.getDocLink(LinkInfoImpl.Kind.METHOD_DOC_COPY,
holder.asClassDoc(), method,
holder.asClassDoc().isIncluded() ?
holder.typeName() : holder.qualifiedTypeName(),
- false));
+ false);
Content codelLink = HtmlTree.CODE(link);
Content strong = HtmlTree.STRONG(holder.asClassDoc().isClass()?
writer.descfrmClassLabel : writer.descfrmInterfaceLabel);
@@ -223,8 +223,8 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
/**
* {@inheritDoc}
*/
- public String getCaption() {
- return configuration.getText("doclet.Methods");
+ public Content getCaption() {
+ return configuration.getResource("doclet.Methods");
}
/**
@@ -260,8 +260,8 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
* {@inheritDoc}
*/
public void addInheritedSummaryLabel(ClassDoc cd, Content inheritedTree) {
- Content classLink = new RawHtml(writer.getPreQualifiedClassLink(
- LinkInfoImpl.CONTEXT_MEMBER, cd, false));
+ Content classLink = writer.getPreQualifiedClassLink(
+ LinkInfoImpl.Kind.MEMBER, cd, false);
Content label = new StringContent(cd.isClass() ?
configuration.getText("doclet.Methods_Inherited_From_Class") :
configuration.getText("doclet.Methods_Inherited_From_Interface"));
@@ -300,25 +300,25 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
return;
}
Content label = writer.overridesLabel;
- int context = LinkInfoImpl.CONTEXT_METHOD_OVERRIDES;
+ LinkInfoImpl.Kind context = LinkInfoImpl.Kind.METHOD_OVERRIDES;
if (method != null) {
if (overriddenType.asClassDoc().isAbstract() && method.isAbstract()){
//Abstract method is implemented from abstract class,
//not overridden
label = writer.specifiedByLabel;
- context = LinkInfoImpl.CONTEXT_METHOD_SPECIFIED_BY;
+ context = LinkInfoImpl.Kind.METHOD_SPECIFIED_BY;
}
Content dt = HtmlTree.DT(HtmlTree.STRONG(label));
dl.addContent(dt);
- Content overriddenTypeLink = new RawHtml(
- writer.getLink(new LinkInfoImpl(writer.configuration, context, overriddenType)));
+ Content overriddenTypeLink =
+ writer.getLink(new LinkInfoImpl(writer.configuration, context, overriddenType));
Content codeOverridenTypeLink = HtmlTree.CODE(overriddenTypeLink);
String name = method.name();
- Content methlink = new RawHtml(writer.getLink(
- new LinkInfoImpl(writer.configuration, LinkInfoImpl.CONTEXT_MEMBER,
- overriddenType.asClassDoc(),
- writer.getAnchor(method), name, false)));
+ Content methlink = writer.getLink(
+ new LinkInfoImpl(writer.configuration, LinkInfoImpl.Kind.MEMBER,
+ overriddenType.asClassDoc())
+ .where(writer.getAnchor(method)).label(name));
Content codeMethLink = HtmlTree.CODE(methlink);
Content dd = HtmlTree.DD(codeMethLink);
dd.addContent(writer.getSpace());
@@ -361,14 +361,14 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
for (int i = 0; i < implementedMethods.length; i++) {
MethodDoc implementedMeth = implementedMethods[i];
Type intfac = implementedMethodsFinder.getMethodHolder(implementedMeth);
- Content intfaclink = new RawHtml(writer.getLink(new LinkInfoImpl(
- writer.configuration, LinkInfoImpl.CONTEXT_METHOD_SPECIFIED_BY, intfac)));
+ Content intfaclink = writer.getLink(new LinkInfoImpl(
+ writer.configuration, LinkInfoImpl.Kind.METHOD_SPECIFIED_BY, intfac));
Content codeIntfacLink = HtmlTree.CODE(intfaclink);
Content dt = HtmlTree.DT(HtmlTree.STRONG(writer.specifiedByLabel));
dl.addContent(dt);
- Content methlink = new RawHtml(writer.getDocLink(
- LinkInfoImpl.CONTEXT_MEMBER, implementedMeth,
- implementedMeth.name(), false));
+ Content methlink = writer.getDocLink(
+ LinkInfoImpl.Kind.MEMBER, implementedMeth,
+ implementedMeth.name(), false);
Content codeMethLink = HtmlTree.CODE(methlink);
Content dd = HtmlTree.DD(codeMethLink);
dd.addContent(writer.getSpace());
@@ -388,8 +388,8 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
protected void addReturnType(MethodDoc method, Content htmltree) {
Type type = method.returnType();
if (type != null) {
- Content linkContent = new RawHtml(writer.getLink(
- new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_RETURN_TYPE, type)));
+ Content linkContent = writer.getLink(
+ new LinkInfoImpl(configuration, LinkInfoImpl.Kind.RETURN_TYPE, type));
htmltree.addContent(linkContent);
htmltree.addContent(writer.getSpace());
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java
index 6ce42e57091..487d9ff101a 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
package com.sun.tools.doclets.formats.html;
import java.io.*;
-import java.util.*;
import com.sun.javadoc.*;
import com.sun.tools.doclets.formats.html.markup.*;
@@ -101,8 +100,8 @@ public class NestedClassWriterImpl extends AbstractMemberWriter
/**
* {@inheritDoc}
*/
- public String getCaption() {
- return configuration.getText("doclet.Nested_Classes");
+ public Content getCaption() {
+ return configuration.getResource("doclet.Nested_Classes");
}
/**
@@ -148,8 +147,8 @@ public class NestedClassWriterImpl extends AbstractMemberWriter
* {@inheritDoc}
*/
public void addInheritedSummaryLabel(ClassDoc cd, Content inheritedTree) {
- Content classLink = new RawHtml(writer.getPreQualifiedClassLink(
- LinkInfoImpl.CONTEXT_MEMBER, cd, false));
+ Content classLink = writer.getPreQualifiedClassLink(
+ LinkInfoImpl.Kind.MEMBER, cd, false);
Content label = new StringContent(cd.isInterface() ?
configuration.getText("doclet.Nested_Classes_Interface_Inherited_From_Interface") :
configuration.getText("doclet.Nested_Classes_Interfaces_Inherited_From_Class"));
@@ -163,10 +162,10 @@ public class NestedClassWriterImpl extends AbstractMemberWriter
/**
* {@inheritDoc}
*/
- protected void addSummaryLink(int context, ClassDoc cd, ProgramElementDoc member,
+ protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member,
Content tdSummary) {
- Content strong = HtmlTree.STRONG(new RawHtml(
- writer.getLink(new LinkInfoImpl(configuration, context, (ClassDoc)member, false))));
+ Content strong = HtmlTree.STRONG(
+ writer.getLink(new LinkInfoImpl(configuration, context, (ClassDoc)member)));
Content code = HtmlTree.CODE(strong);
tdSummary.addContent(code);
}
@@ -176,9 +175,9 @@ public class NestedClassWriterImpl extends AbstractMemberWriter
*/
protected void addInheritedSummaryLink(ClassDoc cd,
ProgramElementDoc member, Content linksTree) {
- linksTree.addContent(new RawHtml(
- writer.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_MEMBER,
- (ClassDoc)member, false))));
+ linksTree.addContent(
+ writer.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER,
+ (ClassDoc)member)));
}
/**
@@ -194,7 +193,7 @@ public class NestedClassWriterImpl extends AbstractMemberWriter
* {@inheritDoc}
*/
protected Content getDeprecatedLink(ProgramElementDoc member) {
- return writer.getQualifiedClassLink(LinkInfoImpl.CONTEXT_MEMBER,
+ return writer.getQualifiedClassLink(LinkInfoImpl.Kind.MEMBER,
(ClassDoc)member);
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java
index 851fed9f82b..cdd88372250 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java
@@ -94,7 +94,7 @@ public class PackageFrameWriter extends HtmlDocletWriter {
packgen = new PackageFrameWriter(configuration, packageDoc);
String pkgName = Util.getPackageName(packageDoc);
Content body = packgen.getBody(false, packgen.getWindowTitle(pkgName));
- Content pkgNameContent = new RawHtml(pkgName);
+ Content pkgNameContent = new StringContent(pkgName);
Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, HtmlStyle.bar,
packgen.getTargetPackageLink(packageDoc, "classFrame", pkgNameContent));
body.addContent(heading);
@@ -166,7 +166,7 @@ public class PackageFrameWriter extends HtmlDocletWriter {
Arrays.sort(arr);
boolean printedHeader = false;
HtmlTree ul = new HtmlTree(HtmlTag.UL);
- ul.addAttr(HtmlAttr.TITLE, labelContent.toString());
+ ul.setTitle(labelContent);
for (int i = 0; i < arr.length; i++) {
if (documentedClasses != null &&
!documentedClasses.contains(arr[i])) {
@@ -182,10 +182,10 @@ public class PackageFrameWriter extends HtmlDocletWriter {
contentTree.addContent(heading);
printedHeader = true;
}
- Content link = new RawHtml (getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.PACKAGE_FRAME, arr[i],
- (arr[i].isInterface() ? italicsText(arr[i].name()) :
- arr[i].name()),"classFrame")));
+ Content arr_i_name = new StringContent(arr[i].name());
+ if (arr[i].isInterface()) arr_i_name = HtmlTree.I(arr_i_name);
+ Content link = getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.PACKAGE_FRAME, arr[i]).label(arr_i_name).target("classFrame"));
Content li = HtmlTree.LI(link);
ul.addContent(li);
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java
index ef602999135..fad1bd39c04 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java
@@ -84,7 +84,7 @@ public class PackageIndexFrameWriter extends AbstractPackageIndexWriter {
packagesLabel);
Content div = HtmlTree.DIV(HtmlStyle.indexContainer, heading);
HtmlTree ul = new HtmlTree(HtmlTag.UL);
- ul.addAttr(HtmlAttr.TITLE, packagesLabel.toString());
+ ul.setTitle(packagesLabel);
for(int i = 0; i < packages.length; i++) {
// Do not list the package if -nodeprecated option is set and the
// package is marked as deprecated.
@@ -112,7 +112,7 @@ public class PackageIndexFrameWriter extends AbstractPackageIndexWriter {
DocPaths.PACKAGE_FRAME), packageLabel, "",
"packageFrame");
} else {
- packageLabel = new RawHtml("<unnamed package>");
+ packageLabel = new StringContent("");
packageLinkContent = getHyperLink(DocPaths.PACKAGE_FRAME,
packageLabel, "", "packageFrame");
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java
index ee497deae07..e11ed98b527 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java
@@ -123,7 +123,7 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
/**
* {@inheritDoc}
*/
- protected void addProfilesList(String profileSummary, String profilesTableSummary,
+ protected void addProfilesList(Content profileSummary, String profilesTableSummary,
Content body) {
Content table = HtmlTree.TABLE(HtmlStyle.overviewSummary, 0, 3, 0, profilesTableSummary,
getTableCaption(profileSummary));
@@ -141,7 +141,7 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
protected void addPackagesList(PackageDoc[] packages, String text,
String tableSummary, Content body) {
Content table = HtmlTree.TABLE(HtmlStyle.overviewSummary, 0, 3, 0, tableSummary,
- getTableCaption(text));
+ getTableCaption(new RawHtml(text)));
table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
addPackagesList(packages, tbody);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java
index e95c370502c..d9510f224f9 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java
index b8369ce6255..3e2668fe0ac 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -152,9 +152,9 @@ public class PackageUseWriter extends SubWriterHolderWriter {
*/
protected void addPackageList(Content contentTree) throws IOException {
Content table = HtmlTree.TABLE(0, 3, 0, useTableSummary,
- getTableCaption(configuration.getText(
+ getTableCaption(configuration.getResource(
"doclet.ClassUse_Packages.that.use.0",
- getPackageLinkString(pkgdoc, Util.getPackageName(pkgdoc), false))));
+ getPackageLink(pkgdoc, Util.getPackageName(pkgdoc)))));
table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
Iterator it = usingPackageToUsedClasses.keySet().iterator();
@@ -197,10 +197,10 @@ public class PackageUseWriter extends SubWriterHolderWriter {
String tableSummary = configuration.getText("doclet.Use_Table_Summary",
configuration.getText("doclet.classes"));
Content table = HtmlTree.TABLE(0, 3, 0, tableSummary,
- getTableCaption(configuration.getText(
+ getTableCaption(configuration.getResource(
"doclet.ClassUse_Classes.in.0.used.by.1",
- getPackageLinkString(pkgdoc, Util.getPackageName(pkgdoc), false),
- getPackageLinkString(usingPackage,Util.getPackageName(usingPackage), false))));
+ getPackageLink(pkgdoc, Util.getPackageName(pkgdoc)),
+ getPackageLink(usingPackage, Util.getPackageName(usingPackage)))));
table.addContent(getSummaryTableHeader(classTableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
Iterator itc =
@@ -247,7 +247,7 @@ public class PackageUseWriter extends SubWriterHolderWriter {
protected void addPackageUse(PackageDoc pkg, Content contentTree) throws IOException {
Content tdFirst = HtmlTree.TD(HtmlStyle.colFirst,
getHyperLink(Util.getPackageName(pkg),
- new RawHtml(Util.getPackageName(pkg))));
+ new StringContent(Util.getPackageName(pkg))));
contentTree.addContent(tdFirst);
HtmlTree tdLast = new HtmlTree(HtmlTag.TD);
tdLast.addStyle(HtmlStyle.colLast);
@@ -272,7 +272,10 @@ public class PackageUseWriter extends SubWriterHolderWriter {
Content bodyTree = getBody(true, getWindowTitle(title));
addTop(bodyTree);
addNavLinks(true, bodyTree);
- Content headContent = getResource("doclet.ClassUse_Title", packageText, name);
+ ContentBuilder headContent = new ContentBuilder();
+ headContent.addContent(getResource("doclet.ClassUse_Title", packageText));
+ headContent.addContent(new HtmlTree(HtmlTag.BR));
+ headContent.addContent(name);
Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
HtmlStyle.title, headContent);
Content div = HtmlTree.DIV(HtmlStyle.header, heading);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java
index c1fcebf5f74..16be6c30c5b 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -102,7 +102,7 @@ public class PackageWriterImpl extends HtmlDocletWriter
Content tHeading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
HtmlStyle.title, packageLabel);
tHeading.addContent(getSpace());
- Content packageHead = new RawHtml(heading);
+ Content packageHead = new StringContent(heading);
tHeading.addContent(packageHead);
div.addContent(tHeading);
addDeprecationInfo(div);
@@ -168,7 +168,7 @@ public class PackageWriterImpl extends HtmlDocletWriter
String tableSummary, String[] tableHeader, Content summaryContentTree) {
if(classes.length > 0) {
Arrays.sort(classes);
- Content caption = getTableCaption(label);
+ Content caption = getTableCaption(new RawHtml(label));
Content table = HtmlTree.TABLE(HtmlStyle.packageSummary, 0, 3, 0,
tableSummary, caption);
table.addContent(getSummaryTableHeader(tableHeader, "col"));
@@ -178,9 +178,8 @@ public class PackageWriterImpl extends HtmlDocletWriter
!configuration.isGeneratedDoc(classes[i])) {
continue;
}
- Content classContent = new RawHtml(getLink(new LinkInfoImpl(
- configuration, LinkInfoImpl.CONTEXT_PACKAGE, classes[i],
- false)));
+ Content classContent = getLink(new LinkInfoImpl(
+ configuration, LinkInfoImpl.Kind.PACKAGE, classes[i]));
Content tdClass = HtmlTree.TD(HtmlStyle.colFirst, classContent);
HtmlTree tr = HtmlTree.TR(tdClass);
if (i%2 == 0)
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java
index f336fe86f03..4689ecadc49 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java
@@ -87,7 +87,7 @@ public class ProfileIndexFrameWriter extends AbstractProfileIndexWriter {
profilesLabel);
Content div = HtmlTree.DIV(HtmlStyle.indexContainer, heading);
HtmlTree ul = new HtmlTree(HtmlTag.UL);
- ul.addAttr(HtmlAttr.TITLE, profilesLabel.toString());
+ ul.setTitle(profilesLabel);
for (int i = 1; i < profiles.getProfileCount(); i++) {
ul.addContent(getProfile(i));
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageFrameWriter.java
index 00ff3070703..ef8c0fbbc5f 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageFrameWriter.java
@@ -158,7 +158,7 @@ public class ProfilePackageFrameWriter extends HtmlDocletWriter {
Arrays.sort(arr);
boolean printedHeader = false;
HtmlTree ul = new HtmlTree(HtmlTag.UL);
- ul.addAttr(HtmlAttr.TITLE, labelContent.toString());
+ ul.setTitle(labelContent);
for (int i = 0; i < arr.length; i++) {
if (!isTypeInProfile(arr[i], profileValue)) {
continue;
@@ -173,10 +173,10 @@ public class ProfilePackageFrameWriter extends HtmlDocletWriter {
contentTree.addContent(heading);
printedHeader = true;
}
- Content link = new RawHtml (getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.PACKAGE_FRAME, arr[i],
- (arr[i].isInterface() ? italicsText(arr[i].name()) :
- arr[i].name()),"classFrame")));
+ Content arr_i_name = new StringContent(arr[i].name());
+ if (arr[i].isInterface()) arr_i_name = HtmlTree.I(arr_i_name);
+ Content link = getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.Kind.PACKAGE_FRAME, arr[i]).label(arr_i_name).target("classFrame"));
Content li = HtmlTree.LI(link);
ul.addContent(li);
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java
index 3d5535d30f6..6764f5fdf27 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java
@@ -91,7 +91,7 @@ public class ProfilePackageIndexFrameWriter extends AbstractProfileIndexWriter {
heading.addContent(packagesLabel);
Content div = HtmlTree.DIV(HtmlStyle.indexContainer, heading);
HtmlTree ul = new HtmlTree(HtmlTag.UL);
- ul.addAttr(HtmlAttr.TITLE, packagesLabel.toString());
+ ul.setTitle(packagesLabel);
PackageDoc[] packages = configuration.profilePackages.get(profileName);
for (int i = 0; i < packages.length; i++) {
if ((!(configuration.nodeprecated && Util.isDeprecated(packages[i])))) {
@@ -118,7 +118,7 @@ public class ProfilePackageIndexFrameWriter extends AbstractProfileIndexWriter {
DocPaths.profilePackageFrame(profileName)), pkgLabel, "",
"packageFrame");
} else {
- pkgLabel = new RawHtml("<unnamed package>");
+ pkgLabel = new StringContent("");
packageLinkContent = getHyperLink(DocPaths.PACKAGE_FRAME,
pkgLabel, "", "packageFrame");
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PropertyWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PropertyWriterImpl.java
index 4fa52f202c7..9018b77ece6 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PropertyWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PropertyWriterImpl.java
@@ -98,9 +98,9 @@ public class PropertyWriterImpl extends AbstractMemberWriter
Content pre = new HtmlTree(HtmlTag.PRE);
writer.addAnnotationInfo(property, pre);
addModifiers(property, pre);
- Content propertylink = new RawHtml(writer.getLink(new LinkInfoImpl(
- configuration, LinkInfoImpl.CONTEXT_MEMBER,
- property.returnType())));
+ Content propertylink = writer.getLink(new LinkInfoImpl(
+ configuration, LinkInfoImpl.Kind.MEMBER,
+ property.returnType()));
pre.addContent(propertylink);
pre.addContent(" ");
if (configuration.linksource) {
@@ -128,12 +128,12 @@ public class PropertyWriterImpl extends AbstractMemberWriter
(! (holder.isPublic() || Util.isLinkable(holder, configuration)))) {
writer.addInlineComment(property, propertyDocTree);
} else {
- Content link = new RawHtml(
- writer.getDocLink(LinkInfoImpl.CONTEXT_PROPERTY_DOC_COPY,
+ Content link =
+ writer.getDocLink(LinkInfoImpl.Kind.PROPERTY_DOC_COPY,
holder, property,
holder.isIncluded() ?
holder.typeName() : holder.qualifiedTypeName(),
- false));
+ false);
Content codeLink = HtmlTree.CODE(link);
Content strong = HtmlTree.STRONG(holder.isClass()?
writer.descfrmClassLabel : writer.descfrmInterfaceLabel);
@@ -199,8 +199,8 @@ public class PropertyWriterImpl extends AbstractMemberWriter
/**
* {@inheritDoc}
*/
- public String getCaption() {
- return configuration.getText("doclet.Properties");
+ public Content getCaption() {
+ return configuration.getResource("doclet.Properties");
}
/**
@@ -235,8 +235,8 @@ public class PropertyWriterImpl extends AbstractMemberWriter
* {@inheritDoc}
*/
public void addInheritedSummaryLabel(ClassDoc cd, Content inheritedTree) {
- Content classLink = new RawHtml(writer.getPreQualifiedClassLink(
- LinkInfoImpl.CONTEXT_MEMBER, cd, false));
+ Content classLink = writer.getPreQualifiedClassLink(
+ LinkInfoImpl.Kind.MEMBER, cd, false);
Content label = new StringContent(cd.isClass() ?
configuration.getText("doclet.Properties_Inherited_From_Class") :
configuration.getText("doclet.Properties_Inherited_From_Interface"));
@@ -250,15 +250,15 @@ public class PropertyWriterImpl extends AbstractMemberWriter
/**
* {@inheritDoc}
*/
- protected void addSummaryLink(int context, ClassDoc cd, ProgramElementDoc member,
+ protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member,
Content tdSummary) {
- Content strong = HtmlTree.STRONG(new RawHtml(
+ Content strong = HtmlTree.STRONG(
writer.getDocLink(context,
cd,
(MemberDoc) member,
member.name().substring(0, member.name().lastIndexOf("Property")),
false,
- true)));
+ true));
Content code = HtmlTree.CODE(strong);
tdSummary.addContent(code);
@@ -269,12 +269,12 @@ public class PropertyWriterImpl extends AbstractMemberWriter
*/
protected void addInheritedSummaryLink(ClassDoc cd,
ProgramElementDoc member, Content linksTree) {
- linksTree.addContent(new RawHtml(
- writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER, cd, (MemberDoc)member,
+ linksTree.addContent(
+ writer.getDocLink(LinkInfoImpl.Kind.MEMBER, cd, (MemberDoc)member,
((member.name().lastIndexOf("Property") != -1) && configuration.javafx)
? member.name().substring(0, member.name().length() - "Property".length())
: member.name(),
- false, true)));
+ false, true));
}
/**
@@ -289,7 +289,7 @@ public class PropertyWriterImpl extends AbstractMemberWriter
* {@inheritDoc}
*/
protected Content getDeprecatedLink(ProgramElementDoc member) {
- return writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER,
+ return writer.getDocLink(LinkInfoImpl.Kind.MEMBER,
(MemberDoc) member, ((MethodDoc)member).qualifiedName());
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SerializedFormWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SerializedFormWriterImpl.java
index 665d15c17bf..23ef78005bf 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SerializedFormWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SerializedFormWriterImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -127,29 +127,28 @@ public class SerializedFormWriterImpl extends SubWriterHolderWriter
* @return a content tree for the class header
*/
public Content getClassHeader(ClassDoc classDoc) {
- String classLink = (classDoc.isPublic() || classDoc.isProtected())?
- getLink(new LinkInfoImpl(configuration, classDoc,
- configuration.getClassName(classDoc))):
- classDoc.qualifiedName();
+ Content classLink = (classDoc.isPublic() || classDoc.isProtected()) ?
+ getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.DEFAULT, classDoc)
+ .label(configuration.getClassName(classDoc))) :
+ new StringContent(classDoc.qualifiedName());
Content li = HtmlTree.LI(HtmlStyle.blockList, getMarkerAnchor(
classDoc.qualifiedName()));
- String superClassLink =
+ Content superClassLink =
classDoc.superclassType() != null ?
getLink(new LinkInfoImpl(configuration,
- LinkInfoImpl.CONTEXT_SERIALIZED_FORM,
+ LinkInfoImpl.Kind.SERIALIZED_FORM,
classDoc.superclassType())) :
null;
//Print the heading.
- String className = superClassLink == null ?
- configuration.getText(
+ Content className = superClassLink == null ?
+ configuration.getResource(
"doclet.Class_0_implements_serializable", classLink) :
- configuration.getText(
+ configuration.getResource(
"doclet.Class_0_extends_implements_serializable", classLink,
superClassLink);
- Content classNameContent = new RawHtml(className);
li.addContent(HtmlTree.HEADING(HtmlConstants.SERIALIZED_MEMBER_HEADING,
- classNameContent));
+ className));
return li;
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java
index c151c3ad228..9d528a93521 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,7 +58,7 @@ public class SourceToHTMLConverter {
/**
* New line to be added to the documentation.
*/
- private static final Content NEW_LINE = new RawHtml(DocletConstants.NL);
+ private static final String NEW_LINE = DocletConstants.NL;
private final ConfigurationImpl configuration;
@@ -269,10 +269,7 @@ public class SourceToHTMLConverter {
*/
private void addLine(Content pre, String line, int currentLineNo) {
if (line != null) {
- StringBuilder lineBuffer = new StringBuilder(line);
- Util.replaceTabs(configuration, lineBuffer);
- Util.escapeHtmlChars(lineBuffer);
- pre.addContent(new RawHtml(lineBuffer.toString()));
+ pre.addContent(Util.replaceTabs(configuration, line));
Content anchor = HtmlTree.A_NAME("line." + Integer.toString(currentLineNo));
pre.addContent(anchor);
pre.addContent(NEW_LINE);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SubWriterHolderWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SubWriterHolderWriter.java
index f3af8432e24..94bde2e35ec 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SubWriterHolderWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SubWriterHolderWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -135,10 +135,8 @@ public abstract class SubWriterHolderWriter extends HtmlDocletWriter {
* @return the content tree for the method type link
*/
public Content getMethodTypeLinks(MethodTypes methodType) {
- StringBuilder jsShow = new StringBuilder("javascript:show(");
- jsShow.append(methodType.value()).append(");");
- HtmlTree link = HtmlTree.A(jsShow.toString(),
- new StringContent(methodType.text()));
+ String jsShow = "javascript:show(" + methodType.value() +");";
+ HtmlTree link = HtmlTree.A(jsShow, new StringContent(methodType.text()));
return link;
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletOutputImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletOutputImpl.java
deleted file mode 100644
index 0dfb46787f5..00000000000
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletOutputImpl.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2003, 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. 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.
- */
-
-package com.sun.tools.doclets.formats.html;
-
-import com.sun.tools.doclets.internal.toolkit.taglets.*;
-
-/**
- * The output for HTML taglets.
- *
- * This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own risk.
- * This code and its internal interfaces are subject to change or
- * deletion without notice.
- *
- * @since 1.5
- * @author Jamie Ho
- */
-
-public class TagletOutputImpl implements TagletOutput {
-
- private StringBuilder output;
-
- public TagletOutputImpl(String o) {
- setOutput(o);
- }
-
- /**
- * {@inheritDoc}
- */
- public void setOutput (Object o) {
- output = new StringBuilder(o == null ? "" : (String) o);
- }
-
- /**
- * {@inheritDoc}
- */
- public void appendOutput(TagletOutput o) {
- output.append(o.toString());
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean hasInheritDocTag() {
- return output.indexOf(InheritDocTaglet.INHERIT_DOC_INLINE_TAG) != -1;
- }
-
- public String toString() {
- return output.toString();
- }
-
- /**
- * Check whether the taglet output is empty.
- */
- public boolean isEmpty() {
- return (toString().trim().isEmpty());
- }
-}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java
index 6f190dab9e5..1939d68f9fc 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,11 @@
package com.sun.tools.doclets.formats.html;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.formats.html.markup.ContentBuilder;
+import com.sun.tools.doclets.formats.html.markup.HtmlStyle;
+import com.sun.tools.doclets.formats.html.markup.HtmlTree;
+import com.sun.tools.doclets.formats.html.markup.RawHtml;
+import com.sun.tools.doclets.formats.html.markup.StringContent;
import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.doclets.internal.toolkit.builders.SerializedFormBuilder;
import com.sun.tools.doclets.internal.toolkit.taglets.*;
@@ -58,39 +63,48 @@ public class TagletWriterImpl extends TagletWriter {
/**
* {@inheritDoc}
*/
- public TagletOutput getOutputInstance() {
- return new TagletOutputImpl("");
+ public Content getOutputInstance() {
+ return new ContentBuilder();
}
/**
* {@inheritDoc}
*/
- public TagletOutput getDocRootOutput() {
+ protected Content codeTagOutput(Tag tag) {
+ Content result = HtmlTree.CODE(new StringContent(tag.text()));
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Content getDocRootOutput() {
+ String path;
if (configuration.docrootparent.length() > 0)
- return new TagletOutputImpl(configuration.docrootparent);
+ path = configuration.docrootparent;
else if (htmlWriter.pathToRoot.isEmpty())
- return new TagletOutputImpl(".");
+ path = ".";
else
- return new TagletOutputImpl(htmlWriter.pathToRoot.getPath());
+ path = htmlWriter.pathToRoot.getPath();
+ return new StringContent(path);
}
/**
* {@inheritDoc}
*/
- public TagletOutput deprecatedTagOutput(Doc doc) {
- StringBuilder output = new StringBuilder();
+ public Content deprecatedTagOutput(Doc doc) {
+ ContentBuilder result = new ContentBuilder();
Tag[] deprs = doc.tags("deprecated");
if (doc instanceof ClassDoc) {
if (Util.isDeprecated((ProgramElementDoc) doc)) {
- output.append("" +
- configuration.
- getText("doclet.Deprecated") + " ");
+ result.addContent(HtmlTree.SPAN(HtmlStyle.strong,
+ new StringContent(configuration.getText("doclet.Deprecated"))));
+ result.addContent(RawHtml.nbsp);
if (deprs.length > 0) {
Tag[] commentTags = deprs[0].inlineTags();
if (commentTags.length > 0) {
-
- output.append(commentTagsToOutput(null, doc,
- deprs[0].inlineTags(), false).toString()
+ result.addContent(commentTagsToOutput(null, doc,
+ deprs[0].inlineTags(), false)
);
}
}
@@ -98,24 +112,31 @@ public class TagletWriterImpl extends TagletWriter {
} else {
MemberDoc member = (MemberDoc) doc;
if (Util.isDeprecated((ProgramElementDoc) doc)) {
- output.append("" +
- configuration.
- getText("doclet.Deprecated") + " ");
+ result.addContent(HtmlTree.SPAN(HtmlStyle.strong,
+ new StringContent(configuration.getText("doclet.Deprecated"))));
+ result.addContent(RawHtml.nbsp);
if (deprs.length > 0) {
- output.append("");
- output.append(commentTagsToOutput(null, doc,
- deprs[0].inlineTags(), false).toString());
- output.append("");
+ Content body = commentTagsToOutput(null, doc,
+ deprs[0].inlineTags(), false);
+ result.addContent(HtmlTree.I(body));
}
} else {
if (Util.isDeprecated(member.containingClass())) {
- output.append("" +
- configuration.
- getText("doclet.Deprecated") + " ");
+ result.addContent(HtmlTree.SPAN(HtmlStyle.strong,
+ new StringContent(configuration.getText("doclet.Deprecated"))));
+ result.addContent(RawHtml.nbsp);
}
}
}
- return new TagletOutputImpl(output.toString());
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected Content literalTagOutput(Tag tag) {
+ Content result = new StringContent(tag.text());
+ return result;
}
/**
@@ -128,177 +149,200 @@ public class TagletWriterImpl extends TagletWriter {
/**
* {@inheritDoc}
*/
- public TagletOutput getParamHeader(String header) {
- StringBuilder result = new StringBuilder();
- result.append("
");
- result.append("").append(header).append("");
- return new TagletOutputImpl(result.toString());
- }
-
- /**
- * {@inheritDoc}
- */
- public TagletOutput paramTagOutput(ParamTag paramTag, String paramName) {
- TagletOutput result = new TagletOutputImpl("" + paramName + ""
- + " - " + htmlWriter.commentTagsToString(paramTag, null, paramTag.inlineTags(), false) + "");
+ public Content getParamHeader(String header) {
+ HtmlTree result = HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong,
+ new StringContent(header)));
return result;
}
/**
* {@inheritDoc}
*/
- public TagletOutput returnTagOutput(Tag returnTag) {
- TagletOutput result = new TagletOutputImpl(DocletConstants.NL + "" +
- "" + configuration.getText("doclet.Returns") +
- "" + "" + "" +
- htmlWriter.commentTagsToString(returnTag, null, returnTag.inlineTags(),
- false) + "");
+ public Content paramTagOutput(ParamTag paramTag, String paramName) {
+ ContentBuilder body = new ContentBuilder();
+ body.addContent(HtmlTree.CODE(new RawHtml(paramName)));
+ body.addContent(" - ");
+ body.addContent(htmlWriter.commentTagsToContent(paramTag, null, paramTag.inlineTags(), false));
+ HtmlTree result = HtmlTree.DD(body);
return result;
}
/**
* {@inheritDoc}
*/
- public TagletOutput seeTagOutput(Doc holder, SeeTag[] seeTags) {
- String result = "";
+ public Content propertyTagOutput(Tag tag, String prefix) {
+ Content body = new ContentBuilder();
+ body.addContent(new RawHtml(prefix));
+ body.addContent(" ");
+ body.addContent(HtmlTree.CODE(new RawHtml(tag.text())));
+ body.addContent(".");
+ Content result = HtmlTree.P(body);
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Content returnTagOutput(Tag returnTag) {
+ ContentBuilder result = new ContentBuilder();
+ result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong,
+ new StringContent(configuration.getText("doclet.Returns")))));
+ result.addContent(HtmlTree.DD(htmlWriter.commentTagsToContent(
+ returnTag, null, returnTag.inlineTags(), false)));
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Content seeTagOutput(Doc holder, SeeTag[] seeTags) {
+ ContentBuilder body = new ContentBuilder();
if (seeTags.length > 0) {
- result = addSeeHeader(result);
for (int i = 0; i < seeTags.length; ++i) {
- if (i > 0) {
- result += ", " + DocletConstants.NL;
- }
- result += htmlWriter.seeTagToString(seeTags[i]);
+ appendSeparatorIfNotEmpty(body);
+ body.addContent(htmlWriter.seeTagToContent(seeTags[i]));
}
}
if (holder.isField() && ((FieldDoc)holder).constantValue() != null &&
htmlWriter instanceof ClassWriterImpl) {
//Automatically add link to constant values page for constant fields.
- result = addSeeHeader(result);
+ appendSeparatorIfNotEmpty(body);
DocPath constantsPath =
htmlWriter.pathToRoot.resolve(DocPaths.CONSTANT_VALUES);
String whichConstant =
((ClassWriterImpl) htmlWriter).getClassDoc().qualifiedName() + "." + ((FieldDoc) holder).name();
DocLink link = constantsPath.fragment(whichConstant);
- result += htmlWriter.getHyperLinkString(link,
- configuration.getText("doclet.Constants_Summary"),
- false);
+ body.addContent(htmlWriter.getHyperLink(link,
+ new StringContent(configuration.getText("doclet.Constants_Summary"))));
}
if (holder.isClass() && ((ClassDoc)holder).isSerializable()) {
//Automatically add link to serialized form page for serializable classes.
if ((SerializedFormBuilder.serialInclude(holder) &&
SerializedFormBuilder.serialInclude(((ClassDoc)holder).containingPackage()))) {
- result = addSeeHeader(result);
+ appendSeparatorIfNotEmpty(body);
DocPath serialPath = htmlWriter.pathToRoot.resolve(DocPaths.SERIALIZED_FORM);
DocLink link = serialPath.fragment(((ClassDoc)holder).qualifiedName());
- result += htmlWriter.getHyperLinkString(link,
- configuration.getText("doclet.Serialized_Form"), false);
+ body.addContent(htmlWriter.getHyperLink(link,
+ new StringContent(configuration.getText("doclet.Serialized_Form"))));
}
}
- return result.equals("") ? null : new TagletOutputImpl(result + "");
+ if (body.isEmpty())
+ return body;
+
+ ContentBuilder result = new ContentBuilder();
+ result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong,
+ new StringContent(configuration.getText("doclet.See_Also")))));
+ result.addContent(HtmlTree.DD(body));
+ return result;
+
}
- private String addSeeHeader(String result) {
- if (result != null && result.length() > 0) {
- return result + ", " + DocletConstants.NL;
- } else {
- return "" +
- configuration.getText("doclet.See_Also") + "";
+ private void appendSeparatorIfNotEmpty(ContentBuilder body) {
+ if (!body.isEmpty()) {
+ body.addContent(", ");
+ body.addContent(DocletConstants.NL);
}
- }
+ }
/**
* {@inheritDoc}
*/
- public TagletOutput simpleTagOutput(Tag[] simpleTags, String header) {
- String result = "" + header + "" + DocletConstants.NL +
- " ";
+ public Content simpleTagOutput(Tag[] simpleTags, String header) {
+ ContentBuilder result = new ContentBuilder();
+ result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong, new RawHtml(header))));
+ ContentBuilder body = new ContentBuilder();
for (int i = 0; i < simpleTags.length; i++) {
if (i > 0) {
- result += ", ";
+ body.addContent(", ");
}
- result += htmlWriter.commentTagsToString(simpleTags[i], null, simpleTags[i].inlineTags(), false);
+ body.addContent(htmlWriter.commentTagsToContent(
+ simpleTags[i], null, simpleTags[i].inlineTags(), false));
}
- result += "" + DocletConstants.NL;
- return new TagletOutputImpl(result);
+ result.addContent(HtmlTree.DD(body));
+ return result;
}
/**
* {@inheritDoc}
*/
- public TagletOutput simpleTagOutput(Tag simpleTag, String header) {
- return new TagletOutputImpl("" + header + "" + " "
- + htmlWriter.commentTagsToString(simpleTag, null, simpleTag.inlineTags(), false)
- + "" + DocletConstants.NL);
+ public Content simpleTagOutput(Tag simpleTag, String header) {
+ ContentBuilder result = new ContentBuilder();
+ result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong, new RawHtml(header))));
+ Content body = htmlWriter.commentTagsToContent(
+ simpleTag, null, simpleTag.inlineTags(), false);
+ result.addContent(HtmlTree.DD(body));
+ return result;
}
/**
* {@inheritDoc}
*/
- public TagletOutput getThrowsHeader() {
- return new TagletOutputImpl(DocletConstants.NL + "" + "" +
- configuration.getText("doclet.Throws") + "");
+ public Content getThrowsHeader() {
+ HtmlTree result = HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong,
+ new StringContent(configuration.getText("doclet.Throws"))));
+ return result;
}
/**
* {@inheritDoc}
*/
- public TagletOutput throwsTagOutput(ThrowsTag throwsTag) {
- String result = DocletConstants.NL + "";
- result += throwsTag.exceptionType() == null ?
- htmlWriter.codeText(throwsTag.exceptionName()) :
- htmlWriter.codeText(
- htmlWriter.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_MEMBER,
- throwsTag.exceptionType())));
- TagletOutput text = new TagletOutputImpl(
- htmlWriter.commentTagsToString(throwsTag, null,
- throwsTag.inlineTags(), false));
- if (text != null && text.toString().length() > 0) {
- result += " - " + text;
+ public Content throwsTagOutput(ThrowsTag throwsTag) {
+ ContentBuilder body = new ContentBuilder();
+ Content excName = (throwsTag.exceptionType() == null) ?
+ new RawHtml(throwsTag.exceptionName()) :
+ htmlWriter.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER,
+ throwsTag.exceptionType()));
+ body.addContent(HtmlTree.CODE(excName));
+ Content desc = htmlWriter.commentTagsToContent(throwsTag, null,
+ throwsTag.inlineTags(), false);
+ if (desc != null && !desc.isEmpty()) {
+ body.addContent(" - ");
+ body.addContent(desc);
}
- result += "";
- return new TagletOutputImpl(result);
+ HtmlTree result = HtmlTree.DD(body);
+ return result;
}
/**
* {@inheritDoc}
*/
- public TagletOutput throwsTagOutput(Type throwsType) {
- return new TagletOutputImpl(DocletConstants.NL + "" +
- htmlWriter.codeText(htmlWriter.getLink(
- new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_MEMBER, throwsType))) + "");
+ public Content throwsTagOutput(Type throwsType) {
+ HtmlTree result = HtmlTree.DD(HtmlTree.CODE(htmlWriter.getLink(
+ new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER, throwsType))));
+ return result;
}
/**
* {@inheritDoc}
*/
- public TagletOutput valueTagOutput(FieldDoc field, String constantVal,
+ public Content valueTagOutput(FieldDoc field, String constantVal,
boolean includeLink) {
- return new TagletOutputImpl(includeLink ?
- htmlWriter.getDocLink(LinkInfoImpl.CONTEXT_VALUE_TAG, field,
- constantVal, false) : constantVal);
+ return includeLink ?
+ htmlWriter.getDocLink(LinkInfoImpl.Kind.VALUE_TAG, field,
+ constantVal, false) : new RawHtml(constantVal);
}
/**
* {@inheritDoc}
*/
- public TagletOutput commentTagsToOutput(Tag holderTag, Tag[] tags) {
+ public Content commentTagsToOutput(Tag holderTag, Tag[] tags) {
return commentTagsToOutput(holderTag, null, tags, false);
}
/**
* {@inheritDoc}
*/
- public TagletOutput commentTagsToOutput(Doc holderDoc, Tag[] tags) {
+ public Content commentTagsToOutput(Doc holderDoc, Tag[] tags) {
return commentTagsToOutput(null, holderDoc, tags, false);
}
/**
* {@inheritDoc}
*/
- public TagletOutput commentTagsToOutput(Tag holderTag,
+ public Content commentTagsToOutput(Tag holderTag,
Doc holderDoc, Tag[] tags, boolean isFirstSentence) {
- return new TagletOutputImpl(htmlWriter.commentTagsToString(
- holderTag, holderDoc, tags, isFirstSentence));
+ return htmlWriter.commentTagsToContent(
+ holderTag, holderDoc, tags, isFirstSentence);
}
/**
@@ -307,13 +351,4 @@ public class TagletWriterImpl extends TagletWriter {
public Configuration configuration() {
return configuration;
}
-
- /**
- * Return an instance of a TagletWriter that knows how to write HTML.
- *
- * @return an instance of a TagletWriter that knows how to write HTML.
- */
- public TagletOutput getTagletOutputInstance() {
- return new TagletOutputImpl("");
- }
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/ContentBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/ContentBuilder.java
new file mode 100644
index 00000000000..a58662763ba
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/ContentBuilder.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.
+ */
+
+package com.sun.tools.doclets.formats.html.markup;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import com.sun.tools.doclets.internal.toolkit.Content;
+
+/**
+ * A sequence of Content nodes.
+ */
+public class ContentBuilder extends Content {
+ protected List contents = Collections.emptyList();
+
+ @Override
+ public void addContent(Content content) {
+ nullCheck(content);
+ if ((content instanceof ContentBuilder) && content.isEmpty())
+ return;
+ ensureMutableContents();
+ if (content instanceof ContentBuilder) {
+ contents.addAll(((ContentBuilder) content).contents);
+ } else
+ contents.add(content);
+ }
+
+ @Override
+ public void addContent(String text) {
+ if (text.isEmpty())
+ return;
+ ensureMutableContents();
+ Content c = contents.isEmpty() ? null : contents.get(contents.size() - 1);
+ StringContent sc;
+ if (c != null && c instanceof StringContent) {
+ sc = (StringContent) c;
+ } else {
+ contents.add(sc = new StringContent());
+ }
+ sc.addContent(text);
+ }
+
+ @Override
+ public boolean write(Writer writer, boolean atNewline) throws IOException {
+ for (Content content: contents) {
+ atNewline = content.write(writer, atNewline);
+ }
+ return atNewline;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ for (Content content: contents) {
+ if (!content.isEmpty())
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int charCount() {
+ int n = 0;
+ for (Content c : contents)
+ n += c.charCount();
+ return n;
+ }
+
+ private void ensureMutableContents() {
+ if (contents.isEmpty())
+ contents = new ArrayList();
+ }
+}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java
index 36b55febcff..c0048f99940 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,6 @@ import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.doclets.internal.toolkit.util.DocFile;
import com.sun.tools.doclets.internal.toolkit.util.DocLink;
import com.sun.tools.doclets.internal.toolkit.util.DocPath;
-import com.sun.tools.doclets.internal.toolkit.util.DocPaths;
/**
@@ -72,43 +71,8 @@ public abstract class HtmlDocWriter extends HtmlWriter {
*/
public abstract Configuration configuration();
- /**
- * Return Html Hyper Link string.
- *
- * @param link String name of the file.
- * @param label Tag for the link.
- * @param strong Boolean that sets label to strong.
- * @return String Hyper Link.
- */
- public String getHyperLinkString(DocPath link,
- String label, boolean strong) {
- return getHyperLinkString(link, label, strong, "", "", "");
- }
-
- public String getHyperLinkString(DocLink link,
- String label, boolean strong) {
- return getHyperLinkString(link, label, strong, "", "", "");
- }
-
- /**
- * Get Html Hyper Link string.
- *
- * @param link String name of the file.
- * @param label Tag for the link.
- * @param strong Boolean that sets label to strong.
- * @param stylename String style of text defined in style sheet.
- * @return String Hyper Link.
- */
- public String getHyperLinkString(DocPath link,
- String label, boolean strong,
- String stylename) {
- return getHyperLinkString(link, label, strong, stylename, "", "");
- }
-
- public String getHyperLinkString(DocLink link,
- String label, boolean strong,
- String stylename) {
- return getHyperLinkString(link, label, strong, stylename, "", "");
+ public Content getHyperLink(DocPath link, String label) {
+ return getHyperLink(link, new StringContent(label), false, "", "", "");
}
/**
@@ -125,69 +89,47 @@ public abstract class HtmlDocWriter extends HtmlWriter {
}
/**
- * Get Html Hyper Link string.
+ * Get Html hyperlink.
*
- * @param link String name of the file.
+ * @param link path of the file.
* @param label Tag for the link.
* @return a content tree for the hyper link
*/
+ public Content getHyperLink(DocPath link, Content label) {
+ return getHyperLink(link, label, "", "");
+ }
+
+ public Content getHyperLink(DocLink link, Content label) {
+ return getHyperLink(link, label, "", "");
+ }
+
public Content getHyperLink(DocPath link,
- Content label) {
- return getHyperLink(link, label, "", "");
- }
-
- public Content getHyperLink(DocLink link,
- Content label) {
- return getHyperLink(link, label, "", "");
- }
-
- /**
- * Get Html Hyper Link string.
- *
- * @param link String name of the file.
- * @param label Tag for the link.
- * @param strong Boolean that sets label to strong.
- * @param stylename String style of text defined in style sheet.
- * @param title String that describes the links content for accessibility.
- * @param target Target frame.
- * @return String Hyper Link.
- */
- public String getHyperLinkString(DocPath link,
- String label, boolean strong,
+ Content label, boolean strong,
String stylename, String title, String target) {
- return getHyperLinkString(new DocLink(link), label, strong,
+ return getHyperLink(new DocLink(link), label, strong,
stylename, title, target);
}
- public String getHyperLinkString(DocLink link,
- String label, boolean strong,
+ public Content getHyperLink(DocLink link,
+ Content label, boolean strong,
String stylename, String title, String target) {
- StringBuilder retlink = new StringBuilder();
- retlink.append("");
- if (stylename != null && stylename.length() != 0) {
- retlink.append("");
- }
- if (strong) {
- retlink.append("");
- }
- retlink.append(label);
- if (strong) {
- retlink.append("");
- }
- if (stylename != null && stylename.length() != 0) {
- retlink.append("");
- }
- retlink.append("");
- return retlink.toString();
+ return l;
}
/**
@@ -216,17 +158,6 @@ public abstract class HtmlDocWriter extends HtmlWriter {
return anchor;
}
- /**
- * Get link string without positioning in the file.
- *
- * @param link String name of the file.
- * @param label Tag for the link.
- * @return Strign Hyper link.
- */
- public String getHyperLinkString(DocPath link, String label) {
- return getHyperLinkString(link, label, false);
- }
-
/**
* Get the name of the package, this class is in.
*
@@ -277,20 +208,6 @@ public abstract class HtmlDocWriter extends HtmlWriter {
write(htmlDocument);
}
- /**
- * Print the appropriate spaces to format the class tree in the class page.
- *
- * @param len Number of spaces.
- */
- public String spaces(int len) {
- String space = "";
-
- for (int i = 0; i < len; i++) {
- space += " ";
- }
- return space;
- }
-
protected String getGeneratedByString() {
Calendar calendar = new GregorianCalendar(TimeZone.getDefault());
Date today = calendar.getTime();
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTag.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTag.java
index a4ee63d772b..fe9f5545937 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTag.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTag.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,7 @@ public enum HtmlTag {
CENTER,
CODE(BlockType.INLINE, EndTag.END),
DD,
+ DIR,
DIV,
DL,
DT,
@@ -63,6 +64,7 @@ public enum HtmlTag {
I(BlockType.INLINE, EndTag.END),
IMG(BlockType.INLINE, EndTag.NOEND),
LI,
+ LISTING,
LINK(BlockType.OTHER, EndTag.NOEND),
MENU,
META(BlockType.OTHER, EndTag.NOEND),
@@ -75,6 +77,7 @@ public enum HtmlTag {
SMALL(BlockType.INLINE, EndTag.END),
SPAN(BlockType.INLINE, EndTag.END),
STRONG(BlockType.INLINE, EndTag.END),
+ SUB(BlockType.INLINE, EndTag.END),
TABLE,
TBODY,
TD,
@@ -84,14 +87,14 @@ public enum HtmlTag {
TT(BlockType.INLINE, EndTag.END),
UL;
- protected final BlockType blockType;
- protected final EndTag endTag;
- private final String value;
+ public final BlockType blockType;
+ public final EndTag endTag;
+ public final String value;
/**
* Enum representing the type of HTML element.
*/
- protected static enum BlockType {
+ public static enum BlockType {
BLOCK,
INLINE,
OTHER;
@@ -100,7 +103,7 @@ public enum HtmlTag {
/**
* Enum representing HTML end tag requirement.
*/
- protected static enum EndTag {
+ public static enum EndTag {
END,
NOEND;
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java
index 6c761050c7a..e6c101a5d4b 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -78,8 +78,12 @@ public class HtmlTree extends Content {
*/
public void addAttr(HtmlAttr attrName, String attrValue) {
if (attrs.isEmpty())
- attrs = new LinkedHashMap();
- attrs.put(nullCheck(attrName), nullCheck(attrValue));
+ attrs = new LinkedHashMap(3);
+ attrs.put(nullCheck(attrName), escapeHtmlChars(attrValue));
+ }
+
+ public void setTitle(Content body) {
+ addAttr(HtmlAttr.TITLE, stripHtml(body));
}
/**
@@ -123,6 +127,42 @@ public class HtmlTree extends Content {
addContent(new StringContent(stringContent));
}
+ public int charCount() {
+ int n = 0;
+ for (Content c : content)
+ n += c.charCount();
+ return n;
+ }
+
+ /**
+ * Given a string, escape all special html characters and
+ * return the result.
+ *
+ * @param s The string to check.
+ * @return the original string with all of the HTML characters escaped.
+ */
+ private static String escapeHtmlChars(String s) {
+ for (int i = 0; i < s.length(); i++) {
+ char ch = s.charAt(i);
+ switch (ch) {
+ // only start building a new string if we need to
+ case '<': case '>': case '&':
+ StringBuilder sb = new StringBuilder(s.substring(0, i));
+ for ( ; i < s.length(); i++) {
+ ch = s.charAt(i);
+ switch (ch) {
+ case '<': sb.append("<"); break;
+ case '>': sb.append(">"); break;
+ case '&': sb.append("&"); break;
+ default: sb.append(ch); break;
+ }
+ }
+ return sb.toString();
+ }
+ }
+ return s;
+ }
+
/**
* Generates an HTML anchor tag.
*
@@ -132,7 +172,7 @@ public class HtmlTree extends Content {
*/
public static HtmlTree A(String ref, Content body) {
HtmlTree htmltree = new HtmlTree(HtmlTag.A, nullCheck(body));
- htmltree.addAttr(HtmlAttr.HREF, nullCheck(ref));
+ htmltree.addAttr(HtmlAttr.HREF, ref);
return htmltree;
}
@@ -317,7 +357,7 @@ public class HtmlTree extends Content {
HtmlStyle styleClass, Content body) {
HtmlTree htmltree = new HtmlTree(headingTag, nullCheck(body));
if (printTitle)
- htmltree.addAttr(HtmlAttr.TITLE, Util.stripHtml(body.toString()));
+ htmltree.setTitle(body);
if (styleClass != null)
htmltree.addStyle(styleClass);
return htmltree;
@@ -802,7 +842,7 @@ public class HtmlTree extends Content {
out.write(tagString);
Iterator iterator = attrs.keySet().iterator();
HtmlAttr key;
- String value = "";
+ String value;
while (iterator.hasNext()) {
key = iterator.next();
value = attrs.get(key);
@@ -830,4 +870,22 @@ public class HtmlTree extends Content {
return false;
}
}
+
+ /**
+ * Given a Content node, strips all html characters and
+ * return the result.
+ *
+ * @param body The content node to check.
+ * @return the plain text from the content node
+ *
+ */
+ private static String stripHtml(Content body) {
+ String rawString = body.toString();
+ // remove HTML tags
+ rawString = rawString.replaceAll("\\<.*?>", " ");
+ // consolidate multiple spaces between a word to a single space
+ rawString = rawString.replaceAll("\\b\\s{2,}\\b", " ");
+ // remove extra whitespaces
+ return rawString.trim();
+ }
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java
index f4d04bb69dd..6fe85c0ee6d 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java
@@ -27,6 +27,8 @@ package com.sun.tools.doclets.formats.html.markup;
import java.io.*;
import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.doclets.internal.toolkit.util.*;
@@ -195,8 +197,7 @@ public class HtmlWriter {
configuration.getText("doclet.Modifier"),
configuration.getText("doclet.Type"));
overviewLabel = getResource("doclet.Overview");
- defaultPackageLabel = new RawHtml(
- DocletConstants.DEFAULT_PACKAGE_NAME);
+ defaultPackageLabel = new StringContent(DocletConstants.DEFAULT_PACKAGE_NAME);
packageLabel = getResource("doclet.Package");
profileLabel = getResource("doclet.Profile");
useLabel = getResource("doclet.navClassUse");
@@ -252,30 +253,30 @@ public class HtmlWriter {
* @return a content tree for the text
*/
public Content getResource(String key) {
- return new StringContent(configuration.getText(key));
+ return configuration.getResource(key);
}
/**
* Get the configuration string as a content.
*
* @param key the key to look for in the configuration file
- * @param a1 string argument added to configuration text
+ * @param o string or content argument added to configuration text
* @return a content tree for the text
*/
- public Content getResource(String key, String a1) {
- return new RawHtml(configuration.getText(key, a1));
+ public Content getResource(String key, Object o) {
+ return configuration.getResource(key, o);
}
/**
* Get the configuration string as a content.
*
* @param key the key to look for in the configuration file
- * @param a1 string argument added to configuration text
- * @param a2 string argument added to configuration text
+ * @param o1 string or content argument added to configuration text
+ * @param o2 string or content argument added to configuration text
* @return a content tree for the text
*/
- public Content getResource(String key, String a1, String a2) {
- return new RawHtml(configuration.getText(key, a1, a2));
+ public Content getResource(String key, Object o0, Object o1) {
+ return configuration.getResource(key, o0, o1);
}
/**
@@ -303,10 +304,11 @@ public class HtmlWriter {
*
* @return a content for the SCRIPT tag
*/
- protected Content getFramesetJavaScript(){
+ protected Content getFramesetJavaScript() {
HtmlTree script = new HtmlTree(HtmlTag.SCRIPT);
script.addAttr(HtmlAttr.TYPE, "text/javascript");
- String scriptCode = DocletConstants.NL + " targetPage = \"\" + window.location.search;" + DocletConstants.NL +
+ String scriptCode = DocletConstants.NL +
+ " targetPage = \"\" + window.location.search;" + DocletConstants.NL +
" if (targetPage != \"\" && targetPage != \"undefined\")" + DocletConstants.NL +
" targetPage = targetPage.substring(1);" + DocletConstants.NL +
" if (targetPage.indexOf(\":\") != -1)" + DocletConstants.NL +
@@ -400,16 +402,6 @@ public class HtmlWriter {
return title;
}
- /**
- * Return, text passed, with Italics <i> and </i> tags, surrounding it.
- * So if the text passed is "Hi", then string returned will be "<i>Hi</i>".
- *
- * @param text String to be printed in between <I> and </I> tags.
- */
- public String italicsText(String text) {
- return "" + text + "";
- }
-
public String codeText(String text) {
return "" + text + "";
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/RawHtml.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/RawHtml.java
index 8ad3c404023..6b4fc6edfc5 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/RawHtml.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/RawHtml.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,7 @@ import com.sun.tools.doclets.internal.toolkit.util.*;
*
* @author Bhavesh Patel
*/
-public class RawHtml extends Content{
+public class RawHtml extends Content {
private String rawHtmlContent;
@@ -90,10 +90,65 @@ public class RawHtml extends Content{
/**
* {@inheritDoc}
*/
+ @Override
public String toString() {
return rawHtmlContent;
}
+ private enum State { TEXT, ENTITY, TAG, STRING };
+
+ @Override
+ public int charCount() {
+ return charCount(rawHtmlContent);
+ }
+
+ static int charCount(String htmlText) {
+ State state = State.TEXT;
+ int count = 0;
+ for (int i = 0; i < htmlText.length(); i++) {
+ char c = htmlText.charAt(i);
+ switch (state) {
+ case TEXT:
+ switch (c) {
+ case '<':
+ state = State.TAG;
+ break;
+ case '&':
+ state = State.ENTITY;
+ count++;
+ break;
+ default:
+ count++;
+ }
+ break;
+
+ case ENTITY:
+ if (!Character.isLetterOrDigit(c))
+ state = State.TEXT;
+ break;
+
+ case TAG:
+ switch (c) {
+ case '"':
+ state = State.STRING;
+ break;
+ case '>':
+ state = State.TEXT;
+ break;
+ }
+ break;
+
+ case STRING:
+ switch (c) {
+ case '"':
+ state = State.TAG;
+ break;
+ }
+ }
+ }
+ return count;
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/StringContent.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/StringContent.java
index adddb32f993..21d67c00cfa 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/StringContent.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/StringContent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,7 @@ import com.sun.tools.doclets.internal.toolkit.util.*;
*
* @author Bhavesh Patel
*/
-public class StringContent extends Content{
+public class StringContent extends Content {
private StringBuilder stringContent;
@@ -58,8 +58,8 @@ public class StringContent extends Content{
* @param initialContent initial content for the object
*/
public StringContent(String initialContent) {
- stringContent = new StringBuilder(
- Util.escapeHtmlChars(nullCheck(initialContent)));
+ stringContent = new StringBuilder();
+ appendChars(initialContent);
}
/**
@@ -81,7 +81,7 @@ public class StringContent extends Content{
* @param strContent string content to be added
*/
public void addContent(String strContent) {
- stringContent.append(Util.escapeHtmlChars(nullCheck(strContent)));
+ appendChars(strContent);
}
/**
@@ -91,6 +91,10 @@ public class StringContent extends Content{
return (stringContent.length() == 0);
}
+ public int charCount() {
+ return RawHtml.charCount(stringContent.toString());
+ }
+
/**
* {@inheritDoc}
*/
@@ -107,4 +111,16 @@ public class StringContent extends Content{
out.write(s);
return s.endsWith(DocletConstants.NL);
}
+
+ private void appendChars(String s) {
+ for (int i = 0; i < s.length(); i++) {
+ char ch = s.charAt(i);
+ switch (ch) {
+ case '<': stringContent.append("<"); break;
+ case '>': stringContent.append(">"); break;
+ case '&': stringContent.append("&"); break;
+ default: stringContent.append(ch); break;
+ }
+ }
+ }
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties
index 1193cf913f9..f288579d392 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties
@@ -132,7 +132,7 @@ doclet.Help_line_13=Each summary entry contains the first sentence from the deta
doclet.Help_line_14=Use
doclet.Help_line_15=Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
doclet.Help_line_16=Tree (Class Hierarchy)
-doclet.Help_line_17_with_tree_link=There is a {0} page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
+doclet.Help_line_17_with_tree_link=There is a {0} page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with {1}. The interfaces do not inherit from {1}.
doclet.Help_line_18=When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
doclet.Help_line_19=When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
doclet.Help_line_20_with_deprecated_api_link=The {0} page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
@@ -179,7 +179,7 @@ doclet.ClassUse_ConstructorArgsTypeParameters=Constructor parameters in {1} with
doclet.ClassUse_ConstructorThrows=Constructors in {1} that throw {0}
doclet.ClassUse_No.usage.of.0=No usage of {0}
doclet.Window_ClassUse_Header=Uses of {0} {1}
-doclet.ClassUse_Title=Uses of {0}
{1}
+doclet.ClassUse_Title=Uses of {0}
doclet.navClassUse=Use
doclet.Error_in_packagelist=Error in using -group option: {0} {1}
doclet.Groupname_already_used=In -group option, groupname already used: {0}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
index 493d0e9a970..b45b944416a 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
@@ -27,6 +27,8 @@ package com.sun.tools.doclets.internal.toolkit;
import java.io.*;
import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import com.sun.javadoc.*;
import com.sun.tools.javac.sym.Profiles;
@@ -825,6 +827,82 @@ public abstract class Configuration {
}
}
+ public abstract Content newContent();
+
+ /**
+ * Get the configuration string as a content.
+ *
+ * @param key the key to look for in the configuration file
+ * @return a content tree for the text
+ */
+ public Content getResource(String key) {
+ Content c = newContent();
+ c.addContent(getText(key));
+ return c;
+ }
+
+ /**
+ * Get the configuration string as a content.
+ *
+ * @param key the key to look for in the configuration file
+ * @param o string or content argument added to configuration text
+ * @return a content tree for the text
+ */
+ public Content getResource(String key, Object o) {
+ return getResource(key, o, null, null);
+ }
+
+ /**
+ * Get the configuration string as a content.
+ *
+ * @param key the key to look for in the configuration file
+ * @param o string or content argument added to configuration text
+ * @return a content tree for the text
+ */
+ public Content getResource(String key, Object o1, Object o2) {
+ return getResource(key, o1, o2, null);
+ }
+
+ /**
+ * Get the configuration string as a content.
+ *
+ * @param key the key to look for in the configuration file
+ * @param o1 string or content argument added to configuration text
+ * @param o2 string or content argument added to configuration text
+ * @return a content tree for the text
+ */
+ public Content getResource(String key, Object o0, Object o1, Object o2) {
+ Content c = newContent();
+ Pattern p = Pattern.compile("\\{([012])\\}");
+ String text = getText(key);
+ Matcher m = p.matcher(text);
+ int start = 0;
+ while (m.find(start)) {
+ c.addContent(text.substring(start, m.start()));
+
+ Object o = null;
+ switch (m.group(1).charAt(0)) {
+ case '0': o = o0; break;
+ case '1': o = o1; break;
+ case '2': o = o2; break;
+ }
+
+ if (o == null) {
+ c.addContent("{" + m.group(1) + "}");
+ } else if (o instanceof String) {
+ c.addContent((String) o);
+ } else if (o instanceof Content) {
+ c.addContent((Content) o);
+ }
+
+ start = m.end();
+ }
+
+ c.addContent(text.substring(start));
+ return c;
+ }
+
+
/**
* Return true if the ClassDoc element is getting documented, depending upon
* -nodeprecated option and the deprecation information. Return true if
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Content.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Content.java
index 836f7cf9e5f..fff01955c6a 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Content.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Content.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -96,6 +96,15 @@ public abstract class Content {
return !isEmpty();
}
+ /**
+ * Return the number of characters of plain text content in this object
+ * (optional operation.)
+ * @return the number of characters of plain text content in this
+ */
+ public int charCount() {
+ return 0;
+ }
+
/**
* Checks for null values.
*
@@ -106,32 +115,4 @@ public abstract class Content {
t.getClass();
return t;
}
-
- /**
- * Returns true if the content ends with a newline character. Empty content
- * is considered as ending with new line.
- *
- * @param contentBuilder content to test for newline character at the end
- * @return true if the content ends with newline.
- */
- protected boolean endsWithNewLine(StringBuilder contentBuilder) {
- int contentLength = contentBuilder.length();
- if (contentLength == 0) {
- return true;
- }
- int nlLength = DocletConstants.NL.length();
- if (contentLength < nlLength) {
- return false;
- }
- int contentIndex = contentLength - 1;
- int nlIndex = nlLength - 1;
- while (nlIndex >= 0) {
- if (contentBuilder.charAt(contentIndex) != DocletConstants.NL.charAt(nlIndex)) {
- return false;
- }
- contentIndex--;
- nlIndex--;
- }
- return true;
- }
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/PackageSummaryBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/PackageSummaryBuilder.java
index abe2740f9ce..b6e8fecc133 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/PackageSummaryBuilder.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/PackageSummaryBuilder.java
@@ -120,8 +120,7 @@ public class PackageSummaryBuilder extends AbstractBuilder {
* @param contentTree the content tree to which the documentation will be added
*/
public void buildPackageDoc(XMLNode node, Content contentTree) throws Exception {
- contentTree = packageWriter.getPackageHeader(
- Util.getPackageName(packageDoc));
+ contentTree = packageWriter.getPackageHeader(Util.getPackageName(packageDoc));
buildChildren(node, contentTree);
packageWriter.addPackageFooter(contentTree);
packageWriter.printDocument(contentTree);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BasePropertyTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BasePropertyTaglet.java
index b212e5dea34..e93c9028053 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BasePropertyTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BasePropertyTaglet.java
@@ -26,6 +26,7 @@
package com.sun.tools.doclets.internal.toolkit.taglets;
import com.sun.javadoc.Tag;
+import com.sun.tools.doclets.internal.toolkit.Content;
/**
* An abstract class that implements the {@link Taglet} interface and
@@ -59,15 +60,8 @@ public abstract class BasePropertyTaglet extends BaseTaglet {
* @param tagletWriter the taglet writer for output.
* @return the TagletOutput representation of this Tag.
*/
- public TagletOutput getTagletOutput(Tag tag, TagletWriter tagletWriter) {
- TagletOutput tagletOutput = tagletWriter.getOutputInstance();
- StringBuilder output = new StringBuilder("");
- output.append(getText(tagletWriter));
- output.append(" ");
- output.append(tag.text());
- output.append(".
");
- tagletOutput.setOutput(output.toString());
- return tagletOutput;
+ public Content getTagletOutput(Tag tag, TagletWriter tagletWriter) {
+ return tagletWriter.propertyTagOutput(tag, getText(tagletWriter));
}
/**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BaseTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BaseTaglet.java
index e83ac8303a1..01ba3ecc5d4 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BaseTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BaseTaglet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
package com.sun.tools.doclets.internal.toolkit.taglets;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
/**
* An abstract class for that implements the {@link Taglet} interface.
@@ -130,7 +131,7 @@ public abstract class BaseTaglet implements Taglet {
* {@inheritDoc}
* @throws IllegalArgumentException thrown when the method is not supported by the taglet.
*/
- public TagletOutput getTagletOutput(Tag tag, TagletWriter writer) {
+ public Content getTagletOutput(Tag tag, TagletWriter writer) {
throw new IllegalArgumentException("Method not supported in taglet " + getName() + ".");
}
@@ -138,7 +139,7 @@ public abstract class BaseTaglet implements Taglet {
* {@inheritDoc}
* @throws IllegalArgumentException thrown when the method is not supported by the taglet.
*/
- public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
+ public Content getTagletOutput(Doc holder, TagletWriter writer) {
throw new IllegalArgumentException("Method not supported in taglet " + getName() + ".");
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/CodeTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/CodeTaglet.java
index 4fec56505d8..5dc50010191 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/CodeTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/CodeTaglet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@ package com.sun.tools.doclets.internal.toolkit.taglets;
import java.util.Map;
import com.sun.javadoc.Tag;
-import com.sun.tools.doclets.Taglet;
+import com.sun.tools.doclets.internal.toolkit.Content;
/**
* An inline Taglet used to denote literal code fragments.
@@ -49,23 +49,23 @@ import com.sun.tools.doclets.Taglet;
* @since 1.5
*/
-public class CodeTaglet extends LiteralTaglet {
+public class CodeTaglet extends BaseInlineTaglet {
- private static final String NAME = "code";
+ private static final String NAME = "code";
- public static void register(Map map) {
- map.remove(NAME);
- map.put(NAME, new CodeTaglet());
- }
+ public static void register(Map map) {
+ map.remove(NAME);
+ map.put(NAME, new CodeTaglet());
+ }
- public String getName() {
- return NAME;
- }
+ public String getName() {
+ return NAME;
+ }
- /*
- * Wraps @literal's result in a element.
- */
- public String toString(Tag tag) {
- return "" + super.toString(tag) + "";
- }
+ /**
+ * {@inheritDoc}
+ */
+ public Content getTagletOutput(Tag tag, TagletWriter writer) {
+ return writer.codeTagOutput(tag);
+ }
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DeprecatedTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DeprecatedTaglet.java
index fc7fc2451b0..258fe7298a5 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DeprecatedTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DeprecatedTaglet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
package com.sun.tools.doclets.internal.toolkit.taglets;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
/**
* A taglet that represents the @deprecated tag.
@@ -48,7 +49,7 @@ public class DeprecatedTaglet extends BaseTaglet{
/**
* {@inheritDoc}
*/
- public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
+ public Content getTagletOutput(Doc holder, TagletWriter writer) {
return writer.deprecatedTagOutput(holder);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DocRootTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DocRootTaglet.java
index 8998f26121f..1a64127358f 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DocRootTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DocRootTaglet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
package com.sun.tools.doclets.internal.toolkit.taglets;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
/**
* An inline Taglet representing {@docRoot}. This taglet is
@@ -60,7 +61,7 @@ public class DocRootTaglet extends BaseInlineTaglet {
* @param writer a {@link TagletWriter} Taglet writer.
* @return the string representation of this Tag.
*/
- public TagletOutput getTagletOutput(Tag tag, TagletWriter writer) {
+ public Content getTagletOutput(Tag tag, TagletWriter writer) {
return writer.getDocRootOutput();
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ExpertTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ExpertTaglet.java
deleted file mode 100644
index 96e56271796..00000000000
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ExpertTaglet.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.
- */
-
-package com.sun.tools.doclets.internal.toolkit.taglets;
-
-import java.util.Map;
-
-import com.sun.tools.doclets.Taglet;
-import com.sun.javadoc.Tag;
-
-/**
- * An inline Taglet used to denote information for experts.
- *
- * This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own risk.
- * This code and its internal interfaces are subject to change or
- * deletion without notice.
- *
- */
-public class ExpertTaglet implements Taglet {
-
- private static final String NAME = "expert";
- private static final String START_TAG = "";
- private static final String END_TAG = "";
-
- /**
- * {@inheritDoc}
- */
- public boolean inField() {
- return true;
- }
-
- public boolean inConstructor() {
- return true;
- }
-
- public boolean inMethod() {
- return true;
- }
-
- public boolean inOverview() {
- return true;
- }
-
- public boolean inPackage() {
- return true;
- }
-
- public boolean inType() {
- return true;
- }
-
- public boolean isInlineTag() {
- return false;
- }
-
- public String getName() {
- return NAME;
- }
-
- public static void register(Map map) {
- map.remove(NAME);
- map.put(NAME, new ExpertTaglet());
- }
-
- public String toString(Tag tag) {
- return (tag.text() == null || tag.text().length() == 0) ? null :
- START_TAG + LiteralTaglet.textToString(tag.text()) + END_TAG;
- }
-
-
- public String toString(Tag[] tags) {
- if (tags == null || tags.length == 0) return null;
-
- StringBuffer sb = new StringBuffer(START_TAG);
-
- for(Tag t:tags) {
- sb.append(LiteralTaglet.textToString(t.text()));
- }
- sb.append(END_TAG);
- return sb.toString();
- }
-
-}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/InheritDocTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/InheritDocTaglet.java
index 65924bbad7f..357a083bd0b 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/InheritDocTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/InheritDocTaglet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@ package com.sun.tools.doclets.internal.toolkit.taglets;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.Configuration;
+import com.sun.tools.doclets.internal.toolkit.Content;
import com.sun.tools.doclets.internal.toolkit.util.*;
/**
@@ -60,8 +61,8 @@ public class InheritDocTaglet extends BaseInlineTaglet {
/**
* Will return false because this inline tag may
- * only appear in Methods.
- * @return false since this is not a method.
+ * not appear in Fields.
+ * @return false
*/
public boolean inField() {
return false;
@@ -69,8 +70,8 @@ public class InheritDocTaglet extends BaseInlineTaglet {
/**
* Will return false because this inline tag may
- * only appear in Methods.
- * @return false since this is not a method.
+ * not appear in Constructors.
+ * @return false
*/
public boolean inConstructor() {
return false;
@@ -78,8 +79,8 @@ public class InheritDocTaglet extends BaseInlineTaglet {
/**
* Will return false because this inline tag may
- * only appear in Methods.
- * @return false since this is not a method.
+ * not appear in Overview.
+ * @return false
*/
public boolean inOverview() {
return false;
@@ -87,20 +88,20 @@ public class InheritDocTaglet extends BaseInlineTaglet {
/**
* Will return false because this inline tag may
- * only appear in Methods.
- * @return false since this is not a method.
+ * not appear in Packages.
+ * @return false
*/
public boolean inPackage() {
return false;
}
/**
- * Will return false because this inline tag may
- * only appear in Methods.
- * @return false since this is not a method.
+ * Will return true because this inline tag may
+ * appear in Type (Class).
+ * @return true
*/
public boolean inType() {
- return false;
+ return true;
}
/**
@@ -109,33 +110,44 @@ public class InheritDocTaglet extends BaseInlineTaglet {
* of @inheritDoc with documentation from it's superclass or superinterface.
*
* @param writer the writer that is writing the output.
- * @param md the {@link MethodDoc} that we are documenting.
- * @param holderTag the tag that holds the inheritDoc tag.
+ * @param ped the {@link ProgramElementDoc} that we are documenting.
+ * @param holderTag the tag that holds the inheritDoc tag or null for type
+ * (class) docs.
* @param isFirstSentence true if we only want to inherit the first sentence.
*/
- private TagletOutput retrieveInheritedDocumentation(TagletWriter writer,
- MethodDoc md, Tag holderTag, boolean isFirstSentence) {
- TagletOutput replacement = writer.getTagletOutputInstance();
+ private Content retrieveInheritedDocumentation(TagletWriter writer,
+ ProgramElementDoc ped, Tag holderTag, boolean isFirstSentence) {
+ Content replacement = writer.getOutputInstance();
Configuration configuration = writer.configuration();
Taglet inheritableTaglet = holderTag == null ?
null : configuration.tagletManager.getTaglet(holderTag.name());
if (inheritableTaglet != null &&
!(inheritableTaglet instanceof InheritableTaglet)) {
+ String message = ped.name() +
+ ((ped instanceof ExecutableMemberDoc)
+ ? ((ExecutableMemberDoc)ped).flatSignature()
+ : "");
//This tag does not support inheritence.
- configuration.message.warning(md.position(),
- "doclet.noInheritedDoc", md.name() + md.flatSignature());
+ configuration.message.warning(ped.position(),
+ "doclet.noInheritedDoc", message);
}
DocFinder.Output inheritedDoc =
- DocFinder.search(new DocFinder.Input(md,
+ DocFinder.search(new DocFinder.Input(ped,
(InheritableTaglet) inheritableTaglet, holderTag,
isFirstSentence, true));
- if (inheritedDoc.isValidInheritDocTag == false) {
- configuration.message.warning(md.position(),
- "doclet.noInheritedDoc", md.name() + md.flatSignature());
- } else if (inheritedDoc.inlineTags.length > 0) {
- replacement = writer.commentTagsToOutput(inheritedDoc.holderTag,
- inheritedDoc.holder, inheritedDoc.inlineTags, isFirstSentence);
+ if (inheritedDoc.isValidInheritDocTag) {
+ if (inheritedDoc.inlineTags.length > 0) {
+ replacement = writer.commentTagsToOutput(inheritedDoc.holderTag,
+ inheritedDoc.holder, inheritedDoc.inlineTags, isFirstSentence);
+ }
+ } else {
+ String message = ped.name() +
+ ((ped instanceof ExecutableMemberDoc)
+ ? ((ExecutableMemberDoc)ped).flatSignature()
+ : "");
+ configuration.message.warning(ped.position(),
+ "doclet.noInheritedDoc", message);
}
return replacement;
}
@@ -146,14 +158,14 @@ public class InheritDocTaglet extends BaseInlineTaglet {
* to the generated page.
* @param tag the Tag representation of this custom tag.
* @param tagletWriter the taglet writer for output.
- * @return the TagletOutput representation of this Tag.
+ * @return the Content representation of this Tag.
*/
- public TagletOutput getTagletOutput(Tag tag, TagletWriter tagletWriter) {
- if (! (tag.holder() instanceof MethodDoc)) {
+ public Content getTagletOutput(Tag tag, TagletWriter tagletWriter) {
+ if (! (tag.holder() instanceof ProgramElementDoc)) {
return tagletWriter.getOutputInstance();
}
return tag.name().equals("@inheritDoc") ?
- retrieveInheritedDocumentation(tagletWriter, (MethodDoc) tag.holder(), null, tagletWriter.isFirstSentence) :
- retrieveInheritedDocumentation(tagletWriter, (MethodDoc) tag.holder(), tag, tagletWriter.isFirstSentence);
+ retrieveInheritedDocumentation(tagletWriter, (ProgramElementDoc) tag.holder(), null, tagletWriter.isFirstSentence) :
+ retrieveInheritedDocumentation(tagletWriter, (ProgramElementDoc) tag.holder(), tag, tagletWriter.isFirstSentence);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java
index 2955406575c..2691c2b4ab3 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
package com.sun.tools.doclets.internal.toolkit.taglets;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.formats.html.markup.RawHtml;
+import com.sun.tools.doclets.internal.toolkit.Content;
/**
* This taglet acts as a wrapper to enable
@@ -115,20 +117,20 @@ public class LegacyTaglet implements Taglet {
/**
* {@inheritDoc}
*/
- public TagletOutput getTagletOutput(Tag tag, TagletWriter writer)
+ public Content getTagletOutput(Tag tag, TagletWriter writer)
throws IllegalArgumentException {
- TagletOutput output = writer.getOutputInstance();
- output.setOutput(legacyTaglet.toString(tag));
+ Content output = writer.getOutputInstance();
+ output.addContent(new RawHtml(legacyTaglet.toString(tag)));
return output;
}
/**
* {@inheritDoc}
*/
- public TagletOutput getTagletOutput(Doc holder, TagletWriter writer)
+ public Content getTagletOutput(Doc holder, TagletWriter writer)
throws IllegalArgumentException {
- TagletOutput output = writer.getOutputInstance();
- output.setOutput(legacyTaglet.toString(holder.tags(getName())));
+ Content output = writer.getOutputInstance();
+ output.addContent(new RawHtml(legacyTaglet.toString(holder.tags(getName()))));
return output;
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LiteralTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LiteralTaglet.java
index 75cc3cf6ec2..8f3d6e6b524 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LiteralTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LiteralTaglet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,9 @@
package com.sun.tools.doclets.internal.toolkit.taglets;
import java.util.Map;
+
import com.sun.javadoc.Tag;
-import com.sun.tools.doclets.Taglet;
+import com.sun.tools.doclets.internal.toolkit.Content;
/**
@@ -47,60 +48,23 @@ import com.sun.tools.doclets.Taglet;
* @since 1.5
*/
-public class LiteralTaglet implements Taglet {
+public class LiteralTaglet extends BaseInlineTaglet {
private static final String NAME = "literal";
- public static void register(Map map) {
- map.remove(NAME);
- map.put(NAME, new LiteralTaglet());
+ public static void register(Map map) {
+ map.remove(NAME);
+ map.put(NAME, new LiteralTaglet());
}
public String getName() {
return NAME;
}
- public String toString(Tag tag) {
- return textToString(tag.text());
- }
-
- public String toString(Tag[] tags) { return null; }
-
- public boolean inField() { return false; }
-
- public boolean inConstructor() { return false; }
-
- public boolean inMethod() { return false; }
-
- public boolean inOverview() { return false; }
-
- public boolean inPackage() { return false; }
-
- public boolean inType() { return false; }
-
- public boolean isInlineTag() { return true; }
-
- /*
- * Replace occurrences of the following characters: < > &
+ /**
+ * {@inheritDoc}
*/
- protected static String textToString(String text) {
- StringBuilder buf = new StringBuilder();
- for (int i = 0; i < text.length(); i++) {
- char c = text.charAt(i);
- switch (c) {
- case '<':
- buf.append("<");
- break;
- case '>':
- buf.append(">");
- break;
- case '&':
- buf.append("&");
- break;
- default:
- buf.append(c);
- }
- }
- return buf.toString();
+ public Content getTagletOutput(Tag tag, TagletWriter writer) {
+ return writer.literalTagOutput(tag);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ParamTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ParamTaglet.java
index ad4bf8bebdb..557d89cba16 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ParamTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ParamTaglet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@ package com.sun.tools.doclets.internal.toolkit.taglets;
import java.util.*;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
import com.sun.tools.doclets.internal.toolkit.util.*;
/**
@@ -101,14 +102,14 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
}
}
ParamTag[] tags = input.isTypeVariableParamTag ?
- input.method.typeParamTags() : input.method.paramTags();
+ ((MethodDoc)input.element).typeParamTags() : ((MethodDoc)input.element).paramTags();
Map rankMap = getRankMap(input.isTypeVariableParamTag ?
- (Object[]) input.method.typeParameters() :
- (Object[]) input.method.parameters());
+ (Object[]) ((MethodDoc)input.element).typeParameters() :
+ (Object[]) ((MethodDoc)input.element).parameters());
for (int i = 0; i < tags.length; i++) {
if (rankMap.containsKey(tags[i].parameterName()) &&
rankMap.get(tags[i].parameterName()).equals((input.tagId))) {
- output.holder = input.method;
+ output.holder = input.element;
output.holderTag = tags[i];
output.inlineTags = input.isFirstSentence ?
tags[i].firstSentenceTags() : tags[i].inlineTags();
@@ -165,12 +166,12 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
* @param writer the TagletWriter that will write this tag.
* @return the TagletOutput representation of these ParamTags.
*/
- public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
+ public Content getTagletOutput(Doc holder, TagletWriter writer) {
if (holder instanceof ExecutableMemberDoc) {
ExecutableMemberDoc member = (ExecutableMemberDoc) holder;
- TagletOutput output = getTagletOutput(false, member, writer,
+ Content output = getTagletOutput(false, member, writer,
member.typeParameters(), member.typeParamTags());
- output.appendOutput(getTagletOutput(true, member, writer,
+ output.addContent(getTagletOutput(true, member, writer,
member.parameters(), member.paramTags()));
return output;
} else {
@@ -191,12 +192,12 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
*
* @return the TagletOutput representation of these ParamTags.
*/
- private TagletOutput getTagletOutput(boolean isNonTypeParams, Doc holder,
+ private Content getTagletOutput(boolean isNonTypeParams, Doc holder,
TagletWriter writer, Object[] formalParameters, ParamTag[] paramTags) {
- TagletOutput result = writer.getOutputInstance();
+ Content result = writer.getOutputInstance();
Set alreadyDocumented = new HashSet();
if (paramTags.length > 0) {
- result.appendOutput(
+ result.addContent(
processParamTags(isNonTypeParams, paramTags,
getRankMap(formalParameters), writer, alreadyDocumented)
);
@@ -204,7 +205,7 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
if (alreadyDocumented.size() != formalParameters.length) {
//Some parameters are missing corresponding @param tags.
//Try to inherit them.
- result.appendOutput(getInheritedTagletOutput (isNonTypeParams, holder,
+ result.addContent(getInheritedTagletOutput (isNonTypeParams, holder,
writer, formalParameters, alreadyDocumented));
}
return result;
@@ -214,10 +215,10 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
* Loop through each indivitual parameter. It it does not have a
* corresponding param tag, try to inherit it.
*/
- private TagletOutput getInheritedTagletOutput(boolean isNonTypeParams, Doc holder,
+ private Content getInheritedTagletOutput(boolean isNonTypeParams, Doc holder,
TagletWriter writer, Object[] formalParameters,
Set alreadyDocumented) {
- TagletOutput result = writer.getOutputInstance();
+ Content result = writer.getOutputInstance();
if ((! alreadyDocumented.contains(null)) &&
holder instanceof MethodDoc) {
for (int i = 0; i < formalParameters.length; i++) {
@@ -231,7 +232,7 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
String.valueOf(i), ! isNonTypeParams));
if (inheritedDoc.inlineTags != null &&
inheritedDoc.inlineTags.length > 0) {
- result.appendOutput(
+ result.addContent(
processParamTag(isNonTypeParams, writer,
(ParamTag) inheritedDoc.holderTag,
isNonTypeParams ?
@@ -261,12 +262,12 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
* of a rank of a parameter to its name. This is
* used to ensure that the right name is used
* when parameter documentation is inherited.
- * @return the TagletOutput representation of this Tag.
+ * @return the Content representation of this Tag.
*/
- private TagletOutput processParamTags(boolean isNonTypeParams,
+ private Content processParamTags(boolean isNonTypeParams,
ParamTag[] paramTags, Map rankMap, TagletWriter writer,
Set alreadyDocumented) {
- TagletOutput result = writer.getOutputInstance();
+ Content result = writer.getOutputInstance();
if (paramTags.length > 0) {
for (int i = 0; i < paramTags.length; ++i) {
ParamTag pt = paramTags[i];
@@ -287,7 +288,7 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
"doclet.Type_Parameters_dup_warn",
paramName);
}
- result.appendOutput(processParamTag(isNonTypeParams, writer, pt,
+ result.addContent(processParamTag(isNonTypeParams, writer, pt,
pt.parameterName(), alreadyDocumented.size() == 0));
alreadyDocumented.add(rank);
}
@@ -295,7 +296,7 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
return result;
}
/**
- * Convert the individual ParamTag into TagletOutput.
+ * Convert the individual ParamTag into Content.
*
* @param isNonTypeParams true if this is just a regular param tag. False
* if this is a type param tag.
@@ -307,16 +308,16 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
* @param isFirstParam true if this is the first param tag being printed.
*
*/
- private TagletOutput processParamTag(boolean isNonTypeParams,
+ private Content processParamTag(boolean isNonTypeParams,
TagletWriter writer, ParamTag paramTag, String name,
boolean isFirstParam) {
- TagletOutput result = writer.getOutputInstance();
+ Content result = writer.getOutputInstance();
String header = writer.configuration().getText(
isNonTypeParams ? "doclet.Parameters" : "doclet.TypeParameters");
if (isFirstParam) {
- result.appendOutput(writer.getParamHeader(header));
+ result.addContent(writer.getParamHeader(header));
}
- result.appendOutput(writer.paramTagOutput(paramTag,
+ result.addContent(writer.paramTagOutput(paramTag,
name));
return result;
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ReturnTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ReturnTaglet.java
index 9d98a9691b7..1e9e18f4c92 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ReturnTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ReturnTaglet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
package com.sun.tools.doclets.internal.toolkit.taglets;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
import com.sun.tools.doclets.internal.toolkit.util.*;
/**
@@ -50,9 +51,9 @@ public class ReturnTaglet extends BaseExecutableMemberTaglet
* {@inheritDoc}
*/
public void inherit(DocFinder.Input input, DocFinder.Output output) {
- Tag[] tags = input.method.tags("return");
+ Tag[] tags = input.element.tags("return");
if (tags.length > 0) {
- output.holder = input.method;
+ output.holder = input.element;
output.holderTag = tags[0];
output.inlineTags = input.isFirstSentence ?
tags[0].firstSentenceTags() : tags[0].inlineTags();
@@ -73,7 +74,7 @@ public class ReturnTaglet extends BaseExecutableMemberTaglet
/**
* {@inheritDoc}
*/
- public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
+ public Content getTagletOutput(Doc holder, TagletWriter writer) {
Type returnType = ((MethodDoc) holder).returnType();
Tag[] tags = holder.tags(name);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SeeTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SeeTaglet.java
index 4e3e8107c05..de88897aef6 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SeeTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SeeTaglet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
package com.sun.tools.doclets.internal.toolkit.taglets;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
import com.sun.tools.doclets.internal.toolkit.util.*;
/**
@@ -49,9 +50,9 @@ public class SeeTaglet extends BaseTaglet implements InheritableTaglet {
* {@inheritDoc}
*/
public void inherit(DocFinder.Input input, DocFinder.Output output) {
- Tag[] tags = input.method.seeTags();
+ Tag[] tags = input.element.seeTags();
if (tags.length > 0) {
- output.holder = input.method;
+ output.holder = input.element;
output.holderTag = tags[0];
output.inlineTags = input.isFirstSentence ?
tags[0].firstSentenceTags() : tags[0].inlineTags();
@@ -61,7 +62,7 @@ public class SeeTaglet extends BaseTaglet implements InheritableTaglet {
/**
* {@inheritDoc}
*/
- public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
+ public Content getTagletOutput(Doc holder, TagletWriter writer) {
SeeTag[] tags = holder.seeTags();
if (tags.length == 0 && holder instanceof MethodDoc) {
DocFinder.Output inheritedDoc =
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SimpleTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SimpleTaglet.java
index 4b21cbd4172..e201eb6adc8 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SimpleTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SimpleTaglet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
package com.sun.tools.doclets.internal.toolkit.taglets;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
+import com.sun.tools.doclets.internal.toolkit.util.DocFinder;
/**
* A simple single argument custom tag.
@@ -38,7 +40,7 @@ import com.sun.javadoc.*;
* @author Jamie Ho
*/
-public class SimpleTaglet extends BaseTaglet {
+public class SimpleTaglet extends BaseTaglet implements InheritableTaglet {
/**
* The marker in the location string for excluded tags.
@@ -199,17 +201,28 @@ public class SimpleTaglet extends BaseTaglet {
return false;
}
+ @Override
+ public void inherit(DocFinder.Input input, DocFinder.Output output) {
+ Tag[] tags = input.element.tags(tagName);
+ if (tags.length > 0) {
+ output.holder = input.element;
+ output.holderTag = tags[0];
+ output.inlineTags = input.isFirstSentence
+ ? tags[0].firstSentenceTags() : tags[0].inlineTags();
+ }
+ }
+
/**
* {@inheritDoc}
*/
- public TagletOutput getTagletOutput(Tag tag, TagletWriter writer) {
+ public Content getTagletOutput(Tag tag, TagletWriter writer) {
return header == null || tag == null ? null : writer.simpleTagOutput(tag, header);
}
/**
* {@inheritDoc}
*/
- public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
+ public Content getTagletOutput(Doc holder, TagletWriter writer) {
if (header == null || holder.tags(getName()).length == 0) {
return null;
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/Taglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/Taglet.java
index 1e2664ae4ca..e10e21ab953 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/Taglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/Taglet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
package com.sun.tools.doclets.internal.toolkit.taglets;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
/**
* The interface for a custom tag used by Doclets. A custom
@@ -132,14 +133,14 @@ public interface Taglet {
/**
* Given the Tag representation of this custom
- * tag, return its TagletOutput representation, which is output
+ * tag, return its Content representation, which is output
* to the generated page.
* @param tag the Tag representation of this custom tag.
* @param writer a {@link TagletWriter} Taglet writer.
* @throws IllegalArgumentException thrown when the method is not supported by the taglet.
- * @return the TagletOutput representation of this Tag.
+ * @return the Content representation of this Tag.
*/
- public abstract TagletOutput getTagletOutput(Tag tag, TagletWriter writer) throws IllegalArgumentException;
+ public abstract Content getTagletOutput(Tag tag, TagletWriter writer) throws IllegalArgumentException;
/**
* Given a Doc object, check if it holds any tags of
@@ -150,6 +151,8 @@ public interface Taglet {
* @throws IllegalArgumentException thrown when the method is not supported by the taglet.
* @return the TagletOutput representation of this Tag.
*/
- public abstract TagletOutput getTagletOutput(Doc holder, TagletWriter writer) throws IllegalArgumentException;
+ public abstract Content getTagletOutput(Doc holder, TagletWriter writer) throws IllegalArgumentException;
+ @Override
+ public abstract String toString();
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java
index 7b928fa498e..377cd670dee 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java
@@ -158,8 +158,7 @@ public class TagletManager {
/**
* True if we want to use JavaFX-related tags (@propertyGetter,
- * @propertySetter, @propertyDescription, @defaultValue, @treatAsPrivate,
- * @expert).
+ * @propertySetter, @propertyDescription, @defaultValue, @treatAsPrivate).
*/
private boolean javafx;
@@ -184,7 +183,7 @@ public class TagletManager {
this.showauthor = showauthor;
this.javafx = javafx;
this.message = message;
- initStandardTags();
+ initStandardTaglets();
initStandardTagsLowercase();
}
@@ -454,9 +453,9 @@ public class TagletManager {
* @return the array of Taglets that can
* appear in packages.
*/
- public Taglet[] getPackageCustomTags() {
+ public Taglet[] getPackageCustomTaglets() {
if (packageTags == null) {
- initCustomTagArrays();
+ initCustomTagletArrays();
}
return packageTags;
}
@@ -467,9 +466,9 @@ public class TagletManager {
* @return the array of Taglets that can
* appear in classes or interfaces.
*/
- public Taglet[] getTypeCustomTags() {
+ public Taglet[] getTypeCustomTaglets() {
if (typeTags == null) {
- initCustomTagArrays();
+ initCustomTagletArrays();
}
return typeTags;
}
@@ -480,9 +479,9 @@ public class TagletManager {
* @return the array of Taglets that can
* appear in comments.
*/
- public Taglet[] getInlineCustomTags() {
+ public Taglet[] getInlineCustomTaglets() {
if (inlineTags == null) {
- initCustomTagArrays();
+ initCustomTagletArrays();
}
return inlineTags;
}
@@ -493,9 +492,9 @@ public class TagletManager {
* @return the array of Taglets that can
* appear in field.
*/
- public Taglet[] getFieldCustomTags() {
+ public Taglet[] getFieldCustomTaglets() {
if (fieldTags == null) {
- initCustomTagArrays();
+ initCustomTagletArrays();
}
return fieldTags;
}
@@ -506,9 +505,9 @@ public class TagletManager {
* @return the array of Taglets that can
* appear in the serialized form.
*/
- public Taglet[] getSerializedFormTags() {
+ public Taglet[] getSerializedFormTaglets() {
if (serializedFormTags == null) {
- initCustomTagArrays();
+ initCustomTagletArrays();
}
return serializedFormTags;
}
@@ -517,19 +516,19 @@ public class TagletManager {
* @return the array of Taglets that can
* appear in the given Doc.
*/
- public Taglet[] getCustomTags(Doc doc) {
+ public Taglet[] getCustomTaglets(Doc doc) {
if (doc instanceof ConstructorDoc) {
- return getConstructorCustomTags();
+ return getConstructorCustomTaglets();
} else if (doc instanceof MethodDoc) {
- return getMethodCustomTags();
+ return getMethodCustomTaglets();
} else if (doc instanceof FieldDoc) {
- return getFieldCustomTags();
+ return getFieldCustomTaglets();
} else if (doc instanceof ClassDoc) {
- return getTypeCustomTags();
+ return getTypeCustomTaglets();
} else if (doc instanceof PackageDoc) {
- return getPackageCustomTags();
+ return getPackageCustomTaglets();
} else if (doc instanceof RootDoc) {
- return getOverviewCustomTags();
+ return getOverviewCustomTaglets();
}
return null;
}
@@ -540,9 +539,9 @@ public class TagletManager {
* @return the array of Taglets that can
* appear in constructors.
*/
- public Taglet[] getConstructorCustomTags() {
+ public Taglet[] getConstructorCustomTaglets() {
if (constructorTags == null) {
- initCustomTagArrays();
+ initCustomTagletArrays();
}
return constructorTags;
}
@@ -553,9 +552,9 @@ public class TagletManager {
* @return the array of Taglets that can
* appear in methods.
*/
- public Taglet[] getMethodCustomTags() {
+ public Taglet[] getMethodCustomTaglets() {
if (methodTags == null) {
- initCustomTagArrays();
+ initCustomTagletArrays();
}
return methodTags;
}
@@ -566,9 +565,9 @@ public class TagletManager {
* @return the array of Taglets that can
* appear in overview.
*/
- public Taglet[] getOverviewCustomTags() {
+ public Taglet[] getOverviewCustomTaglets() {
if (overviewTags == null) {
- initCustomTagArrays();
+ initCustomTagletArrays();
}
return overviewTags;
}
@@ -576,7 +575,7 @@ public class TagletManager {
/**
* Initialize the custom tag arrays.
*/
- private void initCustomTagArrays() {
+ private void initCustomTagletArrays() {
Iterator it = customTags.values().iterator();
ArrayList pTags = new ArrayList(customTags.size());
ArrayList tTags = new ArrayList(customTags.size());
@@ -631,88 +630,72 @@ public class TagletManager {
/**
* Initialize standard Javadoc tags for ordering purposes.
*/
- private void initStandardTags() {
+ private void initStandardTaglets() {
Taglet temp;
- customTags.put((temp = new ParamTaglet()).getName(), temp);
- customTags.put((temp = new ReturnTaglet()).getName(), temp);
- customTags.put((temp = new ThrowsTaglet()).getName(), temp);
- customTags.put((temp = new SimpleTaglet("exception",
- null, SimpleTaglet.METHOD + SimpleTaglet.CONSTRUCTOR)).getName(), temp);
- if (!nosince) {
- customTags.put((temp = new SimpleTaglet("since", message.getText("doclet.Since"),
- SimpleTaglet.ALL)).getName(), temp);
- }
- if (showversion) {
- customTags.put((temp = new SimpleTaglet("version", message.getText("doclet.Version"),
- SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW)).getName(), temp);
- }
- if (showauthor) {
- customTags.put((temp = new SimpleTaglet("author", message.getText("doclet.Author"),
- SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW)).getName(), temp);
- }
- customTags.put((temp = new SimpleTaglet("serialData", message.getText("doclet.SerialData"),
- SimpleTaglet.EXCLUDED)).getName(), temp);
+ addStandardTaglet(new ParamTaglet());
+ addStandardTaglet(new ReturnTaglet());
+ addStandardTaglet(new ThrowsTaglet());
+ addStandardTaglet(new SimpleTaglet("exception", null,
+ SimpleTaglet.METHOD + SimpleTaglet.CONSTRUCTOR));
+ addStandardTaglet(!nosince, new SimpleTaglet("since", message.getText("doclet.Since"),
+ SimpleTaglet.ALL));
+ addStandardTaglet(showversion, new SimpleTaglet("version", message.getText("doclet.Version"),
+ SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW));
+ addStandardTaglet(showauthor, new SimpleTaglet("author", message.getText("doclet.Author"),
+ SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW));
+ addStandardTaglet(new SimpleTaglet("serialData", message.getText("doclet.SerialData"),
+ SimpleTaglet.EXCLUDED));
customTags.put((temp = new SimpleTaglet("factory", message.getText("doclet.Factory"),
SimpleTaglet.METHOD)).getName(), temp);
- customTags.put((temp = new SeeTaglet()).getName(), temp);
+ addStandardTaglet(new SeeTaglet());
//Standard inline tags
- customTags.put((temp = new DocRootTaglet()).getName(), temp);
- customTags.put((temp = new InheritDocTaglet()).getName(), temp);
- customTags.put((temp = new ValueTaglet()).getName(), temp);
- customTags.put((temp = new LegacyTaglet(new LiteralTaglet())).getName(),
- temp);
- customTags.put((temp = new LegacyTaglet(new CodeTaglet())).getName(),
- temp);
+ addStandardTaglet(new DocRootTaglet());
+ addStandardTaglet(new InheritDocTaglet());
+ addStandardTaglet(new ValueTaglet());
+ addStandardTaglet(new LiteralTaglet());
+ addStandardTaglet(new CodeTaglet());
- //Keep track of the names of standard tags for error
- //checking purposes.
- standardTags.add("param");
- standardTags.add("return");
- standardTags.add("throws");
- standardTags.add("exception");
- standardTags.add("since");
- standardTags.add("version");
- standardTags.add("author");
- standardTags.add("see");
+ // Keep track of the names of standard tags for error
+ // checking purposes. The following are not handled above.
+ // See, for example, com.sun.tools.javadoc.Comment
standardTags.add("deprecated");
standardTags.add("link");
standardTags.add("linkplain");
- standardTags.add("inheritDoc");
- standardTags.add("docRoot");
- standardTags.add("value");
standardTags.add("serial");
- standardTags.add("serialData");
standardTags.add("serialField");
standardTags.add("Text");
- standardTags.add("literal");
- standardTags.add("code");
if (javafx) {
- initJavaFXTags();
+ initJavaFXTaglets();
}
}
/**
* Initialize JavaFX-related tags.
*/
- private void initJavaFXTags() {
- Taglet temp;
- customTags.put((temp = new PropertyGetterTaglet()).getName(), temp);
- customTags.put((temp = new PropertySetterTaglet()).getName(), temp);
- customTags.put((temp = new SimpleTaglet("propertyDescription", message.getText("doclet.PropertyDescription"),
- SimpleTaglet.FIELD + SimpleTaglet.METHOD)).getName(), temp);
- customTags.put((temp = new SimpleTaglet("defaultValue", message.getText("doclet.DefaultValue"),
- SimpleTaglet.FIELD + SimpleTaglet.METHOD)).getName(), temp);
- customTags.put((temp = new SimpleTaglet("treatAsPrivate", null,
- SimpleTaglet.FIELD + SimpleTaglet.METHOD + SimpleTaglet.TYPE)).getName(), temp);
- customTags.put((temp = new LegacyTaglet(new ExpertTaglet())).getName(), temp);
+ private void initJavaFXTaglets() {
+ addStandardTaglet(new PropertyGetterTaglet());
+ addStandardTaglet(new PropertySetterTaglet());
+ addStandardTaglet(new SimpleTaglet("propertyDescription",
+ message.getText("doclet.PropertyDescription"),
+ SimpleTaglet.FIELD + SimpleTaglet.METHOD));
+ addStandardTaglet(new SimpleTaglet("defaultValue", message.getText("doclet.DefaultValue"),
+ SimpleTaglet.FIELD + SimpleTaglet.METHOD));
+ addStandardTaglet(new SimpleTaglet("treatAsPrivate", null,
+ SimpleTaglet.FIELD + SimpleTaglet.METHOD + SimpleTaglet.TYPE));
+ }
- standardTags.add("propertyGetter");
- standardTags.add("propertySetter");
- standardTags.add("propertyDescription");
- standardTags.add("defaultValue");
- standardTags.add("treatAsPrivate");
- standardTags.add("expert");
+ void addStandardTaglet(Taglet taglet) {
+ String name = taglet.getName();
+ customTags.put(name, taglet);
+ standardTags.add(name);
+ }
+
+ void addStandardTaglet(boolean enable, Taglet taglet) {
+ String name = taglet.getName();
+ if (enable)
+ customTags.put(name, taglet);
+ standardTags.add(name);
}
/**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletOutput.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletOutput.java
deleted file mode 100644
index c7bbef457c1..00000000000
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletOutput.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2003, 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. 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.
- */
-
-package com.sun.tools.doclets.internal.toolkit.taglets;
-
-/**
- * The interface for taglet output. This interface is needed because
- * different doclets work with different formats of output. A single taglet can
- * work with any doclet that provides an implementation of taglet output.
- *
- * This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own risk.
- * This code and its internal interfaces are subject to change or
- * deletion without notice.
- *
- * @author Jamie Ho
- * @since 1.5
- */
-public interface TagletOutput {
-
- /**
- * Set the output for the taglet.
- * @param o an object representing the output.
- */
- public abstract void setOutput(Object o);
-
- /**
- * Append the given output to this output.
- * @param o a TagletOutput representing the output.
- */
- public abstract void appendOutput(TagletOutput o);
-
- /**
- * Return true if this output has any occurances of @inheritDoc.
- * @return true if inheritDoc tag is found.
- */
- public abstract boolean hasInheritDocTag();
-}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletWriter.java
index fe0093fdd1f..9f77cc8915f 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletWriter.java
@@ -53,15 +53,23 @@ public abstract class TagletWriter {
}
/**
- * @return an instance of the output object.
+ * @return an instance of an output object.
*/
- public abstract TagletOutput getOutputInstance();
+ public abstract Content getOutputInstance();
+
+ /**
+ * Return the output for a {@code...} tag.
+ *
+ * @param tag the tag.
+ * @return the output of the taglet.
+ */
+ protected abstract Content codeTagOutput(Tag tag);
/**
* Returns the output for the DocRoot inline tag.
* @return the output for the DocRoot inline tag.
*/
- protected abstract TagletOutput getDocRootOutput();
+ protected abstract Content getDocRootOutput();
/**
* Return the deprecated tag output.
@@ -69,7 +77,15 @@ public abstract class TagletWriter {
* @param doc the doc to write deprecated documentation for.
* @return the output of the deprecated tag.
*/
- protected abstract TagletOutput deprecatedTagOutput(Doc doc);
+ protected abstract Content deprecatedTagOutput(Doc doc);
+
+ /**
+ * Return the output for a {@literal...} tag.
+ *
+ * @param tag the tag.
+ * @return the output of the taglet.
+ */
+ protected abstract Content literalTagOutput(Tag tag);
/**
* Returns {@link MessageRetriever} for output purposes.
@@ -84,7 +100,7 @@ public abstract class TagletWriter {
* @param header the header to display.
* @return the header for the param tags.
*/
- protected abstract TagletOutput getParamHeader(String header);
+ protected abstract Content getParamHeader(String header);
/**
* Return the output for param tags.
@@ -93,16 +109,25 @@ public abstract class TagletWriter {
* @param paramName the name of the parameter.
* @return the output of the param tag.
*/
- protected abstract TagletOutput paramTagOutput(ParamTag paramTag,
+ protected abstract Content paramTagOutput(ParamTag paramTag,
String paramName);
+ /**
+ * Return the output for property tags.
+ *
+ * @param propertyTag the parameter to document.
+ * @param prefix the text with which to prefix the property name.
+ * @return the output of the param tag.
+ */
+ protected abstract Content propertyTagOutput(Tag propertyTag, String prefix);
+
/**
* Return the return tag output.
*
* @param returnTag the return tag to output.
* @return the output of the return tag.
*/
- protected abstract TagletOutput returnTagOutput(Tag returnTag);
+ protected abstract Content returnTagOutput(Tag returnTag);
/**
* Return the see tag output.
@@ -110,7 +135,7 @@ public abstract class TagletWriter {
* @param seeTags the array of See tags.
* @return the output of the see tags.
*/
- protected abstract TagletOutput seeTagOutput(Doc holder, SeeTag[] seeTags);
+ protected abstract Content seeTagOutput(Doc holder, SeeTag[] seeTags);
/**
* Return the output for a simple tag.
@@ -118,7 +143,7 @@ public abstract class TagletWriter {
* @param simpleTags the array of simple tags.
* @return the output of the simple tags.
*/
- protected abstract TagletOutput simpleTagOutput(Tag[] simpleTags,
+ protected abstract Content simpleTagOutput(Tag[] simpleTags,
String header);
/**
@@ -127,14 +152,14 @@ public abstract class TagletWriter {
* @param simpleTag the simple tag.
* @return the output of the simple tag.
*/
- protected abstract TagletOutput simpleTagOutput(Tag simpleTag, String header);
+ protected abstract Content simpleTagOutput(Tag simpleTag, String header);
/**
* Return the header for the throws tag.
*
* @return the header for the throws tag.
*/
- protected abstract TagletOutput getThrowsHeader();
+ protected abstract Content getThrowsHeader();
/**
* Return the header for the throws tag.
@@ -142,7 +167,7 @@ public abstract class TagletWriter {
* @param throwsTag the throws tag.
* @return the output of the throws tag.
*/
- protected abstract TagletOutput throwsTagOutput(ThrowsTag throwsTag);
+ protected abstract Content throwsTagOutput(ThrowsTag throwsTag);
/**
* Return the output for the throws tag.
@@ -150,7 +175,7 @@ public abstract class TagletWriter {
* @param throwsType the throws type.
* @return the output of the throws type.
*/
- protected abstract TagletOutput throwsTagOutput(Type throwsType);
+ protected abstract Content throwsTagOutput(Type throwsType);
/**
* Return the output for the value tag.
@@ -161,7 +186,7 @@ public abstract class TagletWriter {
* constant field itself.
* @return the output of the value tag.
*/
- protected abstract TagletOutput valueTagOutput(FieldDoc field,
+ protected abstract Content valueTagOutput(FieldDoc field,
String constantVal, boolean includeLink);
/**
@@ -175,10 +200,10 @@ public abstract class TagletWriter {
* @param output the output buffer to store the output in.
*/
public static void genTagOuput(TagletManager tagletManager, Doc doc,
- Taglet[] taglets, TagletWriter writer, TagletOutput output) {
+ Taglet[] taglets, TagletWriter writer, Content output) {
tagletManager.checkTags(doc, doc.tags(), false);
tagletManager.checkTags(doc, doc.inlineTags(), true);
- TagletOutput currentOutput = null;
+ Content currentOutput = null;
for (int i = 0; i < taglets.length; i++) {
currentOutput = null;
if (doc instanceof ClassDoc && taglets[i] instanceof ParamTaglet) {
@@ -203,7 +228,7 @@ public abstract class TagletWriter {
}
if (currentOutput != null) {
tagletManager.seenCustomTag(taglets[i].getName());
- output.appendOutput(currentOutput);
+ output.addContent(currentOutput);
}
}
}
@@ -217,16 +242,16 @@ public abstract class TagletWriter {
* @param tagletWriter The taglet writer to write the output.
* @return The output of the inline tag.
*/
- public static TagletOutput getInlineTagOuput(TagletManager tagletManager,
+ public static Content getInlineTagOuput(TagletManager tagletManager,
Tag holderTag, Tag inlineTag, TagletWriter tagletWriter) {
- Taglet[] definedTags = tagletManager.getInlineCustomTags();
+ Taglet[] definedTags = tagletManager.getInlineCustomTaglets();
//This is a custom inline tag.
for (int j = 0; j < definedTags.length; j++) {
if (("@"+definedTags[j].getName()).equals(inlineTag.name())) {
//Given a name of a seen custom tag, remove it from the
// set of unseen custom tags.
tagletManager.seenCustomTag(definedTags[j].getName());
- TagletOutput output = definedTags[j].getTagletOutput(
+ Content output = definedTags[j].getTagletOutput(
holderTag != null &&
definedTags[j].getName().equals("inheritDoc") ?
holderTag : inlineTag, tagletWriter);
@@ -245,9 +270,9 @@ public abstract class TagletWriter {
* @param holderTag the tag that holds the documentation.
* @param tags array of text tags and inline tags (often alternating)
* present in the text of interest for this doc.
- * @return the {@link TagletOutput} representing the comments.
+ * @return the {@link Content} representing the comments.
*/
- public abstract TagletOutput commentTagsToOutput(Tag holderTag, Tag[] tags);
+ public abstract Content commentTagsToOutput(Tag holderTag, Tag[] tags);
/**
* Converts inline tags and text to TagOutput, expanding the
@@ -258,9 +283,9 @@ public abstract class TagletWriter {
* @param holderDoc specific doc where comment resides.
* @param tags array of text tags and inline tags (often alternating)
* present in the text of interest for this doc.
- * @return the {@link TagletOutput} representing the comments.
+ * @return the {@link Content} representing the comments.
*/
- public abstract TagletOutput commentTagsToOutput(Doc holderDoc, Tag[] tags);
+ public abstract Content commentTagsToOutput(Doc holderDoc, Tag[] tags);
/**
* Converts inline tags and text to TagOutput, expanding the
@@ -273,18 +298,13 @@ public abstract class TagletWriter {
* @param tags array of text tags and inline tags (often alternating)
* present in the text of interest for this doc.
* @param isFirstSentence true if this is the first sentence.
- * @return the {@link TagletOutput} representing the comments.
+ * @return the {@link Content} representing the comments.
*/
- public abstract TagletOutput commentTagsToOutput(Tag holderTag,
+ public abstract Content commentTagsToOutput(Tag holderTag,
Doc holderDoc, Tag[] tags, boolean isFirstSentence);
/**
* @return an instance of the configuration used for this doclet.
*/
public abstract Configuration configuration();
-
- /**
- * @return an instance of the taglet output object.
- */
- public abstract TagletOutput getTagletOutputInstance();
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ThrowsTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ThrowsTaglet.java
index 7b8b365b165..dfe1fbba5ee 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ThrowsTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ThrowsTaglet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@ package com.sun.tools.doclets.internal.toolkit.taglets;
import java.util.*;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
import com.sun.tools.doclets.internal.toolkit.util.*;
/**
@@ -60,15 +61,15 @@ public class ThrowsTaglet extends BaseExecutableMemberTaglet
throwsTag.exceptionName() :
throwsTag.exception().qualifiedName();
} else {
- exception = input.method.containingClass().findClass(input.tagId);
+ exception = input.element.containingClass().findClass(input.tagId);
}
- ThrowsTag[] tags = input.method.throwsTags();
+ ThrowsTag[] tags = ((MethodDoc)input.element).throwsTags();
for (int i = 0; i < tags.length; i++) {
if (input.tagId.equals(tags[i].exceptionName()) ||
(tags[i].exception() != null &&
(input.tagId.equals(tags[i].exception().qualifiedName())))) {
- output.holder = input.method;
+ output.holder = input.element;
output.holderTag = tags[i];
output.inlineTags = input.isFirstSentence ?
tags[i].firstSentenceTags() : tags[i].inlineTags();
@@ -83,10 +84,10 @@ public class ThrowsTaglet extends BaseExecutableMemberTaglet
/**
* Add links for exceptions that are declared but not documented.
*/
- private TagletOutput linkToUndocumentedDeclaredExceptions(
+ private Content linkToUndocumentedDeclaredExceptions(
Type[] declaredExceptionTypes, Set alreadyDocumented,
TagletWriter writer) {
- TagletOutput result = writer.getOutputInstance();
+ Content result = writer.getOutputInstance();
//Add links to the exceptions declared but not documented.
for (int i = 0; i < declaredExceptionTypes.length; i++) {
if (declaredExceptionTypes[i].asClassDoc() != null &&
@@ -95,9 +96,9 @@ public class ThrowsTaglet extends BaseExecutableMemberTaglet
! alreadyDocumented.contains(
declaredExceptionTypes[i].asClassDoc().qualifiedName())) {
if (alreadyDocumented.size() == 0) {
- result.appendOutput(writer.getThrowsHeader());
+ result.addContent(writer.getThrowsHeader());
}
- result.appendOutput(writer.throwsTagOutput(declaredExceptionTypes[i]));
+ result.addContent(writer.throwsTagOutput(declaredExceptionTypes[i]));
alreadyDocumented.add(declaredExceptionTypes[i].asClassDoc().name());
}
}
@@ -108,10 +109,10 @@ public class ThrowsTaglet extends BaseExecutableMemberTaglet
* Inherit throws documentation for exceptions that were declared but not
* documented.
*/
- private TagletOutput inheritThrowsDocumentation(Doc holder,
+ private Content inheritThrowsDocumentation(Doc holder,
Type[] declaredExceptionTypes, Set alreadyDocumented,
TagletWriter writer) {
- TagletOutput result = writer.getOutputInstance();
+ Content result = writer.getOutputInstance();
if (holder instanceof MethodDoc) {
Set declaredExceptionTags = new LinkedHashSet();
for (int j = 0; j < declaredExceptionTypes.length; j++) {
@@ -125,7 +126,7 @@ public class ThrowsTaglet extends BaseExecutableMemberTaglet
}
declaredExceptionTags.addAll(inheritedDoc.tagList);
}
- result.appendOutput(throwsTagsOutput(
+ result.addContent(throwsTagsOutput(
declaredExceptionTags.toArray(new ThrowsTag[] {}),
writer, alreadyDocumented, false));
}
@@ -135,18 +136,18 @@ public class ThrowsTaglet extends BaseExecutableMemberTaglet
/**
* {@inheritDoc}
*/
- public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
+ public Content getTagletOutput(Doc holder, TagletWriter writer) {
ExecutableMemberDoc execHolder = (ExecutableMemberDoc) holder;
ThrowsTag[] tags = execHolder.throwsTags();
- TagletOutput result = writer.getOutputInstance();
+ Content result = writer.getOutputInstance();
HashSet alreadyDocumented = new HashSet();
if (tags.length > 0) {
- result.appendOutput(throwsTagsOutput(
+ result.addContent(throwsTagsOutput(
execHolder.throwsTags(), writer, alreadyDocumented, true));
}
- result.appendOutput(inheritThrowsDocumentation(holder,
+ result.addContent(inheritThrowsDocumentation(holder,
execHolder.thrownExceptionTypes(), alreadyDocumented, writer));
- result.appendOutput(linkToUndocumentedDeclaredExceptions(
+ result.addContent(linkToUndocumentedDeclaredExceptions(
execHolder.thrownExceptionTypes(), alreadyDocumented, writer));
return result;
}
@@ -160,11 +161,11 @@ public class ThrowsTaglet extends BaseExecutableMemberTaglet
* @param alreadyDocumented the set of exceptions that have already
* been documented.
* @param allowDups True if we allow duplicate throws tags to be documented.
- * @return the TagletOutput representation of this Tag.
+ * @return the Content representation of this Tag.
*/
- protected TagletOutput throwsTagsOutput(ThrowsTag[] throwTags,
+ protected Content throwsTagsOutput(ThrowsTag[] throwTags,
TagletWriter writer, Set alreadyDocumented, boolean allowDups) {
- TagletOutput result = writer.getOutputInstance();
+ Content result = writer.getOutputInstance();
if (throwTags.length > 0) {
for (int i = 0; i < throwTags.length; ++i) {
ThrowsTag tt = throwTags[i];
@@ -174,9 +175,9 @@ public class ThrowsTaglet extends BaseExecutableMemberTaglet
continue;
}
if (alreadyDocumented.size() == 0) {
- result.appendOutput(writer.getThrowsHeader());
+ result.addContent(writer.getThrowsHeader());
}
- result.appendOutput(writer.throwsTagOutput(tt));
+ result.addContent(writer.throwsTagOutput(tt));
alreadyDocumented.add(cd != null ?
cd.qualifiedName() : tt.exceptionName());
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java
index 90794bff625..f4d58c8cc68 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@ import java.util.*;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.Configuration;
+import com.sun.tools.doclets.internal.toolkit.Content;
import com.sun.tools.doclets.internal.toolkit.util.*;
/**
@@ -160,7 +161,7 @@ public class ValueTaglet extends BaseInlineTaglet {
/**
* {@inheritDoc}
*/
- public TagletOutput getTagletOutput(Tag tag, TagletWriter writer) {
+ public Content getTagletOutput(Tag tag, TagletWriter writer) {
FieldDoc field = getFieldDoc(
writer.configuration(), tag, tag.text());
if (field == null) {
@@ -169,7 +170,7 @@ public class ValueTaglet extends BaseInlineTaglet {
"doclet.value_tag_invalid_reference", tag.text());
} else if (field.constantValue() != null) {
return writer.valueTagOutput(field,
- Util.escapeHtmlChars(field.constantValueExpression()),
+ field.constantValueExpression(),
! field.equals(tag.holder()));
} else {
//Referenced field is not a constant.
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFinder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFinder.java
index a0e4015d045..d68b09d1d8d 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFinder.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFinder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,9 +48,9 @@ public class DocFinder {
*/
public static class Input {
/**
- * The method to search documentation from.
+ * The element to search documentation from.
*/
- public MethodDoc method = null;
+ public ProgramElementDoc element;
/**
* The taglet to search for documentation on behalf of. Null if we want
* to search for overall documentation.
@@ -84,54 +84,55 @@ public class DocFinder {
*/
public boolean isTypeVariableParamTag = false;
- public Input() {}
-
- public Input(MethodDoc method, InheritableTaglet taglet, Tag tag,
+ public Input(ProgramElementDoc element, InheritableTaglet taglet, Tag tag,
boolean isFirstSentence, boolean isInheritDocTag) {
- this.method = method;
+ this(element);
this.taglet = taglet;
this.tag = tag;
this.isFirstSentence = isFirstSentence;
this.isInheritDocTag = isInheritDocTag;
}
- public Input(MethodDoc method, InheritableTaglet taglet, String tagId) {
- this.method = method;
+ public Input(ProgramElementDoc element, InheritableTaglet taglet, String tagId) {
+ this(element);
this.taglet = taglet;
this.tagId = tagId;
}
- public Input(MethodDoc method, InheritableTaglet taglet, String tagId,
+ public Input(ProgramElementDoc element, InheritableTaglet taglet, String tagId,
boolean isTypeVariableParamTag) {
- this.method = method;
+ this(element);
this.taglet = taglet;
this.tagId = tagId;
this.isTypeVariableParamTag = isTypeVariableParamTag;
}
- public Input(MethodDoc method, InheritableTaglet taglet) {
- this.method = method;
+ public Input(ProgramElementDoc element, InheritableTaglet taglet) {
+ this(element);
this.taglet = taglet;
}
- public Input(MethodDoc method) {
- this.method = method;
+ public Input(ProgramElementDoc element) {
+ if (element == null)
+ throw new NullPointerException();
+ this.element = element;
}
- public Input(MethodDoc method, boolean isFirstSentence) {
- this.method = method;
+ public Input(ProgramElementDoc element, boolean isFirstSentence) {
+ this(element);
this.isFirstSentence = isFirstSentence;
}
public Input copy() {
- Input clone = new Input();
- clone.method = this.method;
+ Input clone = new Input(this.element);
clone.taglet = this.taglet;
clone.tagId = this.tagId;
clone.tag = this.tag;
clone.isFirstSentence = this.isFirstSentence;
clone.isInheritDocTag = this.isInheritDocTag;
clone.isTypeVariableParamTag = this.isTypeVariableParamTag;
+ if (clone.element == null)
+ throw new NullPointerException();
return clone;
}
@@ -164,8 +165,8 @@ public class DocFinder {
/**
* When automatically inheriting throws tags, you sometime must inherit
- * more than one tag. For example if the method declares that it throws
- * IOException and the overidden method has throws tags for IOException and
+ * more than one tag. For example if the element declares that it throws
+ * IOException and the overridden element has throws tags for IOException and
* ZipException, both tags would be inherited because ZipException is a
* subclass of IOException. This subclass of DocFinder.Output allows
* multiple tag inheritence.
@@ -174,9 +175,9 @@ public class DocFinder {
}
/**
- * Search for the requested comments in the given method. If it does not
- * have comments, return documentation from the overriden method if possible.
- * If the overriden method does not exist or does not have documentation to
+ * Search for the requested comments in the given element. If it does not
+ * have comments, return documentation from the overriden element if possible.
+ * If the overriden element does not exist or does not have documentation to
* inherit, search for documentation to inherit from implemented methods.
*
* @param input the input object used to perform the search.
@@ -186,14 +187,14 @@ public class DocFinder {
public static Output search(Input input) {
Output output = new Output();
if (input.isInheritDocTag) {
- //Do nothing because "method" does not have any documentation.
+ //Do nothing because "element" does not have any documentation.
//All it has it {@inheritDoc}.
} else if (input.taglet == null) {
//We want overall documentation.
output.inlineTags = input.isFirstSentence ?
- input.method.firstSentenceTags() :
- input.method.inlineTags();
- output.holder = input.method;
+ input.element.firstSentenceTags() :
+ input.element.inlineTags();
+ output.holder = input.element;
} else {
input.taglet.inherit(input, output);
}
@@ -204,25 +205,38 @@ public class DocFinder {
output.isValidInheritDocTag = false;
Input inheritedSearchInput = input.copy();
inheritedSearchInput.isInheritDocTag = false;
- if (input.method.overriddenMethod() != null) {
- inheritedSearchInput.method = input.method.overriddenMethod();
- output = search(inheritedSearchInput);
- output.isValidInheritDocTag = true;
- if (output != null && output.inlineTags.length > 0) {
- return output;
+ if (input.element instanceof MethodDoc) {
+ MethodDoc overriddenMethod = ((MethodDoc) input.element).overriddenMethod();
+ if (overriddenMethod != null) {
+ inheritedSearchInput.element = overriddenMethod;
+ output = search(inheritedSearchInput);
+ output.isValidInheritDocTag = true;
+ if (output.inlineTags.length > 0) {
+ return output;
+ }
}
- }
- //NOTE: When we fix the bug where ClassDoc.interfaceTypes() does
- // not pass all implemented interfaces, we will use the
- // appropriate method here.
- MethodDoc[] implementedMethods =
- (new ImplementedMethods(input.method, null)).build(false);
- for (int i = 0; i < implementedMethods.length; i++) {
- inheritedSearchInput.method = implementedMethods[i];
- output = search(inheritedSearchInput);
- output.isValidInheritDocTag = true;
- if (output != null && output.inlineTags.length > 0) {
- return output;
+ //NOTE: When we fix the bug where ClassDoc.interfaceTypes() does
+ // not pass all implemented interfaces, we will use the
+ // appropriate element here.
+ MethodDoc[] implementedMethods =
+ (new ImplementedMethods((MethodDoc) input.element, null)).build(false);
+ for (int i = 0; i < implementedMethods.length; i++) {
+ inheritedSearchInput.element = implementedMethods[i];
+ output = search(inheritedSearchInput);
+ output.isValidInheritDocTag = true;
+ if (output.inlineTags.length > 0) {
+ return output;
+ }
+ }
+ } else if (input.element instanceof ClassDoc) {
+ ProgramElementDoc superclass = ((ClassDoc) input.element).superclass();
+ if (superclass != null) {
+ inheritedSearchInput.element = superclass;
+ output = search(inheritedSearchInput);
+ output.isValidInheritDocTag = true;
+ if (output.inlineTags.length > 0) {
+ return output;
+ }
}
}
return output;
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletConstants.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletConstants.java
index 878a06bcb3c..c76b2ed26c1 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletConstants.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletConstants.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,7 @@ public class DocletConstants {
/**
* The default package name.
*/
- public static final String DEFAULT_PACKAGE_NAME = "<Unnamed>";
+ public static final String DEFAULT_PACKAGE_NAME = "";
/**
* The default package file name.
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
index 7eb0c7fc13a..acdae4545a7 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
@@ -419,69 +419,6 @@ public class Util {
return originalStr.replace(oldStr, newStr);
}
- /**
- * Given a string, escape all special html characters and
- * return the result.
- *
- * @param s The string to check.
- * @return the original string with all of the HTML characters escaped.
- */
- public static String escapeHtmlChars(String s) {
- for (int i = 0; i < s.length(); i++) {
- char ch = s.charAt(i);
- switch (ch) {
- // only start building a new string if we need to
- case '<': case '>': case '&':
- StringBuilder sb = new StringBuilder(s.substring(0, i));
- for ( ; i < s.length(); i++) {
- ch = s.charAt(i);
- switch (ch) {
- case '<': sb.append("<"); break;
- case '>': sb.append(">"); break;
- case '&': sb.append("&"); break;
- default: sb.append(ch); break;
- }
- }
- return sb.toString();
- }
- }
- return s;
- }
-
- /**
- * Escape all special html characters in a string buffer.
- *
- * @param sb The string buffer to update
- */
- public static void escapeHtmlChars(StringBuilder sb) {
- // scan backwards, replacing characters as needed.
- for (int i = sb.length() - 1; i >= 0; i--) {
- switch (sb.charAt(i)) {
- case '<': sb.replace(i, i+1, "<"); break;
- case '>': sb.replace(i, i+1, ">"); break;
- case '&': sb.replace(i, i+1, "&"); break;
- }
- }
- }
-
- /**
- * Given a string, strips all html characters and
- * return the result.
- *
- * @param rawString The string to check.
- * @return the original string with all of the HTML characters
- * stripped.
- *
- */
- public static String stripHtml(String rawString) {
- // remove HTML tags
- rawString = rawString.replaceAll("\\<.*?>", " ");
- // consolidate multiple spaces between a word to a single space
- rawString = rawString.replaceAll("\\b\\s{2,}\\b", " ");
- // remove extra whitespaces
- return rawString.trim();
- }
-
/**
* Given an annotation, return true if it should be documented and false
* otherwise.
@@ -656,20 +593,42 @@ public class Util {
}
/**
- * Replace all tabs with the appropriate number of spaces.
+ * Replace all tabs in a string with the appropriate number of spaces.
+ * The string may be a multi-line string.
* @param configuration the doclet configuration defining the setting for the
* tab length.
- * @param sb the StringBuilder in which to replace the tabs
+ * @param text the text for which the tabs should be expanded
+ * @return the text with all tabs expanded
*/
- public static void replaceTabs(Configuration configuration, StringBuilder sb) {
- int tabLength = configuration.sourcetab;
- String whitespace = configuration.tabSpaces;
- int index = 0;
- while ((index = sb.indexOf("\t", index)) != -1) {
- int spaceCount = tabLength - index % tabLength;
- sb.replace(index, index+1, whitespace.substring(0, spaceCount));
- index += spaceCount;
+ public static String replaceTabs(Configuration configuration, String text) {
+ if (text.indexOf("\t") == -1)
+ return text;
+
+ final int tabLength = configuration.sourcetab;
+ final String whitespace = configuration.tabSpaces;
+ final int textLength = text.length();
+ StringBuilder result = new StringBuilder(textLength);
+ int pos = 0;
+ int lineLength = 0;
+ for (int i = 0; i < textLength; i++) {
+ char ch = text.charAt(i);
+ switch (ch) {
+ case '\n': case '\r':
+ lineLength = 0;
+ break;
+ case '\t':
+ result.append(text, pos, i);
+ int spaceCount = tabLength - lineLength % tabLength;
+ result.append(whitespace, 0, spaceCount);
+ lineLength += spaceCount;
+ pos = i + 1;
+ break;
+ default:
+ lineLength++;
+ }
}
+ result.append(text, pos, textLength);
+ return result.toString();
}
/**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java
index 97e6fe75f5a..6ecea31ffba 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java
@@ -26,6 +26,7 @@
package com.sun.tools.doclets.internal.toolkit.util.links;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
/**
* A factory that constructs links from given link information.
@@ -41,11 +42,11 @@ import com.sun.javadoc.*;
public abstract class LinkFactory {
/**
- * Return an empty instance of the link output object.
+ * Return an empty instance of a content object.
*
- * @return an empty instance of the link output object.
+ * @return an empty instance of a content object.
*/
- protected abstract LinkOutput getOutputInstance();
+ protected abstract Content newContent();
/**
* Constructs a link from the given link information.
@@ -53,63 +54,59 @@ public abstract class LinkFactory {
* @param linkInfo the information about the link.
* @return the output of the link.
*/
- public LinkOutput getLinkOutput(LinkInfo linkInfo) {
+ public Content getLink(LinkInfo linkInfo) {
if (linkInfo.type != null) {
Type type = linkInfo.type;
- LinkOutput linkOutput = getOutputInstance();
+ Content link = newContent();
if (type.isPrimitive()) {
//Just a primitive.
- linkInfo.displayLength += type.typeName().length();
- linkOutput.append(type.typeName());
+ link.addContent(type.typeName());
} else if (type.asAnnotatedType() != null && type.dimension().length() == 0) {
- linkOutput.append(getTypeAnnotationLinks(linkInfo));
+ link.addContent(getTypeAnnotationLinks(linkInfo));
linkInfo.type = type.asAnnotatedType().underlyingType();
- linkOutput.append(getLinkOutput(linkInfo));
- return linkOutput;
+ link.addContent(getLink(linkInfo));
+ return link;
} else if (type.asWildcardType() != null) {
//Wildcard type.
linkInfo.isTypeBound = true;
- linkInfo.displayLength += 1;
- linkOutput.append("?");
+ link.addContent("?");
WildcardType wildcardType = type.asWildcardType();
Type[] extendsBounds = wildcardType.extendsBounds();
for (int i = 0; i < extendsBounds.length; i++) {
- linkInfo.displayLength += i > 0 ? 2 : 9;
- linkOutput.append(i > 0 ? ", " : " extends ");
+ link.addContent(i > 0 ? ", " : " extends ");
setBoundsLinkInfo(linkInfo, extendsBounds[i]);
- linkOutput.append(getLinkOutput(linkInfo));
+ link.addContent(getLink(linkInfo));
}
Type[] superBounds = wildcardType.superBounds();
for (int i = 0; i < superBounds.length; i++) {
- linkInfo.displayLength += i > 0 ? 2 : 7;
- linkOutput.append(i > 0 ? ", " : " super ");
+ link.addContent(i > 0 ? ", " : " super ");
setBoundsLinkInfo(linkInfo, superBounds[i]);
- linkOutput.append(getLinkOutput(linkInfo));
+ link.addContent(getLink(linkInfo));
}
} else if (type.asTypeVariable()!= null) {
- linkOutput.append(getTypeAnnotationLinks(linkInfo));
+ link.addContent(getTypeAnnotationLinks(linkInfo));
linkInfo.isTypeBound = true;
//A type variable.
Doc owner = type.asTypeVariable().owner();
if ((! linkInfo.excludeTypeParameterLinks) &&
owner instanceof ClassDoc) {
linkInfo.classDoc = (ClassDoc) owner;
- linkInfo.label = type.typeName();
- linkOutput.append(getClassLink(linkInfo));
+ Content label = newContent();
+ label.addContent(type.typeName());
+ linkInfo.label = label;
+ link.addContent(getClassLink(linkInfo));
} else {
//No need to link method type parameters.
- linkInfo.displayLength += type.typeName().length();
- linkOutput.append(type.typeName());
+ link.addContent(type.typeName());
}
Type[] bounds = type.asTypeVariable().bounds();
if (! linkInfo.excludeTypeBounds) {
linkInfo.excludeTypeBounds = true;
for (int i = 0; i < bounds.length; i++) {
- linkInfo.displayLength += i > 0 ? 2 : 9;
- linkOutput.append(i > 0 ? " & " : " extends ");
+ link.addContent(i > 0 ? " & " : " extends ");
setBoundsLinkInfo(linkInfo, bounds[i]);
- linkOutput.append(getLinkOutput(linkInfo));
+ link.addContent(getLink(linkInfo));
}
}
} else if (type.asClassDoc() != null) {
@@ -118,15 +115,15 @@ public abstract class LinkFactory {
linkInfo.excludeTypeBoundsLinks) {
//Since we are excluding type parameter links, we should not
//be linking to the type bound.
- linkInfo.displayLength += type.typeName().length();
- linkOutput.append(type.typeName());
- linkOutput.append(getTypeParameterLinks(linkInfo));
- return linkOutput;
+ link.addContent(type.typeName());
+ link.addContent(getTypeParameterLinks(linkInfo));
+ return link;
} else {
linkInfo.classDoc = type.asClassDoc();
- linkOutput = getClassLink(linkInfo);
+ link = newContent();
+ link.addContent(getClassLink(linkInfo));
if (linkInfo.includeTypeAsSepLink) {
- linkOutput.append(getTypeParameterLinks(linkInfo, false));
+ link.addContent(getTypeParameterLinks(linkInfo, false));
}
}
}
@@ -135,36 +132,37 @@ public abstract class LinkFactory {
if (type.dimension().length() > 2) {
//Javadoc returns var args as array.
//Strip out the first [] from the var arg.
- linkInfo.displayLength += type.dimension().length()-2;
- linkOutput.append(type.dimension().substring(2));
+ link.addContent(type.dimension().substring(2));
}
- linkInfo.displayLength += 3;
- linkOutput.append("...");
+ link.addContent("...");
} else {
while (type != null && type.dimension().length() > 0) {
- linkInfo.displayLength += type.dimension().length();
if (type.asAnnotatedType() != null) {
linkInfo.type = type;
- linkOutput.append(" ");
- linkOutput.append(getTypeAnnotationLinks(linkInfo));
- linkOutput.append("[]");
+ link.addContent(" ");
+ link.addContent(getTypeAnnotationLinks(linkInfo));
+ link.addContent("[]");
type = type.asAnnotatedType().underlyingType().getElementType();
} else {
- linkOutput.append("[]");
+ link.addContent("[]");
type = type.getElementType();
}
}
linkInfo.type = type;
- linkOutput.insert(0, getTypeAnnotationLinks(linkInfo));
+ Content newLink = newContent();
+ newLink.addContent(getTypeAnnotationLinks(linkInfo));
+ newLink.addContent(link);
+ link = newLink;
}
- return linkOutput;
+ return link;
} else if (linkInfo.classDoc != null) {
//Just a class link
- LinkOutput linkOutput = getClassLink(linkInfo);
+ Content link = newContent();
+ link.addContent(getClassLink(linkInfo));
if (linkInfo.includeTypeAsSepLink) {
- linkOutput.append(getTypeParameterLinks(linkInfo, false));
+ link.addContent(getTypeParameterLinks(linkInfo, false));
}
- return linkOutput;
+ return link;
} else {
return null;
}
@@ -183,7 +181,7 @@ public abstract class LinkFactory {
*
* @return the link for the given class.
*/
- protected abstract LinkOutput getClassLink(LinkInfo linkInfo);
+ protected abstract Content getClassLink(LinkInfo linkInfo);
/**
* Return the link to the given type parameter.
@@ -191,10 +189,10 @@ public abstract class LinkFactory {
* @param linkInfo the information about the link to construct.
* @param typeParam the type parameter to link to.
*/
- protected abstract LinkOutput getTypeParameterLink(LinkInfo linkInfo,
+ protected abstract Content getTypeParameterLink(LinkInfo linkInfo,
Type typeParam);
- protected abstract LinkOutput getTypeAnnotationLink(LinkInfo linkInfo,
+ protected abstract Content getTypeAnnotationLink(LinkInfo linkInfo,
AnnotationDesc annotation);
/**
@@ -203,7 +201,7 @@ public abstract class LinkFactory {
* @param linkInfo the information about the link to construct.
* @return the links to the type parameters.
*/
- public LinkOutput getTypeParameterLinks(LinkInfo linkInfo) {
+ public Content getTypeParameterLinks(LinkInfo linkInfo) {
return getTypeParameterLinks(linkInfo, true);
}
@@ -215,8 +213,8 @@ public abstract class LinkFactory {
* the type parameters portion of the link.
* @return the links to the type parameters.
*/
- public LinkOutput getTypeParameterLinks(LinkInfo linkInfo, boolean isClassLabel) {
- LinkOutput output = getOutputInstance();
+ public Content getTypeParameterLinks(LinkInfo linkInfo, boolean isClassLabel) {
+ Content links = newContent();
Type[] vars;
if (linkInfo.executableMemberDoc != null) {
vars = linkInfo.executableMemberDoc.typeParameters();
@@ -227,62 +225,37 @@ public abstract class LinkFactory {
vars = linkInfo.classDoc.typeParameters();
} else {
//Nothing to document.
- return output;
+ return links;
}
if (((linkInfo.includeTypeInClassLinkLabel && isClassLabel) ||
(linkInfo.includeTypeAsSepLink && ! isClassLabel)
)
&& vars.length > 0) {
- linkInfo.displayLength += 1;
- output.append(getLessThanString());
+ links.addContent("<");
for (int i = 0; i < vars.length; i++) {
if (i > 0) {
- linkInfo.displayLength += 1;
- output.append(",");
+ links.addContent(",");
}
- output.append(getTypeParameterLink(linkInfo, vars[i]));
+ links.addContent(getTypeParameterLink(linkInfo, vars[i]));
}
- linkInfo.displayLength += 1;
- output.append(getGreaterThanString());
+ links.addContent(">");
}
- return output;
+ return links;
}
- public LinkOutput getTypeAnnotationLinks(LinkInfo linkInfo) {
- LinkOutput output = getOutputInstance();
+ public Content getTypeAnnotationLinks(LinkInfo linkInfo) {
+ Content links = newContent();
if (linkInfo.type.asAnnotatedType() == null)
- return output;
+ return links;
AnnotationDesc[] annotations = linkInfo.type.asAnnotatedType().annotations();
for (int i = 0; i < annotations.length; i++) {
if (i > 0) {
- linkInfo.displayLength += 1;
- output.append(" ");
+ links.addContent(" ");
}
- output.append(getTypeAnnotationLink(linkInfo, annotations[i]));
+ links.addContent(getTypeAnnotationLink(linkInfo, annotations[i]));
}
- linkInfo.displayLength += 1;
- output.append(" ");
- return output;
- }
-
- /**
- * Return <, which is used in type parameters. Override this
- * if your doclet uses something different.
- *
- * @return return <, which is used in type parameters.
- */
- protected String getLessThanString() {
- return "<";
- }
-
- /**
- * Return >, which is used in type parameters. Override this
- * if your doclet uses something different.
- *
- * @return return >, which is used in type parameters.
- */
- protected String getGreaterThanString() {
- return ">";
+ links.addContent(" ");
+ return links;
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java
index e46a9f748da..842dd616d2b 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java
@@ -27,6 +27,7 @@ package com.sun.tools.doclets.internal.toolkit.util.links;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.Configuration;
+import com.sun.tools.doclets.internal.toolkit.Content;
/**
* Encapsulates information about a link.
@@ -77,7 +78,7 @@ public abstract class LinkInfo {
/**
* The label for the link.
*/
- public String label;
+ public Content label;
/**
* True if the link should be strong.
@@ -90,7 +91,7 @@ public abstract class LinkInfo {
public boolean includeTypeInClassLinkLabel = true;
/**
- * True if we should include the type as seperate link. False otherwise.
+ * True if we should include the type as separate link. False otherwise.
*/
public boolean includeTypeAsSepLink = false;
@@ -116,24 +117,11 @@ public abstract class LinkInfo {
public boolean linkToSelf = true;
/**
- * The display length for the link.
- */
- public int displayLength = 0;
-
- /**
- * Return the id indicating where the link appears in the documentation.
- * This is used for special processing of different types of links.
+ * Return an empty instance of a content object.
*
- * @return the id indicating where the link appears in the documentation.
+ * @return an empty instance of a content object.
*/
- public abstract int getContext();
-
- /**
- * Set the context.
- *
- * @param c the context id to set.
- */
- public abstract void setContext(int c);
+ protected abstract Content newContent();
/**
* Return true if this link is linkable and false if we can't link to the
@@ -150,13 +138,17 @@ public abstract class LinkInfo {
* @param configuration the current configuration of the doclet.
* @return the label for this class link.
*/
- public String getClassLinkLabel(Configuration configuration) {
- if (label != null && label.length() > 0) {
+ public Content getClassLinkLabel(Configuration configuration) {
+ if (label != null && !label.isEmpty()) {
return label;
} else if (isLinkable()) {
- return classDoc.name();
+ Content label = newContent();
+ label.addContent(classDoc.name());
+ return label;
} else {
- return configuration.getClassName(classDoc);
+ Content label = newContent();
+ label.addContent(configuration.getClassName(classDoc));
+ return label;
}
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java
index f1d9d35a964..701813dfae1 100644
--- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java
+++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java
@@ -42,7 +42,6 @@ import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Name;
-import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic.Kind;
@@ -70,7 +69,8 @@ import com.sun.source.doctree.TextTree;
import com.sun.source.doctree.ThrowsTree;
import com.sun.source.doctree.ValueTree;
import com.sun.source.doctree.VersionTree;
-import com.sun.source.util.DocTreeScanner;
+import com.sun.source.util.DocTreePath;
+import com.sun.source.util.DocTreePathScanner;
import com.sun.source.util.TreePath;
import com.sun.tools.doclint.HtmlTag.AttrKind;
import com.sun.tools.javac.tree.DocPretty;
@@ -85,7 +85,7 @@ import static com.sun.tools.doclint.Messages.Group.*;
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.
*/
-public class Checker extends DocTreeScanner {
+public class Checker extends DocTreePathScanner {
final Env env;
Set foundParams = new HashSet();
@@ -152,7 +152,7 @@ public class Checker extends DocTreeScanner {
foundInheritDoc = false;
foundReturn = false;
- scan(tree, (Void) null);
+ scan(new DocTreePath(p, tree), null);
if (!isOverridingMethod) {
switch (env.currElement.getKind()) {
@@ -620,47 +620,36 @@ public class Checker extends DocTreeScanner {
}
@Override
+ @SuppressWarnings("fallthrough")
public Void visitParam(ParamTree tree, Void ignore) {
boolean typaram = tree.isTypeParameter();
IdentifierTree nameTree = tree.getName();
- Element e = env.currElement;
- switch (e.getKind()) {
- case METHOD: case CONSTRUCTOR: {
- ExecutableElement ee = (ExecutableElement) e;
- checkParamDeclared(nameTree, typaram ? ee.getTypeParameters() : ee.getParameters());
- break;
- }
+ Element paramElement = nameTree != null ? env.trees.getElement(new DocTreePath(getCurrentPath(), nameTree)) : null;
- case CLASS: case INTERFACE: {
- TypeElement te = (TypeElement) e;
- if (typaram) {
- checkParamDeclared(nameTree, te.getTypeParameters());
- } else {
- env.messages.error(REFERENCE, tree, "dc.invalid.param");
+ if (paramElement == null) {
+ switch (env.currElement.getKind()) {
+ case CLASS: case INTERFACE: {
+ if (!typaram) {
+ env.messages.error(REFERENCE, tree, "dc.invalid.param");
+ break;
+ }
+ }
+ case METHOD: case CONSTRUCTOR: {
+ env.messages.error(REFERENCE, nameTree, "dc.param.name.not.found");
+ break;
}
- break;
- }
- default:
- env.messages.error(REFERENCE, tree, "dc.invalid.param");
- break;
+ default:
+ env.messages.error(REFERENCE, tree, "dc.invalid.param");
+ break;
+ }
+ } else {
+ foundParams.add(paramElement);
}
+
warnIfEmpty(tree, tree.getDescription());
return super.visitParam(tree, ignore);
}
- // where
- private void checkParamDeclared(IdentifierTree nameTree, List extends Element> list) {
- Name name = nameTree.getName();
- boolean found = false;
- for (Element e: list) {
- if (name.equals(e.getSimpleName())) {
- foundParams.add(e);
- found = true;
- }
- }
- if (!found)
- env.messages.error(REFERENCE, nameTree, "dc.param.name.not.found");
- }
private void checkParamsDocumented(List extends Element> list) {
if (foundInheritDoc)
@@ -678,7 +667,7 @@ public class Checker extends DocTreeScanner {
@Override
public Void visitReference(ReferenceTree tree, Void ignore) {
- Element e = env.trees.getElement(env.currPath, tree);
+ Element e = env.trees.getElement(getCurrentPath());
if (e == null)
env.messages.error(REFERENCE, tree, "dc.ref.not.found");
return super.visitReference(tree, ignore);
@@ -716,7 +705,7 @@ public class Checker extends DocTreeScanner {
@Override
public Void visitThrows(ThrowsTree tree, Void ignore) {
ReferenceTree exName = tree.getExceptionName();
- Element ex = env.trees.getElement(env.currPath, exName);
+ Element ex = env.trees.getElement(new DocTreePath(getCurrentPath(), exName));
if (ex == null) {
env.messages.error(REFERENCE, tree, "dc.ref.not.found");
} else if (ex.asType().getKind() == TypeKind.DECLARED
diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Env.java b/langtools/src/share/classes/com/sun/tools/doclint/Env.java
index 979c01ab7ff..ffe3a7a0da7 100644
--- a/langtools/src/share/classes/com/sun/tools/doclint/Env.java
+++ b/langtools/src/share/classes/com/sun/tools/doclint/Env.java
@@ -29,6 +29,7 @@ package com.sun.tools.doclint;
import java.util.Set;
import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.type.TypeMirror;
@@ -144,7 +145,7 @@ public class Env {
AccessKind ak = null;
for (TreePath p = path; p != null; p = p.getParentPath()) {
Element e = trees.getElement(p);
- if (e != null) {
+ if (e != null && e.getKind() != ElementKind.PACKAGE) {
ak = min(ak, AccessKind.of(e.getModifiers()));
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java
index 545b883f7f0..19dde2aef0d 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java
@@ -33,6 +33,7 @@ import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
@@ -44,12 +45,12 @@ import javax.tools.JavaFileObject;
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.doctree.DocTree;
-import com.sun.source.doctree.ReferenceTree;
import com.sun.source.tree.CatchTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Scope;
import com.sun.source.tree.Tree;
import com.sun.source.util.DocSourcePositions;
+import com.sun.source.util.DocTreePath;
import com.sun.source.util.DocTreeScanner;
import com.sun.source.util.DocTrees;
import com.sun.source.util.JavacTask;
@@ -314,7 +315,7 @@ public class JavacTrees extends DocTrees {
return TreePath.getPath(treeTopLevel.snd, treeTopLevel.fst);
}
- public Element getElement(TreePath path) {
+ public Symbol getElement(TreePath path) {
JCTree tree = (JCTree) path.getLeaf();
Symbol sym = TreeInfo.symbolFor(tree);
if (sym == null) {
@@ -332,22 +333,25 @@ public class JavacTrees extends DocTrees {
}
}
}
- } else if (tree.hasTag(Tag.TOPLEVEL)) {
- JCCompilationUnit cu = (JCCompilationUnit) tree;
- if (cu.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE)) {
- sym = cu.packge;
- }
}
}
return sym;
}
@Override
- public Element getElement(TreePath path, ReferenceTree reference) {
- if (!(reference instanceof DCReference))
- return null;
- DCReference ref = (DCReference) reference;
+ public Element getElement(DocTreePath path) {
+ DocTree forTree = path.getLeaf();
+ if (forTree instanceof DCReference)
+ return attributeDocReference(path.getTreePath(), ((DCReference) forTree));
+ if (forTree instanceof DCIdentifier) {
+ if (path.getParentPath().getLeaf() instanceof DCParam) {
+ return attributeParamIdentifier(path.getTreePath(), (DCParam) path.getParentPath().getLeaf());
+ }
+ }
+ return null;
+ }
+ private Symbol attributeDocReference(TreePath path, DCReference ref) {
Env env = getAttrContext(path);
Log.DeferredDiagnosticHandler deferredDiagnosticHandler =
@@ -427,6 +431,30 @@ public class JavacTrees extends DocTrees {
}
}
+ private Symbol attributeParamIdentifier(TreePath path, DCParam ptag) {
+ Symbol javadocSymbol = getElement(path);
+ if (javadocSymbol == null)
+ return null;
+ ElementKind kind = javadocSymbol.getKind();
+ List extends Symbol> params = List.nil();
+ if (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) {
+ MethodSymbol ee = (MethodSymbol) javadocSymbol;
+ params = ptag.isTypeParameter()
+ ? ee.getTypeParameters()
+ : ee.getParameters();
+ } else if (kind.isClass() || kind.isInterface()) {
+ ClassSymbol te = (ClassSymbol) javadocSymbol;
+ params = te.getTypeParameters();
+ }
+
+ for (Symbol param : params) {
+ if (param.getSimpleName() == ptag.getName().getName()) {
+ return param;
+ }
+ }
+ return null;
+ }
+
/** @see com.sun.tools.javadoc.ClassDocImpl#findField */
private VarSymbol findField(ClassSymbol tsym, Name fieldName) {
return searchField(tsym, fieldName, new HashSet());
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java
index 5d1af1147b6..5be0865c042 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java
@@ -76,10 +76,23 @@ public class Annotations {
private List attributes = DECL_NOT_STARTED;
/*
- * This field should never be null
+ * Type attributes for this symbol.
+ * This field should never be null.
*/
private List type_attributes = List.nil();
+ /*
+ * Type attributes of initializers in this class.
+ * Unused if the current symbol is not a ClassSymbol.
+ */
+ private List init_type_attributes = List.nil();
+
+ /*
+ * Type attributes of class initializers in this class.
+ * Unused if the current symbol is not a ClassSymbol.
+ */
+ private List clinit_type_attributes = List.nil();
+
/*
* The Symbol this Annotations instance belongs to
*/
@@ -97,6 +110,14 @@ public class Annotations {
return type_attributes;
}
+ public List getInitTypeAttributes() {
+ return init_type_attributes;
+ }
+
+ public List getClassInitTypeAttributes() {
+ return clinit_type_attributes;
+ }
+
public void setDeclarationAttributes(List a) {
Assert.check(pendingCompletion() || !isStarted());
if (a == null) {
@@ -112,12 +133,28 @@ public class Annotations {
type_attributes = a;
}
+ public void setInitTypeAttributes(List a) {
+ if (a == null) {
+ throw new NullPointerException();
+ }
+ init_type_attributes = a;
+ }
+
+ public void setClassInitTypeAttributes(List a) {
+ if (a == null) {
+ throw new NullPointerException();
+ }
+ clinit_type_attributes = a;
+ }
+
public void setAttributes(Annotations other) {
if (other == null) {
throw new NullPointerException();
}
setDeclarationAttributes(other.getDeclarationAttributes());
setTypeAttributes(other.getTypeAttributes());
+ setInitTypeAttributes(other.getInitTypeAttributes());
+ setClassInitTypeAttributes(other.getClassInitTypeAttributes());
}
public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext ctx) {
@@ -232,6 +269,28 @@ public class Annotations {
return this;
}
+ public Annotations appendInitTypeAttributes(List l) {
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (init_type_attributes.isEmpty()) {
+ init_type_attributes = l;
+ } else {
+ init_type_attributes = init_type_attributes.appendList(l);
+ }
+ return this;
+ }
+
+ public Annotations appendClassInitTypeAttributes(List l) {
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (clinit_type_attributes.isEmpty()) {
+ clinit_type_attributes = l;
+ } else {
+ clinit_type_attributes = clinit_type_attributes.appendList(l);
+ }
+ return this;
+ }
+
public Annotations prepend(List l) {
attributes = filterDeclSentinels(attributes);
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java
index 4ba35b3aba6..ec76bbf7637 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java
@@ -230,6 +230,42 @@ public abstract class Attribute implements AnnotationValue {
this.position = position;
}
+ public boolean hasUnknownPosition() {
+ return position == null || position.type == TargetType.UNKNOWN;
+ }
+
+ public boolean isContainerTypeCompound() {
+ if (isSynthesized() && values.size() == 1)
+ return getFirstEmbeddedTC() != null;
+ return false;
+ }
+
+ private TypeCompound getFirstEmbeddedTC() {
+ if (values.size() == 1) {
+ Pair val = values.get(0);
+ if (val.fst.getSimpleName().contentEquals("value")
+ && val.snd instanceof Array) {
+ Array arr = (Array) val.snd;
+ if (arr.values.length != 0
+ && arr.values[0] instanceof Attribute.TypeCompound)
+ return (Attribute.TypeCompound) arr.values[0];
+ }
+ }
+ return null;
+ }
+
+ public boolean tryFixPosition() {
+ if (!isContainerTypeCompound())
+ return false;
+
+ TypeCompound from = getFirstEmbeddedTC();
+ if (from != null && from.position != null &&
+ from.position.type != TargetType.UNKNOWN) {
+ position = from.position;
+ return true;
+ }
+ return false;
+ }
}
/** The value for an annotation element of an array type.
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java
index 3a8982f42cc..76e54103062 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java
@@ -31,6 +31,7 @@ import javax.lang.model.type.TypeKind;
import com.sun.tools.javac.api.Messages;
import com.sun.tools.javac.code.Type.AnnotatedType;
+import com.sun.tools.javac.code.Type.ArrayType;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.util.List;
@@ -127,7 +128,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi
}
/**
- * Get a localized string represenation for a given type.
+ * Get a localized string representation for a given type.
*
* @param t type to be displayed
* @param locale the locale in which the string is to be rendered
@@ -138,7 +139,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi
}
/**
- * Get a localized string represenation for a given symbol.
+ * Get a localized string representation for a given symbol.
*
* @param s symbol to be displayed
* @param locale the locale in which the string is to be rendered
@@ -182,7 +183,33 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi
@Override
public String visitArrayType(ArrayType t, Locale locale) {
- return visit(t.elemtype, locale) + "[]";
+ StringBuilder res = new StringBuilder();
+ printBaseElementType(t, res, locale);
+ printBrackets(t, res, locale);
+ return res.toString();
+ }
+
+ void printBaseElementType(Type t, StringBuilder sb, Locale locale) {
+ Type arrel = t;
+ while (arrel.getKind() == TypeKind.ARRAY) {
+ arrel = arrel.unannotatedType();
+ arrel = ((ArrayType) arrel).elemtype;
+ }
+ sb.append(visit(arrel, locale));
+ }
+
+ void printBrackets(Type t, StringBuilder sb, Locale locale) {
+ Type arrel = t;
+ while (arrel.getKind() == TypeKind.ARRAY) {
+ if (arrel.isAnnotated()) {
+ sb.append(' ');
+ sb.append(arrel.getAnnotationMirrors());
+ sb.append(' ');
+ }
+ sb.append("[]");
+ arrel = arrel.unannotatedType();
+ arrel = ((ArrayType) arrel).elemtype;
+ }
}
@Override
@@ -237,10 +264,22 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi
public String visitAnnotatedType(AnnotatedType t, Locale locale) {
if (t.typeAnnotations != null &&
t.typeAnnotations.nonEmpty()) {
- // TODO: better logic for arrays, ...
- return "(" + t.typeAnnotations + " :: " + visit(t.underlyingType, locale) + ")";
+ if (t.underlyingType.getKind() == TypeKind.ARRAY) {
+ StringBuilder res = new StringBuilder();
+ printBaseElementType(t, res, locale);
+ printBrackets(t, res, locale);
+ return res.toString();
+ } else if (t.underlyingType.getKind() == TypeKind.DECLARED &&
+ t.underlyingType.getEnclosingType() != Type.noType) {
+ return visit(t.underlyingType.getEnclosingType(), locale) +
+ ". " +
+ t.typeAnnotations +
+ " " + className((ClassType)t.underlyingType, false, locale);
+ } else {
+ return t.typeAnnotations + " " + visit(t.underlyingType, locale);
+ }
} else {
- return "({} :: " + visit(t.underlyingType, locale) + ")";
+ return visit(t.underlyingType, locale);
}
}
@@ -253,7 +292,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi
/**
* Converts a class name into a (possibly localized) string. Anonymous
- * inner classes gets converted into a localized string.
+ * inner classes get converted into a localized string.
*
* @param t the type of the class whose name is to be rendered
* @param longform if set, the class' fullname is displayed - if unset the
@@ -266,7 +305,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi
if (sym.name.length() == 0 && (sym.flags() & COMPOUND) != 0) {
StringBuilder s = new StringBuilder(visit(t.supertype_field, locale));
for (List is = t.interfaces_field; is.nonEmpty(); is = is.tail) {
- s.append("&");
+ s.append('&');
s.append(visit(is.head, locale));
}
return s.toString();
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java
index aebfda502da..5f968f486a8 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java
@@ -131,7 +131,6 @@ public class Symtab {
public final Type methodHandleLookupType;
public final Type methodTypeType;
public final Type nativeHeaderType;
- public final Type nativeHeaderType_old;
public final Type throwableType;
public final Type errorType;
public final Type interruptedExceptionType;
@@ -526,7 +525,6 @@ public class Symtab {
autoCloseableType.tsym);
trustMeType = enterClass("java.lang.SafeVarargs");
nativeHeaderType = enterClass("java.lang.annotation.Native");
- nativeHeaderType_old = enterClass("javax.tools.annotation.GenerateNativeHeader");
lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory");
functionalInterfaceType = enterClass("java.lang.FunctionalInterface");
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java
index 0d2a14612e4..43784a2f4ff 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java
@@ -25,8 +25,6 @@
package com.sun.tools.javac.code;
-import com.sun.tools.javac.model.JavacAnnoConstructs;
-import com.sun.tools.javac.model.JavacTypes;
import java.lang.annotation.Annotation;
import java.util.Collections;
import java.util.EnumMap;
@@ -34,10 +32,10 @@ import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
-import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.type.*;
import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.model.JavacAnnoConstructs;
import com.sun.tools.javac.util.*;
import static com.sun.tools.javac.code.BoundKind.*;
import static com.sun.tools.javac.code.Flags.*;
@@ -729,7 +727,7 @@ public class Type implements PrimitiveType {
return s.toString();
} else if (sym.name.isEmpty()) {
String s;
- ClassType norm = (ClassType) tsym.type;
+ ClassType norm = (ClassType) tsym.type.unannotatedType();
if (norm == null) {
s = Log.getLocalizedString("anonymous.class", (Object)null);
} else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
@@ -781,7 +779,7 @@ public class Type implements PrimitiveType {
return
getEnclosingType().isErroneous() ||
isErroneous(getTypeArguments()) ||
- this != tsym.type && tsym.type.isErroneous();
+ this != tsym.type.unannotatedType() && tsym.type.isErroneous();
}
public boolean isParameterized() {
@@ -1693,7 +1691,10 @@ public class Type implements PrimitiveType {
@Override
public String toString() {
- // TODO more logic for arrays, etc.
+ // This method is only used for internal debugging output.
+ // See
+ // com.sun.tools.javac.code.Printer.visitAnnotatedType(AnnotatedType, Locale)
+ // for the user-visible logic.
if (typeAnnotations != null &&
!typeAnnotations.isEmpty()) {
return "(" + typeAnnotations.toString() + " :: " + underlyingType.toString() + ")";
@@ -1705,9 +1706,13 @@ public class Type implements PrimitiveType {
@Override
public boolean contains(Type t) { return underlyingType.contains(t); }
- // TODO: attach annotations?
@Override
- public Type withTypeVar(Type t) { return underlyingType.withTypeVar(t); }
+ public Type withTypeVar(Type t) {
+ // Don't create a new AnnotatedType, as 'this' will
+ // get its annotations set later.
+ underlyingType = underlyingType.withTypeVar(t);
+ return this;
+ }
// TODO: attach annotations?
@Override
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java
index d61a9f66c04..89f6ea40799 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java
@@ -27,6 +27,7 @@ package com.sun.tools.javac.code;
import java.util.Iterator;
+import com.sun.tools.javac.tree.JCTree.JCLambda;
import com.sun.tools.javac.util.*;
/** A type annotation position.
@@ -145,9 +146,18 @@ public class TypeAnnotationPosition {
// For class extends, implements, and throws clauses
public int type_index = Integer.MIN_VALUE;
- // For exception parameters, index into exception table
+ // For exception parameters, index into exception table.
+ // In com.sun.tools.javac.jvm.Gen.genCatch we first set the type_index
+ // to the catch type index - that value is only temporary.
+ // Then in com.sun.tools.javac.jvm.Code.fillExceptionParameterPositions
+ // we use that value to determine the exception table index.
public int exception_index = Integer.MIN_VALUE;
+ // If this type annotation is within a lambda expression,
+ // store a pointer to the lambda expression tree in order
+ // to allow a later translation to the right method.
+ public JCLambda onLambda = null;
+
public TypeAnnotationPosition() {}
@Override
@@ -258,6 +268,11 @@ public class TypeAnnotationPosition {
sb.append(", pos = ");
sb.append(pos);
+ if (onLambda != null) {
+ sb.append(", onLambda hash = ");
+ sb.append(onLambda.hashCode());
+ }
+
sb.append(']');
return sb.toString();
}
@@ -271,6 +286,17 @@ public class TypeAnnotationPosition {
return !type.isLocal() || isValidOffset;
}
+
+ public boolean matchesPos(int pos) {
+ return this.pos == pos;
+ }
+
+ public void updatePosOffset(int to) {
+ offset = to;
+ lvarOffset = new int[]{to};
+ isValidOffset = true;
+ }
+
/**
* Decode the binary representation for a type path and set
* the {@code location} field.
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
index 94c57fe43b8..6ac82e5cfa5 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
@@ -49,12 +49,16 @@ import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntry;
import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.code.Symbol.MethodSymbol;
+import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.comp.Annotate.Annotator;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCLambda;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCNewClass;
import com.sun.tools.javac.tree.JCTree.JCTypeApply;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.tree.TreeScanner;
@@ -81,17 +85,18 @@ public class TypeAnnotations {
* determine the correct positions for type annotations.
* This version only visits types in signatures and should be
* called from MemberEnter.
- * The method returns the Annotator object that should be added
- * to the correct Annotate queue for later processing.
+ * The method takes the Annotate object as parameter and
+ * adds an Annotator to the correct Annotate queue for
+ * later processing.
*/
- public static Annotator organizeTypeAnnotationsSignatures(final Symtab syms, final Names names,
- final Log log, final JCClassDecl tree) {
- return new Annotator() {
+ public static void organizeTypeAnnotationsSignatures(final Symtab syms, final Names names,
+ final Log log, final JCClassDecl tree, Annotate annotate) {
+ annotate.afterRepeated( new Annotator() {
@Override
public void enterAnnotation() {
new TypeAnnotationPositions(syms, names, log, true).scan(tree);
}
- };
+ } );
}
/**
@@ -102,9 +107,103 @@ public class TypeAnnotations {
new TypeAnnotationPositions(syms, names, log, false).scan(tree);
}
- private static class TypeAnnotationPositions extends TreeScanner {
+ public enum AnnotationType { DECLARATION, TYPE, BOTH };
- private enum AnnotationType { DECLARATION, TYPE, BOTH };
+ /**
+ * Determine whether an annotation is a declaration annotation,
+ * a type annotation, or both.
+ */
+ public static AnnotationType annotationType(Symtab syms, Names names,
+ Attribute.Compound a, Symbol s) {
+ Attribute.Compound atTarget =
+ a.type.tsym.attribute(syms.annotationTargetType.tsym);
+ if (atTarget == null) {
+ return inferTargetMetaInfo(a, s);
+ }
+ Attribute atValue = atTarget.member(names.value);
+ if (!(atValue instanceof Attribute.Array)) {
+ Assert.error("annotationType(): bad @Target argument " + atValue +
+ " (" + atValue.getClass() + ")");
+ return AnnotationType.DECLARATION; // error recovery
+ }
+ Attribute.Array arr = (Attribute.Array) atValue;
+ boolean isDecl = false, isType = false;
+ for (Attribute app : arr.values) {
+ if (!(app instanceof Attribute.Enum)) {
+ Assert.error("annotationType(): unrecognized Attribute kind " + app +
+ " (" + app.getClass() + ")");
+ isDecl = true;
+ continue;
+ }
+ Attribute.Enum e = (Attribute.Enum) app;
+ if (e.value.name == names.TYPE) {
+ if (s.kind == Kinds.TYP)
+ isDecl = true;
+ } else if (e.value.name == names.FIELD) {
+ if (s.kind == Kinds.VAR &&
+ s.owner.kind != Kinds.MTH)
+ isDecl = true;
+ } else if (e.value.name == names.METHOD) {
+ if (s.kind == Kinds.MTH &&
+ !s.isConstructor())
+ isDecl = true;
+ } else if (e.value.name == names.PARAMETER) {
+ if (s.kind == Kinds.VAR &&
+ s.owner.kind == Kinds.MTH &&
+ (s.flags() & Flags.PARAMETER) != 0)
+ isDecl = true;
+ } else if (e.value.name == names.CONSTRUCTOR) {
+ if (s.kind == Kinds.MTH &&
+ s.isConstructor())
+ isDecl = true;
+ } else if (e.value.name == names.LOCAL_VARIABLE) {
+ if (s.kind == Kinds.VAR &&
+ s.owner.kind == Kinds.MTH &&
+ (s.flags() & Flags.PARAMETER) == 0)
+ isDecl = true;
+ } else if (e.value.name == names.ANNOTATION_TYPE) {
+ if (s.kind == Kinds.TYP &&
+ (s.flags() & Flags.ANNOTATION) != 0)
+ isDecl = true;
+ } else if (e.value.name == names.PACKAGE) {
+ if (s.kind == Kinds.PCK)
+ isDecl = true;
+ } else if (e.value.name == names.TYPE_USE) {
+ if (s.kind == Kinds.TYP ||
+ s.kind == Kinds.VAR ||
+ (s.kind == Kinds.MTH && !s.isConstructor() &&
+ !s.type.getReturnType().hasTag(TypeTag.VOID)) ||
+ (s.kind == Kinds.MTH && s.isConstructor()))
+ isType = true;
+ } else if (e.value.name == names.TYPE_PARAMETER) {
+ /* Irrelevant in this case */
+ // TYPE_PARAMETER doesn't aid in distinguishing between
+ // Type annotations and declaration annotations on an
+ // Element
+ } else {
+ Assert.error("annotationType(): unrecognized Attribute name " + e.value.name +
+ " (" + e.value.name.getClass() + ")");
+ isDecl = true;
+ }
+ }
+ if (isDecl && isType) {
+ return AnnotationType.BOTH;
+ } else if (isType) {
+ return AnnotationType.TYPE;
+ } else {
+ return AnnotationType.DECLARATION;
+ }
+ }
+
+ /** Infer the target annotation kind, if none is give.
+ * We only infer declaration annotations.
+ */
+ private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) {
+ return AnnotationType.DECLARATION;
+ }
+
+
+ private static class TypeAnnotationPositions extends TreeScanner {
private final Symtab syms;
private final Names names;
@@ -154,7 +253,7 @@ public class TypeAnnotations {
ListBuffer typeAnnos = new ListBuffer();
for (Attribute.Compound a : annotations) {
- switch (annotationType(a, sym)) {
+ switch (annotationType(syms, names, a, sym)) {
case DECLARATION:
declAnnos.append(a);
break;
@@ -175,6 +274,10 @@ public class TypeAnnotations {
sym.annotations.reset();
sym.annotations.setDeclarationAttributes(declAnnos.toList());
+ if (typeAnnos.isEmpty()) {
+ return;
+ }
+
List typeAnnotations = typeAnnos.toList();
if (type == null) {
@@ -190,16 +293,33 @@ public class TypeAnnotations {
if (sym.getKind() == ElementKind.METHOD) {
sym.type.asMethodType().restype = type;
+ } else if (sym.getKind() == ElementKind.PARAMETER) {
+ sym.type = type;
+ if (sym.getQualifiedName().equals(names._this)) {
+ sym.owner.type.asMethodType().recvtype = type;
+ // note that the typeAnnotations will also be added to the owner below.
+ } else {
+ MethodType methType = sym.owner.type.asMethodType();
+ List params = ((MethodSymbol)sym.owner).params;
+ List oldArgs = methType.argtypes;
+ ListBuffer newArgs = new ListBuffer();
+ while (params.nonEmpty()) {
+ if (params.head == sym) {
+ newArgs.add(type);
+ } else {
+ newArgs.add(oldArgs.head);
+ }
+ oldArgs = oldArgs.tail;
+ params = params.tail;
+ }
+ methType.argtypes = newArgs.toList();
+ }
} else {
sym.type = type;
}
sym.annotations.appendUniqueTypes(typeAnnotations);
- if (sym.getKind() == ElementKind.PARAMETER &&
- sym.getQualifiedName().equals(names._this)) {
- sym.owner.type.asMethodType().recvtype = type;
- // note that the typeAnnotations will also be added to the owner below.
- }
+
if (sym.getKind() == ElementKind.PARAMETER ||
sym.getKind() == ElementKind.LOCAL_VARIABLE ||
sym.getKind() == ElementKind.RESOURCE_VARIABLE ||
@@ -276,10 +396,21 @@ public class TypeAnnotations {
TypeAnnotationPosition p = a.position;
p.location = p.location.prependList(depth.toList());
}
+ typetree.type = toreturn;
return toreturn;
} else if (type.hasTag(TypeTag.TYPEVAR)) {
// Nothing to do for type variables.
return type;
+ } else if (type.getKind() == TypeKind.UNION) {
+ // There is a TypeKind, but no TypeTag.
+ JCTypeUnion tutree = (JCTypeUnion) typetree;
+ JCExpression fst = tutree.alternatives.get(0);
+ Type res = typeWithAnnotations(fst, fst.type, annotations, log);
+ fst.type = res;
+ // TODO: do we want to set res as first element in uct.alternatives?
+ // UnionClassType uct = (com.sun.tools.javac.code.Type.UnionClassType)type;
+ // Return the un-annotated union-type.
+ return type;
} else {
Type enclTy = type;
Element enclEl = type.asElement();
@@ -357,6 +488,7 @@ public class TypeAnnotations {
}
Type ret = typeWithAnnotations(type, enclTy, annotations);
+ typetree.type = ret;
return ret;
}
}
@@ -480,94 +612,6 @@ public class TypeAnnotations {
return new Attribute.TypeCompound(a, p);
}
- private AnnotationType annotationType(Attribute.Compound a, Symbol s) {
- Attribute.Compound atTarget =
- a.type.tsym.attribute(syms.annotationTargetType.tsym);
- if (atTarget == null) {
- return inferTargetMetaInfo(a, s);
- }
- Attribute atValue = atTarget.member(names.value);
- if (!(atValue instanceof Attribute.Array)) {
- Assert.error("annotationType(): bad @Target argument " + atValue +
- " (" + atValue.getClass() + ")");
- return AnnotationType.DECLARATION; // error recovery
- }
- Attribute.Array arr = (Attribute.Array) atValue;
- boolean isDecl = false, isType = false;
- for (Attribute app : arr.values) {
- if (!(app instanceof Attribute.Enum)) {
- Assert.error("annotationType(): unrecognized Attribute kind " + app +
- " (" + app.getClass() + ")");
- isDecl = true;
- continue;
- }
- Attribute.Enum e = (Attribute.Enum) app;
- if (e.value.name == names.TYPE) {
- if (s.kind == Kinds.TYP)
- isDecl = true;
- } else if (e.value.name == names.FIELD) {
- if (s.kind == Kinds.VAR &&
- s.owner.kind != Kinds.MTH)
- isDecl = true;
- } else if (e.value.name == names.METHOD) {
- if (s.kind == Kinds.MTH &&
- !s.isConstructor())
- isDecl = true;
- } else if (e.value.name == names.PARAMETER) {
- if (s.kind == Kinds.VAR &&
- s.owner.kind == Kinds.MTH &&
- (s.flags() & Flags.PARAMETER) != 0)
- isDecl = true;
- } else if (e.value.name == names.CONSTRUCTOR) {
- if (s.kind == Kinds.MTH &&
- s.isConstructor())
- isDecl = true;
- } else if (e.value.name == names.LOCAL_VARIABLE) {
- if (s.kind == Kinds.VAR &&
- s.owner.kind == Kinds.MTH &&
- (s.flags() & Flags.PARAMETER) == 0)
- isDecl = true;
- } else if (e.value.name == names.ANNOTATION_TYPE) {
- if (s.kind == Kinds.TYP &&
- (s.flags() & Flags.ANNOTATION) != 0)
- isDecl = true;
- } else if (e.value.name == names.PACKAGE) {
- if (s.kind == Kinds.PCK)
- isDecl = true;
- } else if (e.value.name == names.TYPE_USE) {
- if (s.kind == Kinds.TYP ||
- s.kind == Kinds.VAR ||
- (s.kind == Kinds.MTH && !s.isConstructor() &&
- !s.type.getReturnType().hasTag(TypeTag.VOID)) ||
- (s.kind == Kinds.MTH && s.isConstructor()))
- isType = true;
- } else if (e.value.name == names.TYPE_PARAMETER) {
- /* Irrelevant in this case */
- // TYPE_PARAMETER doesn't aid in distinguishing between
- // Type annotations and declaration annotations on an
- // Element
- } else {
- Assert.error("annotationType(): unrecognized Attribute name " + e.value.name +
- " (" + e.value.name.getClass() + ")");
- isDecl = true;
- }
- }
- if (isDecl && isType) {
- return AnnotationType.BOTH;
- } else if (isType) {
- return AnnotationType.TYPE;
- } else {
- return AnnotationType.DECLARATION;
- }
- }
-
- /** Infer the target annotation kind, if none is give.
- * We only infer declaration annotations.
- */
- private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) {
- return AnnotationType.DECLARATION;
- }
-
/* This is the beginning of the second part of organizing
* type annotations: determine the type annotation positions.
@@ -585,7 +629,13 @@ public class TypeAnnotations {
switch (frame.getKind()) {
case TYPE_CAST:
+ JCTypeCast frameTC = (JCTypeCast) frame;
p.type = TargetType.CAST;
+ if (frameTC.clazz.hasTag(Tag.TYPEINTERSECTION)) {
+ // This case was already handled by INTERSECTION_TYPE
+ } else {
+ p.type_index = 0;
+ }
p.pos = frame.pos;
return;
@@ -595,8 +645,22 @@ public class TypeAnnotations {
return;
case NEW_CLASS:
- JCNewClass frameNewClass = (JCNewClass)frame;
- if (frameNewClass.typeargs.contains(tree)) {
+ JCNewClass frameNewClass = (JCNewClass) frame;
+ if (frameNewClass.def != null) {
+ // Special handling for anonymous class instantiations
+ JCClassDecl frameClassDecl = frameNewClass.def;
+ if (frameClassDecl.extending == tree) {
+ p.type = TargetType.CLASS_EXTENDS;
+ p.type_index = -1;
+ } else if (frameClassDecl.implementing.contains(tree)) {
+ p.type = TargetType.CLASS_EXTENDS;
+ p.type_index = frameClassDecl.implementing.indexOf(tree);
+ } else {
+ // In contrast to CLASS below, typarams cannot occur here.
+ Assert.error("Could not determine position of tree " + tree +
+ " within frame " + frame);
+ }
+ } else if (frameNewClass.typeargs.contains(tree)) {
p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
p.type_index = frameNewClass.typeargs.indexOf(tree);
} else {
@@ -649,6 +713,8 @@ public class TypeAnnotations {
}
case PARAMETERIZED_TYPE: {
+ List newPath = path.tail;
+
if (((JCTypeApply)frame).clazz == tree) {
// generic: RAW; noop
} else if (((JCTypeApply)frame).arguments.contains(tree)) {
@@ -656,13 +722,21 @@ public class TypeAnnotations {
int arg = taframe.arguments.indexOf(tree);
p.location = p.location.prepend(new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg));
- locateNestedTypes(taframe.type, p);
+ Type typeToUse;
+ if (newPath.tail != null && newPath.tail.head.hasTag(Tag.NEWCLASS)) {
+ // If we are within an anonymous class instantiation, use its type,
+ // because it contains a correctly nested type.
+ typeToUse = newPath.tail.head.type;
+ } else {
+ typeToUse = taframe.type;
+ }
+
+ locateNestedTypes(typeToUse, p);
} else {
Assert.error("Could not determine type argument position of tree " + tree +
" within frame " + frame);
}
- List newPath = path.tail;
resolveFrame(newPath.head, newPath.tail.head, newPath, p);
return;
}
@@ -780,6 +854,9 @@ public class TypeAnnotations {
default:
Assert.error("Found unexpected type annotation for variable: " + v + " with kind: " + v.getKind());
}
+ if (v.getKind() != ElementKind.FIELD) {
+ v.owner.annotations.appendUniqueTypes(v.getRawTypeAttributes());
+ }
return;
case ANNOTATED_TYPE: {
@@ -789,6 +866,11 @@ public class TypeAnnotations {
// not care about inner types.
JCAnnotatedType atypetree = (JCAnnotatedType) frame;
final Type utype = atypetree.underlyingType.type;
+ if (utype == null) {
+ // This might happen during DeferredAttr;
+ // we will be back later.
+ return;
+ }
Symbol tsym = utype.tsym;
if (tsym.getKind().equals(ElementKind.TYPE_PARAMETER) ||
utype.getKind().equals(TypeKind.WILDCARD) ||
@@ -806,8 +888,6 @@ public class TypeAnnotations {
}
case UNION_TYPE: {
- // TODO: can we store any information here to help in
- // determining the final position?
List newPath = path.tail;
resolveFrame(newPath.head, newPath.tail.head, newPath, p);
return;
@@ -873,11 +953,20 @@ public class TypeAnnotations {
private static int methodParamIndex(List path, JCTree param) {
List curr = path;
- while (curr.head.getTag() != Tag.METHODDEF) {
+ while (curr.head.getTag() != Tag.METHODDEF &&
+ curr.head.getTag() != Tag.LAMBDA) {
curr = curr.tail;
}
- JCMethodDecl method = (JCMethodDecl)curr.head;
- return method.params.indexOf(param);
+ if (curr.head.getTag() == Tag.METHODDEF) {
+ JCMethodDecl method = (JCMethodDecl)curr.head;
+ return method.params.indexOf(param);
+ } else if (curr.head.getTag() == Tag.LAMBDA) {
+ JCLambda lambda = (JCLambda)curr.head;
+ return lambda.params.indexOf(param);
+ } else {
+ Assert.error("methodParamIndex expected to find method or lambda for param: " + param);
+ return -1;
+ }
}
// Each class (including enclosed inner classes) is visited separately.
@@ -889,6 +978,7 @@ public class TypeAnnotations {
if (isInClass)
return;
isInClass = true;
+
if (sigOnly) {
scan(tree.mods);
scan(tree.typarams);
@@ -910,7 +1000,9 @@ public class TypeAnnotations {
return;
}
if (sigOnly) {
- {
+ if (!tree.mods.annotations.isEmpty()) {
+ // Nothing to do for separateAnnotationsKinds if
+ // there are no annotations of either kind.
TypeAnnotationPosition pos = new TypeAnnotationPosition();
pos.type = TargetType.METHOD_RETURN;
if (tree.sym.isConstructor()) {
@@ -923,7 +1015,10 @@ public class TypeAnnotations {
tree.sym, pos);
}
}
- if (tree.recvparam != null && tree.recvparam.sym != null) {
+ if (tree.recvparam != null && tree.recvparam.sym != null &&
+ !tree.recvparam.mods.annotations.isEmpty()) {
+ // Nothing to do for separateAnnotationsKinds if
+ // there are no annotations of either kind.
// TODO: make sure there are no declaration annotations.
TypeAnnotationPosition pos = new TypeAnnotationPosition();
pos.type = TargetType.METHOD_RECEIVER;
@@ -933,11 +1028,15 @@ public class TypeAnnotations {
}
int i = 0;
for (JCVariableDecl param : tree.params) {
- TypeAnnotationPosition pos = new TypeAnnotationPosition();
- pos.type = TargetType.METHOD_FORMAL_PARAMETER;
- pos.parameter_index = i;
- pos.pos = param.vartype.pos;
- separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
+ if (!param.mods.annotations.isEmpty()) {
+ // Nothing to do for separateAnnotationsKinds if
+ // there are no annotations of either kind.
+ TypeAnnotationPosition pos = new TypeAnnotationPosition();
+ pos.type = TargetType.METHOD_FORMAL_PARAMETER;
+ pos.parameter_index = i;
+ pos.pos = param.vartype.pos;
+ separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
+ }
++i;
}
}
@@ -958,16 +1057,53 @@ public class TypeAnnotations {
pop();
}
+ /* Store a reference to the current lambda expression, to
+ * be used by all type annotations within this expression.
+ */
+ private JCLambda currentLambda = null;
+
+ public void visitLambda(JCLambda tree) {
+ JCLambda prevLambda = currentLambda;
+ try {
+ currentLambda = tree;
+
+ int i = 0;
+ for (JCVariableDecl param : tree.params) {
+ if (!param.mods.annotations.isEmpty()) {
+ // Nothing to do for separateAnnotationsKinds if
+ // there are no annotations of either kind.
+ TypeAnnotationPosition pos = new TypeAnnotationPosition();
+ pos.type = TargetType.METHOD_FORMAL_PARAMETER;
+ pos.parameter_index = i;
+ pos.pos = param.vartype.pos;
+ pos.onLambda = tree;
+ separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
+ }
+ ++i;
+ }
+
+ push(tree);
+ scan(tree.body);
+ scan(tree.params);
+ pop();
+ } finally {
+ currentLambda = prevLambda;
+ }
+ }
+
/**
* Resolve declaration vs. type annotations in variable declarations and
* then determine the positions.
*/
@Override
public void visitVarDef(final JCVariableDecl tree) {
- if (tree.sym == null) {
+ if (tree.mods.annotations.isEmpty()) {
+ // Nothing to do for separateAnnotationsKinds if
+ // there are no annotations of either kind.
+ } else if (tree.sym == null) {
// Something is wrong already. Quietly ignore.
} else if (tree.sym.getKind() == ElementKind.PARAMETER) {
- // Parameters are handled in visitMethodDef above.
+ // Parameters are handled in visitMethodDef or visitLambda.
} else if (tree.sym.getKind() == ElementKind.FIELD) {
if (sigOnly) {
TypeAnnotationPosition pos = new TypeAnnotationPosition();
@@ -979,16 +1115,19 @@ public class TypeAnnotations {
TypeAnnotationPosition pos = new TypeAnnotationPosition();
pos.type = TargetType.LOCAL_VARIABLE;
pos.pos = tree.pos;
+ pos.onLambda = currentLambda;
separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
} else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
TypeAnnotationPosition pos = new TypeAnnotationPosition();
pos.type = TargetType.EXCEPTION_PARAMETER;
pos.pos = tree.pos;
+ pos.onLambda = currentLambda;
separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
} else if (tree.sym.getKind() == ElementKind.RESOURCE_VARIABLE) {
TypeAnnotationPosition pos = new TypeAnnotationPosition();
pos.type = TargetType.RESOURCE_VARIABLE;
pos.pos = tree.pos;
+ pos.onLambda = currentLambda;
separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
} else if (tree.sym.getKind() == ElementKind.ENUM_CONSTANT) {
// No type annotations can occur here.
@@ -1030,6 +1169,40 @@ public class TypeAnnotations {
super.visitTypeParameter(tree);
}
+ @Override
+ public void visitNewClass(JCNewClass tree) {
+ if (tree.def != null &&
+ !tree.def.mods.annotations.isEmpty()) {
+ JCClassDecl classdecl = tree.def;
+ TypeAnnotationPosition pos = new TypeAnnotationPosition();
+ pos.type = TargetType.CLASS_EXTENDS;
+ pos.pos = tree.pos;
+ if (classdecl.extending == tree.clazz) {
+ pos.type_index = -1;
+ } else if (classdecl.implementing.contains(tree.clazz)) {
+ pos.type_index = classdecl.implementing.indexOf(tree.clazz);
+ } else {
+ // In contrast to CLASS elsewhere, typarams cannot occur here.
+ Assert.error("Could not determine position of tree " + tree);
+ }
+ Type before = classdecl.sym.type;
+ separateAnnotationsKinds(classdecl, tree.clazz.type, classdecl.sym, pos);
+
+ // classdecl.sym.type now contains an annotated type, which
+ // is not what we want there.
+ // TODO: should we put this type somewhere in the superclass/interface?
+ classdecl.sym.type = before;
+ }
+
+ scan(tree.encl);
+ scan(tree.typeargs);
+ scan(tree.clazz);
+ scan(tree.args);
+
+ // The class body will already be scanned.
+ // scan(tree.def);
+ }
+
@Override
public void visitNewArray(JCNewArray tree) {
findPosition(tree, tree, tree.annotations);
@@ -1040,6 +1213,7 @@ public class TypeAnnotations {
for (int i = 0; i < dimAnnosCount; ++i) {
TypeAnnotationPosition p = new TypeAnnotationPosition();
p.pos = tree.pos;
+ p.onLambda = currentLambda;
p.type = TargetType.NEW;
if (i != 0) {
depth = depth.append(TypePathEntry.ARRAY);
@@ -1053,18 +1227,23 @@ public class TypeAnnotations {
// int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1;
// TODO: is depth.size == i here?
JCExpression elemType = tree.elemtype;
+ depth = depth.append(TypePathEntry.ARRAY);
while (elemType != null) {
if (elemType.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
JCAnnotatedType at = (JCAnnotatedType)elemType;
TypeAnnotationPosition p = new TypeAnnotationPosition();
p.type = TargetType.NEW;
p.pos = tree.pos;
- p.location = p.location.appendList(depth.toList());
+ p.onLambda = currentLambda;
+ locateNestedTypes(elemType.type, p);
+ p.location = p.location.prependList(depth.toList());
setTypeAnnotationPos(at.annotations, p);
elemType = at.underlyingType;
} else if (elemType.hasTag(JCTree.Tag.TYPEARRAY)) {
depth = depth.append(TypePathEntry.ARRAY);
elemType = ((JCArrayTypeTree)elemType).elemtype;
+ } else if (elemType.hasTag(JCTree.Tag.SELECT)) {
+ elemType = ((JCFieldAccess)elemType).selected;
} else {
break;
}
@@ -1076,10 +1255,11 @@ public class TypeAnnotations {
if (!annotations.isEmpty()) {
/*
System.out.println("Finding pos for: " + annotations);
- System.out.println(" tree: " + tree);
- System.out.println(" frame: " + frame);
+ System.out.println(" tree: " + tree + " kind: " + tree.getKind());
+ System.out.println(" frame: " + frame + " kind: " + frame.getKind());
*/
TypeAnnotationPosition p = new TypeAnnotationPosition();
+ p.onLambda = currentLambda;
resolveFrame(tree, frame, frames.toList(), p);
setTypeAnnotationPos(annotations, p);
}
@@ -1088,8 +1268,17 @@ public class TypeAnnotations {
private static void setTypeAnnotationPos(List annotations,
TypeAnnotationPosition position) {
for (JCAnnotation anno : annotations) {
- ((Attribute.TypeCompound) anno.attribute).position = position;
+ // attribute might be null during DeferredAttr;
+ // we will be back later.
+ if (anno.attribute != null) {
+ ((Attribute.TypeCompound) anno.attribute).position = position;
+ }
}
}
+
+ @Override
+ public String toString() {
+ return super.toString() + ": sigOnly: " + sigOnly;
+ }
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
index 083dc223db5..0927a339e1e 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
@@ -26,7 +26,6 @@
package com.sun.tools.javac.code;
import java.lang.ref.SoftReference;
-import java.util.Comparator;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Locale;
@@ -34,8 +33,6 @@ import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
-import javax.lang.model.type.TypeKind;
-
import com.sun.tools.javac.code.Attribute.RetentionPolicy;
import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
@@ -204,7 +201,7 @@ public class Types {
WildcardType unb = new WildcardType(syms.objectType,
BoundKind.UNBOUND,
syms.boundClass,
- (TypeVar)parms.head);
+ (TypeVar)parms.head.unannotatedType());
if (!containsType(args.head, unb))
return false;
parms = parms.tail;
@@ -268,7 +265,7 @@ public class Types {
List opens = openVars.toList();
ListBuffer qs = new ListBuffer();
for (List iter = opens; iter.nonEmpty(); iter = iter.tail) {
- qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head));
+ qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head.unannotatedType()));
}
res = subst(res, opens, qs.toList());
}
@@ -581,12 +578,12 @@ public class Types {
//simply replace the wildcards with its bound
for (Type t : formalInterface.getTypeArguments()) {
if (actualTypeargs.head.hasTag(WILDCARD)) {
- WildcardType wt = (WildcardType)actualTypeargs.head;
+ WildcardType wt = (WildcardType)actualTypeargs.head.unannotatedType();
Type bound;
switch (wt.kind) {
case EXTENDS:
case UNBOUND:
- CapturedType capVar = (CapturedType)capturedTypeargs.head;
+ CapturedType capVar = (CapturedType)capturedTypeargs.head.unannotatedType();
//use declared bound if it doesn't depend on formal type-args
bound = capVar.bound.containsAny(capturedSite.getTypeArguments()) ?
wt.type : capVar.bound;
@@ -964,6 +961,9 @@ public class Types {
isSameTypeStrict.visit(t, s) :
isSameTypeLoose.visit(t, s);
}
+ public boolean isSameAnnotatedType(Type t, Type s) {
+ return isSameAnnotatedType.visit(t, s);
+ }
// where
abstract class SameTypeVisitor extends TypeRelation {
@@ -982,7 +982,7 @@ public class Types {
if (s.tag == TYPEVAR) {
//type-substitution does not preserve type-var types
//check that type var symbols and bounds are indeed the same
- return sameTypeVars((TypeVar)t, (TypeVar)s);
+ return sameTypeVars((TypeVar)t.unannotatedType(), (TypeVar)s.unannotatedType());
}
else {
//special case for s == ? super X, where upper(s) = u
@@ -1096,7 +1096,9 @@ public class Types {
* Standard type-equality relation - type variables are considered
* equals if they share the same type symbol.
*/
- TypeRelation isSameTypeLoose = new SameTypeVisitor() {
+ TypeRelation isSameTypeLoose = new LooseSameTypeVisitor();
+
+ private class LooseSameTypeVisitor extends SameTypeVisitor {
@Override
boolean sameTypeVars(TypeVar tv1, TypeVar tv2) {
return tv1.tsym == tv2.tsym && visit(tv1.getUpperBound(), tv2.getUpperBound());
@@ -1126,12 +1128,29 @@ public class Types {
if (!s.hasTag(WILDCARD)) {
return false;
} else {
- WildcardType t2 = (WildcardType)s;
+ WildcardType t2 = (WildcardType)s.unannotatedType();
return t.kind == t2.kind &&
isSameType(t.type, t2.type, true);
}
}
};
+
+ /**
+ * A version of LooseSameTypeVisitor that takes AnnotatedTypes
+ * into account.
+ */
+ TypeRelation isSameAnnotatedType = new LooseSameTypeVisitor() {
+ @Override
+ public Boolean visitAnnotatedType(AnnotatedType t, Type s) {
+ if (!s.isAnnotated())
+ return false;
+ if (!t.getAnnotationMirrors().containsAll(s.getAnnotationMirrors()))
+ return false;
+ if (!s.getAnnotationMirrors().containsAll(t.getAnnotationMirrors()))
+ return false;
+ return visit(t.underlyingType, s);
+ }
+ };
//
//
@@ -1140,7 +1159,7 @@ public class Types {
case UNDETVAR:
if (s.tag == WILDCARD) {
UndetVar undetvar = (UndetVar)t;
- WildcardType wt = (WildcardType)s;
+ WildcardType wt = (WildcardType)s.unannotatedType();
switch(wt.kind) {
case UNBOUND: //similar to ? extends Object
case EXTENDS: {
@@ -1207,7 +1226,7 @@ public class Types {
private Type U(Type t) {
while (t.tag == WILDCARD) {
- WildcardType w = (WildcardType)t;
+ WildcardType w = (WildcardType)t.unannotatedType();
if (w.isSuperBound())
return w.bound == null ? syms.objectType : w.bound.bound;
else
@@ -1218,7 +1237,7 @@ public class Types {
private Type L(Type t) {
while (t.tag == WILDCARD) {
- WildcardType w = (WildcardType)t;
+ WildcardType w = (WildcardType)t.unannotatedType();
if (w.isExtendsBound())
return syms.botType;
else
@@ -1276,15 +1295,15 @@ public class Types {
};
public boolean isCaptureOf(Type s, WildcardType t) {
- if (s.tag != TYPEVAR || !((TypeVar)s).isCaptured())
+ if (s.tag != TYPEVAR || !((TypeVar)s.unannotatedType()).isCaptured())
return false;
- return isSameWildcard(t, ((CapturedType)s).wildcard);
+ return isSameWildcard(t, ((CapturedType)s.unannotatedType()).wildcard);
}
public boolean isSameWildcard(WildcardType t, Type s) {
if (s.tag != WILDCARD)
return false;
- WildcardType w = (WildcardType)s;
+ WildcardType w = (WildcardType)s.unannotatedType();
return w.kind == t.kind && w.type == t.type;
}
@@ -1373,8 +1392,8 @@ public class Types {
if (t.isCompound() || s.isCompound()) {
return !t.isCompound() ?
- visitIntersectionType((IntersectionClassType)s, t, true) :
- visitIntersectionType((IntersectionClassType)t, s, false);
+ visitIntersectionType((IntersectionClassType)s.unannotatedType(), t, true) :
+ visitIntersectionType((IntersectionClassType)t.unannotatedType(), s, false);
}
if (s.tag == CLASS || s.tag == ARRAY) {
@@ -3070,7 +3089,7 @@ public class Types {
for (Type t : tvars) {
if (!first) s.append(", ");
first = false;
- appendTyparamString(((TypeVar)t), s);
+ appendTyparamString(((TypeVar)t.unannotatedType()), s);
}
s.append('>');
return s.toString();
@@ -3710,9 +3729,9 @@ public class Types {
!currentS.isEmpty()) {
if (currentS.head != currentT.head) {
captured = true;
- WildcardType Ti = (WildcardType)currentT.head;
+ WildcardType Ti = (WildcardType)currentT.head.unannotatedType();
Type Ui = currentA.head.getUpperBound();
- CapturedType Si = (CapturedType)currentS.head;
+ CapturedType Si = (CapturedType)currentS.head.unannotatedType();
if (Ui == null)
Ui = syms.objectType;
switch (Ti.kind) {
@@ -3749,6 +3768,7 @@ public class Types {
ListBuffer result = lb();
for (Type t : types) {
if (t.tag == WILDCARD) {
+ t = t.unannotatedType();
Type bound = ((WildcardType)t).getExtendsBound();
if (bound == null)
bound = syms.objectType;
@@ -3842,7 +3862,7 @@ public class Types {
private boolean giveWarning(Type from, Type to) {
List bounds = to.isCompound() ?
- ((IntersectionClassType)to).getComponents() : List.of(to);
+ ((IntersectionClassType)to.unannotatedType()).getComponents() : List.of(to);
for (Type b : bounds) {
Type subFrom = asSub(from, b.tsym);
if (b.isParameterized() &&
@@ -4107,7 +4127,7 @@ public class Types {
Type B(Type t) {
while (t.tag == WILDCARD) {
- WildcardType w = (WildcardType)t;
+ WildcardType w = (WildcardType)t.unannotatedType();
t = high ?
w.getExtendsBound() :
w.getSuperBound();
@@ -4182,7 +4202,7 @@ public class Types {
public boolean equals(Object obj) {
return (obj instanceof UniqueType) &&
- types.isSameType(type, ((UniqueType)obj).type);
+ types.isSameAnnotatedType(type, ((UniqueType)obj).type);
}
public String toString() {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java
index 3c5d9bef03a..ebc6fa33863 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java
@@ -216,18 +216,42 @@ public class Annotate {
Attribute.Compound enterAnnotation(JCAnnotation a,
Type expected,
Env env) {
+ return enterAnnotation(a, expected, env, false);
+ }
+
+ Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a,
+ Type expected,
+ Env env) {
+ return (Attribute.TypeCompound) enterAnnotation(a, expected, env, true);
+ }
+
+ // boolean typeAnnotation determines whether the method returns
+ // a Compound (false) or TypeCompound (true).
+ Attribute.Compound enterAnnotation(JCAnnotation a,
+ Type expected,
+ Env env,
+ boolean typeAnnotation) {
// The annotation might have had its type attributed (but not checked)
// by attr.attribAnnotationTypes during MemberEnter, in which case we do not
// need to do it again.
Type at = (a.annotationType.type != null ? a.annotationType.type
: attr.attribType(a.annotationType, env));
a.type = chk.checkType(a.annotationType.pos(), at, expected);
- if (a.type.isErroneous())
- return new Attribute.Compound(a.type, List.>nil());
+ if (a.type.isErroneous()) {
+ if (typeAnnotation) {
+ return new Attribute.TypeCompound(a.type, List.>nil(), null);
+ } else {
+ return new Attribute.Compound(a.type, List.>nil());
+ }
+ }
if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0) {
log.error(a.annotationType.pos(),
"not.annotation.type", a.type.toString());
- return new Attribute.Compound(a.type, List.>nil());
+ if (typeAnnotation) {
+ return new Attribute.TypeCompound(a.type, List.>nil(), null);
+ } else {
+ return new Attribute.Compound(a.type, List.>nil());
+ }
}
List args = a.args;
if (args.length() == 1 && !args.head.hasTag(ASSIGN)) {
@@ -266,12 +290,21 @@ public class Annotate {
((MethodSymbol)method, value));
t.type = result;
}
- // TODO: this should be a TypeCompound if "a" is a JCTypeAnnotation.
- // However, how do we find the correct position?
- Attribute.Compound ac = new Attribute.Compound(a.type, buf.toList());
- // TODO: is this something we want? Who would use it?
- // a.attribute = ac;
- return ac;
+ if (typeAnnotation) {
+ if (a.attribute == null || !(a.attribute instanceof Attribute.TypeCompound)) {
+ // Create a new TypeCompound
+ Attribute.TypeCompound tc = new Attribute.TypeCompound(a.type, buf.toList(), new TypeAnnotationPosition());
+ a.attribute = tc;
+ return tc;
+ } else {
+ // Use an existing TypeCompound
+ return a.attribute;
+ }
+ } else {
+ Attribute.Compound ac = new Attribute.Compound(a.type, buf.toList());
+ a.attribute = ac;
+ return ac;
+ }
}
Attribute enterAttributeValue(Type expected,
@@ -354,15 +387,6 @@ public class Annotate {
return new Attribute.Error(attr.attribExpr(tree, env, expected));
}
- Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a,
- Type expected,
- Env env) {
- Attribute.Compound c = enterAnnotation(a, expected, env);
- Attribute.TypeCompound tc = new Attribute.TypeCompound(c.type, c.values, new TypeAnnotationPosition());
- a.attribute = tc;
- return tc;
- }
-
/* *********************************
* Support for repeating annotations
***********************************/
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
index 34998862480..bff462f8f29 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
@@ -768,7 +768,12 @@ public class Attr extends JCTree.Visitor {
JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
try {
- memberEnter.typeAnnotate(initializer, env, env.info.enclVar);
+ // Use null as symbol to not attach the type annotation to any symbol.
+ // The initializer will later also be visited and then we'll attach
+ // to the symbol.
+ // This prevents having multiple type annotations, just because of
+ // lazy constant value evaluation.
+ memberEnter.typeAnnotate(initializer, env, null);
annotate.flush();
Type itype = attribExpr(initializer, env, type);
if (itype.constValue() != null)
@@ -935,11 +940,6 @@ public class Attr extends JCTree.Visitor {
Env newEnv = memberEnter.methodEnv(tree, env);
attribType(tree.recvparam, newEnv);
chk.validate(tree.recvparam, newEnv);
- if (!(tree.recvparam.type == m.owner.type || types.isSameType(tree.recvparam.type, m.owner.type))) {
- // The == covers the common non-generic case, but for generic classes we need isSameType;
- // note that equals didn't work.
- log.error(tree.recvparam.pos(), "incorrect.receiver.type");
- }
}
// annotation method checks
@@ -1056,7 +1056,10 @@ public class Attr extends JCTree.Visitor {
Lint prevLint = chk.setLint(lint);
// Check that the variable's declared type is well-formed.
- chk.validate(tree.vartype, env);
+ boolean isImplicitLambdaParameter = env.tree.hasTag(LAMBDA) &&
+ ((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT &&
+ (tree.sym.flags() & PARAMETER) != 0;
+ chk.validate(tree.vartype, env, !isImplicitLambdaParameter);
deferredLintHandler.flush(tree.pos());
try {
@@ -1112,6 +1115,18 @@ public class Attr extends JCTree.Visitor {
memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner);
annotate.flush();
+ {
+ // Store init and clinit type annotations with the ClassSymbol
+ // to allow output in Gen.normalizeDefs.
+ ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
+ List tas = localEnv.info.scope.owner.getRawTypeAttributes();
+ if ((tree.flags & STATIC) != 0) {
+ cs.annotations.appendClassInitTypeAttributes(tas);
+ } else {
+ cs.annotations.appendInitTypeAttributes(tas);
+ }
+ }
+
attribStats(tree.stats, localEnv);
} else {
// Create a new local environment with a local scope.
@@ -1338,7 +1353,7 @@ public class Attr extends JCTree.Visitor {
//check that resource type cannot throw InterruptedException
checkAutoCloseable(resource.pos(), localEnv, resource.type);
- VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource);
+ VarSymbol var = ((JCVariableDecl) resource).sym;
var.setData(ElementKind.RESOURCE_VARIABLE);
} else {
attribTree(resource, tryEnv, twrResult);
@@ -2131,6 +2146,11 @@ public class Attr extends JCTree.Visitor {
tree.constructor,
localEnv,
new ResultInfo(VAL, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
+ } else {
+ if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
+ checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
+ tree.clazz.type.tsym);
+ }
}
if (tree.constructor != null && tree.constructor.kind == MTH)
@@ -2195,6 +2215,20 @@ public class Attr extends JCTree.Visitor {
}
}
+ private void checkForDeclarationAnnotations(List extends JCAnnotation> annotations,
+ Symbol sym) {
+ // Ensure that no declaration annotations are present.
+ // Note that a tree type might be an AnnotatedType with
+ // empty annotations, if only declaration annotations were given.
+ // This method will raise an error for such a type.
+ for (JCAnnotation ai : annotations) {
+ if (TypeAnnotations.annotationType(syms, names, ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
+ log.error(ai.pos(), "annotation.type.not.applicable");
+ }
+ }
+ }
+
+
/** Make an attributed null check tree.
*/
public JCExpression makeNullCheck(JCExpression arg) {
@@ -2221,6 +2255,10 @@ public class Attr extends JCTree.Visitor {
attribExpr(l.head, localEnv, syms.intType);
owntype = new ArrayType(owntype, syms.arrayClass);
}
+ if (tree.elemtype.hasTag(ANNOTATED_TYPE)) {
+ checkForDeclarationAnnotations(((JCAnnotatedType) tree.elemtype).annotations,
+ tree.elemtype.type.tsym);
+ }
} else {
// we are seeing an untyped aggregate { ... }
// this is allowed only if the prototype is an array
@@ -2309,7 +2347,7 @@ public class Attr extends JCTree.Visitor {
Type argType = arityMismatch ?
syms.errType :
actuals.head;
- params.head.vartype = make.Type(argType);
+ params.head.vartype = make.at(params.head).Type(argType);
params.head.sym = null;
actuals = actuals.isEmpty() ?
actuals :
@@ -2356,7 +2394,8 @@ public class Attr extends JCTree.Visitor {
for (JCDiagnostic deferredDiag : lambdaDeferredHandler.getDiagnostics()) {
if (deferredDiag.getKind() == JCDiagnostic.Kind.ERROR) {
resultInfo.checkContext
- .report(that, diags.fragment("bad.arg.types.in.lambda", TreeInfo.types(that.params)));
+ .report(that, diags.fragment("bad.arg.types.in.lambda", TreeInfo.types(that.params),
+ deferredDiag)); //hidden diag parameter
//we mark the lambda as erroneous - this is crucial in the recovery step
//as parameter-dependent type error won't be reported in that stage,
//meaning that a lambda will be deemed erroeneous only if there is
@@ -2606,10 +2645,11 @@ public class Attr extends JCTree.Visitor {
return;
}
- if (TreeInfo.isStaticSelector(that.expr, names) &&
- (that.getMode() != ReferenceMode.NEW || !that.expr.type.isRaw())) {
- //if the qualifier is a type, validate it
- chk.validate(that.expr, env);
+ if (TreeInfo.isStaticSelector(that.expr, names)) {
+ //if the qualifier is a type, validate it; raw warning check is
+ //omitted as we don't know at this stage as to whether this is a
+ //raw selector (because of inference)
+ chk.validate(that.expr, env, false);
}
//attrib type-arguments
@@ -2695,6 +2735,13 @@ public class Attr extends JCTree.Visitor {
if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) {
+ if (that.getMode() == ReferenceMode.INVOKE &&
+ TreeInfo.isStaticSelector(that.expr, names) &&
+ that.kind.isUnbound() &&
+ !desc.getParameterTypes().head.isParameterized()) {
+ chk.checkRaw(that.expr, localEnv);
+ }
+
if (!that.kind.isUnbound() &&
that.getMode() == ReferenceMode.INVOKE &&
TreeInfo.isStaticSelector(that.expr, names) &&
@@ -3763,6 +3810,12 @@ public class Attr extends JCTree.Visitor {
}
}
owntype = new ClassType(clazzOuter, actuals, clazztype.tsym);
+ if (clazztype.isAnnotated()) {
+ // Use the same AnnotatedType, because it will have
+ // its annotations set later.
+ ((AnnotatedType)clazztype).underlyingType = owntype;
+ owntype = clazztype;
+ }
} else {
if (formals.length() != 0) {
log.error(tree.pos(), "wrong.number.type.args",
@@ -3961,7 +4014,14 @@ public class Attr extends JCTree.Visitor {
ListBuffer buf = ListBuffer.lb();
for (JCAnnotation anno : annotations) {
- buf.append((Attribute.TypeCompound) anno.attribute);
+ if (anno.attribute != null) {
+ // TODO: this null-check is only needed for an obscure
+ // ordering issue, where annotate.flush is called when
+ // the attribute is not set yet. For an example failure
+ // try the referenceinfos/NestedTypes.java test.
+ // Any better solutions?
+ buf.append((Attribute.TypeCompound) anno.attribute);
+ }
}
return buf.toList();
}
@@ -4266,15 +4326,12 @@ public class Attr extends JCTree.Visitor {
tree.accept(typeAnnotationsValidator);
}
//where
- private final JCTree.Visitor typeAnnotationsValidator =
- new TreeScanner() {
+ private final JCTree.Visitor typeAnnotationsValidator = new TreeScanner() {
+
+ private boolean checkAllAnnotations = false;
+
public void visitAnnotation(JCAnnotation tree) {
- if (tree.hasTag(TYPE_ANNOTATION)) {
- // TODO: It seems to WMD as if the annotation in
- // parameters, in particular also the recvparam, are never
- // of type JCTypeAnnotation and therefore never checked!
- // Luckily this check doesn't really do anything that isn't
- // also done elsewhere.
+ if (tree.hasTag(TYPE_ANNOTATION) || checkAllAnnotations) {
chk.validateTypeAnnotation(tree, false);
}
super.visitAnnotation(tree);
@@ -4288,15 +4345,10 @@ public class Attr extends JCTree.Visitor {
// super.visitTypeParameter(tree);
}
public void visitMethodDef(JCMethodDecl tree) {
- // Static methods cannot have receiver type annotations.
- // In test case FailOver15.java, the nested method getString has
- // a null sym, because an unknown class is instantiated.
- // I would say it's safe to skip.
- if (tree.sym != null && (tree.sym.flags() & Flags.STATIC) != 0) {
- if (tree.recvparam != null) {
- // TODO: better error message. Is the pos good?
- log.error(tree.recvparam.pos(), "annotation.type.not.applicable");
- }
+ if (tree.recvparam != null &&
+ tree.recvparam.vartype.type.getKind() != TypeKind.ERROR) {
+ checkForDeclarationAnnotations(tree.recvparam.mods.annotations,
+ tree.recvparam.vartype.type.tsym);
}
if (tree.restype != null && tree.restype.type != null) {
validateAnnotatedType(tree.restype, tree.restype.type);
@@ -4318,9 +4370,30 @@ public class Attr extends JCTree.Visitor {
validateAnnotatedType(tree.clazz, tree.clazz.type);
super.visitTypeTest(tree);
}
- // TODO: what else do we need?
- // public void visitNewClass(JCNewClass tree) {
- // public void visitNewArray(JCNewArray tree) {
+ public void visitNewClass(JCNewClass tree) {
+ if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
+ boolean prevCheck = this.checkAllAnnotations;
+ try {
+ this.checkAllAnnotations = true;
+ scan(((JCAnnotatedType)tree.clazz).annotations);
+ } finally {
+ this.checkAllAnnotations = prevCheck;
+ }
+ }
+ super.visitNewClass(tree);
+ }
+ public void visitNewArray(JCNewArray tree) {
+ if (tree.elemtype != null && tree.elemtype.hasTag(ANNOTATED_TYPE)) {
+ boolean prevCheck = this.checkAllAnnotations;
+ try {
+ this.checkAllAnnotations = true;
+ scan(((JCAnnotatedType)tree.elemtype).annotations);
+ } finally {
+ this.checkAllAnnotations = prevCheck;
+ }
+ }
+ super.visitNewArray(tree);
+ }
/* I would want to model this after
* com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess)
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
index 01fc16abd95..cd550d6edaf 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
@@ -1213,7 +1213,7 @@ public class Check {
/** Validate a type expression. That is,
* check that all type arguments of a parametric type are within
- * their bounds. This must be done in a second phase after type attributon
+ * their bounds. This must be done in a second phase after type attribution
* since a class might have a subclass as type parameter bound. E.g:
*
* {@code
@@ -1361,23 +1361,23 @@ public class Check {
for (List extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
validateTree(l.head, checkRaw, isOuter);
}
+ }
- void checkRaw(JCTree tree, Env env) {
- if (lint.isEnabled(LintCategory.RAW) &&
- tree.type.hasTag(CLASS) &&
- !TreeInfo.isDiamond(tree) &&
- !withinAnonConstr(env) &&
- tree.type.isRaw()) {
- log.warning(LintCategory.RAW,
- tree.pos(), "raw.class.use", tree.type, tree.type.tsym.type);
- }
+ void checkRaw(JCTree tree, Env env) {
+ if (lint.isEnabled(LintCategory.RAW) &&
+ tree.type.hasTag(CLASS) &&
+ !TreeInfo.isDiamond(tree) &&
+ !withinAnonConstr(env) &&
+ tree.type.isRaw()) {
+ log.warning(LintCategory.RAW,
+ tree.pos(), "raw.class.use", tree.type, tree.type.tsym.type);
}
-
- boolean withinAnonConstr(Env env) {
+ }
+ //where
+ private boolean withinAnonConstr(Env env) {
return env.enclClass.name.isEmpty() &&
env.enclMethod != null && env.enclMethod.name == names.init;
}
- }
/* *************************************************************************
* Exception checking
@@ -3024,9 +3024,9 @@ public class Check {
// collect an inventory of the annotation elements
Set members = new LinkedHashSet();
for (Scope.Entry e = a.annotationType.type.tsym.members().elems;
- e != null;
- e = e.sibling)
- if (e.sym.kind == MTH)
+ e != null;
+ e = e.sibling)
+ if (e.sym.kind == MTH && e.sym.name != names.clinit)
members.add((MethodSymbol) e.sym);
// remove the ones that are assigned values
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
index bcf4e6ba99f..a7d98fdac8e 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
@@ -25,12 +25,11 @@
package com.sun.tools.javac.comp;
import com.sun.tools.javac.tree.*;
-import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
import com.sun.tools.javac.tree.TreeMaker;
-import com.sun.tools.javac.tree.TreeScanner;
import com.sun.tools.javac.tree.TreeTranslator;
+import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Scope;
import com.sun.tools.javac.code.Symbol;
@@ -46,7 +45,6 @@ import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzerPreprocessor.*;
import com.sun.tools.javac.comp.Lower.BasicFreeVarCollector;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
@@ -166,7 +164,7 @@ public class LambdaToMethod extends TreeTranslator {
return translate(tree, newContext != null ? newContext : context);
}
- public T translate(T tree, TranslationContext> newContext) {
+ T translate(T tree, TranslationContext> newContext) {
TranslationContext> prevContext = context;
try {
context = newContext;
@@ -177,7 +175,7 @@ public class LambdaToMethod extends TreeTranslator {
}
}
- public List translate(List trees, TranslationContext> newContext) {
+ List translate(List trees, TranslationContext> newContext) {
ListBuffer buf = ListBuffer.lb();
for (T tree : trees) {
buf.append(translate(tree, newContext));
@@ -238,6 +236,24 @@ public class LambdaToMethod extends TreeTranslator {
MethodSymbol sym = (MethodSymbol)localContext.translatedSym;
MethodType lambdaType = (MethodType) sym.type;
+ {
+ MethodSymbol owner = (MethodSymbol) localContext.owner;
+ ListBuffer ownerTypeAnnos = new ListBuffer();
+ ListBuffer lambdaTypeAnnos = new ListBuffer();
+
+ for (Attribute.TypeCompound tc : owner.getRawTypeAttributes()) {
+ if (tc.position.onLambda == tree) {
+ lambdaTypeAnnos.append(tc);
+ } else {
+ ownerTypeAnnos.append(tc);
+ }
+ }
+ if (lambdaTypeAnnos.nonEmpty()) {
+ owner.annotations.setTypeAttributes(ownerTypeAnnos.toList());
+ sym.annotations.setTypeAttributes(lambdaTypeAnnos.toList());
+ }
+ }
+
//create the method declaration hoisting the lambda body
JCMethodDecl lambdaDecl = make.MethodDef(make.Modifiers(sym.flags_field),
sym.name,
@@ -373,12 +389,15 @@ public class LambdaToMethod extends TreeTranslator {
if (lambdaContext.getSymbolMap(PARAM).containsKey(tree.sym)) {
Symbol translatedSym = lambdaContext.getSymbolMap(PARAM).get(tree.sym);
result = make.Ident(translatedSym).setType(tree.type);
+ translatedSym.annotations.setTypeAttributes(tree.sym.getRawTypeAttributes());
} else if (lambdaContext.getSymbolMap(LOCAL_VAR).containsKey(tree.sym)) {
Symbol translatedSym = lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym);
result = make.Ident(translatedSym).setType(tree.type);
+ translatedSym.annotations.setTypeAttributes(tree.sym.getRawTypeAttributes());
} else if (lambdaContext.getSymbolMap(TYPE_VAR).containsKey(tree.sym)) {
Symbol translatedSym = lambdaContext.getSymbolMap(TYPE_VAR).get(tree.sym);
result = make.Ident(translatedSym).setType(translatedSym.type);
+ translatedSym.annotations.setTypeAttributes(tree.sym.getRawTypeAttributes());
} else if (lambdaContext.getSymbolMap(CAPTURED_VAR).containsKey(tree.sym)) {
Symbol translatedSym = lambdaContext.getSymbolMap(CAPTURED_VAR).get(tree.sym);
result = make.Ident(translatedSym).setType(tree.type);
@@ -1252,8 +1271,17 @@ public class LambdaToMethod extends TreeTranslator {
List ptypes = ((MethodType) consSym.type).getParameterTypes();
Type classType = consSym.owner.type;
+ // Build lambda parameters
+ // partially cloned from TreeMaker.Params until 8014021 is fixed
+ Symbol owner = owner();
+ ListBuffer paramBuff = new ListBuffer();
+ int i = 0;
+ for (List l = ptypes; l.nonEmpty(); l = l.tail) {
+ paramBuff.append(make.Param(make.paramName(i++), l.head, owner));
+ }
+ List params = paramBuff.toList();
+
// Make new-class call
- List params = make.Params(ptypes, owner());
JCNewClass nc = makeNewClass(classType, make.Idents(params));
nc.pos = tree.pos;
@@ -1274,7 +1302,11 @@ public class LambdaToMethod extends TreeTranslator {
@Override
public void visitSelect(JCFieldAccess tree) {
- if (context() != null && lambdaSelectSymbolFilter(tree.sym)) {
+ if (context() != null && tree.sym.kind == VAR &&
+ (tree.sym.name == names._this ||
+ tree.sym.name == names._super)) {
+ // A select of this or super means, if we are in a lambda,
+ // we much have an instance context
TranslationContext> localContext = context();
while (localContext != null) {
if (localContext.tree.hasTag(LAMBDA)) {
@@ -1525,13 +1557,6 @@ public class LambdaToMethod extends TreeTranslator {
&& sym.name != names.init;
}
- private boolean lambdaSelectSymbolFilter(Symbol sym) {
- return (sym.kind == VAR || sym.kind == MTH) &&
- !sym.isStatic() &&
- (sym.name == names._this ||
- sym.name == names._super);
- }
-
/**
* This is used to filter out those new class expressions that need to
* be qualified with an enclosing tree
@@ -1667,24 +1692,33 @@ public class LambdaToMethod extends TreeTranslator {
* synthetic lambda body
*/
Symbol translate(Name name, final Symbol sym, LambdaSymbolKind skind) {
+ Symbol ret;
switch (skind) {
case CAPTURED_THIS:
- return sym; // self represented
+ ret = sym; // self represented
+ break;
case TYPE_VAR:
// Just erase the type var
- return new VarSymbol(sym.flags(), name,
+ ret = new VarSymbol(sym.flags(), name,
types.erasure(sym.type), sym.owner);
+ break;
case CAPTURED_VAR:
- return new VarSymbol(SYNTHETIC | FINAL, name, types.erasure(sym.type), translatedSym) {
+ ret = new VarSymbol(SYNTHETIC | FINAL, name, types.erasure(sym.type), translatedSym) {
@Override
public Symbol baseSymbol() {
//keep mapping with original captured symbol
return sym;
}
};
+ break;
default:
- return makeSyntheticVar(FINAL, name, types.erasure(sym.type), translatedSym);
+ ret = makeSyntheticVar(FINAL, name, types.erasure(sym.type), translatedSym);
}
+ if (ret != sym) {
+ ret.annotations.setDeclarationAttributes(sym.getRawAttributes());
+ ret.annotations.setTypeAttributes(sym.getRawTypeAttributes());
+ }
+ return ret;
}
void addSymbol(Symbol sym, LambdaSymbolKind skind) {
@@ -1755,12 +1789,13 @@ public class LambdaToMethod extends TreeTranslator {
}
boolean inInterface = translatedSym.owner.isInterface();
boolean thisReferenced = !getSymbolMap(CAPTURED_THIS).isEmpty();
- boolean needInstance = thisReferenced || inInterface;
- // If instance access isn't needed, make it static
- // Interface methods much be public default methods, otherwise make it private
- translatedSym.flags_field = SYNTHETIC | (needInstance? 0 : STATIC) |
- (inInterface? PUBLIC | DEFAULT : PRIVATE);
+ // If instance access isn't needed, make it static.
+ // Interface instance methods must be default methods.
+ // Awaiting VM channges, default methods are public
+ translatedSym.flags_field = SYNTHETIC |
+ ((inInterface && thisReferenced)? PUBLIC : PRIVATE) |
+ (thisReferenced? (inInterface? DEFAULT : 0) : STATIC);
//compute synthetic params
ListBuffer params = ListBuffer.lb();
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
index 6b1caf6a701..7ed28941fb7 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
@@ -28,6 +28,7 @@ package com.sun.tools.javac.comp;
import java.util.*;
import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Type.AnnotatedType;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.main.Option.PkgInfo;
import com.sun.tools.javac.tree.*;
@@ -2767,10 +2768,28 @@ public class Lower extends TreeTranslator {
}
public void visitAnnotatedType(JCAnnotatedType tree) {
- // No need to retain type annotations any longer.
+ // No need to retain type annotations in the tree
// tree.annotations = translate(tree.annotations);
+ tree.annotations = List.nil();
tree.underlyingType = translate(tree.underlyingType);
- result = tree.underlyingType;
+ // but maintain type annotations in the type.
+ if (tree.type.isAnnotated()) {
+ if (tree.underlyingType.type.isAnnotated()) {
+ // The erasure of a type variable might be annotated.
+ // Merge all annotations.
+ AnnotatedType newat = (AnnotatedType) tree.underlyingType.type;
+ AnnotatedType at = (AnnotatedType) tree.type;
+ at.underlyingType = newat.underlyingType;
+ newat.typeAnnotations = at.typeAnnotations.appendList(newat.typeAnnotations);
+ tree.type = newat;
+ } else {
+ // Create a new AnnotatedType to have the correct tag.
+ AnnotatedType oldat = (AnnotatedType) tree.type;
+ tree.type = new AnnotatedType(tree.underlyingType.type);
+ ((AnnotatedType) tree.type).typeAnnotations = oldat.typeAnnotations;
+ }
+ }
+ result = tree;
}
public void visitTypeCast(JCTypeCast tree) {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
index 1e2d1e1e0a4..74e3d97bd42 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
@@ -31,7 +31,6 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
-import javax.lang.model.type.TypeKind;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.*;
@@ -617,7 +616,26 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
if (TreeInfo.isEnumInit(tree)) {
attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
} else {
+ // Make sure type annotations are processed.
+ // But we don't have a symbol to attach them to yet - use null.
+ typeAnnotate(tree.vartype, env, null);
attr.attribType(tree.vartype, localEnv);
+ if (tree.nameexpr != null) {
+ attr.attribExpr(tree.nameexpr, localEnv);
+ MethodSymbol m = localEnv.enclMethod.sym;
+ if (m.isConstructor()) {
+ Type outertype = m.owner.owner.type;
+ if (outertype.hasTag(TypeTag.CLASS)) {
+ checkType(tree.vartype, outertype, "incorrect.constructor.receiver.type");
+ checkType(tree.nameexpr, outertype, "incorrect.constructor.receiver.name");
+ } else {
+ log.error(tree, "receiver.parameter.not.applicable.constructor.toplevel.class");
+ }
+ } else {
+ checkType(tree.vartype, m.owner.type, "incorrect.receiver.type");
+ checkType(tree.nameexpr, m.owner.type, "incorrect.receiver.name");
+ }
+ }
}
} finally {
chk.setDeferredLintHandler(prevLintHandler);
@@ -651,10 +669,16 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
enclScope.enter(v);
}
annotateLater(tree.mods.annotations, localEnv, v);
- typeAnnotate(tree.vartype, env, tree.sym);
+ typeAnnotate(tree.vartype, env, v);
annotate.flush();
v.pos = tree.pos;
}
+ // where
+ void checkType(JCTree tree, Type type, String diag) {
+ if (!tree.type.isErroneous() && !types.isSameType(tree.type, type)) {
+ log.error(tree, diag, type, tree.type);
+ }
+ }
/** Create a fresh environment for a variable's initializer.
* If the variable is a field, the owner of the environment's scope
@@ -1040,9 +1064,12 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
isFirst = true;
}
}
- annotate.afterRepeated(TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree));
+ TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree, annotate);
}
+ /*
+ * If the symbol is non-null, attach the type annotation to it.
+ */
private void actualEnterTypeAnnotations(final List annotations,
final Env env,
final Symbol s) {
@@ -1075,8 +1102,10 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
}
}
- s.annotations.appendTypeAttributesWithCompletion(
- annotate.new AnnotateRepeatedContext(env, annotated, pos, log, true));
+ if (s != null) {
+ s.annotations.appendTypeAttributesWithCompletion(
+ annotate.new AnnotateRepeatedContext(env, annotated, pos, log, true));
+ }
}
public void typeAnnotate(final JCTree tree, final Env env, final Symbol sym) {
@@ -1150,6 +1179,33 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
// Do not annotate the body, just the signature.
// scan(tree.body);
}
+
+ @Override
+ public void visitVarDef(final JCVariableDecl tree) {
+ if (sym != null && sym.kind == Kinds.VAR) {
+ // Don't visit a parameter once when the sym is the method
+ // and once when the sym is the parameter.
+ scan(tree.mods);
+ scan(tree.vartype);
+ }
+ scan(tree.init);
+ }
+
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ // We can only hit a classdef if it is declared within
+ // a method. Ignore it - the class will be visited
+ // separately later.
+ }
+
+ @Override
+ public void visitNewClass(JCNewClass tree) {
+ if (tree.def == null) {
+ // For an anonymous class instantiation the class
+ // will be visited separately.
+ super.visitNewClass(tree);
+ }
+ }
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
index 03ae28854c2..de949a7a243 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
@@ -37,7 +37,10 @@ import com.sun.tools.javac.comp.DeferredAttr.DeferredType;
import com.sun.tools.javac.comp.Infer.InferenceContext;
import com.sun.tools.javac.comp.Infer.FreeTypeListener;
import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
+import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.DiagnosticRewriter;
+import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
import com.sun.tools.javac.jvm.*;
+import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
@@ -94,6 +97,7 @@ public class Resolve {
public final boolean allowDefaultMethods;
public final boolean allowStructuralMostSpecific;
private final boolean debugResolve;
+ private final boolean compactMethodDiags;
final EnumSet verboseResolutionMode;
Scope polymorphicSignatureScope;
@@ -124,6 +128,8 @@ public class Resolve {
varargsEnabled = source.allowVarargs();
Options options = Options.instance(context);
debugResolve = options.isSet("debugresolve");
+ compactMethodDiags = options.isSet(Option.XDIAGS, "compact") ||
+ options.isUnset(Option.XDIAGS) && options.isUnset("rawDiagnostics");
verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
Target target = Target.instance(context);
allowMethodHandles = target.hasMethodHandles();
@@ -661,6 +667,10 @@ public class Resolve {
this.basicKey = basicKey;
this.inferKey = inferKey;
}
+
+ String regex() {
+ return String.format("([a-z]*\\.)*(%s|%s)", basicKey, inferKey);
+ }
}
/**
@@ -691,6 +701,7 @@ public class Resolve {
Warner warn) {
//should we expand formals?
boolean useVarargs = deferredAttrContext.phase.isVarargsRequired();
+ List trees = TreeInfo.args(env.tree);
//inference context used during this method check
InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
@@ -699,17 +710,19 @@ public class Resolve {
if (varargsFormal == null &&
argtypes.size() != formals.size()) {
- reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
+ reportMC(env.tree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
}
while (argtypes.nonEmpty() && formals.head != varargsFormal) {
- checkArg(false, argtypes.head, formals.head, deferredAttrContext, warn);
+ DiagnosticPosition pos = trees != null ? trees.head : null;
+ checkArg(pos, false, argtypes.head, formals.head, deferredAttrContext, warn);
argtypes = argtypes.tail;
formals = formals.tail;
+ trees = trees != null ? trees.tail : trees;
}
if (formals.head != varargsFormal) {
- reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
+ reportMC(env.tree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
}
if (useVarargs) {
@@ -717,8 +730,10 @@ public class Resolve {
//the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
final Type elt = types.elemtype(varargsFormal);
while (argtypes.nonEmpty()) {
- checkArg(true, argtypes.head, elt, deferredAttrContext, warn);
+ DiagnosticPosition pos = trees != null ? trees.head : null;
+ checkArg(pos, true, argtypes.head, elt, deferredAttrContext, warn);
argtypes = argtypes.tail;
+ trees = trees != null ? trees.tail : trees;
}
}
}
@@ -726,9 +741,9 @@ public class Resolve {
/**
* Does the actual argument conforms to the corresponding formal?
*/
- abstract void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn);
+ abstract void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn);
- protected void reportMC(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
+ protected void reportMC(DiagnosticPosition pos, MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
boolean inferDiag = inferenceContext != infer.emptyContext;
InapplicableMethodException ex = inferDiag ?
infer.inferenceException : inapplicableMethodException;
@@ -738,7 +753,8 @@ public class Resolve {
args2[0] = inferenceContext.inferenceVars();
args = args2;
}
- throw ex.setMessage(inferDiag ? diag.inferKey : diag.basicKey, args);
+ String key = inferDiag ? diag.inferKey : diag.basicKey;
+ throw ex.setMessage(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args));
}
public MethodCheck mostSpecificCheck(List actuals, boolean strict) {
@@ -752,7 +768,7 @@ public class Resolve {
*/
MethodCheck arityMethodCheck = new AbstractMethodCheck() {
@Override
- void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
+ void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
//do nothing - actual always compatible to formals
}
};
@@ -778,9 +794,9 @@ public class Resolve {
MethodCheck resolveMethodCheck = new AbstractMethodCheck() {
@Override
- void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
+ void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
- mresult.check(null, actual);
+ mresult.check(pos, actual);
}
@Override
@@ -809,7 +825,7 @@ public class Resolve {
} else {
if (!isAccessible(env, t)) {
Symbol location = env.enclClass.sym;
- reportMC(MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
+ reportMC(env.tree, MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
}
}
}
@@ -822,7 +838,7 @@ public class Resolve {
@Override
public void report(DiagnosticPosition pos, JCDiagnostic details) {
- reportMC(methodDiag, deferredAttrContext.inferenceContext, details);
+ reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details);
}
};
return new MethodResultInfo(to, checkContext);
@@ -3327,6 +3343,18 @@ public class Resolve {
}
else {
Candidate c = errCandidate();
+ if (compactMethodDiags) {
+ for (Map.Entry _entry :
+ MethodResolutionDiagHelper.rewriters.entrySet()) {
+ if (_entry.getKey().matches(c.details)) {
+ JCDiagnostic simpleDiag =
+ _entry.getValue().rewriteDiagnostic(diags, pos,
+ log.currentSource(), dkind, c.details);
+ simpleDiag.setFlag(DiagnosticFlag.COMPRESSED);
+ return simpleDiag;
+ }
+ }
+ }
Symbol ws = c.sym.asMemberOf(site, types);
return diags.create(dkind, log.currentSource(), pos,
"cant.apply.symbol",
@@ -3375,35 +3403,75 @@ public class Resolve {
Name name,
List argtypes,
List typeargtypes) {
- if (!resolveContext.candidates.isEmpty()) {
+ Map candidatesMap = mapCandidates();
+ Map filteredCandidates = filterCandidates(candidatesMap);
+ if (filteredCandidates.isEmpty()) {
+ filteredCandidates = candidatesMap;
+ }
+ boolean truncatedDiag = candidatesMap.size() != filteredCandidates.size();
+ if (filteredCandidates.size() > 1) {
JCDiagnostic err = diags.create(dkind,
+ null,
+ truncatedDiag ?
+ EnumSet.of(DiagnosticFlag.COMPRESSED) :
+ EnumSet.noneOf(DiagnosticFlag.class),
log.currentSource(),
pos,
"cant.apply.symbols",
name == names.init ? KindName.CONSTRUCTOR : absentKind(kind),
name == names.init ? site.tsym.name : name,
methodArguments(argtypes));
- return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site));
+ return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(filteredCandidates, site));
+ } else if (filteredCandidates.size() == 1) {
+ JCDiagnostic d = new InapplicableSymbolError(resolveContext).getDiagnostic(dkind, pos,
+ location, site, name, argtypes, typeargtypes);
+ if (truncatedDiag) {
+ d.setFlag(DiagnosticFlag.COMPRESSED);
+ }
+ return d;
} else {
return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
location, site, name, argtypes, typeargtypes);
}
}
-
//where
- List candidateDetails(Type site) {
- Map details = new LinkedHashMap();
- for (Candidate c : resolveContext.candidates) {
- if (c.isApplicable()) continue;
- JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
- Kinds.kindName(c.sym),
- c.sym.location(site, types),
- c.sym.asMemberOf(site, types),
- c.details);
- details.put(c.sym, detailDiag);
+ private Map mapCandidates() {
+ Map candidates = new LinkedHashMap();
+ for (Candidate c : resolveContext.candidates) {
+ if (c.isApplicable()) continue;
+ candidates.put(c.sym, c.details);
+ }
+ return candidates;
+ }
+
+ Map filterCandidates(Map candidatesMap) {
+ Map candidates = new LinkedHashMap();
+ for (Map.Entry _entry : candidatesMap.entrySet()) {
+ JCDiagnostic d = _entry.getValue();
+ if (!compactMethodDiags ||
+ !new Template(MethodCheckDiag.ARITY_MISMATCH.regex()).matches(d)) {
+ candidates.put(_entry.getKey(), d);
+ }
+ }
+ return candidates;
+ }
+
+ private List candidateDetails(Map candidatesMap, Type site) {
+ List details = List.nil();
+ for (Map.Entry _entry : candidatesMap.entrySet()) {
+ Symbol sym = _entry.getKey();
+ JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
+ Kinds.kindName(sym),
+ sym.location(site, types),
+ sym.asMemberOf(site, types),
+ _entry.getValue());
+ details = details.prepend(detailDiag);
+ }
+ //typically members are visited in reverse order (see Scope)
+ //so we need to reverse the candidate list so that candidates
+ //conform to source order
+ return details;
}
- return List.from(details.values());
- }
}
/**
@@ -3624,6 +3692,105 @@ public class Resolve {
}
}
+ /**
+ * Helper class for method resolution diagnostic simplification.
+ * Certain resolution diagnostic are rewritten as simpler diagnostic
+ * where the enclosing resolution diagnostic (i.e. 'inapplicable method')
+ * is stripped away, as it doesn't carry additional info. The logic
+ * for matching a given diagnostic is given in terms of a template
+ * hierarchy: a diagnostic template can be specified programmatically,
+ * so that only certain diagnostics are matched. Each templete is then
+ * associated with a rewriter object that carries out the task of rewtiting
+ * the diagnostic to a simpler one.
+ */
+ static class MethodResolutionDiagHelper {
+
+ /**
+ * A diagnostic rewriter transforms a method resolution diagnostic
+ * into a simpler one
+ */
+ interface DiagnosticRewriter {
+ JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
+ DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
+ DiagnosticType preferredKind, JCDiagnostic d);
+ }
+
+ /**
+ * A diagnostic template is made up of two ingredients: (i) a regular
+ * expression for matching a diagnostic key and (ii) a list of sub-templates
+ * for matching diagnostic arguments.
+ */
+ static class Template {
+
+ /** regex used to match diag key */
+ String regex;
+
+ /** templates used to match diagnostic args */
+ Template[] subTemplates;
+
+ Template(String key, Template... subTemplates) {
+ this.regex = key;
+ this.subTemplates = subTemplates;
+ }
+
+ /**
+ * Returns true if the regex matches the diagnostic key and if
+ * all diagnostic arguments are matches by corresponding sub-templates.
+ */
+ boolean matches(Object o) {
+ JCDiagnostic d = (JCDiagnostic)o;
+ Object[] args = d.getArgs();
+ if (!d.getCode().matches(regex) ||
+ subTemplates.length != d.getArgs().length) {
+ return false;
+ }
+ for (int i = 0; i < args.length ; i++) {
+ if (!subTemplates[i].matches(args[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ /** a dummy template that match any diagnostic argument */
+ static final Template skip = new Template("") {
+ @Override
+ boolean matches(Object d) {
+ return true;
+ }
+ };
+
+ /** rewriter map used for method resolution simplification */
+ static final Map rewriters =
+ new LinkedHashMap();
+
+ static {
+ String argMismatchRegex = MethodCheckDiag.ARG_MISMATCH.regex();
+ rewriters.put(new Template(argMismatchRegex, new Template("(.*)(bad.arg.types.in.lambda)", skip, skip)),
+ new DiagnosticRewriter() {
+ @Override
+ public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
+ DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
+ DiagnosticType preferredKind, JCDiagnostic d) {
+ return (JCDiagnostic)((JCDiagnostic)d.getArgs()[0]).getArgs()[1];
+ }
+ });
+
+ rewriters.put(new Template(argMismatchRegex, skip),
+ new DiagnosticRewriter() {
+ @Override
+ public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
+ DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
+ DiagnosticType preferredKind, JCDiagnostic d) {
+ JCDiagnostic cause = (JCDiagnostic)d.getArgs()[0];
+ return diags.create(preferredKind, preferredSource, d.getDiagnosticPosition(),
+ "prob.found.req", cause);
+ }
+ });
+ }
+ }
+
enum MethodResolutionPhase {
BASIC(false, false),
BOX(true, false),
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
index 85b1a200e9d..ca6ebbb872d 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
@@ -1518,7 +1518,7 @@ public class ClassReader implements Completer {
break;
// exception parameter
case EXCEPTION_PARAMETER:
- position.exception_index = nextByte();
+ position.exception_index = nextChar();
break;
// method receiver
case METHOD_RECEIVER:
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
index 5ce323b0e94..8c020a43343 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
@@ -632,7 +632,7 @@ public class ClassWriter extends ClassFile {
acount++;
}
acount += writeJavaAnnotations(sym.getRawAttributes());
- acount += writeTypeAnnotations(sym.getRawTypeAttributes());
+ acount += writeTypeAnnotations(sym.getRawTypeAttributes(), false);
return acount;
}
@@ -759,44 +759,30 @@ public class ClassWriter extends ClassFile {
return attrCount;
}
- int writeTypeAnnotations(List typeAnnos) {
+ int writeTypeAnnotations(List typeAnnos, boolean inCode) {
if (typeAnnos.isEmpty()) return 0;
ListBuffer visibles = ListBuffer.lb();
ListBuffer invisibles = ListBuffer.lb();
for (Attribute.TypeCompound tc : typeAnnos) {
- if (tc.position == null || tc.position.type == TargetType.UNKNOWN) {
- boolean found = false;
- // TODO: the position for the container annotation of a
- // repeating type annotation has to be set.
- // This cannot be done when the container is created, because
- // then the position is not determined yet.
- // How can we link these pieces better together?
- if (tc.values.size() == 1) {
- Pair val = tc.values.get(0);
- if (val.fst.getSimpleName().contentEquals("value") &&
- val.snd instanceof Attribute.Array) {
- Attribute.Array arr = (Attribute.Array) val.snd;
- if (arr.values.length != 0 &&
- arr.values[0] instanceof Attribute.TypeCompound) {
- TypeCompound atycomp = (Attribute.TypeCompound) arr.values[0];
- if (atycomp.position.type != TargetType.UNKNOWN) {
- tc.position = atycomp.position;
- found = true;
- }
- }
- }
- }
- if (!found) {
+ if (tc.hasUnknownPosition()) {
+ boolean fixed = tc.tryFixPosition();
+
+ // Could we fix it?
+ if (!fixed) {
// This happens for nested types like @A Outer. @B Inner.
// For method parameters we get the annotation twice! Once with
// a valid position, once unknown.
// TODO: find a cleaner solution.
- // System.err.println("ClassWriter: Position UNKNOWN in type annotation: " + tc);
+ PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
+ pw.println("ClassWriter: Position UNKNOWN in type annotation: " + tc);
continue;
}
}
+
+ if (tc.position.type.isLocal() != inCode)
+ continue;
if (!tc.position.emitToClassfile())
continue;
switch (types.getRetention(tc)) {
@@ -936,7 +922,7 @@ public class ClassWriter extends ClassFile {
break;
// exception parameter
case EXCEPTION_PARAMETER:
- databuf.appendByte(p.exception_index);
+ databuf.appendChar(p.exception_index);
break;
// method receiver
case METHOD_RECEIVER:
@@ -1241,6 +1227,9 @@ public class ClassWriter extends ClassFile {
endAttr(alenIdx);
acount++;
}
+
+ acount += writeTypeAnnotations(code.meth.getRawTypeAttributes(), true);
+
endAttrs(acountIdx, acount);
}
//where
@@ -1627,7 +1616,7 @@ public class ClassWriter extends ClassFile {
out = null;
} finally {
if (out != null) {
- // if we are propogating an exception, delete the file
+ // if we are propagating an exception, delete the file
out.close();
outFile.delete();
outFile = null;
@@ -1741,7 +1730,7 @@ public class ClassWriter extends ClassFile {
acount += writeFlagAttrs(c.flags());
acount += writeJavaAnnotations(c.getRawAttributes());
- acount += writeTypeAnnotations(c.getRawTypeAttributes());
+ acount += writeTypeAnnotations(c.getRawTypeAttributes(), false);
acount += writeEnclosingMethodAttribute(c);
acount += writeExtraClassAttributes(c);
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
index d4b8eff6bde..90fc63f9e1c 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
@@ -1010,7 +1010,16 @@ public class Code {
state.pop(((Symbol)(pool.pool[od])).erasure(types));
break;
case new_:
- state.push(uninitializedObject(((Symbol)(pool.pool[od])).erasure(types), cp-3));
+ Symbol sym;
+ if (pool.pool[od] instanceof UniqueType) {
+ // Required by change in Gen.makeRef to allow
+ // annotated types.
+ // TODO: is this needed anywhere else?
+ sym = ((UniqueType)(pool.pool[od])).type.tsym;
+ } else {
+ sym = (Symbol)(pool.pool[od]);
+ }
+ state.push(uninitializedObject(sym.erasure(types), cp-3));
break;
case sipush:
state.push(syms.intType);
@@ -1972,25 +1981,38 @@ public class Code {
if (lv == null || lv.sym == null
|| lv.sym.annotations.isTypesEmpty()
|| !lv.sym.isExceptionParameter())
- return;
-
- int exidx = findExceptionIndex(lv);
+ continue;
for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
TypeAnnotationPosition p = ta.position;
- p.exception_index = exidx;
+ // At this point p.type_index contains the catch type index.
+ // Use that index to determine the exception table index.
+ // We can afterwards discard the type_index.
+ // A TA position is shared for all type annotations in the
+ // same location; updating one is enough.
+ // Use -666 as a marker that the exception_index was already updated.
+ if (p.type_index != -666) {
+ p.exception_index = findExceptionIndex(p.type_index);
+ p.type_index = -666;
+ }
}
}
}
- private int findExceptionIndex(LocalVar lv) {
+ private int findExceptionIndex(int catchType) {
+ if (catchType == Integer.MIN_VALUE) {
+ // We didn't set the catch type index correctly.
+ // This shouldn't happen.
+ // TODO: issue error?
+ return -1;
+ }
List iter = catchInfo.toList();
int len = catchInfo.length();
for (int i = 0; i < len; ++i) {
char[] catchEntry = iter.head;
iter = iter.tail;
- char handlerpc = catchEntry[2];
- if (lv.start_pc == handlerpc + 1) {
+ char ct = catchEntry[3];
+ if (catchType == ct) {
return i;
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java
index ec11a1194da..739f49db084 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java
@@ -30,6 +30,8 @@ import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Attribute.TypeCompound;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.comp.*;
import com.sun.tools.javac.tree.*;
@@ -47,7 +49,6 @@ import static com.sun.tools.javac.jvm.ByteCodes.*;
import static com.sun.tools.javac.jvm.CRTFlags.*;
import static com.sun.tools.javac.main.Option.*;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
-import static com.sun.tools.javac.tree.JCTree.Tag.BLOCK;
/** This pass maps flat Java (i.e. without inner classes) to bytecodes.
*
@@ -308,7 +309,15 @@ public class Gen extends JCTree.Visitor {
*/
int makeRef(DiagnosticPosition pos, Type type) {
checkDimension(pos, type);
- return pool.put(type.hasTag(CLASS) ? (Object)type.tsym : (Object)type);
+ if (type.isAnnotated()) {
+ // Treat annotated types separately - we don't want
+ // to collapse all of them - at least for annotated
+ // exceptions.
+ // TODO: review this.
+ return pool.put((Object)type);
+ } else {
+ return pool.put(type.hasTag(CLASS) ? (Object)type.tsym : (Object)type);
+ }
}
/** Check if the given type is an array with too many dimensions.
@@ -456,7 +465,9 @@ public class Gen extends JCTree.Visitor {
*/
List normalizeDefs(List defs, ClassSymbol c) {
ListBuffer initCode = new ListBuffer();
+ ListBuffer initTAs = new ListBuffer();
ListBuffer clinitCode = new ListBuffer();
+ ListBuffer clinitTAs = new ListBuffer();
ListBuffer methodDefs = new ListBuffer();
// Sort definitions into three listbuffers:
// - initCode for instance initializers
@@ -486,6 +497,7 @@ public class Gen extends JCTree.Visitor {
Assignment(sym, vdef.init);
initCode.append(init);
endPosTable.replaceTree(vdef, init);
+ initTAs.addAll(getAndRemoveNonFieldTAs(sym));
} else if (sym.getConstValue() == null) {
// Initialize class (static) variables only if
// they are not compile-time constants.
@@ -493,6 +505,7 @@ public class Gen extends JCTree.Visitor {
Assignment(sym, vdef.init);
clinitCode.append(init);
endPosTable.replaceTree(vdef, init);
+ clinitTAs.addAll(getAndRemoveNonFieldTAs(sym));
} else {
checkStringConstant(vdef.init.pos(), sym.getConstValue());
}
@@ -505,8 +518,10 @@ public class Gen extends JCTree.Visitor {
// Insert any instance initializers into all constructors.
if (initCode.length() != 0) {
List inits = initCode.toList();
+ initTAs.addAll(c.annotations.getInitTypeAttributes());
+ List initTAlist = initTAs.toList();
for (JCTree t : methodDefs) {
- normalizeMethod((JCMethodDecl)t, inits);
+ normalizeMethod((JCMethodDecl)t, inits, initTAlist);
}
}
// If there are class initializers, create a method
@@ -524,11 +539,31 @@ public class Gen extends JCTree.Visitor {
JCBlock block = make.at(clinitStats.head.pos()).Block(0, clinitStats);
block.endpos = TreeInfo.endPos(clinitStats.last());
methodDefs.append(make.MethodDef(clinit, block));
+
+ if (!clinitTAs.isEmpty())
+ clinit.annotations.appendUniqueTypes(clinitTAs.toList());
+ if (!c.annotations.getClassInitTypeAttributes().isEmpty())
+ clinit.annotations.appendUniqueTypes(c.annotations.getClassInitTypeAttributes());
}
// Return all method definitions.
return methodDefs.toList();
}
+ private List getAndRemoveNonFieldTAs(VarSymbol sym) {
+ List tas = sym.getRawTypeAttributes();
+ ListBuffer fieldTAs = new ListBuffer();
+ ListBuffer nonfieldTAs = new ListBuffer();
+ for (TypeCompound ta : tas) {
+ if (ta.position.type == TargetType.FIELD) {
+ fieldTAs.add(ta);
+ } else {
+ nonfieldTAs.add(ta);
+ }
+ }
+ sym.annotations.setTypeAttributes(fieldTAs.toList());
+ return nonfieldTAs.toList();
+ }
+
/** Check a constant value and report if it is a string that is
* too large.
*/
@@ -546,8 +581,9 @@ public class Gen extends JCTree.Visitor {
* @param md The tree potentially representing a
* constructor's definition.
* @param initCode The list of instance initializer statements.
+ * @param initTAs Type annotations from the initializer expression.
*/
- void normalizeMethod(JCMethodDecl md, List initCode) {
+ void normalizeMethod(JCMethodDecl md, List initCode, List initTAs) {
if (md.name == names.init && TreeInfo.isInitialConstructor(md)) {
// We are seeing a constructor that does not call another
// constructor of the same class.
@@ -581,6 +617,8 @@ public class Gen extends JCTree.Visitor {
md.body.stats = newstats.toList();
if (md.body.endpos == Position.NOPOS)
md.body.endpos = TreeInfo.endPos(md.body.stats.last());
+
+ md.sym.annotations.appendUniqueTypes(initTAs);
}
}
@@ -1527,6 +1565,11 @@ public class Gen extends JCTree.Visitor {
registerCatch(tree.pos(),
startpc, end, code.curPc(),
catchType);
+ if (subCatch.type.isAnnotated()) {
+ // All compounds share the same position, simply update the
+ // first one.
+ subCatch.type.getAnnotationMirrors().head.position.type_index = catchType;
+ }
}
gaps = gaps.tail;
startpc = gaps.head.intValue();
@@ -1538,6 +1581,11 @@ public class Gen extends JCTree.Visitor {
registerCatch(tree.pos(),
startpc, endpc, code.curPc(),
catchType);
+ if (subCatch.type.isAnnotated()) {
+ // All compounds share the same position, simply update the
+ // first one.
+ subCatch.type.getAnnotationMirrors().head.position.type_index = catchType;
+ }
}
}
VarSymbol exparam = tree.param.sym;
@@ -1783,42 +1831,44 @@ public class Gen extends JCTree.Visitor {
result = items.makeStackItem(pt);
}
- private void setTypeAnnotationPositions(int treePos) {
- MethodSymbol meth = code.meth;
+ private void setTypeAnnotationPositions(int treePos) {
+ MethodSymbol meth = code.meth;
+ boolean initOrClinit = code.meth.getKind() == javax.lang.model.element.ElementKind.CONSTRUCTOR
+ || code.meth.getKind() == javax.lang.model.element.ElementKind.STATIC_INIT;
- for (Attribute.TypeCompound ta : meth.getRawTypeAttributes()) {
- if (ta.position.pos == treePos) {
- ta.position.offset = code.cp;
- ta.position.lvarOffset = new int[] { code.cp };
- ta.position.isValidOffset = true;
- }
- }
+ for (Attribute.TypeCompound ta : meth.getRawTypeAttributes()) {
+ if (ta.hasUnknownPosition())
+ ta.tryFixPosition();
- if (code.meth.getKind() != javax.lang.model.element.ElementKind.CONSTRUCTOR
- && code.meth.getKind() != javax.lang.model.element.ElementKind.STATIC_INIT)
- return;
+ if (ta.position.matchesPos(treePos))
+ ta.position.updatePosOffset(code.cp);
+ }
- for (Attribute.TypeCompound ta : meth.owner.getRawTypeAttributes()) {
- if (ta.position.pos == treePos) {
- ta.position.offset = code.cp;
- ta.position.lvarOffset = new int[] { code.cp };
- ta.position.isValidOffset = true;
- }
- }
+ if (!initOrClinit)
+ return;
- ClassSymbol clazz = meth.enclClass();
- for (Symbol s : new com.sun.tools.javac.model.FilteredMemberList(clazz.members())) {
- if (!s.getKind().isField())
- continue;
- for (Attribute.TypeCompound ta : s.getRawTypeAttributes()) {
- if (ta.position.pos == treePos) {
- ta.position.offset = code.cp;
- ta.position.lvarOffset = new int[] { code.cp };
- ta.position.isValidOffset = true;
- }
- }
- }
- }
+ for (Attribute.TypeCompound ta : meth.owner.getRawTypeAttributes()) {
+ if (ta.hasUnknownPosition())
+ ta.tryFixPosition();
+
+ if (ta.position.matchesPos(treePos))
+ ta.position.updatePosOffset(code.cp);
+ }
+
+ ClassSymbol clazz = meth.enclClass();
+ for (Symbol s : new com.sun.tools.javac.model.FilteredMemberList(clazz.members())) {
+ if (!s.getKind().isField())
+ continue;
+
+ for (Attribute.TypeCompound ta : s.getRawTypeAttributes()) {
+ if (ta.hasUnknownPosition())
+ ta.tryFixPosition();
+
+ if (ta.position.matchesPos(treePos))
+ ta.position.updatePosOffset(code.cp);
+ }
+ }
+ }
public void visitNewClass(JCNewClass tree) {
// Enclosing instances or anonymous classes should have been eliminated
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java
index 139ba519a9f..bd8e340b974 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java
@@ -157,13 +157,6 @@ public class JNIWriter {
if (c.isLocal() || (c.flags() & Flags.SYNTHETIC) != 0)
return false;
- /* temporary code for backwards compatibility */
- for (Attribute.Compound a: c.annotations.getDeclarationAttributes()) {
- if (a.type.tsym == syms.nativeHeaderType_old.tsym)
- return true;
- }
- /* end of temporary code for backwards compatibility */
-
for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) {
if (i.sym.kind == Kinds.MTH && (i.sym.flags() & Flags.NATIVE) != 0)
return true;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
index f186a81785e..291a3414205 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
@@ -25,7 +25,6 @@
package com.sun.tools.javac.main;
-import com.sun.tools.javac.comp.CompileStates;
import java.io.*;
import java.util.HashMap;
import java.util.HashSet;
@@ -55,6 +54,7 @@ import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.comp.*;
+import com.sun.tools.javac.comp.CompileStates.CompileState;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.parser.*;
@@ -62,7 +62,6 @@ import com.sun.tools.javac.processing.*;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.comp.CompileStates.CompileState;
import com.sun.tools.javac.util.Log.WriterKind;
import static com.sun.tools.javac.code.TypeTag.CLASS;
@@ -484,7 +483,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
*/
protected boolean werror;
- /** Switch: is annotation processing requested explitly via
+ /** Switch: is annotation processing requested explicitly via
* CompilationTask.setProcessors?
*/
protected boolean explicitAnnotationProcessingRequested = false;
@@ -1615,6 +1614,9 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
log.warning("proc.use.proc.or.implicit");
}
chk.reportDeferredDiagnostics();
+ if (log.compressedOutput) {
+ log.mandatoryNote(null, "compressed.diags");
+ }
}
/** Close the compiler, flushing the logs
@@ -1666,6 +1668,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
throw new FatalError(msg, e);
}
}
+ closeables = List.nil();
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java
index 9c74095412a..44a6cd57dd5 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java
@@ -35,7 +35,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
-import java.util.ServiceLoader;
import java.util.Set;
import javax.annotation.processing.Processor;
@@ -56,6 +55,7 @@ import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.Log.PrefixKind;
import com.sun.tools.javac.util.Log.WriterKind;
+import com.sun.tools.javac.util.ServiceLoader;
import static com.sun.tools.javac.main.Option.*;
/** This class provides a command line interface to the javac compiler.
@@ -469,7 +469,6 @@ public class Main {
pluginMessage(ex);
return Result.SYSERR;
}
-
}
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/Option.java b/langtools/src/share/classes/com/sun/tools/javac/main/Option.java
index b6bfa33ae08..dd3bbe80c6b 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Option.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Option.java
@@ -407,6 +407,8 @@ public enum Option {
}
},
+ XDIAGS("-Xdiags:", "opt.diags", EXTENDED, BASIC, ONEOF, "compact", "verbose"),
+
/* This is a back door to the compiler's option table.
* -XDx=y sets the option x to the value y.
* -XDx sets the option x to the value x.
diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
index 17e9d94058b..bdd79d04392 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
@@ -2013,7 +2013,7 @@ public class JavacParser implements Parser {
/** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
*/
JCExpression creator(int newpos, List typeArgs) {
- List newAnnotations = typeAnnotationsOpt();
+ List newAnnotations = annotationsOpt(Tag.ANNOTATION);
switch (token.kind) {
case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
@@ -2030,11 +2030,6 @@ public class JavacParser implements Parser {
}
JCExpression t = qualident(true);
- // handle type annotations for non primitive arrays
- if (newAnnotations.nonEmpty()) {
- t = insertAnnotationsToMostInner(t, newAnnotations, false);
- }
-
int oldmode = mode;
mode = TYPE;
boolean diamondFound = false;
@@ -2068,6 +2063,11 @@ public class JavacParser implements Parser {
}
mode = oldmode;
if (token.kind == LBRACKET || token.kind == MONKEYS_AT) {
+ // handle type annotations for non primitive arrays
+ if (newAnnotations.nonEmpty()) {
+ t = insertAnnotationsToMostInner(t, newAnnotations, false);
+ }
+
JCExpression e = arrayCreatorRest(newpos, t);
if (diamondFound) {
reportSyntaxError(lastTypeargsPos, "cannot.create.array.with.diamond");
@@ -2092,8 +2092,18 @@ public class JavacParser implements Parser {
if (newClass.def != null) {
assert newClass.def.mods.annotations.isEmpty();
if (newAnnotations.nonEmpty()) {
+ // Add type and declaration annotations to the new class;
+ // com.sun.tools.javac.code.TypeAnnotations.TypeAnnotationPositions.visitNewClass(JCNewClass)
+ // will later remove all type annotations and only leave the
+ // declaration annotations.
newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos);
- newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
+ newClass.def.mods.annotations = newAnnotations;
+ }
+ } else {
+ // handle type annotations for instantiations
+ if (newAnnotations.nonEmpty()) {
+ t = insertAnnotationsToMostInner(t, newAnnotations, false);
+ newClass.clazz = t;
}
}
return newClass;
@@ -2987,7 +2997,22 @@ public class JavacParser implements Parser {
syntaxError(pos, "expected", IDENTIFIER);
name = token.name();
} else {
- name = ident();
+ if (allowThisIdent) {
+ JCExpression pn = qualident(false);
+ if (pn.hasTag(Tag.IDENT) && ((JCIdent)pn).name != names._this) {
+ name = ((JCIdent)pn).name;
+ } else {
+ if ((mods.flags & Flags.VARARGS) != 0) {
+ log.error(token.pos, "varargs.and.receiver");
+ }
+ if (token.kind == LBRACKET) {
+ log.error(token.pos, "array.and.receiver");
+ }
+ return toP(F.at(pos).ReceiverVarDef(mods, pn, type));
+ }
+ } else {
+ name = ident();
+ }
}
if ((mods.flags & Flags.VARARGS) != 0 &&
token.kind == LBRACKET) {
@@ -3526,18 +3551,24 @@ public class JavacParser implements Parser {
ListBuffer ts = new ListBuffer();
List typeAnnos = typeAnnotationsOpt();
- if (!typeAnnos.isEmpty())
- ts.append(toP(F.at(typeAnnos.head.pos).AnnotatedType(typeAnnos, qualident(true))));
- else
- ts.append(qualident(true));
+ JCExpression qi = qualident(true);
+ if (!typeAnnos.isEmpty()) {
+ JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
+ ts.append(at);
+ } else {
+ ts.append(qi);
+ }
while (token.kind == COMMA) {
nextToken();
typeAnnos = typeAnnotationsOpt();
- if (!typeAnnos.isEmpty())
- ts.append(toP(F.at(typeAnnos.head.pos).AnnotatedType(typeAnnos, qualident(true))));
- else
- ts.append(qualident(true));
+ qi = qualident(true);
+ if (!typeAnnos.isEmpty()) {
+ JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
+ ts.append(at);
+ } else {
+ ts.append(qi);
+ }
}
return ts.toList();
}
@@ -3601,7 +3632,7 @@ public class JavacParser implements Parser {
if (token.kind != RPAREN) {
this.allowThisIdent = true;
lastParam = formalParameter(lambdaParameters);
- if (lastParam.name.contentEquals(TokenKind.THIS.name)) {
+ if (lastParam.nameexpr != null) {
this.receiverParam = lastParam;
} else {
params.append(lastParam);
diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
index 48429decbae..83b1ee23bb9 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
@@ -76,6 +76,7 @@ import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names;
import com.sun.tools.javac.util.Options;
+import com.sun.tools.javac.util.ServiceLoader;
import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
import static com.sun.tools.javac.main.Option.*;
import static com.sun.tools.javac.comp.CompileStates.CompileState;
@@ -166,6 +167,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
protected JavacProcessingEnvironment(Context context) {
this.context = context;
+ context.put(JavacProcessingEnvironment.class, this);
log = Log.instance(context);
source = Source.instance(context);
diags = JCDiagnostic.Factory.instance(context);
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
index 683e57f59cc..192780ab956 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
@@ -221,17 +221,19 @@ compiler.misc.bad.intersection.target.for.functional.expr=\
bad intersection type target for lambda or method reference\n\
{0}
-# 0: type
+# 0: symbol or type
compiler.misc.not.an.intf.component=\
component type {0} is not an interface
# 0: symbol kind, 1: message segment
compiler.err.invalid.mref=\
- invalid {0} reference; {1}
+ invalid {0} reference\n\
+ {1}
# 0: symbol kind, 1: message segment
compiler.misc.invalid.mref=\
- invalid {0} reference; {1}
+ invalid {0} reference\n\
+ {1}
compiler.misc.static.mref.with.targs=\
parameterized qualifier on static method reference
@@ -331,29 +333,29 @@ compiler.err.duplicate.annotation.member.value=\
# 0: type, 1: type
compiler.err.duplicate.annotation.missing.container=\
- duplicate annotation, the declaration of {0} does not have a valid {1} annotation
+ duplicate annotation: the declaration of {0} does not have a valid {1} annotation
# 0: type
compiler.err.invalid.repeatable.annotation=\
- duplicate annotation, {0} is annotated with an invalid Repeatable annotation
+ duplicate annotation: {0} is annotated with an invalid Repeatable annotation
-# 0: type
+# 0: symbol or type
compiler.err.invalid.repeatable.annotation.no.value=\
- duplicate annotation, {0} is not a valid Repeatable, no value element method declared
+ duplicate annotation: {0} is not a valid Repeatable, no value element method declared
# 0: type, 1: number
compiler.err.invalid.repeatable.annotation.multiple.values=\
- duplicate annotation, {0} is not a valid Repeatable, {1} value element methods declared
+ duplicate annotation: {0} is not a valid Repeatable, {1} value element methods declared
# 0: type
compiler.err.invalid.repeatable.annotation.invalid.value=\
- duplicate annotation, {0} is not a valid Repeatable, invalid value element, need a method
+ duplicate annotation: {0} is not a valid Repeatable: invalid value element
-# 0: type, 1: type, 2: type
+# 0: symbol type, 1: type, 2: type
compiler.err.invalid.repeatable.annotation.value.return=\
- duplicate annotation, value element of containing annotation {0} should have type {2}, found {1}
+ duplicate annotation: value element of containing annotation {0} should have type {2}, found {1}
-# 0: type, 1: symbol
+# 0: symbol or type, 1: symbol
compiler.err.invalid.repeatable.annotation.elem.nondefault=\
containing annotation {0} does not have a default value for element {1}
@@ -592,6 +594,12 @@ compiler.err.invalid.meth.decl.ret.type.req=\
compiler.err.varargs.and.old.array.syntax=\
legacy array notation not allowed on variable-arity parameter
+compiler.err.varargs.and.receiver =\
+ varargs notation not allowed on receiver parameter
+
+compiler.err.array.and.receiver =\
+ legacy array notation not allowed on receiver parameter
+
compiler.err.variable.not.allowed=\
variable declaration not allowed here
@@ -659,6 +667,7 @@ compiler.err.missing.meth.body.or.decl.abstract=\
compiler.err.missing.ret.stmt=\
missing return statement
+# 0: unused
compiler.misc.missing.ret.val=\
missing return value
@@ -707,7 +716,8 @@ compiler.err.neither.conditional.subtype=\
# 0: message segment
compiler.misc.incompatible.type.in.conditional=\
- bad type in conditional expression; {0}
+ bad type in conditional expression\n\
+ {0}
compiler.misc.conditional.target.cant.be.void=\
target-type for conditional expression cannot be void
@@ -736,7 +746,7 @@ compiler.misc.incompatible.arg.types.in.lambda=\
compiler.misc.incompatible.arg.types.in.mref=\
incompatible parameter types in method reference
-# 0: list of type
+# 0: list of type, 1: message segment
compiler.misc.bad.arg.types.in.lambda=\
cannot type-check lambda expression with inferred parameter types\n\
inferred types: {0}
@@ -983,7 +993,7 @@ compiler.err.illegal.default.super.call=\
compiler.misc.overridden.default=\
method {0} is overridden in {1}
-# 0: symbol, 1: symbol
+# 0: symbol, 1: type or symbol
compiler.misc.redundant.supertype=\
redundant interface {0} is extended by {1}
@@ -1147,6 +1157,9 @@ compiler.misc.x.print.rounds=\
## The following string will appear before all messages keyed as:
## "compiler.note".
+compiler.note.compressed.diags=\
+ Some messages have been simplified; recompile with -Xdiags:verbose to get full output
+
compiler.note.potential.lambda.found=\
This anonymous inner class creation can be turned into a lambda expression.
@@ -1735,6 +1748,10 @@ compiler.err.not.within.bounds=\
compiler.err.prob.found.req=\
incompatible types: {0}
+# 0: message segment
+compiler.misc.prob.found.req=\
+ incompatible types: {0}
+
# 0: message segment, 1: type, 2: type
compiler.warn.prob.found.req=\
{0}\n\
@@ -1896,11 +1913,10 @@ compiler.misc.varargs.argument.mismatch=\
#####
-# 0: type, 1: file name
+# 0: symbol or type, 1: file name
compiler.warn.auxiliary.class.accessed.from.outside.of.its.source.file=\
auxiliary class {0} in {1} should not be accessed from outside its own source file
-
## The first argument ({0}) is a "kindname".
# 0: symbol kind, 1: symbol, 2: symbol
compiler.err.abstract.cant.be.accessed.directly=\
@@ -2185,15 +2201,42 @@ compiler.err.assert.as.identifier=\
compiler.err.this.as.identifier=\
as of release 8, ''this'' is allowed as the parameter name for the receiver type only, which has to be the first parameter
+# 0: symbol
+compiler.err.receiver.parameter.not.applicable.constructor.toplevel.class=\
+ receiver parameter not applicable for constructor of top-level class
+
# TODO 308: make a better error message
compiler.err.cant.annotate.static.class=\
enclosing static nested class cannot be annotated
+
# TODO 308: make a better error message
+# 0: unused
compiler.err.cant.annotate.nested.type=\
nested type cannot be annotated
+# 0: type, 1: type
+compiler.err.incorrect.receiver.name=\
+ the receiver name does not match the enclosing class type\n\
+ required: {0}\n\
+ found: {1}
+
+# 0: type, 1: type
compiler.err.incorrect.receiver.type=\
- the receiver type does not match the enclosing class type
+ the receiver type does not match the enclosing class type\n\
+ required: {0}\n\
+ found: {1}
+
+# 0: type, 1: type
+compiler.err.incorrect.constructor.receiver.type=\
+ the receiver type does not match the enclosing outer class type\n\
+ required: {0}\n\
+ found: {1}
+
+# 0: type, 1: type
+compiler.err.incorrect.constructor.receiver.name=\
+ the receiver name does not match the enclosing outer class type\n\
+ required: {0}\n\
+ found: {1}
compiler.err.no.annotations.on.dot.class=\
no annotations are allowed in the type of a class literal
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties
index 490a9276cee..caf67462a82 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties
@@ -168,6 +168,8 @@ javac.opt.prefer=\
Specify which file to read when both a source file and class file are found for an implicitly compiled class
javac.opt.AT=\
Read options and filenames from file
+javac.opt.diags=\
+ Select a diagnostic mode
## errors
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java
index 28e3b889fe0..1ab8051279b 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java
@@ -42,7 +42,6 @@ import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
-import static com.sun.tools.javac.code.BoundKind.*;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
/**
@@ -807,12 +806,15 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
public JCModifiers mods;
/** variable name */
public Name name;
+ /** variable name expression */
+ public JCExpression nameexpr;
/** type of the variable */
public JCExpression vartype;
/** variable's initial value */
public JCExpression init;
/** symbol */
public VarSymbol sym;
+
protected JCVariableDecl(JCModifiers mods,
Name name,
JCExpression vartype,
@@ -824,12 +826,27 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
this.init = init;
this.sym = sym;
}
+
+ protected JCVariableDecl(JCModifiers mods,
+ JCExpression nameexpr,
+ JCExpression vartype) {
+ this(mods, null, vartype, null, null);
+ this.nameexpr = nameexpr;
+ if (nameexpr.hasTag(Tag.IDENT)) {
+ this.name = ((JCIdent)nameexpr).name;
+ } else {
+ // Only other option is qualified name x.y.this;
+ this.name = ((JCFieldAccess)nameexpr).name;
+ }
+ }
+
@Override
public void accept(Visitor v) { v.visitVarDef(this); }
public Kind getKind() { return Kind.VARIABLE; }
public JCModifiers getModifiers() { return mods; }
public Name getName() { return name; }
+ public JCExpression getNameExpression() { return nameexpr; }
public JCTree getType() { return vartype; }
public JCExpression getInitializer() {
return init;
@@ -845,7 +862,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
}
}
- /**
+ /**
* A no-op statement ";".
*/
public static class JCSkip extends JCStatement implements EmptyStatementTree {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java
index 3e6c149fbbc..7a2f93368c1 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java
@@ -261,8 +261,6 @@ public class Pretty extends JCTree.Visitor {
}
public void printTypeAnnotations(List trees) throws IOException {
- if (trees.nonEmpty())
- print(" ");
for (List l = trees; l.nonEmpty(); l = l.tail) {
printExpr(l.head);
print(" ");
@@ -564,8 +562,10 @@ public class Pretty extends JCTree.Visitor {
vartype = ((JCAnnotatedType)vartype).underlyingType;
}
printExpr(((JCArrayTypeTree) vartype).elemtype);
- if (tas != null)
+ if (tas != null) {
+ print(' ');
printTypeAnnotations(tas);
+ }
print("... " + tree.name);
} else {
printExpr(tree.vartype);
@@ -918,6 +918,9 @@ public class Pretty extends JCTree.Visitor {
printExprs(tree.typeargs);
print(">");
}
+ if (tree.def != null && tree.def.mods.annotations.nonEmpty()) {
+ printTypeAnnotations(tree.def.mods.annotations);
+ }
printExpr(tree.clazz);
print("(");
printExprs(tree.args);
@@ -948,7 +951,8 @@ public class Pretty extends JCTree.Visitor {
int i = 0;
List> da = tree.dimAnnotations;
for (List l = tree.dims; l.nonEmpty(); l = l.tail) {
- if (da.size() > i) {
+ if (da.size() > i && !da.get(i).isEmpty()) {
+ print(' ');
printTypeAnnotations(da.get(i));
}
print("[");
@@ -958,6 +962,7 @@ public class Pretty extends JCTree.Visitor {
}
if (tree.elems != null) {
if (isElemAnnoType) {
+ print(' ');
printTypeAnnotations(((JCAnnotatedType)tree.elemtype).annotations);
}
print("[]");
@@ -1264,6 +1269,7 @@ public class Pretty extends JCTree.Visitor {
JCAnnotatedType atype = (JCAnnotatedType) elem;
elem = atype.underlyingType;
if (!elem.hasTag(TYPEARRAY)) break;
+ print(' ');
printTypeAnnotations(atype.annotations);
}
print("[]");
@@ -1301,6 +1307,9 @@ public class Pretty extends JCTree.Visitor {
public void visitTypeParameter(JCTypeParameter tree) {
try {
+ if (tree.annotations.nonEmpty()) {
+ this.printTypeAnnotations(tree.annotations);
+ }
print(tree.name);
if (tree.bounds.nonEmpty()) {
print(" extends ");
@@ -1379,6 +1388,7 @@ public class Pretty extends JCTree.Visitor {
} else if (tree.underlyingType.getKind() == JCTree.Kind.ARRAY_TYPE) {
JCArrayTypeTree array = (JCArrayTypeTree) tree.underlyingType;
printBaseElementType(tree);
+ print(' ');
printTypeAnnotations(tree.annotations);
print("[]");
JCExpression elem = array.elemtype;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java
index 49f988d8b6d..a06fa349156 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java
@@ -422,8 +422,13 @@ public class TreeCopier implements TreeVisitor {
JCVariableDecl t = (JCVariableDecl) node;
JCModifiers mods = copy(t.mods, p);
JCExpression vartype = copy(t.vartype, p);
- JCExpression init = copy(t.init, p);
- return M.at(t.pos).VarDef(mods, t.name, vartype, init);
+ if (t.nameexpr == null) {
+ JCExpression init = copy(t.init, p);
+ return M.at(t.pos).VarDef(mods, t.name, vartype, init);
+ } else {
+ JCExpression nameexpr = copy(t.nameexpr, p);
+ return M.at(t.pos).ReceiverVarDef(mods, nameexpr, vartype);
+ }
}
public JCTree visitWhileLoop(WhileLoopTree node, P p) {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
index d5a575264af..f6a4da42c32 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
@@ -763,14 +763,40 @@ public class TreeInfo {
}
public static Symbol symbolFor(JCTree node) {
+ Symbol sym = symbolForImpl(node);
+
+ return sym != null ? sym.baseSymbol() : null;
+ }
+
+ private static Symbol symbolForImpl(JCTree node) {
node = skipParens(node);
switch (node.getTag()) {
+ case TOPLEVEL:
+ return ((JCCompilationUnit) node).packge;
case CLASSDEF:
return ((JCClassDecl) node).sym;
case METHODDEF:
return ((JCMethodDecl) node).sym;
case VARDEF:
return ((JCVariableDecl) node).sym;
+ case IDENT:
+ return ((JCIdent) node).sym;
+ case SELECT:
+ return ((JCFieldAccess) node).sym;
+ case REFERENCE:
+ return ((JCMemberReference) node).sym;
+ case NEWCLASS:
+ return ((JCNewClass) node).constructor;
+ case APPLY:
+ return symbolFor(((JCMethodInvocation) node).meth);
+ case TYPEAPPLY:
+ return symbolFor(((JCTypeApply) node).clazz);
+ case ANNOTATION:
+ case TYPE_ANNOTATION:
+ case TYPEPARAMETER:
+ if (node.type != null)
+ return node.type.tsym;
+ return null;
default:
return null;
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
index cc6405e22d9..c2757c7d05d 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
@@ -204,6 +204,12 @@ public class TreeMaker implements JCTree.Factory {
return tree;
}
+ public JCVariableDecl ReceiverVarDef(JCModifiers mods, JCExpression name, JCExpression vartype) {
+ JCVariableDecl tree = new JCVariableDecl(mods, name, vartype);
+ tree.pos = pos;
+ return tree;
+ }
+
public JCSkip Skip() {
JCSkip tree = new JCSkip();
tree.pos = pos;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java
index 57724d34292..626f70ac5b3 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java
@@ -94,6 +94,7 @@ public class TreeScanner extends Visitor {
public void visitVarDef(JCVariableDecl tree) {
scan(tree.mods);
scan(tree.vartype);
+ scan(tree.nameexpr);
scan(tree.init);
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java
index 42e97deee11..b290ac8902b 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java
@@ -148,6 +148,7 @@ public class TreeTranslator extends JCTree.Visitor {
public void visitVarDef(JCVariableDecl tree) {
tree.mods = translate(tree.mods);
+ tree.nameexpr = translate(tree.nameexpr);
tree.vartype = translate(tree.vartype);
tree.init = translate(tree.init);
result = tree;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java b/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java
index b1e7700e83c..f49331795fd 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java
@@ -349,6 +349,7 @@ public class JCDiagnostic implements Diagnostic {
SYNTAX,
RECOVERABLE,
NON_DEFERRABLE,
+ COMPRESSED
}
private final DiagnosticType type;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/List.java b/langtools/src/share/classes/com/sun/tools/javac/util/List.java
index 30b00fa0b67..611798d9caa 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/List.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/List.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@ import java.util.NoSuchElementException;
/** A class for generic linked lists. Links are supposed to be
* immutable, the only exception being the incremental construction of
* lists via ListBuffers. List is the main container class in
- * GJC. Most data structures and algorthms in GJC use lists rather
+ * GJC. Most data structures and algorithms in GJC use lists rather
* than arrays.
*
* Lists are always trailed by a sentinel element, whose head and tail
@@ -154,11 +154,11 @@ public class List extends AbstractCollection implements java.util.List
}
public static List from(Iterable extends A> coll) {
- List xs = nil();
+ ListBuffer xs = ListBuffer.lb();
for (A a : coll) {
- xs = new List(a, xs);
+ xs.append(a);
}
- return xs;
+ return xs.toList();
}
/** Construct a list consisting of a given number of identical elements.
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java
index c2f42fe5a28..5ed6d784103 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java
@@ -213,6 +213,11 @@ public class Log extends AbstractLog {
*/
public Set expectDiagKeys;
+ /**
+ * Set to true if a compressed diagnostic is reported
+ */
+ public boolean compressedOutput;
+
/**
* JavacMessages object used for localization.
*/
@@ -597,6 +602,9 @@ public class Log extends AbstractLog {
}
break;
}
+ if (diagnostic.isFlagSet(JCDiagnostic.DiagnosticFlag.COMPRESSED)) {
+ compressedOutput = true;
+ }
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/ServiceLoader.java b/langtools/src/share/classes/com/sun/tools/javac/util/ServiceLoader.java
new file mode 100644
index 00000000000..f24f1fb36fb
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/ServiceLoader.java
@@ -0,0 +1,437 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.ServiceConfigurationError;
+
+
+/**
+ * This is a temporary, modified copy of java.util.ServiceLoader, for use by
+ * javac, to work around bug JDK-8004082.
+ *
+ * The bug describes problems in the interaction between ServiceLoader and
+ * URLClassLoader, such that references to a jar file passed to URLClassLoader
+ * may be retained after calling URLClassLoader.close(), preventing the jar
+ * file from being deleted on Windows.
+ *
+ * This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.
+ */
+
+public final class ServiceLoader
+ implements Iterable
+{
+
+ private static final String PREFIX = "META-INF/services/";
+
+ // The class or interface representing the service being loaded
+ private Class service;
+
+ // The class loader used to locate, load, and instantiate providers
+ private ClassLoader loader;
+
+ // Cached providers, in instantiation order
+ private LinkedHashMap providers = new LinkedHashMap<>();
+
+ // The current lazy-lookup iterator
+ private LazyIterator lookupIterator;
+
+ /**
+ * Clear this loader's provider cache so that all providers will be
+ * reloaded.
+ *
+ * After invoking this method, subsequent invocations of the {@link
+ * #iterator() iterator} method will lazily look up and instantiate
+ * providers from scratch, just as is done by a newly-created loader.
+ *
+ *
This method is intended for use in situations in which new providers
+ * can be installed into a running Java virtual machine.
+ */
+ public void reload() {
+ providers.clear();
+ lookupIterator = new LazyIterator(service, loader);
+ }
+
+ private ServiceLoader(Class svc, ClassLoader cl) {
+ service = Objects.requireNonNull(svc, "Service interface cannot be null");
+ loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl;
+ reload();
+ }
+
+ private static void fail(Class> service, String msg, Throwable cause)
+ throws ServiceConfigurationError
+ {
+ throw new ServiceConfigurationError(service.getName() + ": " + msg,
+ cause);
+ }
+
+ private static void fail(Class> service, String msg)
+ throws ServiceConfigurationError
+ {
+ throw new ServiceConfigurationError(service.getName() + ": " + msg);
+ }
+
+ private static void fail(Class> service, URL u, int line, String msg)
+ throws ServiceConfigurationError
+ {
+ fail(service, u + ":" + line + ": " + msg);
+ }
+
+ // Parse a single line from the given configuration file, adding the name
+ // on the line to the names list.
+ //
+ private int parseLine(Class> service, URL u, BufferedReader r, int lc,
+ List names)
+ throws IOException, ServiceConfigurationError
+ {
+ String ln = r.readLine();
+ if (ln == null) {
+ return -1;
+ }
+ int ci = ln.indexOf('#');
+ if (ci >= 0) ln = ln.substring(0, ci);
+ ln = ln.trim();
+ int n = ln.length();
+ if (n != 0) {
+ if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))
+ fail(service, u, lc, "Illegal configuration-file syntax");
+ int cp = ln.codePointAt(0);
+ if (!Character.isJavaIdentifierStart(cp))
+ fail(service, u, lc, "Illegal provider-class name: " + ln);
+ for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
+ cp = ln.codePointAt(i);
+ if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))
+ fail(service, u, lc, "Illegal provider-class name: " + ln);
+ }
+ if (!providers.containsKey(ln) && !names.contains(ln))
+ names.add(ln);
+ }
+ return lc + 1;
+ }
+
+ // Parse the content of the given URL as a provider-configuration file.
+ //
+ // @param service
+ // The service type for which providers are being sought;
+ // used to construct error detail strings
+ //
+ // @param u
+ // The URL naming the configuration file to be parsed
+ //
+ // @return A (possibly empty) iterator that will yield the provider-class
+ // names in the given configuration file that are not yet members
+ // of the returned set
+ //
+ // @throws ServiceConfigurationError
+ // If an I/O error occurs while reading from the given URL, or
+ // if a configuration-file format error is detected
+ //
+ private Iterator parse(Class> service, URL u)
+ throws ServiceConfigurationError
+ {
+ InputStream in = null;
+ BufferedReader r = null;
+ ArrayList names = new ArrayList<>();
+ try {
+ // The problem is that by default, streams opened with
+ // u.openInputStream use a cached reference to a JarFile, which
+ // is separate from the reference used by URLClassLoader, and
+ // which is not closed by URLClassLoader.close().
+ // The workaround is to disable caching for this specific jar file,
+ // so that the reference to the jar file can be closed when the
+ // file has been read.
+ // Original code:
+ // in = u.openStream();
+ // Workaround ...
+ URLConnection uc = u.openConnection();
+ uc.setUseCaches(false);
+ in = uc.getInputStream();
+ // ... end of workaround.
+ r = new BufferedReader(new InputStreamReader(in, "utf-8"));
+ int lc = 1;
+ while ((lc = parseLine(service, u, r, lc, names)) >= 0);
+ } catch (IOException x) {
+ fail(service, "Error reading configuration file", x);
+ } finally {
+ try {
+ if (r != null) r.close();
+ if (in != null) in.close();
+ } catch (IOException y) {
+ fail(service, "Error closing configuration file", y);
+ }
+ }
+ return names.iterator();
+ }
+
+ // Private inner class implementing fully-lazy provider lookup
+ //
+ private class LazyIterator
+ implements Iterator
+ {
+
+ Class service;
+ ClassLoader loader;
+ Enumeration configs = null;
+ Iterator pending = null;
+ String nextName = null;
+
+ private LazyIterator(Class service, ClassLoader loader) {
+ this.service = service;
+ this.loader = loader;
+ }
+
+ public boolean hasNext() {
+ if (nextName != null) {
+ return true;
+ }
+ if (configs == null) {
+ try {
+ String fullName = PREFIX + service.getName();
+ if (loader == null)
+ configs = ClassLoader.getSystemResources(fullName);
+ else
+ configs = loader.getResources(fullName);
+ } catch (IOException x) {
+ fail(service, "Error locating configuration files", x);
+ }
+ }
+ while ((pending == null) || !pending.hasNext()) {
+ if (!configs.hasMoreElements()) {
+ return false;
+ }
+ pending = parse(service, configs.nextElement());
+ }
+ nextName = pending.next();
+ return true;
+ }
+
+ public S next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ String cn = nextName;
+ nextName = null;
+ Class> c = null;
+ try {
+ c = Class.forName(cn, false, loader);
+ } catch (ClassNotFoundException x) {
+ fail(service,
+ "Provider " + cn + " not found");
+ }
+ if (!service.isAssignableFrom(c)) {
+ fail(service,
+ "Provider " + cn + " not a subtype");
+ }
+ try {
+ S p = service.cast(c.newInstance());
+ providers.put(cn, p);
+ return p;
+ } catch (Throwable x) {
+ fail(service,
+ "Provider " + cn + " could not be instantiated: " + x,
+ x);
+ }
+ throw new Error(); // This cannot happen
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ }
+
+ /**
+ * Lazily loads the available providers of this loader's service.
+ *
+ * The iterator returned by this method first yields all of the
+ * elements of the provider cache, in instantiation order. It then lazily
+ * loads and instantiates any remaining providers, adding each one to the
+ * cache in turn.
+ *
+ *
To achieve laziness the actual work of parsing the available
+ * provider-configuration files and instantiating providers must be done by
+ * the iterator itself. Its {@link java.util.Iterator#hasNext hasNext} and
+ * {@link java.util.Iterator#next next} methods can therefore throw a
+ * {@link ServiceConfigurationError} if a provider-configuration file
+ * violates the specified format, or if it names a provider class that
+ * cannot be found and instantiated, or if the result of instantiating the
+ * class is not assignable to the service type, or if any other kind of
+ * exception or error is thrown as the next provider is located and
+ * instantiated. To write robust code it is only necessary to catch {@link
+ * ServiceConfigurationError} when using a service iterator.
+ *
+ *
If such an error is thrown then subsequent invocations of the
+ * iterator will make a best effort to locate and instantiate the next
+ * available provider, but in general such recovery cannot be guaranteed.
+ *
+ *
Design Note
+ * Throwing an error in these cases may seem extreme. The rationale for
+ * this behavior is that a malformed provider-configuration file, like a
+ * malformed class file, indicates a serious problem with the way the Java
+ * virtual machine is configured or is being used. As such it is
+ * preferable to throw an error rather than try to recover or, even worse,
+ * fail silently.
+ *
+ * The iterator returned by this method does not support removal.
+ * Invoking its {@link java.util.Iterator#remove() remove} method will
+ * cause an {@link UnsupportedOperationException} to be thrown.
+ *
+ * @return An iterator that lazily loads providers for this loader's
+ * service
+ */
+ public Iterator iterator() {
+ return new Iterator() {
+
+ Iterator> knownProviders
+ = providers.entrySet().iterator();
+
+ public boolean hasNext() {
+ if (knownProviders.hasNext())
+ return true;
+ return lookupIterator.hasNext();
+ }
+
+ public S next() {
+ if (knownProviders.hasNext())
+ return knownProviders.next().getValue();
+ return lookupIterator.next();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ };
+ }
+
+ /**
+ * Creates a new service loader for the given service type and class
+ * loader.
+ *
+ * @param service
+ * The interface or abstract class representing the service
+ *
+ * @param loader
+ * The class loader to be used to load provider-configuration files
+ * and provider classes, or null if the system class
+ * loader (or, failing that, the bootstrap class loader) is to be
+ * used
+ *
+ * @return A new service loader
+ */
+ public static ServiceLoader load(Class service,
+ ClassLoader loader)
+ {
+ return new ServiceLoader<>(service, loader);
+ }
+
+ /**
+ * Creates a new service loader for the given service type, using the
+ * current thread's {@linkplain java.lang.Thread#getContextClassLoader
+ * context class loader}.
+ *
+ * An invocation of this convenience method of the form
+ *
+ *
+ * ServiceLoader.load(service)
+ *
+ * is equivalent to
+ *
+ *
+ * ServiceLoader.load(service,
+ * Thread.currentThread().getContextClassLoader())
+ *
+ * @param service
+ * The interface or abstract class representing the service
+ *
+ * @return A new service loader
+ */
+ public static ServiceLoader load(Class service) {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ return ServiceLoader.load(service, cl);
+ }
+
+ /**
+ * Creates a new service loader for the given service type, using the
+ * extension class loader.
+ *
+ * This convenience method simply locates the extension class loader,
+ * call it extClassLoader, and then returns
+ *
+ *
+ * ServiceLoader.load(service, extClassLoader)
+ *
+ * If the extension class loader cannot be found then the system class
+ * loader is used; if there is no system class loader then the bootstrap
+ * class loader is used.
+ *
+ *
This method is intended for use when only installed providers are
+ * desired. The resulting service will only find and load providers that
+ * have been installed into the current Java virtual machine; providers on
+ * the application's class path will be ignored.
+ *
+ * @param service
+ * The interface or abstract class representing the service
+ *
+ * @return A new service loader
+ */
+ public static ServiceLoader loadInstalled(Class service) {
+ ClassLoader cl = ClassLoader.getSystemClassLoader();
+ ClassLoader prev = null;
+ while (cl != null) {
+ prev = cl;
+ cl = cl.getParent();
+ }
+ return ServiceLoader.load(service, prev);
+ }
+
+ /**
+ * Returns a string describing this service.
+ *
+ * @return A descriptive string
+ */
+ public String toString() {
+ return "java.util.ServiceLoader[" + service.getName() + "]";
+ }
+
+}
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java
index f4bfd5e4463..032b5f70912 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,9 +31,7 @@ import com.sun.source.util.TreePath;
import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Scope;
import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.Names;
/**
* Represents an annotation type.
@@ -92,7 +90,6 @@ public class AnnotationTypeDocImpl
* Elements are always public, so no need to filter them.
*/
public AnnotationTypeElementDoc[] elements() {
- Names names = tsym.name.table.names;
List elements = List.nil();
for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
if (e.sym != null && e.sym.kind == Kinds.MTH) {
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeElementDocImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeElementDocImpl.java
index ebd5f804ba5..230542958f0 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeElementDocImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeElementDocImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,6 @@ import com.sun.javadoc.*;
import com.sun.source.util.TreePath;
import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.tree.JCTree.*;
/**
* Represents an element of an annotation type.
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java
index 20ed8fdbd5d..b79a19ce8ff 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,6 @@ package com.sun.tools.javadoc;
import com.sun.javadoc.*;
import com.sun.tools.javac.code.Attribute;
-import com.sun.tools.javac.code.Symbol.*;
import static com.sun.tools.javac.code.TypeTag.BOOLEAN;
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/Comment.java b/langtools/src/share/classes/com/sun/tools/javadoc/Comment.java
index 59236f3ed6c..036ad67bde7 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/Comment.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/Comment.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
package com.sun.tools.javadoc;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import com.sun.javadoc.*;
import com.sun.tools.javac.util.ListBuffer;
@@ -296,6 +298,7 @@ class Comment {
static Tag[] getInlineTags(DocImpl holder, String inlinetext) {
ListBuffer taglist = new ListBuffer