diff --git a/.hgtags b/.hgtags
index 88b9530dfc8..3392c1b99b7 100644
--- a/.hgtags
+++ b/.hgtags
@@ -211,3 +211,4 @@ da9a4c9312816451884aa6db6f18be51a07bff13 jdk8-b86
5ebf6c63714de2c9dcf831074086d31daec819df jdk8-b87
e517701a4d0e25ae9c7945bca6e1762a8c5d8aa6 jdk8-b88
4dec41b3c5e3bb616f0c6f15830d940905aa5d16 jdk8-b89
+f09ab0c416185e3cba371e81bcb6a16060c90f44 jdk8-b90
diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index 3d22910518e..f74c0bcfaa6 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -211,3 +211,4 @@ df9b5240f0a76c91cfe1a5b39da4d08df56e05be jdk8-b86
b9415faa7066a4d3b16d466556d5428446918d95 jdk8-b87
e1a929afcfc492470d50be0b6b0e8dc77d3760b9 jdk8-b88
892a0196d10c67f3a12f0eefb0bb536e423d8868 jdk8-b89
+69b773a221b956a3386933ecdbfeccee0edeac47 jdk8-b90
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/spec.gmk.in b/common/autoconf/spec.gmk.in
index 2172ee8ef68..a7e66a31320 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!
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..20b78fa3d32 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -211,3 +211,4 @@ a45bb25a67c7517b45f00c9682e317f46fecbba9 jdk8-b83
f1709874d55a06bc3d5dfa02dbcdfbc59f4cba34 jdk8-b87
4e3a881ebb1ee96ce0872508b0066d74f310dbfa jdk8-b88
fe4150590ee597f4e125fea950aa3b352622cc2d jdk8-b89
+c8286839d0df04aba819ec4bef12b86babccf30e jdk8-b90
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index fb98d2c5ed1..f202d86f926 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -341,3 +341,5 @@ c4af77d2045476c56fbf3f914b336bb1b7cd18af hs25-b30
4ec91349972255650f97bedfd07e6423e02428cf hs25-b31
9c1fe0b419b40a9ecdd1653cc9af1b6d67a12c46 jdk8-b89
69494caf57908ba2c8efa9eaaa472b4d1875588a hs25-b32
+1ae0472ff3a0117b5b019d380ad59fface2fde14 jdk8-b90
+b19517cecc2e91636d7c16ba2f35e3d3dc628099 hs25-b33
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/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/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 d247031a67a..f668b4e5334 100644
--- a/hotspot/make/bsd/makefiles/vm.make
+++ b/hotspot/make/bsd/makefiles/vm.make
@@ -331,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 ae66a044772..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=33
+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/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/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/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/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/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/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/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/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/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index d9e9b9d032d..16d4023fb17 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -3041,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");
@@ -3066,7 +3066,7 @@ static void parseAndPrintGenericSignatures(
}
}
}
-#endif // ndef PRODUCT
+#endif // def ASSERT
instanceKlassHandle ClassFileParser::parse_super_class(int super_class_index,
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/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/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
index 0f92b3602de..6da891572c4 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;
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..58ef49e1f5b 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
@@ -1257,6 +1257,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..11dcb0beb20 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();
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 34339b25e74..d148721df17 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
@@ -707,10 +707,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);
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
index 3d4cbedd827..adf18645f8b 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
@@ -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"
@@ -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..7c6cf515c73 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp
@@ -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;
@@ -156,22 +146,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 +176,11 @@ 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
};
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)
+{ }
inline void ParMarkBitMap::clear_range(idx_t beg, idx_t end)
{
@@ -240,12 +202,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 +306,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 +386,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/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/psMarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
index adbaee43fc3..90b0d091486 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());
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..72177e10619 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
@@ -948,7 +948,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 +2041,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 +2084,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());
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
index 4bc7870b98a..f427c3941c5 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
@@ -552,19 +552,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 905869e72cf..817a1e62609 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
@@ -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;
diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
index ec724afa5ec..dc3af9aa6c0 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
@@ -113,7 +113,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 +147,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/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp
index 0ac674a324a..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 */,
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/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp
index c8a9a36df39..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);
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/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/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/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp
index a1dba8dc8bf..58957eed067 100644
--- a/hotspot/src/share/vm/prims/methodHandles.cpp
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp
@@ -1306,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
@@ -1325,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)},
@@ -1343,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.");
@@ -1362,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/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
index 19ad81502dd..b1cfb3cc362 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
@@ -2985,6 +3082,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) &&
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index 6a0e4a403fb..1131c8e103b 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, \
@@ -1429,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" \
@@ -1516,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") \
\
@@ -1834,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") \
\
@@ -1873,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, \
@@ -2017,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") \
@@ -3046,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") \
\
@@ -3074,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)") \
\
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/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
index aacc63b5e41..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*) \
diff --git a/hotspot/src/share/vm/utilities/quickSort.cpp b/hotspot/src/share/vm/utilities/quickSort.cpp
index 86c33a208a2..0cb7f6ef833 100644
--- a/hotspot/src/share/vm/utilities/quickSort.cpp
+++ b/hotspot/src/share/vm/utilities/quickSort.cpp
@@ -34,6 +34,7 @@
#include "memory/allocation.inline.hpp"
#include
+#ifdef ASSERT
static int test_comparator(int a, int b) {
if (a == b) {
return 0;
@@ -43,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;
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/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/jaxp/.hgtags b/jaxp/.hgtags
index 62e9fbe5fe0..7ba815339e0 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -211,3 +211,4 @@ ca71ec37b2efc9c3f0971ebabb3a6eb1213d76de jdk8-b86
eddbc8ad2435a89f64729512337c9f2669e4dd85 jdk8-b87
7122f7bb0fcc8a39e5254402119b2ee3fa0ad313 jdk8-b88
893d2ba8bbea3a8d090e51d8eaea285b390789ea jdk8-b89
+668acc0e1034bc1bec6d02be92e0dd4a63d0667e jdk8-b90
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..547a3a5bcd5 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, 2006, 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".
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:
+ *
+ *
+ *
+ * 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:
+ *
+ *
+ *
+ * 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:
+ *
+ *
+ *
+ * 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..b60c92ca352 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -211,3 +211,4 @@ a5e7c2f093c9996ab3419db1565094a07b059e9c jdk8-b86
72e03566f0a61282cc48ebc869803b256cccd66c jdk8-b87
24fa5452e5d4e9df8b85196283275a6ca4b4adb4 jdk8-b88
88838e08e4ef6a254867c8126070a1975683108d jdk8-b89
+3e5b9ea5ac35ea7096da484e24a863cf4552179f jdk8-b90
diff --git a/jdk/.hgtags b/jdk/.hgtags
index 303bb6739f7..7be0eb3751c 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -211,3 +211,4 @@ ac519af51769e92c51b597a730974e8607357709 jdk8-b83
d5228e624826a10ccc5b05f30ad8d839b58fe48d jdk8-b87
8dbb4b159e04de3c447c9242c70505e71f8624c7 jdk8-b88
845025546e35519fbb8970e79fc2a834063a5e19 jdk8-b89
+c63eda8f63008a4398d2c22ac8d72f7fef6f9238 jdk8-b90
diff --git a/jdk/make/com/sun/Makefile b/jdk/make/com/sun/Makefile
index 052cd541032..e33b27f8c18 100644
--- a/jdk/make/com/sun/Makefile
+++ b/jdk/make/com/sun/Makefile
@@ -31,13 +31,6 @@ BUILDDIR = ../..
PRODUCT = sun
include $(BUILDDIR)/common/Defs.gmk
-ifndef OPENJDK
- ORG_EXISTS := $(call DirExists,$(CLOSED_SRC)/share/classes/sun/org,,)
- ifneq ("$(ORG_EXISTS)", "")
- SCRIPT_SUBDIR = script
- endif
-endif
-
# jarsigner is part of JRE
SUBDIRS = java security net/ssl jarsigner
diff --git a/jdk/make/com/sun/script/Makefile b/jdk/make/com/sun/script/Makefile
deleted file mode 100644
index 58e134fad53..00000000000
--- a/jdk/make/com/sun/script/Makefile
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# Copyright (c) 2005, 2011, 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.
-#
-
-
-BUILDDIR = ../../..
-PACKAGE = com.sun.script
-PRODUCT = sun
-include $(BUILDDIR)/common/Defs.gmk
-
-AUTO_FILES_JAVA_DIRS = com/sun/script
-
-#
-# Files that need to be copied
-#
-SERVICEDIR = $(CLASSBINDIR)/META-INF/services
-
-FILES_copy = \
- $(SERVICEDIR)/javax.script.ScriptEngineFactory
-
-include $(BUILDDIR)/common/Classes.gmk
-
-all: classes copy-files
-
-#
-# Copy the service provider configuration file into the resource
-# directory.
-#
-
-copy-files: $(FILES_copy)
-
-$(SERVICEDIR)/%: $(SHARE_SRC)/classes/com/sun/script/javascript/META-INF/services/%
- $(install-file)
-
-.PHONY: copy-files
-
-
-clean::
- $(RM) -r $(CLASSDESTDIR)/com/sun/script/javascript
- $(RM) $(FILES_copy)
-
diff --git a/jdk/make/common/Release.gmk b/jdk/make/common/Release.gmk
index 2cdfc0ef6ba..ce2dda53d1d 100644
--- a/jdk/make/common/Release.gmk
+++ b/jdk/make/common/Release.gmk
@@ -969,26 +969,35 @@ else
# Create the list of db *.zip files to bundle with jdk
ABS_DB_PATH :=$(call FullPath,$(CLOSED_SHARE_SRC)/db)
-DB_ZIP_LIST = $(shell $(LS) $(ABS_DB_PATH)/*.zip 2>/dev/null)
+DB_BINARY_BUNDLE = $(shell $(LS) $(ABS_DB_PATH)/db-derby-*-bin.zip 2>/dev/null)
# Java DB image. Move the Java DB demo directory into the JDK's demo
# dir and in the process, rename it to db. Also remove index.html,
-# since it presumes docs are co-located. Also remove register.html (no
-# longer relevant).
-initial-image-jdk-db: $(DB_ZIP_LIST)
+# since it presumes docs are co-located, javadoc, docs and tests and
+# update the copyright year of the JDK READMEs to that of the release.
+initial-image-jdk-db: $(DB_BINARY_BUNDLE)
$(MKDIR) -p $(JDK_IMAGE_DIR)/db
- for d in $(DB_ZIP_LIST); do \
- ($(CD) $(JDK_IMAGE_DIR)/db && $(UNZIP) -o $$d); \
- done
- $(CP) $(ABS_DB_PATH)/README-JDK.html $(JDK_IMAGE_DIR)/db
+ $(CD) $(JDK_IMAGE_DIR)/db && $(UNZIP) -o $(DB_BINARY_BUNDLE)
+ $(CD) $(JDK_IMAGE_DIR)/db && $(MV) db-derby-*-bin/* .
+ $(CD) $(JDK_IMAGE_DIR)/db && $(RM) -r db-derby-*-bin
+ $(CAT) $(ABS_DB_PATH)/README-JDK.html | \
+ $(SED) "s/XXXX/$(shell cat $(JDK_TOPDIR)/src/closed/share/db/COPYRIGHTYEAR)/" > \
+ $(JDK_IMAGE_DIR)/db/README-JDK.html
+ $(CAT) $(ABS_DB_PATH)/3RDPARTY | \
+ $(SED) "s/XXXX/$(shell cat $(JDK_TOPDIR)/src/closed/share/db/COPYRIGHTYEAR)/" > \
+ $(JDK_IMAGE_DIR)/db/3RDPARTY
ifndef NO_DEMOS
- $(RM) -rf $(DEMODIR)/db
+ $(RM) -r $(DEMODIR)/db
$(MV) $(JDK_IMAGE_DIR)/db/demo $(DEMODIR)/db
- $(CP) $(ABS_DB_PATH)/README-JDK-DEMOS.html $(DEMODIR)/db/
+ $(CAT) $(ABS_DB_PATH)/README-JDK-DEMOS.html | \
+ $(SED) "s/XXXX/$(shell cat $(JDK_TOPDIR)/src/closed/share/db/COPYRIGHTYEAR)/" > \
+ $(DEMODIR)/db/README-JDK-DEMOS.html
else
- $(RM) -rf $(JDK_IMAGE_DIR)/db/demo
+ $(RM) -r $(JDK_IMAGE_DIR)/db/demo
endif
- $(RM) $(JDK_IMAGE_DIR)/db/index.html $(JDK_IMAGE_DIR)/db/register.html
+ @# remove stuff from original distro we don't want
+ $(RM) $(JDK_IMAGE_DIR)/db/index.html $(JDK_IMAGE_DIR)/db/KEYS
+ $(RM) -r $(JDK_IMAGE_DIR)/db/{docs,javadoc,test}
endif
# The launcher source files we need for src.zip
diff --git a/jdk/make/sun/Makefile b/jdk/make/sun/Makefile
index 35fb554a81a..c9d6f9cc663 100644
--- a/jdk/make/sun/Makefile
+++ b/jdk/make/sun/Makefile
@@ -31,12 +31,6 @@ BUILDDIR = ..
PRODUCT = sun
include $(BUILDDIR)/common/Defs.gmk
-# Rhino/Mozilla java sources
-ORG_EXISTS := $(call DirExists,$(CLOSED_SRC)/share/classes/sun/org,,)
-ifneq ("$(ORG_EXISTS)", "")
- ORG_SUBDIR = org
-endif
-
# Non windows subdirs
ifneq ($(PLATFORM), windows)
ifndef OPENJDK
@@ -83,7 +77,7 @@ SUBDIRS_desktop = audio $(RENDER_SUBDIR) image \
$(LWAWT_PRE_SUBDIR) $(DISPLAY_LIBS) $(DGA_SUBDIR) $(LWAWT_SUBDIR) \
jawt font jpeg cmm $(DISPLAY_TOOLS)
SUBDIRS_management = management
-SUBDIRS_misc = $(ORG_SUBDIR) rmi tracing
+SUBDIRS_misc = rmi tracing
SUBDIRS_tools = native2ascii serialver tools jconsole
ifndef OPENJDK
diff --git a/jdk/make/sun/awt/mapfile-vers b/jdk/make/sun/awt/mapfile-vers
index 5c6cfea808b..f68ef5cfb9d 100644
--- a/jdk/make/sun/awt/mapfile-vers
+++ b/jdk/make/sun/awt/mapfile-vers
@@ -87,6 +87,7 @@ SUNWprivate_1.1 {
Java_sun_java2d_pipe_ShapeSpanIterator_skipDownTo;
Java_java_awt_Dimension_initIDs;
+ Java_java_awt_Choice_initIDs;
Java_java_awt_event_MouseEvent_initIDs;
Java_java_awt_image_DataBufferInt_initIDs;
Java_java_awt_image_SinglePixelPackedSampleModel_initIDs;
diff --git a/jdk/make/sun/awt/mapfile-vers-bsd b/jdk/make/sun/awt/mapfile-vers-bsd
index f606b3fbbb0..dcc59f09e0e 100644
--- a/jdk/make/sun/awt/mapfile-vers-bsd
+++ b/jdk/make/sun/awt/mapfile-vers-bsd
@@ -87,6 +87,7 @@ SUNWprivate_1.1 {
Java_sun_java2d_pipe_ShapeSpanIterator_skipDownTo;
Java_java_awt_Dimension_initIDs;
+ Java_java_awt_Choice_initIDs;
Java_java_awt_event_MouseEvent_initIDs;
Java_java_awt_image_DataBufferInt_initIDs;
Java_java_awt_image_SinglePixelPackedSampleModel_initIDs;
diff --git a/jdk/make/sun/awt/mapfile-vers-linux b/jdk/make/sun/awt/mapfile-vers-linux
index b7033b89fa8..03f0cc07e47 100644
--- a/jdk/make/sun/awt/mapfile-vers-linux
+++ b/jdk/make/sun/awt/mapfile-vers-linux
@@ -87,6 +87,7 @@ SUNWprivate_1.1 {
Java_sun_java2d_pipe_ShapeSpanIterator_skipDownTo;
Java_java_awt_Dimension_initIDs;
+ Java_java_awt_Choice_initIDs;
Java_java_awt_event_MouseEvent_initIDs;
Java_java_awt_image_DataBufferInt_initIDs;
Java_java_awt_image_SinglePixelPackedSampleModel_initIDs;
diff --git a/jdk/make/sun/javazic/tzdata/VERSION b/jdk/make/sun/javazic/tzdata/VERSION
index 85db871ccf3..8ad1064e058 100644
--- a/jdk/make/sun/javazic/tzdata/VERSION
+++ b/jdk/make/sun/javazic/tzdata/VERSION
@@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
-tzdata2012i
+tzdata2013c
diff --git a/jdk/make/sun/javazic/tzdata/africa b/jdk/make/sun/javazic/tzdata/africa
index 7db9b3d269d..2f5d3c5e3fc 100644
--- a/jdk/make/sun/javazic/tzdata/africa
+++ b/jdk/make/sun/javazic/tzdata/africa
@@ -27,9 +27,9 @@
# This data is by no means authoritative; if you think you know better,
# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
-# From Paul Eggert (2006-03-22):
+# From Paul Eggert (2013-02-21):
#
# A good source for time zone historical data outside the U.S. is
# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
@@ -48,6 +48,10 @@
# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
# I found in the UCLA library.
#
+# For data circa 1899, a common source is:
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+# .
+#
# A reliable and entertaining source about time zones is
# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
#
@@ -139,8 +143,12 @@ Zone Africa/Porto-Novo 0:10:28 - LMT 1912
1:00 - WAT
# Botswana
+# From Paul Eggert (2013-02-21):
+# Milne says they were regulated by the Cape Town Signal in 1899;
+# assume they switched to 2:00 when Cape Town did.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Africa/Gaborone 1:43:40 - LMT 1885
+ 1:30 - SAST 1903 Mar
2:00 - CAT 1943 Sep 19 2:00
2:00 1:00 CAST 1944 Mar 19 2:00
2:00 - CAT
@@ -212,6 +220,11 @@ Zone Africa/Djibouti 2:52:36 - LMT 1911 Jul
# Egypt
+# Milne says Cairo used 2:05:08.9, the local mean time of the Abbasizeh
+# observatory; round to nearest. Milne also says that the official time for
+# Egypt was mean noon at the Great Pyramid, 2:04:30.5, but apparently this
+# did not apply to Cairo, Alexandria, or Port Said.
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Egypt 1940 only - Jul 15 0:00 1:00 S
Rule Egypt 1940 only - Oct 1 0:00 0 -
@@ -352,7 +365,7 @@ Rule Egypt 2010 only - Sep 10 0:00 1:00 S
Rule Egypt 2010 only - Sep lastThu 23:00s 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Africa/Cairo 2:05:00 - LMT 1900 Oct
+Zone Africa/Cairo 2:05:09 - LMT 1900 Oct
2:00 Egypt EE%sT
# Equatorial Guinea
@@ -447,6 +460,20 @@ Zone Africa/Monrovia -0:43:08 - LMT 1882
# Libya
+# From Even Scharning (2012-11-10):
+# Libya set their time one hour back at 02:00 on Saturday November 10.
+# http://www.libyaherald.com/2012/11/04/clocks-to-go-back-an-hour-on-saturday/
+# Here is an official source [in Arabic]: http://ls.ly/fb6Yc
+#
+# Steffen Thorsen forwarded a translation (2012-11-10) in
+# http://mm.icann.org/pipermail/tz/2012-November/018451.html
+#
+# From Tim Parenti (2012-11-11):
+# Treat the 2012-11-10 change as a zone change from UTC+2 to UTC+1.
+# The DST rules planned for 2013 and onward roughly mirror those of Europe
+# (either two days before them or five days after them, so as to fall on
+# lastFri instead of lastSun).
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Libya 1951 only - Oct 14 2:00 1:00 S
Rule Libya 1952 only - Jan 1 0:00 0 -
@@ -461,17 +488,21 @@ Rule Libya 1986 only - Apr 4 0:00 1:00 S
Rule Libya 1986 only - Oct 3 0:00 0 -
Rule Libya 1987 1989 - Apr 1 0:00 1:00 S
Rule Libya 1987 1989 - Oct 1 0:00 0 -
+Rule Libya 1997 only - Apr 4 0:00 1:00 S
+Rule Libya 1997 only - Oct 4 0:00 0 -
+Rule Libya 2013 max - Mar lastFri 1:00 1:00 S
+Rule Libya 2013 max - Oct lastFri 2:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Africa/Tripoli 0:52:44 - LMT 1920
1:00 Libya CE%sT 1959
2:00 - EET 1982
1:00 Libya CE%sT 1990 May 4
-# The following entries are from Shanks & Pottenger;
+# The 1996 and 1997 entries are from Shanks & Pottenger;
# the IATA SSIM data contain some obvious errors.
2:00 - EET 1996 Sep 30
- 1:00 - CET 1997 Apr 4
- 1:00 1:00 CEST 1997 Oct 4
- 2:00 - EET
+ 1:00 Libya CE%sT 1997 Oct 4
+ 2:00 - EET 2012 Nov 10 2:00
+ 1:00 Libya CE%sT
# Madagascar
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
@@ -838,6 +869,41 @@ Zone Indian/Mayotte 3:00:56 - LMT 1911 Jul # Mamoutzou
# 3:00 am Friday, July 20, 2012 and will again be advanced by 60 minutes
# August 20, 2012 from 2:00 am.
+# From Paul Eggert (2013-03-06):
+# Morocco's daylight-saving transitions due to Ramadan seem to be
+# announced a bit in advance. On 2012-07-11 the Moroccan government
+# announced that year's Ramadan daylight-saving transitions would be
+# 2012-07-20 and 2012-08-20; see
+# .
+#
+# To estimate what the Moroccan government will do in future years,
+# transition dates for 2013 through 2021 were determined by running
+# the following program under GNU Emacs 24.3:
+#
+# (let ((islamic-year 1434))
+# (while (< islamic-year 1444)
+# (let ((a
+# (calendar-gregorian-from-absolute
+# (calendar-islamic-to-absolute (list 9 1 islamic-year))))
+# (b
+# (calendar-gregorian-from-absolute
+# (calendar-islamic-to-absolute (list 10 1 islamic-year)))))
+# (insert
+# (format
+# (concat "Rule\tMorocco\t%d\tonly\t-\t%s\t %2d\t 3:00\t0\t-\n"
+# "Rule\tMorocco\t%d\tonly\t-\t%s\t %2d\t 2:00\t1:00\tS\n")
+# (car (cdr (cdr a))) (calendar-month-name (car a) t) (car (cdr a))
+# (car (cdr (cdr b))) (calendar-month-name (car b) t) (car (cdr b)))))
+# (setq islamic-year (+ 1 islamic-year))))
+#
+# with the results hand-edited for 2020-2022, when the normal spring-forward
+# date falls during the estimated Ramadan.
+#
+# From 2023 through 2038 Ramadan is not predicted to overlap with
+# daylight saving time. Starting in 2039 there will be overlap again,
+# but 32-bit time_t values roll around in 2038 so for now do not worry
+# about dates after 2038.
+
# RULE NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Morocco 1939 only - Sep 12 0:00 1:00 S
@@ -863,10 +929,28 @@ Rule Morocco 2010 only - May 2 0:00 1:00 S
Rule Morocco 2010 only - Aug 8 0:00 0 -
Rule Morocco 2011 only - Apr 3 0:00 1:00 S
Rule Morocco 2011 only - Jul 31 0 0 -
-Rule Morocco 2012 max - Apr lastSun 2:00 1:00 S
+Rule Morocco 2012 2019 - Apr lastSun 2:00 1:00 S
Rule Morocco 2012 max - Sep lastSun 3:00 0 -
Rule Morocco 2012 only - Jul 20 3:00 0 -
Rule Morocco 2012 only - Aug 20 2:00 1:00 S
+Rule Morocco 2013 only - Jul 9 3:00 0 -
+Rule Morocco 2013 only - Aug 8 2:00 1:00 S
+Rule Morocco 2014 only - Jun 29 3:00 0 -
+Rule Morocco 2014 only - Jul 29 2:00 1:00 S
+Rule Morocco 2015 only - Jun 18 3:00 0 -
+Rule Morocco 2015 only - Jul 18 2:00 1:00 S
+Rule Morocco 2016 only - Jun 7 3:00 0 -
+Rule Morocco 2016 only - Jul 7 2:00 1:00 S
+Rule Morocco 2017 only - May 27 3:00 0 -
+Rule Morocco 2017 only - Jun 26 2:00 1:00 S
+Rule Morocco 2018 only - May 16 3:00 0 -
+Rule Morocco 2018 only - Jun 15 2:00 1:00 S
+Rule Morocco 2019 only - May 6 3:00 0 -
+Rule Morocco 2019 only - Jun 5 2:00 1:00 S
+Rule Morocco 2020 only - May 24 2:00 1:00 S
+Rule Morocco 2021 only - May 13 2:00 1:00 S
+Rule Morocco 2022 only - May 3 2:00 1:00 S
+Rule Morocco 2023 max - Apr lastSun 2:00 1:00 S
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Africa/Casablanca -0:30:20 - LMT 1913 Oct 26
diff --git a/jdk/make/sun/javazic/tzdata/antarctica b/jdk/make/sun/javazic/tzdata/antarctica
index 64b71d5c052..daa03ea830c 100644
--- a/jdk/make/sun/javazic/tzdata/antarctica
+++ b/jdk/make/sun/javazic/tzdata/antarctica
@@ -73,38 +73,8 @@ Rule ChileAQ 2009 only - Mar Sun>=9 3:00u 0 -
Rule ChileAQ 2010 only - Apr Sun>=1 3:00u 0 -
Rule ChileAQ 2011 only - May Sun>=2 3:00u 0 -
Rule ChileAQ 2011 only - Aug Sun>=16 4:00u 1:00 S
-Rule ChileAQ 2012 only - Apr Sun>=23 3:00u 0 -
-Rule ChileAQ 2012 only - Sep Sun>=2 4:00u 1:00 S
-Rule ChileAQ 2013 max - Mar Sun>=9 3:00u 0 -
-Rule ChileAQ 2013 max - Oct Sun>=9 4:00u 1:00 S
-
-# These rules are stolen from the `australasia' file.
-Rule AusAQ 1917 only - Jan 1 0:01 1:00 -
-Rule AusAQ 1917 only - Mar 25 2:00 0 -
-Rule AusAQ 1942 only - Jan 1 2:00 1:00 -
-Rule AusAQ 1942 only - Mar 29 2:00 0 -
-Rule AusAQ 1942 only - Sep 27 2:00 1:00 -
-Rule AusAQ 1943 1944 - Mar lastSun 2:00 0 -
-Rule AusAQ 1943 only - Oct 3 2:00 1:00 -
-Rule ATAQ 1967 only - Oct Sun>=1 2:00s 1:00 -
-Rule ATAQ 1968 only - Mar lastSun 2:00s 0 -
-Rule ATAQ 1968 1985 - Oct lastSun 2:00s 1:00 -
-Rule ATAQ 1969 1971 - Mar Sun>=8 2:00s 0 -
-Rule ATAQ 1972 only - Feb lastSun 2:00s 0 -
-Rule ATAQ 1973 1981 - Mar Sun>=1 2:00s 0 -
-Rule ATAQ 1982 1983 - Mar lastSun 2:00s 0 -
-Rule ATAQ 1984 1986 - Mar Sun>=1 2:00s 0 -
-Rule ATAQ 1986 only - Oct Sun>=15 2:00s 1:00 -
-Rule ATAQ 1987 1990 - Mar Sun>=15 2:00s 0 -
-Rule ATAQ 1987 only - Oct Sun>=22 2:00s 1:00 -
-Rule ATAQ 1988 1990 - Oct lastSun 2:00s 1:00 -
-Rule ATAQ 1991 1999 - Oct Sun>=1 2:00s 1:00 -
-Rule ATAQ 1991 2005 - Mar lastSun 2:00s 0 -
-Rule ATAQ 2000 only - Aug lastSun 2:00s 1:00 -
-Rule ATAQ 2001 max - Oct Sun>=1 2:00s 1:00 -
-Rule ATAQ 2006 only - Apr Sun>=1 2:00s 0 -
-Rule ATAQ 2007 only - Mar lastSun 2:00s 0 -
-Rule ATAQ 2008 max - Apr Sun>=1 2:00s 0 -
+Rule ChileAQ 2012 max - Apr Sun>=23 3:00u 0 -
+Rule ChileAQ 2012 max - Sep Sun>=2 4:00u 1:00 S
# Argentina - year-round bases
# Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
@@ -147,10 +117,7 @@ Rule ATAQ 2008 max - Apr Sun>=1 2:00s 0 -
#
# From Steffen Thorsen (2010-03-10):
-# We got these changes from the Australian Antarctic Division:
-# - Macquarie Island will stay on UTC+11 for winter and therefore not
-# switch back from daylight savings time when other parts of Australia do
-# on 4 April.
+# We got these changes from the Australian Antarctic Division: ...
#
# - Casey station reverted to its normal time of UTC+8 on 5 March 2010.
# The change to UTC+11 is being considered as a regular summer thing but
@@ -161,9 +128,6 @@ Rule ATAQ 2008 max - Apr Sun>=1 2:00s 0 -
#
# - Mawson station stays on UTC+5.
#
-# In addition to the Rule changes for Casey/Davis, it means that Macquarie
-# will no longer be like Hobart and will have to have its own Zone created.
-#
# Background:
#
# http://www.timeanddate.com/news/time/antartica-time-changes-2010.html
@@ -190,12 +154,6 @@ Zone Antarctica/Mawson 0 - zzz 1954 Feb 13
6:00 - MAWT 2009 Oct 18 2:00
# Mawson Time
5:00 - MAWT
-Zone Antarctica/Macquarie 0 - zzz 1911
- 10:00 - EST 1916 Oct 1 2:00
- 10:00 1:00 EST 1917 Feb
- 10:00 AusAQ EST 1967
- 10:00 ATAQ EST 2010 Apr 4 3:00
- 11:00 - MIST # Macquarie Island Time
# References:
#
# Casey Weather (1998-02-26)
diff --git a/jdk/make/sun/javazic/tzdata/asia b/jdk/make/sun/javazic/tzdata/asia
index 9ef3ef8df54..7818c029a60 100644
--- a/jdk/make/sun/javazic/tzdata/asia
+++ b/jdk/make/sun/javazic/tzdata/asia
@@ -27,9 +27,9 @@
# This data is by no means authoritative; if you think you know better,
# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
-# From Paul Eggert (2006-03-22):
+# From Paul Eggert (2013-02-21):
#
# A good source for time zone historical data outside the U.S. is
# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
@@ -48,6 +48,10 @@
# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
# I found in the UCLA library.
#
+# For data circa 1899, a common source is:
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+# .
+#
# A reliable and entertaining source about time zones is
# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
#
@@ -302,9 +306,12 @@ Zone Asia/Brunei 7:39:40 - LMT 1926 Mar # Bandar Seri Begawan
8:00 - BNT
# Burma / Myanmar
+
+# Milne says 6:24:40 was the meridian of the time ball observatory at Rangoon.
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Rangoon 6:24:40 - LMT 1880 # or Yangon
- 6:24:36 - RMT 1920 # Rangoon Mean Time?
+ 6:24:40 - RMT 1920 # Rangoon Mean Time?
6:30 - BURT 1942 May # Burma Time
9:00 - JST 1945 May 3
6:30 - MMT # Myanmar Time
@@ -407,7 +414,8 @@ Zone Asia/Harbin 8:26:44 - LMT 1928 # or Haerbin
8:00 PRC C%sT
# Zhongyuan Time ("Central plain Time")
# most of China
-Zone Asia/Shanghai 8:05:52 - LMT 1928
+# Milne gives 8:05:56.7; round to nearest.
+Zone Asia/Shanghai 8:05:57 - LMT 1928
8:00 Shang C%sT 1949
8:00 PRC C%sT
# Long-shu Time (probably due to Long and Shu being two names of that area)
@@ -504,6 +512,10 @@ Zone Asia/Kashgar 5:03:56 - LMT 1928 # or Kashi or Kaxgar
8:00 PRC C%sT
+# Hong Kong (Xianggang)
+
+# Milne gives 7:36:41.7; round this.
+
# From Lee Yiu Chung (2009-10-24):
# I found there are some mistakes for the...DST rule for Hong
# Kong. [According] to the DST record from Hong Kong Observatory (actually,
@@ -570,7 +582,6 @@ Zone Asia/Kashgar 5:03:56 - LMT 1928 # or Kashi or Kaxgar
# The Japanese surrender of Hong Kong was signed 1945-09-15.
# For lack of anything better, use start of those days as the transition times.
-# Hong Kong (Xianggang)
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule HK 1941 only - Apr 1 3:30 1:00 S
Rule HK 1941 only - Sep 30 3:30 0 -
@@ -592,7 +603,7 @@ Rule HK 1973 only - Dec 30 3:30 1:00 S
Rule HK 1979 only - May Sun>=8 3:30 1:00 S
Rule HK 1979 only - Oct Sun>=16 3:30 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Asia/Hong_Kong 7:36:36 - LMT 1904 Oct 30
+Zone Asia/Hong_Kong 7:36:42 - LMT 1904 Oct 30
8:00 HK HK%sT 1941 Dec 25
9:00 - JST 1945 Sep 15
8:00 HK HK%sT
@@ -669,6 +680,9 @@ Zone Asia/Macau 7:34:20 - LMT 1912
###############################################################################
# Cyprus
+#
+# Milne says the Eastern Telegraph Company used 2:14:00. Stick with LMT.
+#
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Cyprus 1975 only - Apr 13 0:00 1:00 S
Rule Cyprus 1975 only - Oct 12 0:00 0 -
@@ -1222,7 +1236,6 @@ Rule Zion 2012 only - Mar Fri>=26 2:00 1:00 D
Rule Zion 2012 only - Sep 23 2:00 0 S
# From Ephraim Silverberg (2012-10-18):
-
# Yesterday, the Interior Ministry Committee, after more than a year
# past, approved sending the proposed June 2011 changes to the Time
# Decree Law back to the Knesset for second and third (final) votes
@@ -1235,6 +1248,10 @@ Rule Zion 2012 only - Sep 23 2:00 0 S
# later (i.e. at 02:00 the first Monday after October 2).
# [Rosh Hashana holidays are factored in until 2100.]
+# From Ephraim Silverberg (2012-11-05):
+# The Knesset passed today (in second and final readings) the amendment to the
+# Time Decree Law making the changes ... law.
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Zion 2013 max - Mar Fri>=23 2:00 1:00 D
Rule Zion 2013 2026 - Oct Sun>=2 2:00 0 S
@@ -1824,8 +1841,11 @@ Zone Asia/Kathmandu 5:41:16 - LMT 1920
5:45 - NPT # Nepal Time
# Oman
+
+# Milne says 3:54:24 was the meridian of the Muscat Tidal Observatory.
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Asia/Muscat 3:54:20 - LMT 1920
+Zone Asia/Muscat 3:54:24 - LMT 1920
4:00 - GST
# Pakistan
@@ -2072,8 +2092,7 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
# occurred before our cutoff date of 1970.
# However, as we get more information, we may need to add entries
# for parts of the West Bank as they transitioned from Israel's rules
-# to Palestine's rules. If you have more info about this, please
-# send it to tz@elsie.nci.nih.gov for incorporation into future editions.
+# to Palestine's rules.
# From IINS News Service - Israel - 1998-03-23 10:38:07 Israel time,
# forwarded by Ephraim Silverberg:
@@ -2295,11 +2314,20 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
# http://www.timeanddate.com/news/time/gaza-west-bank-dst-2012.html
#
-# From Arthur David Olson (2012-03-27):
-# The timeanddate article for 2012 says that "the end date has not yet been
-# announced" and that "Last year, both...paused daylight saving time during...
-# Ramadan. It is not yet known [for] 2012."
-# For now, assume both switch back on the last Friday in September. XXX
+# From Steffen Thorsen (2013-03-26):
+# The following news sources tells that Palestine will "start daylight saving
+# time from midnight on Friday, March 29, 2013" (translated).
+# [These are in Arabic and are for Gaza and for Ramallah, respectively.]
+# http://www.samanews.com/index.php?act=Show&id=154120
+# http://safa.ps/details/news/99844/%D8%B1%D8%A7%D9%85-%D8%A7%D9%84%D9%84%D9%87-%D8%A8%D8%AF%D8%A1-%D8%A7%D9%84%D8%AA%D9%88%D9%82%D9%8A%D8%AA-%D8%A7%D9%84%D8%B5%D9%8A%D9%81%D9%8A-29-%D8%A7%D9%84%D8%AC%D8%A7%D8%B1%D9%8A.html
+
+# From Paul Eggert (2013-04-15):
+# For future dates, guess the last Thursday in March at 24:00 through
+# the first Friday on or after September 21 at 01:00. This is consistent with
+# the predictions in today's editions of the following URLs,
+# which are for Gaza and Hebron respectively:
+# http://www.timeanddate.com/worldclock/timezone.html?n=702
+# http://www.timeanddate.com/worldclock/timezone.html?n=2364
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule EgyptAsia 1957 only - May 10 0:00 1:00 S
@@ -2313,19 +2341,20 @@ Rule Palestine 1999 2005 - Apr Fri>=15 0:00 1:00 S
Rule Palestine 1999 2003 - Oct Fri>=15 0:00 0 -
Rule Palestine 2004 only - Oct 1 1:00 0 -
Rule Palestine 2005 only - Oct 4 2:00 0 -
-Rule Palestine 2006 2008 - Apr 1 0:00 1:00 S
+Rule Palestine 2006 2007 - Apr 1 0:00 1:00 S
Rule Palestine 2006 only - Sep 22 0:00 0 -
Rule Palestine 2007 only - Sep Thu>=8 2:00 0 -
-Rule Palestine 2008 only - Aug lastFri 0:00 0 -
-Rule Palestine 2009 only - Mar lastFri 0:00 1:00 S
-Rule Palestine 2009 only - Sep Fri>=1 2:00 0 -
-Rule Palestine 2010 only - Mar lastSat 0:01 1:00 S
+Rule Palestine 2008 2009 - Mar lastFri 0:00 1:00 S
+Rule Palestine 2008 only - Sep 1 0:00 0 -
+Rule Palestine 2009 only - Sep Fri>=1 1:00 0 -
+Rule Palestine 2010 only - Mar 26 0:00 1:00 S
Rule Palestine 2010 only - Aug 11 0:00 0 -
-
-# From Arthur David Olson (2011-09-20):
-# 2011 transitions per http://www.timeanddate.com as of 2011-09-20.
-# From Paul Eggert (2012-10-12):
-# 2012 transitions per http://www.timeanddate.com as of 2012-10-12.
+Rule Palestine 2011 only - Apr 1 0:01 1:00 S
+Rule Palestine 2011 only - Aug 1 0:00 0 -
+Rule Palestine 2011 only - Aug 30 0:00 1:00 S
+Rule Palestine 2011 only - Sep 30 0:00 0 -
+Rule Palestine 2012 max - Mar lastThu 24:00 1:00 S
+Rule Palestine 2012 max - Sep Fri>=21 1:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Gaza 2:17:52 - LMT 1900 Oct
@@ -2333,26 +2362,20 @@ Zone Asia/Gaza 2:17:52 - LMT 1900 Oct
2:00 EgyptAsia EE%sT 1967 Jun 5
2:00 Zion I%sT 1996
2:00 Jordan EE%sT 1999
- 2:00 Palestine EE%sT 2011 Apr 2 12:01
- 2:00 1:00 EEST 2011 Aug 1
- 2:00 - EET 2012 Mar 30
- 2:00 1:00 EEST 2012 Sep 21 1:00
- 2:00 - EET
+ 2:00 Palestine EE%sT 2008 Aug 29 0:00
+ 2:00 - EET 2008 Sep
+ 2:00 Palestine EE%sT 2010
+ 2:00 - EET 2010 Mar 27 0:01
+ 2:00 Palestine EE%sT 2011 Aug 1
+ 2:00 - EET 2012
+ 2:00 Palestine EE%sT
Zone Asia/Hebron 2:20:23 - LMT 1900 Oct
2:00 Zion EET 1948 May 15
2:00 EgyptAsia EE%sT 1967 Jun 5
2:00 Zion I%sT 1996
2:00 Jordan EE%sT 1999
- 2:00 Palestine EE%sT 2008 Aug
- 2:00 1:00 EEST 2008 Sep
- 2:00 Palestine EE%sT 2011 Apr 1 12:01
- 2:00 1:00 EEST 2011 Aug 1
- 2:00 - EET 2011 Aug 30
- 2:00 1:00 EEST 2011 Sep 30 3:00
- 2:00 - EET 2012 Mar 30
- 2:00 1:00 EEST 2012 Sep 21 1:00
- 2:00 - EET
+ 2:00 Palestine EE%sT
# Paracel Is
# no information
@@ -2421,6 +2444,13 @@ Zone Asia/Singapore 6:55:25 - LMT 1901 Jan 1
# no information
# Sri Lanka
+
+# From Paul Eggert (2013-02-21):
+# Milne says "Madras mean time use from May 1, 1898. Prior to this Colombo
+# mean time, 5h. 4m. 21.9s. F., was used." But 5:04:21.9 differs considerably
+# from Colombo's meridian 5:19:24, so for now ignore Milne and stick with
+# Shanks and Pottenger.
+
# From Paul Eggert (1996-09-03):
# "Sri Lanka advances clock by an hour to avoid blackout"
# (www.virtual-pc.com/lankaweb/news/items/240596-2.html, 1996-05-24,
@@ -2720,6 +2750,12 @@ Zone Asia/Tashkent 4:37:12 - LMT 1924 May 2
# Vietnam
+# From Paul Eggert (2013-02-21):
+# Milne gives 7:16:56 for the meridian of Saigon in 1899, as being
+# used in Lower Laos, Cambodia, and Annam. But this is quite a ways
+# from Saigon's location. For now, ignore this and stick with Shanks
+# and Pottenger.
+
# From Arthur David Olson (2008-03-18):
# The English-language name of Vietnam's most populous city is "Ho Chi Min City";
# we use Ho_Chi_Minh below to avoid a name of more than 14 characters.
@@ -2733,6 +2769,10 @@ Zone Asia/Ho_Chi_Minh 7:06:40 - LMT 1906 Jun 9
7:00 - ICT
# Yemen
+
+# Milne says 2:59:54 was the meridian of the saluting battery at Aden,
+# and that Yemen was at 1:55:56, the meridian of the Hagia Sophia.
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Asia/Aden 3:00:48 - LMT 1950
+Zone Asia/Aden 2:59:54 - LMT 1950
3:00 - AST
diff --git a/jdk/make/sun/javazic/tzdata/australasia b/jdk/make/sun/javazic/tzdata/australasia
index 7f83448f3fb..db954a81dcd 100644
--- a/jdk/make/sun/javazic/tzdata/australasia
+++ b/jdk/make/sun/javazic/tzdata/australasia
@@ -241,9 +241,26 @@ Zone Australia/Lord_Howe 10:36:20 - LMT 1895 Feb
# no times are set
#
# Macquarie
-# permanent occupation (scientific station) since 1948;
-# sealing and penguin oil station operated 1888/1917
-# like Australia/Hobart
+# Permanent occupation (scientific station) 1911-1915 and since 25 March 1948;
+# sealing and penguin oil station operated Nov 1899 to Apr 1919. See the
+# Tasmania Parks & Wildlife Service history of sealing at Macquarie Island
+#
+# .
+# Guess that it was like Australia/Hobart while inhabited before 2010.
+#
+# From Steffen Thorsen (2010-03-10):
+# We got these changes from the Australian Antarctic Division:
+# - Macquarie Island will stay on UTC+11 for winter and therefore not
+# switch back from daylight savings time when other parts of Australia do
+# on 4 April.
+Zone Antarctica/Macquarie 0 - zzz 1899 Nov
+ 10:00 - EST 1916 Oct 1 2:00
+ 10:00 1:00 EST 1917 Feb
+ 10:00 Aus EST 1919 Apr
+ 0 - zzz 1948 Mar 25
+ 10:00 Aus EST 1967
+ 10:00 AT EST 2010 Apr 4 3:00
+ 11:00 - MIST # Macquarie I Standard Time
# Christmas
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
@@ -269,6 +286,9 @@ Zone Indian/Cocos 6:27:40 - LMT 1900
6:30 - CCT # Cocos Islands Time
# Fiji
+
+# Milne gives 11:55:44 for Suva.
+
# From Alexander Krivenyshev (2009-11-10):
# According to Fiji Broadcasting Corporation, Fiji plans to re-introduce DST
# from November 29th 2009 to April 25th 2010.
@@ -362,7 +382,7 @@ Rule Fiji 2010 max - Oct Sun>=18 2:00 1:00 S
Rule Fiji 2011 only - Mar Sun>=1 3:00 0 -
Rule Fiji 2012 max - Jan Sun>=18 3:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Pacific/Fiji 11:53:40 - LMT 1915 Oct 26 # Suva
+Zone Pacific/Fiji 11:55:44 - LMT 1915 Oct 26 # Suva
12:00 Fiji FJ%sT # Fiji Time
# French Polynesia
@@ -803,9 +823,9 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901
# This data is by no means authoritative; if you think you know better,
# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
-# From Paul Eggert (2006-03-22):
+# From Paul Eggert (2013-02-21):
# A good source for time zone historical data outside the U.S. is
# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
# San Diego: ACS Publications, Inc. (2003).
@@ -823,6 +843,10 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901
# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
# I found in the UCLA library.
#
+# For data circa 1899, a common source is:
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+# .
+#
# A reliable and entertaining source about time zones is
# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
#
diff --git a/jdk/make/sun/javazic/tzdata/europe b/jdk/make/sun/javazic/tzdata/europe
index 9a0d0b9db94..268504d0983 100644
--- a/jdk/make/sun/javazic/tzdata/europe
+++ b/jdk/make/sun/javazic/tzdata/europe
@@ -27,7 +27,7 @@
# This data is by no means authoritative; if you think you know better,
# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
# From Paul Eggert (2006-03-22):
# A good source for time zone historical data outside the U.S. is
@@ -53,6 +53,12 @@
# William Willett, The Waste of Daylight, 19th edition
# (1914-03)
#
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+# . He writes:
+# "It is requested that corrections and additions to these tables
+# may be sent to Mr. John Milne, Royal Geographical Society,
+# Savile Row, London." Nowadays please email them to tz@iana.org.
+#
# Brazil's Departamento Servico da Hora (DSH),
#
# History of Summer Time
@@ -689,6 +695,8 @@ Zone Europe/Andorra 0:06:04 - LMT 1901
# Austria
+# Milne says Vienna time was 1:05:21.
+
# From Paul Eggert (2006-03-22): Shanks & Pottenger give 1918-06-16 and
# 1945-11-18, but the Austrian Federal Office of Metrology and
# Surveying (BEV) gives 1918-09-16 and for Vienna gives the "alleged"
@@ -706,7 +714,7 @@ Rule Austria 1948 only - Apr 18 2:00s 1:00 S
Rule Austria 1980 only - Apr 6 0:00 1:00 S
Rule Austria 1980 only - Sep 28 0:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Europe/Vienna 1:05:20 - LMT 1893 Apr
+Zone Europe/Vienna 1:05:21 - LMT 1893 Apr
1:00 C-Eur CE%sT 1920
1:00 Austria CE%sT 1940 Apr 1 2:00s
1:00 C-Eur CE%sT 1945 Apr 2 2:00s
@@ -1262,6 +1270,21 @@ Zone Europe/Berlin 0:53:28 - LMT 1893 Apr
1:00 Germany CE%sT 1980
1:00 EU CE%sT
+# From Tobias Conradi (2011-09-12):
+# Busingen , surrounded by the Swiss canton
+# Schaffhausen, did not start observing DST in 1980 as the rest of DE
+# (West Germany at that time) and DD (East Germany at that time) did.
+# DD merged into DE, the area is currently covered by code DE in ISO 3166-1,
+# which in turn is covered by the zone Europe/Berlin.
+#
+# Source for the time in Busingen 1980:
+# http://www.srf.ch/player/video?id=c012c029-03b7-4c2b-9164-aa5902cd58d3
+
+# From Arthur David Olson (2012-03-03):
+# Busingen and Zurich have shared clocks since 1970.
+
+Link Europe/Zurich Europe/Busingen
+
# Georgia
# Please see the "asia" file for Asia/Tbilisi.
# Herodotus (Histories, IV.45) says Georgia north of the Phasis (now Rioni)
@@ -2066,6 +2089,70 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct
# Russia
+# From Alexander Krivenyshev (2011-09-15):
+# Based on last Russian Government Decree # 725 on August 31, 2011
+# (Government document
+#
+# http://www.government.ru/gov/results/16355/print/
+#
+# in Russian)
+# there are few corrections have to be made for some Russian time zones...
+# All updated Russian Time Zones were placed in table and translated to English
+# by WorldTimeZone.com at the link below:
+#
+# http://www.worldtimezone.com/dst_news/dst_news_russia36.htm
+#
+
+# From Sanjeev Gupta (2011-09-27):
+# Scans of [Decree #23 of January 8, 1992] are available at:
+#
+# http://government.consultant.ru/page.aspx?1223966
+# They are in Cyrillic letters (presumably Russian).
+
+# From Arthur David Olson (2012-05-09):
+# Regarding the instant when clocks in time-zone-shifting parts of Russia
+# changed in September 2011:
+#
+# One source is
+# < a href="http://government.ru/gov/results/16355/>
+# http://government.ru/gov/results/16355/
+#
+# which, according to translate.google.com, begins "Decree of August 31,
+# 2011 No 725" and contains no other dates or "effective date" information.
+#
+# Another source is
+#
+# http://www.rg.ru/2011/09/06/chas-zona-dok.html
+#
+# which, according to translate.google.com, begins "Resolution of the
+# Government of the Russian Federation on August 31, 2011 N 725" and also
+# contains "Date first official publication: September 6, 2011 Posted on:
+# in the 'RG' - Federal Issue number 5573 September 6, 2011" but which
+# does not contain any "effective date" information.
+#
+# Another source is
+#
+# http://en.wikipedia.org/wiki/Oymyakonsky_District#cite_note-RuTime-7
+#
+# which, in note 8, contains "Resolution #725 of August 31, 2011...
+# Effective as of after 7 days following the day of the official publication"
+# but which does not contain any reference to September 6, 2011.
+#
+# The Wikipedia article refers to
+#
+# http://base.consultant.ru/cons/cgi/online.cgi?req=doc;base=LAW;n=118896
+#
+# which seems to copy the text of the government.ru page.
+#
+# Tobias Conradi combines Wikipedia's
+# "as of after 7 days following the day of the official publication"
+# with www.rg.ru's "Date of first official publication: September 6, 2011" to get
+# September 13, 2011 as the cutover date (unusually, a Tuesday, as Tobias Conradi notes).
+#
+# None of the sources indicates a time of day for changing clocks.
+#
+# Go with 2011-09-13 0:00s.
+
# From Paul Eggert (2006-03-22):
# Except for Moscow after 1919-07-01, I invented the time zone abbreviations.
# Moscow time zone abbreviations after 1919-07-01, and Moscow rules after 1991,
@@ -2293,14 +2380,32 @@ Zone Asia/Yakutsk 8:38:40 - LMT 1919 Dec 15
# [parts of] Respublika Sakha (Yakutiya).
# From Oscar van Vlijmen (2009-11-29):
-# The Sakha districts are: Bulunskij, Verkhoyanskij, Tomponskij, Ust'-Majskij,
-# Ust'-Yanskij.
+# The Sakha districts are: Bulunskij, Verkhoyanskij, ... Ust'-Yanskij.
Zone Asia/Vladivostok 8:47:44 - LMT 1922 Nov 15
9:00 - VLAT 1930 Jun 21 # Vladivostok Time
10:00 Russia VLA%sT 1991 Mar 31 2:00s
9:00 Russia VLA%sST 1992 Jan 19 2:00s
10:00 Russia VLA%sT 2011 Mar 27 2:00s
11:00 - VLAT
+
+# From Arthur David Olson (2012-05-09):
+# Tomponskij and Ust'-Majskij switched from Vladivostok time to Yakutsk time
+# in 2011.
+#
+# From Paul Eggert (2012-11-25):
+# Shanks and Pottenger (2003) has Khandyga on Yakutsk time.
+# Make a wild guess that it switched to Vladivostok time in 2004.
+# This transition is no doubt wrong, but we have no better info.
+#
+Zone Asia/Khandyga 9:02:13 - LMT 1919 Dec 15
+ 8:00 - YAKT 1930 Jun 21 # Yakutsk Time
+ 9:00 Russia YAK%sT 1991 Mar 31 2:00s
+ 8:00 Russia YAK%sT 1992 Jan 19 2:00s
+ 9:00 Russia YAK%sT 2004
+ 10:00 Russia VLA%sT 2011 Mar 27 2:00s
+ 11:00 - VLAT 2011 Sep 13 0:00s # Decree 725?
+ 10:00 - YAKT
+
#
# Sakhalinskaya oblast'.
# The Zone name should be Yuzhno-Sakhalinsk, but that's too long.
@@ -2319,14 +2424,26 @@ Zone Asia/Sakhalin 9:30:48 - LMT 1905 Aug 23
# From Oscar van Vlijmen (2009-11-29):
# The Sakha districts are: Abyjskij, Allaikhovskij, Verkhhhnekolymskij, Momskij,
-# Nizhnekolymskij, Ojmyakonskij, Srednekolymskij.
+# Nizhnekolymskij, ... Srednekolymskij.
Zone Asia/Magadan 10:03:12 - LMT 1924 May 2
10:00 - MAGT 1930 Jun 21 # Magadan Time
11:00 Russia MAG%sT 1991 Mar 31 2:00s
10:00 Russia MAG%sT 1992 Jan 19 2:00s
11:00 Russia MAG%sT 2011 Mar 27 2:00s
12:00 - MAGT
-#
+
+# From Arthur David Olson (2012-05-09):
+# Ojmyakonskij and the Kuril Islands switched from
+# Magadan time to Vladivostok time in 2011.
+Zone Asia/Ust-Nera 9:32:54 - LMT 1919 Dec 15
+ 8:00 - YAKT 1930 Jun 21 # Yakutsk Time
+ 9:00 Russia YAKT 1981 Apr 1
+ 11:00 Russia MAG%sT 1991 Mar 31 2:00s
+ 10:00 Russia MAG%sT 1992 Jan 19 2:00s
+ 11:00 Russia MAG%sT 2011 Mar 27 2:00s
+ 12:00 - MAGT 2011 Sep 13 0:00s # Decree 725?
+ 11:00 - VLAT
+
# From Oscar van Vlijmen (2001-08-25): [This region consists of]
# Kamchatskaya oblast', Koryakskij avtonomnyj okrug.
#
diff --git a/jdk/make/sun/javazic/tzdata/northamerica b/jdk/make/sun/javazic/tzdata/northamerica
index c3033267404..858bf811ac9 100644
--- a/jdk/make/sun/javazic/tzdata/northamerica
+++ b/jdk/make/sun/javazic/tzdata/northamerica
@@ -29,7 +29,7 @@
# This data is by no means authoritative; if you think you know better,
# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
# From Paul Eggert (1999-03-22):
# A reliable and entertaining source about time zones is
@@ -1042,6 +1042,9 @@ Zone America/Menominee -5:50:27 - LMT 1885 Sep 18 12:00
# William Willett, The Waste of Daylight, 19th edition
# (1914-03)
#
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+# .
+#
# See the `europe' file for Greenland.
# Canada
@@ -2577,6 +2580,8 @@ Zone America/Antigua -4:07:12 - LMT 1912 Mar 2
# Bahamas
#
+# For 1899 Milne gives -5:09:29.5; round that.
+#
# From Sue Williams (2006-12-07):
# The Bahamas announced about a month ago that they plan to change their DST
# rules to sync with the U.S. starting in 2007....
@@ -2586,11 +2591,14 @@ Zone America/Antigua -4:07:12 - LMT 1912 Mar 2
Rule Bahamas 1964 1975 - Oct lastSun 2:00 0 S
Rule Bahamas 1964 1975 - Apr lastSun 2:00 1:00 D
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone America/Nassau -5:09:24 - LMT 1912 Mar 2
+Zone America/Nassau -5:09:30 - LMT 1912 Mar 2
-5:00 Bahamas E%sT 1976
-5:00 US E%sT
# Barbados
+
+# For 1899 Milne gives -3:58:29.2; round that.
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Barb 1977 only - Jun 12 2:00 1:00 D
Rule Barb 1977 1978 - Oct Sun>=1 2:00 0 S
@@ -2598,8 +2606,8 @@ Rule Barb 1978 1980 - Apr Sun>=15 2:00 1:00 D
Rule Barb 1979 only - Sep 30 2:00 0 S
Rule Barb 1980 only - Sep 25 2:00 0 S
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone America/Barbados -3:58:28 - LMT 1924 # Bridgetown
- -3:58:28 - BMT 1932 # Bridgetown Mean Time
+Zone America/Barbados -3:58:29 - LMT 1924 # Bridgetown
+ -3:58:29 - BMT 1932 # Bridgetown Mean Time
-4:00 Barb A%sT
# Belize
@@ -2617,6 +2625,9 @@ Zone America/Belize -5:52:48 - LMT 1912 Apr
# Bermuda
+# For 1899 Milne gives -4:19:18.3 as the meridian of the clock tower,
+# Bermuda dockyard, Ireland I; round that.
+
# From Dan Jones, reporting in The Royal Gazette (2006-06-26):
# Next year, however, clocks in the US will go forward on the second Sunday
@@ -2626,7 +2637,7 @@ Zone America/Belize -5:52:48 - LMT 1912 Apr
# http://www.theroyalgazette.com/apps/pbcs.dll/article?AID=/20060529/NEWS/105290135
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Atlantic/Bermuda -4:19:04 - LMT 1930 Jan 1 2:00 # Hamilton
+Zone Atlantic/Bermuda -4:19:18 - LMT 1930 Jan 1 2:00 # Hamilton
-4:00 - AST 1974 Apr 28 2:00
-4:00 Bahamas A%sT 1976
-4:00 US A%sT
@@ -2638,6 +2649,9 @@ Zone America/Cayman -5:25:32 - LMT 1890 # Georgetown
-5:00 - EST
# Costa Rica
+
+# Milne gives -5:36:13.3 as San Jose mean time; round to nearest.
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule CR 1979 1980 - Feb lastSun 0:00 1:00 D
Rule CR 1979 1980 - Jun Sun>=1 0:00 0 S
@@ -2648,14 +2662,19 @@ Rule CR 1991 only - Jul 1 0:00 0 S
Rule CR 1992 only - Mar 15 0:00 0 S
# There are too many San Joses elsewhere, so we'll use `Costa Rica'.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone America/Costa_Rica -5:36:20 - LMT 1890 # San Jose
- -5:36:20 - SJMT 1921 Jan 15 # San Jose Mean Time
+Zone America/Costa_Rica -5:36:13 - LMT 1890 # San Jose
+ -5:36:13 - SJMT 1921 Jan 15 # San Jose Mean Time
-6:00 CR C%sT
# Coco
# no information; probably like America/Costa_Rica
# Cuba
+# From Paul Eggert (2013-02-21):
+# Milne gives -5:28:50.45 for the observatory at Havana, -5:29:23.57
+# for the port, and -5:30 for meteorological observations.
+# For now, stick with Shanks & Pottenger.
+
# From Arthur David Olson (1999-03-29):
# The 1999-03-28 exhibition baseball game held in Havana, Cuba, between
# the Cuban National Team and the Baltimore Orioles was carried live on
@@ -3004,24 +3023,21 @@ Zone America/Guatemala -6:02:04 - LMT 1918 Oct 5
# apparently using the same start and end date as USA/Canada.
# So this means they have already changed their time.
#
-# (Sources in French):
-#
# http://www.alterpresse.org/spip.php?article12510
-#
-#
# http://radiovision2000haiti.net/home/?p=13253
-#
#
-# Our coverage:
-#
-# http://www.timeanddate.com/news/time/haiti-dst-2012.html
-#
-
# From Arthur David Olson (2012-03-11):
# The alterpresse.org source seems to show a US-style leap from 2:00 a.m. to
# 3:00 a.m. rather than the traditional Haitian jump at midnight.
-# Assume a US-style fall back as well XXX.
-# Do not yet assume that the change carries forward past 2012 XXX.
+# Assume a US-style fall back as well.
+
+# From Steffen Thorsen (2013-03-10):
+# It appears that Haiti is observing DST this year as well, same rules
+# as US/Canada. They did it last year as well, and it looks like they
+# are going to observe DST every year now...
+#
+# http://radiovision2000haiti.net/public/haiti-avis-changement-dheure-dimanche/
+# http://www.canalplushaiti.net/?p=6714
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Haiti 1983 only - May 8 0:00 1:00 D
@@ -3033,8 +3049,8 @@ Rule Haiti 1988 1997 - Apr Sun>=1 1:00s 1:00 D
Rule Haiti 1988 1997 - Oct lastSun 1:00s 0 S
Rule Haiti 2005 2006 - Apr Sun>=1 0:00 1:00 D
Rule Haiti 2005 2006 - Oct lastSun 0:00 0 S
-Rule Haiti 2012 only - Mar Sun>=8 2:00 1:00 D
-Rule Haiti 2012 only - Nov Sun>=1 2:00 0 S
+Rule Haiti 2012 max - Mar Sun>=8 2:00 1:00 D
+Rule Haiti 2012 max - Nov Sun>=1 2:00 0 S
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone America/Port-au-Prince -4:49:20 - LMT 1890
-4:49 - PPMT 1917 Jan 24 12:00 # P-a-P MT
diff --git a/jdk/make/sun/javazic/tzdata/southamerica b/jdk/make/sun/javazic/tzdata/southamerica
index 0d6797eab6b..d1865d3f19b 100644
--- a/jdk/make/sun/javazic/tzdata/southamerica
+++ b/jdk/make/sun/javazic/tzdata/southamerica
@@ -27,13 +27,17 @@
# This data is by no means authoritative; if you think you know better,
# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
# From Paul Eggert (2006-03-22):
# A good source for time zone historical data outside the U.S. is
# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
# San Diego: ACS Publications, Inc. (2003).
#
+# For data circa 1899, a common source is:
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+# .
+#
# Gwillim Law writes that a good source
# for recent time zone data is the International Air Transport
# Association's Standard Schedules Information Manual (IATA SSIM),
@@ -404,21 +408,11 @@ Rule Arg 2008 only - Oct Sun>=15 0:00 1:00 S
#
# is the official page for the Province Government).
#
-# There's also a note in only one of the major national papers (La Nación) at
-#
+# There's also a note in only one of the major national papers ...
# http://www.lanacion.com.ar/nota.asp?nota_id=1107912
-#
#
-# The press release says:
-# (...) anunció que el próximo domingo a las 00:00 los puntanos deberán
-# atrasar una hora sus relojes.
-#
-# A partir de entonces, San Luis establecerá el huso horario propio de
-# la Provincia. De esta manera, durante el periodo del calendario anual
-# 2009, el cambio horario quedará comprendido entre las 00:00 del tercer
-# domingo de marzo y las 24:00 del segundo sábado de octubre.
-# Quick&dirty translation
-# (...) announced that next Sunday, at 00:00, Puntanos (the San Luis
+# The press release says [quick and dirty translation]:
+# ... announced that next Sunday, at 00:00, Puntanos (the San Luis
# inhabitants) will have to turn back one hour their clocks
#
# Since then, San Luis will establish its own Province timezone. Thus,
@@ -480,6 +474,9 @@ Rule Arg 2008 only - Oct Sun>=15 0:00 1:00 S
# rules...San Luis is still using "Western ARgentina Time" and it got
# stuck on Summer daylight savings time even though the summer is over.
+# From Paul Eggert (2013-02-21):
+# Milne says Cordoba time was -4:16:48.2. Round to the nearest second.
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
#
# Buenos Aires (BA), Capital Federal (CF),
@@ -835,9 +832,9 @@ Zone America/La_Paz -4:32:36 - LMT 1890
# From Guilherme Bernardes Rodrigues (2011-10-07):
# There is news in the media, however there is still no decree about it.
-# I just send a e-mail to Zulmira Brandão at
+# I just send a e-mail to Zulmira Brandao at
# http://pcdsh01.on.br/ the
-# oficial agency about time in Brazil, and she confirmed that the old rule is
+# official agency about time in Brazil, and she confirmed that the old rule is
# still in force.
# From Guilherme Bernardes Rodrigues (2011-10-14)
@@ -1266,9 +1263,13 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
# b. Saturday, September 1, 2012, clocks should go forward 60 minutes; that is,
# at 23:59:59, instead of passing to 0:00, the time should be adjusted to be
# 01:00 on September 2.
-#
-# Note that...this is yet another "temporary" change that will be reevaluated
-# AGAIN in 2013.
+
+# From Steffen Thorsen (2013-02-15):
+# According to several news sources, Chile has extended DST this year,
+# they will end DST later and start DST earlier than planned. They
+# hope to save energy. The new end date is 2013-04-28 00:00 and new
+# start date is 2013-09-08 00:00....
+# http://www.gob.cl/informa/2013/02/15/gobierno-anuncia-fechas-de-cambio-de-hora-para-el-ano-2013.htm
# NOTE: ChileAQ rules for Antarctic bases are stored separately in the
# 'antarctica' file.
@@ -1311,10 +1312,8 @@ Rule Chile 2009 only - Mar Sun>=9 3:00u 0 -
Rule Chile 2010 only - Apr Sun>=1 3:00u 0 -
Rule Chile 2011 only - May Sun>=2 3:00u 0 -
Rule Chile 2011 only - Aug Sun>=16 4:00u 1:00 S
-Rule Chile 2012 only - Apr Sun>=23 3:00u 0 -
-Rule Chile 2012 only - Sep Sun>=2 4:00u 1:00 S
-Rule Chile 2013 max - Mar Sun>=9 3:00u 0 -
-Rule Chile 2013 max - Oct Sun>=9 4:00u 1:00 S
+Rule Chile 2012 max - Apr Sun>=23 3:00u 0 -
+Rule Chile 2012 max - Sep Sun>=2 4:00u 1:00 S
# IATA SSIM anomalies: (1992-02) says 1992-03-14;
# (1996-09) says 1998-03-08. Ignore these.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
@@ -1336,17 +1335,23 @@ Zone Pacific/Easter -7:17:44 - LMT 1890
# San Felix, and Antarctic bases, are like America/Santiago.
# Colombia
+
+# Milne gives 4:56:16.4 for Bogota time in 1899; round to nearest. He writes,
+# "A variation of fifteen minutes in the public clocks of Bogota is not rare."
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule CO 1992 only - May 3 0:00 1:00 S
Rule CO 1993 only - Apr 4 0:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone America/Bogota -4:56:20 - LMT 1884 Mar 13
- -4:56:20 - BMT 1914 Nov 23 # Bogota Mean Time
+Zone America/Bogota -4:56:16 - LMT 1884 Mar 13
+ -4:56:16 - BMT 1914 Nov 23 # Bogota Mean Time
-5:00 CO CO%sT # Colombia Time
# Malpelo, Providencia, San Andres
# no information; probably like America/Bogota
# Curacao
+
+# Milne gives 4:35:46.9 for Curacao mean time; round to nearest.
#
# From Paul Eggert (2006-03-22):
# Shanks & Pottenger say that The Bottom and Philipsburg have been at
@@ -1363,7 +1368,7 @@ Zone America/Bogota -4:56:20 - LMT 1884 Mar 13
# though, as far as we know.
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone America/Curacao -4:35:44 - LMT 1912 Feb 12 # Willemstad
+Zone America/Curacao -4:35:47 - LMT 1912 Feb 12 # Willemstad
-4:30 - ANT 1965 # Netherlands Antilles Time
-4:00 - AST
@@ -1377,6 +1382,8 @@ Link America/Curacao America/Kralendijk # Bonaire, Sint Estatius and Saba
# Ecuador
#
+# Milne says the Sentral and South American Telegraph Company used -5:24:15.
+#
# From Paul Eggert (2007-03-04):
# Apparently Ecuador had a failed experiment with DST in 1992.
# (2007-02-27) and
@@ -1582,7 +1589,16 @@ Rule Para 2005 2009 - Mar Sun>=8 0:00 0 -
# forward 60 minutes, in all the territory of the Paraguayan Republic.
# ...
Rule Para 2010 max - Oct Sun>=1 0:00 1:00 S
-Rule Para 2010 max - Apr Sun>=8 0:00 0 -
+Rule Para 2010 2012 - Apr Sun>=8 0:00 0 -
+#
+# From Steffen Thorsen (2013-03-07):
+# Paraguay will end DST on 2013-03-24 00:00....
+# http://www.ande.gov.py/interna.php?id=1075
+#
+# From Carlos Raul Perasso (2013-03-15):
+# The change in Paraguay is now final. Decree number 10780
+# http://www.presidencia.gov.py/uploads/pdf/presidencia-3b86ff4b691c79d4f5927ca964922ec74772ce857c02ca054a52a37b49afc7fb.pdf
+Rule Para 2013 max - Mar Sun>=22 0:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone America/Asuncion -3:50:40 - LMT 1890
diff --git a/jdk/make/sun/javazic/tzdata/zone.tab b/jdk/make/sun/javazic/tzdata/zone.tab
index ef380cd19fb..cbcdc075bf7 100644
--- a/jdk/make/sun/javazic/tzdata/zone.tab
+++ b/jdk/make/sun/javazic/tzdata/zone.tab
@@ -65,7 +65,6 @@ AQ -6617+11031 Antarctica/Casey Casey Station, Bailey Peninsula
AQ -7824+10654 Antarctica/Vostok Vostok Station, Lake Vostok
AQ -6640+14001 Antarctica/DumontDUrville Dumont-d'Urville Station, Terre Adelie
AQ -690022+0393524 Antarctica/Syowa Syowa Station, E Ongul I
-AQ -5430+15857 Antarctica/Macquarie Macquarie Island Station, Macquarie Island
AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF)
AR -3124-06411 America/Argentina/Cordoba most locations (CB, CC, CN, ER, FM, MN, SE, SF)
AR -2447-06525 America/Argentina/Salta (SA, LP, NQ, RN)
@@ -81,6 +80,7 @@ AR -5448-06818 America/Argentina/Ushuaia Tierra del Fuego (TF)
AS -1416-17042 Pacific/Pago_Pago
AT +4813+01620 Europe/Vienna
AU -3133+15905 Australia/Lord_Howe Lord Howe Island
+AU -5430+15857 Antarctica/Macquarie Macquarie Island
AU -4253+14719 Australia/Hobart Tasmania - most locations
AU -3956+14352 Australia/Currie Tasmania - King Island
AU -3749+14458 Australia/Melbourne Victoria
@@ -182,7 +182,8 @@ CW +1211-06900 America/Curacao
CX -1025+10543 Indian/Christmas
CY +3510+03322 Asia/Nicosia
CZ +5005+01426 Europe/Prague
-DE +5230+01322 Europe/Berlin
+DE +5230+01322 Europe/Berlin most locations
+DE +4742+00841 Europe/Busingen Busingen
DJ +1136+04309 Africa/Djibouti
DK +5540+01235 Europe/Copenhagen
DM +1518-06124 America/Dominica
@@ -364,8 +365,10 @@ RU +5345+08707 Asia/Novokuznetsk Moscow+03 - Novokuznetsk
RU +5601+09250 Asia/Krasnoyarsk Moscow+04 - Yenisei River
RU +5216+10420 Asia/Irkutsk Moscow+05 - Lake Baikal
RU +6200+12940 Asia/Yakutsk Moscow+06 - Lena River
+RU +623923+1353314 Asia/Khandyga Moscow+06 - Tomponsky, Ust-Maysky
RU +4310+13156 Asia/Vladivostok Moscow+07 - Amur River
RU +4658+14242 Asia/Sakhalin Moscow+07 - Sakhalin Island
+RU +643337+1431336 Asia/Ust-Nera Moscow+07 - Oymyakonsky
RU +5934+15048 Asia/Magadan Moscow+08 - Magadan
RU +5301+15839 Asia/Kamchatka Moscow+08 - Kamchatka
RU +6445+17729 Asia/Anadyr Moscow+08 - Bering Sea
diff --git a/jdk/make/sun/nio/cs/Makefile b/jdk/make/sun/nio/cs/Makefile
index 73fe55fbd08..3b45c774fe0 100644
--- a/jdk/make/sun/nio/cs/Makefile
+++ b/jdk/make/sun/nio/cs/Makefile
@@ -87,9 +87,6 @@ build: $(FILES_genout_extcs) $(CHARSETS_JAR)
#
# Extra rules to build character converters.
-SERVICE_DESCRIPTION = java.nio.charset.spi.CharsetProvider
-SERVICE_DESCRIPTION_PATH = META-INF/services/$(SERVICE_DESCRIPTION)
-
GENCSDATASRC = $(BUILDDIR)/tools/CharsetMapping
GENCSSRCDIR = $(BUILDDIR)/tools/src/build/tools/charsetmapping
GENCSEXT = $(GENSRCDIR)/sun/nio/cs/ext
@@ -118,10 +115,6 @@ $(FILES_genout_extcs): \
$(GENCSSRCDIR)/HKSCS.java
$(BOOT_JAVA_CMD) -jar $(CHARSETMAPPING_JARFILE) $(GENCSDATASRC) $(GENCSEXT) dbcs
-$(CLASSDESTDIR)/$(SERVICE_DESCRIPTION_PATH): \
- $(SHARE_SRC)/classes/sun/nio/cs/ext/$(SERVICE_DESCRIPTION_PATH)
- $(install-file)
-
# no compression unless requested
ifndef COMPRESS_JARS
CREATE_JAR_OPTS_NOMANIFEST = cf0
@@ -129,10 +122,9 @@ else
CREATE_JAR_OPTS_NOMANIFEST = cf
endif
-$(CHARSETS_JAR): $(FILES_class) $(CLASSDESTDIR)/$(SERVICE_DESCRIPTION_PATH) $(FILES_DAT)
+$(CHARSETS_JAR): $(FILES_class) $(FILES_DAT)
$(BOOT_JAR_CMD) $(CREATE_JAR_OPTS_NOMANIFEST) $(CHARSETS_JAR) \
-C $(CLASSDESTDIR) sun \
- -C $(CLASSDESTDIR) $(SERVICE_DESCRIPTION_PATH) \
$(BOOT_JAR_JFLAGS)
@$(java-vm-cleanup)
diff --git a/jdk/make/sun/org/mozilla/Makefile b/jdk/make/sun/org/mozilla/Makefile
deleted file mode 100644
index 0805da63bda..00000000000
--- a/jdk/make/sun/org/mozilla/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright (c) 2005, 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. 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.
-#
-
-#
-# Makefile for building Mozilla JavaScript modules
-#
-
-BUILDDIR = ../../..
-PRODUCT = org
-include $(BUILDDIR)/common/Defs.gmk
-
-SUBDIRS = javascript
-include $(BUILDDIR)/common/Subdirs.gmk
-
-all build clean clobber::
- $(SUBDIRS-loop)
-
diff --git a/jdk/make/sun/org/mozilla/javascript/Makefile b/jdk/make/sun/org/mozilla/javascript/Makefile
deleted file mode 100644
index f381b94e33c..00000000000
--- a/jdk/make/sun/org/mozilla/javascript/Makefile
+++ /dev/null
@@ -1,64 +0,0 @@
-#
-# Copyright (c) 2005, 2011, 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.
-#
-
-#
-# Makefile for building all of sun.org.mozilla.javascript.internal.*
-#
-
-BUILDDIR = ../../../..
-PACKAGE = sun.org.mozilla.javascript.internal
-PRODUCT = sun
-include $(BUILDDIR)/common/Defs.gmk
-
-AUTO_FILES_JAVA_DIRS = sun/org/mozilla/javascript/internal
-
-RESOURCEDIR = \
- $(CLASSDESTDIR)/sun/org/mozilla/javascript/internal/resources
-
-FILES_copy = \
- $(RESOURCEDIR)/Messages.properties \
- $(RESOURCEDIR)/Messages_fr.properties
-
-#
-# Rules
-#
-
-include $(BUILDDIR)/common/Classes.gmk
-
-all: classes copy-files
-
-#
-# Copy resource messages file for Rhino JavaScript interpreter
-#
-
-copy-files: $(FILES_copy)
-
-$(RESOURCEDIR)/%: $(CLOSED_SRC)/share/classes/sun/org/mozilla/javascript/internal/resources/%
- $(install-file)
-
-.PHONY: copy-files
-
-clean clobber::
- $(RM) -rf $(CLASSDESTDIR)/sun/org/mozilla/javascript
diff --git a/jdk/make/sun/security/Makefile b/jdk/make/sun/security/Makefile
index 9e9f8c50d36..0a1a7aa7265 100644
--- a/jdk/make/sun/security/Makefile
+++ b/jdk/make/sun/security/Makefile
@@ -38,12 +38,10 @@ SUBDIRS_MAKEFLAGS += JAVAC_MAX_WARNINGS=true
SUBDIRS_MAKEFLAGS += JAVAC_WARNINGS_FATAL=true
include $(BUILDDIR)/common/Defs.gmk
-# build sun/security/jgss/wrapper on non-windows non-macosx platforms
+# build sun/security/jgss/wrapper on non-windows platforms
JGSS_WRAPPER =
ifneq ($(PLATFORM), windows)
- ifneq ($(PLATFORM), macosx)
- JGSS_WRAPPER = jgss/wrapper
- endif
+ JGSS_WRAPPER = jgss/wrapper
endif
# Build PKCS#11 on all platforms
diff --git a/jdk/make/sun/security/ec/Makefile b/jdk/make/sun/security/ec/Makefile
index f04ec0eec17..bceb031ad0a 100644
--- a/jdk/make/sun/security/ec/Makefile
+++ b/jdk/make/sun/security/ec/Makefile
@@ -124,15 +124,6 @@ CLASSDESTDIR = $(TEMPDIR)/classes
#
AUTO_FILES_JAVA_DIRS = $(PKGDIR)
-#
-# Exclude the sources that get built by ../other/Makefile
-#
-AUTO_JAVA_PRUNE = \
- ECParameters.java \
- ECPrivateKeyImpl.java \
- ECPublicKeyImpl.java \
- NamedCurve.java
-
#
# Some licensees do not get the native ECC sources, but we still need to
# be able to build "all" for them. Check here to see if the sources are
diff --git a/jdk/make/sun/security/other/Makefile b/jdk/make/sun/security/other/Makefile
index 5a3d9b04c95..cb62c983c9e 100644
--- a/jdk/make/sun/security/other/Makefile
+++ b/jdk/make/sun/security/other/Makefile
@@ -49,15 +49,6 @@ AUTO_FILES_JAVA_DIRS = \
sun/security/x509 \
com/sun/net/ssl/internal/ssl
-#
-# EC classes used by the packages above
-#
-FILES_java += \
- sun/security/ec/ECParameters.java \
- sun/security/ec/ECPrivateKeyImpl.java \
- sun/security/ec/ECPublicKeyImpl.java \
- sun/security/ec/NamedCurve.java
-
#
# Rules
#
diff --git a/jdk/make/tools/src/build/tools/cldrconverter/CLDRConverter.java b/jdk/make/tools/src/build/tools/cldrconverter/CLDRConverter.java
index f1185f18978..9cbf02a9c3b 100644
--- a/jdk/make/tools/src/build/tools/cldrconverter/CLDRConverter.java
+++ b/jdk/make/tools/src/build/tools/cldrconverter/CLDRConverter.java
@@ -34,6 +34,8 @@ import java.nio.file.Path;
import java.util.*;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
/**
@@ -234,6 +236,17 @@ public class CLDRConverter {
}
}
+ /**
+ * Configure the parser to allow access to DTDs on the file system.
+ */
+ private static void enableFileAccess(SAXParser parser) throws SAXNotSupportedException {
+ try {
+ parser.setProperty("http://javax.xml.XMLConstants/property/accessExternalDTD", "file");
+ } catch (SAXNotRecognizedException ignore) {
+ // property requires >= JAXP 1.5
+ }
+ }
+
private static List readBundleList() throws Exception {
ResourceBundle.Control defCon = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT);
List retList = new ArrayList<>();
@@ -279,6 +292,7 @@ public class CLDRConverter {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(true);
SAXParser parser = factory.newSAXParser();
+ enableFileAccess(parser);
LDMLParseHandler handler = new LDMLParseHandler(id);
File file = new File(SOURCE_FILE_DIR + File.separator + id + ".xml");
if (!file.exists()) {
@@ -314,6 +328,7 @@ public class CLDRConverter {
SAXParserFactory factorySuppl = SAXParserFactory.newInstance();
factorySuppl.setValidating(true);
SAXParser parserSuppl = factorySuppl.newSAXParser();
+ enableFileAccess(parserSuppl);
handlerSuppl = new SupplementDataParseHandler();
File fileSupply = new File(SPPL_SOURCE_FILE);
parserSuppl.parse(fileSupply, handlerSuppl);
@@ -322,6 +337,7 @@ public class CLDRConverter {
SAXParserFactory numberingParser = SAXParserFactory.newInstance();
numberingParser.setValidating(true);
SAXParser parserNumbering = numberingParser.newSAXParser();
+ enableFileAccess(parserNumbering);
handlerNumbering = new NumberingSystemsParseHandler();
File fileNumbering = new File(NUMBERING_SOURCE_FILE);
parserNumbering.parse(fileNumbering, handlerNumbering);
@@ -330,6 +346,7 @@ public class CLDRConverter {
SAXParserFactory metazonesParser = SAXParserFactory.newInstance();
metazonesParser.setValidating(true);
SAXParser parserMetaZones = metazonesParser.newSAXParser();
+ enableFileAccess(parserMetaZones);
handlerMetaZones = new MetaZonesParseHandler();
File fileMetaZones = new File(METAZONES_SOURCE_FILE);
parserNumbering.parse(fileMetaZones, handlerMetaZones);
diff --git a/jdk/make/tools/src/build/tools/deps/refs.allowed b/jdk/make/tools/src/build/tools/deps/refs.allowed
index ef1bec7bbcd..7c15a04d91b 100644
--- a/jdk/make/tools/src/build/tools/deps/refs.allowed
+++ b/jdk/make/tools/src/build/tools/deps/refs.allowed
@@ -30,7 +30,5 @@ sun.security.krb5.Realm=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,comp
# Residual references to java.beans.
# The RemoveMethods tool does not yet purge the constant pool.
-# Rhino is due to be replaced so not worth addressing this dependency now.
#
-java.beans.PropertyChangeListener=java.util.logging.LogManager,sun.org.mozilla.javascript.internal.Context,compact1,compact2,compact3
-java.beans.PropertyChangeEvent=sun.org.mozilla.javascript.internal.Context,compact3
+java.beans.PropertyChangeListener=java.util.logging.LogManager,compact1,compact2,compact3
diff --git a/jdk/makefiles/CompileDemos.gmk b/jdk/makefiles/CompileDemos.gmk
index f61d9404020..0a093b586a9 100644
--- a/jdk/makefiles/CompileDemos.gmk
+++ b/jdk/makefiles/CompileDemos.gmk
@@ -1,3 +1,4 @@
+
#
# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -432,20 +433,22 @@ endif
##################################################################################################
ifndef OPENJDK
- DB_DEMO_ZIPFILE := $(wildcard $(JDK_TOPDIR)/src/closed/share/db/*demo*.zip)
+ DB_DEMO_ZIPFILE := $(wildcard $(JDK_TOPDIR)/src/closed/share/db/*.zip)
$(JDK_OUTPUTDIR)/demo/_the.db.unzipped: $(DB_DEMO_ZIPFILE)
$(MKDIR) -p $(@D)
$(RM) -r $(JDK_OUTPUTDIR)/demo/db $(JDK_OUTPUTDIR)/demo/demo
$(CD) $(JDK_OUTPUTDIR)/demo && $(UNZIP) -q -o $<
- $(MV) $(JDK_OUTPUTDIR)/demo/demo $(JDK_OUTPUTDIR)/demo/db
+ $(MV) $(JDK_OUTPUTDIR)/demo/db-derby-*-bin/demo $(JDK_OUTPUTDIR)/demo/db
+ $(CD) $(JDK_OUTPUTDIR)/demo && $(RM) -r db-derby-*-bin
$(TOUCH) $@
# Copy this after the unzip above to avoid race with directory creation and mv command.
$(JDK_OUTPUTDIR)/demo/db/README-JDK-DEMOS.html: \
$(JDK_TOPDIR)/src/closed/share/db/README-JDK-DEMOS.html \
| $(JDK_OUTPUTDIR)/demo/_the.db.unzipped
- $(call install-file)
+ $(MKDIR) -p $(@D)
+ $(CAT) $< | $(SED) "s/XXXX/$(shell cat $(JDK_TOPDIR)/src/closed/share/db/COPYRIGHTYEAR)/" > $@
BUILD_DEMOS += $(JDK_OUTPUTDIR)/demo/_the.db.unzipped $(JDK_OUTPUTDIR)/demo/db/README-JDK-DEMOS.html
endif
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/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk
index bb30367c276..1836cbb13f9 100644
--- a/jdk/makefiles/CompileNativeLibraries.gmk
+++ b/jdk/makefiles/CompileNativeLibraries.gmk
@@ -2560,7 +2560,6 @@ BUILD_LIBRARIES += $(BUILD_LIBJ2PCSC)
##########################################################################################
ifneq ($(OPENJDK_TARGET_OS), windows)
-ifneq ($(OPENJDK_TARGET_OS), macosx)
$(eval $(call SetupNativeCompilation,BUILD_LIBJ2GSS,\
LIBRARY:=j2gss,\
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
@@ -2581,7 +2580,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJ2GSS,\
BUILD_LIBRARIES += $(BUILD_LIBJ2GSS)
endif
-endif
##########################################################################################
diff --git a/jdk/makefiles/CopyFiles.gmk b/jdk/makefiles/CopyFiles.gmk
index ab3a360daaf..272fd1f28b6 100644
--- a/jdk/makefiles/CopyFiles.gmk
+++ b/jdk/makefiles/CopyFiles.gmk
@@ -458,24 +458,6 @@ endif # OPENJDK
ifndef OPENJDK
-JS_RESOURCES_FILES := Messages.properties Messages_fr.properties
-JS_RESOURCES_SRC_DIR := $(JDK_TOPDIR)/src/closed/share/classes/sun/org/mozilla/javascript/internal/resources
-JS_RESOURCES_DST_DIR := $(JDK_OUTPUTDIR)/classes/sun/org/mozilla/javascript/internal/resources
-
-JS_RESOURCES_SRC := $(foreach F,$(JS_RESOURCES_FILES),$(JS_RESOURCES_SRC_DIR)/$(F))
-JS_RESOURCES_DST := $(foreach F,$(JS_RESOURCES_FILES),$(JS_RESOURCES_DST_DIR)/$(F))
-
-$(JS_RESOURCES_DST_DIR)/% : $(JS_RESOURCES_SRC_DIR)/%
- $(call install-file)
-
-COPY_FILES += $(JS_RESOURCES_DST)
-
-endif
-
-##########################################################################################
-
-ifndef OPENJDK
-
#
# Solaris X11 Direct Graphics Access library
#
diff --git a/jdk/makefiles/CopyIntoClasses.gmk b/jdk/makefiles/CopyIntoClasses.gmk
index 8b5a1cd0a3f..88ab3c48e42 100644
--- a/jdk/makefiles/CopyIntoClasses.gmk
+++ b/jdk/makefiles/CopyIntoClasses.gmk
@@ -172,10 +172,6 @@ ifneq ($(ALL_META-INF_DIRS_targetapi),)
else
ALL_META-INF_DIRS:=$(ALL_META-INF_DIRS_share)
endif
-# Filter out META-INF dirs that shouldn't be included
-ifdef OPENJDK
- ALL_META-INF_DIRS:=$(filter-out %com/sun/script/javascript/META-INF,$(ALL_META-INF_DIRS))
-endif
ifndef OPENJDK
ALL_META-INF_DIRS += $(JDK_TOPDIR)/src/closed/share/classes/sun/java2d/cmm/kcms/META-INF
diff --git a/jdk/makefiles/CreateJars.gmk b/jdk/makefiles/CreateJars.gmk
index 8127b054459..3225a862653 100644
--- a/jdk/makefiles/CreateJars.gmk
+++ b/jdk/makefiles/CreateJars.gmk
@@ -201,7 +201,6 @@ RT_JAR_EXCLUDES += \
META-INF/services/com.sun.jdi.connect.spi.TransportService \
META-INF/services/com.sun.tools.attach.spi.AttachProvider \
META-INF/services/com.sun.tools.xjc.Plugin \
- META-INF/services/java.nio.charset.spi.CharsetProvider \
META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor \
org/relaxng/datatype \
sun/awt/HKSCS.class \
@@ -217,19 +216,7 @@ RT_JAR_EXCLUDES += \
sun/net/spi/nameservice/dns \
sun/nio/cs/ext \
sun/rmi/rmic \
- sun/security/ec/ECDHKeyAgreement.class \
- sun/security/ec/ECDSASignature.class \
- sun/security/ec/ECDSASignature\$$$$Raw.class \
- sun/security/ec/ECDSASignature\$$$$SHA1.class \
- sun/security/ec/ECDSASignature\$$$$SHA224.class \
- sun/security/ec/ECDSASignature\$$$$SHA256.class \
- sun/security/ec/ECDSASignature\$$$$SHA384.class \
- sun/security/ec/ECDSASignature\$$$$SHA512.class \
- sun/security/ec/ECKeyFactory.class \
- sun/security/ec/ECKeyPairGenerator.class \
- sun/security/ec/SunEC\$$$$1.class \
- sun/security/ec/SunEC.class \
- sun/security/ec/SunECEntries.class \
+ sun/security/ec \
sun/security/internal \
sun/security/mscapi \
sun/security/pkcs11 \
@@ -428,8 +415,7 @@ $(eval $(call SetupArchive,BUILD_CHARSETS_JAR,,\
SUFFIXES:=.class .dat,\
INCLUDES:=sun/nio/cs/ext,\
EXTRA_FILES := sun/awt/HKSCS.class \
- $(CHARSETS_EXTRA_FILES) \
- META-INF/services/java.nio.charset.spi.CharsetProvider, \
+ $(CHARSETS_EXTRA_FILES), \
JAR:=$(IMAGES_OUTPUTDIR)/lib/charsets.jar, \
SKIP_METAINF := true, \
CHECK_COMPRESS_JAR:=true))
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 2dde16fdf66..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
@@ -532,17 +529,22 @@ ifndef OPENJDK
$(IMAGES_OUTPUTDIR)/_unzip/%.unzipped: $(JDK_TOPDIR)/src/closed/share/db/%
$(ECHO) Unzipping $(patsubst $(SRC_ROOT)/%,%,$<)
$(MKDIR) -p $(JDK_IMAGE_DIR)/db
- cd $(JDK_IMAGE_DIR)/db && $(UNZIP) -q -o $< -x index.html 2> /dev/null
+ cd $(JDK_IMAGE_DIR)/db && $(UNZIP) -q -o $< -x */index.html */KEYS */test/* *javadoc/* */docs/* */demo/* 2> /dev/null
+ cd $(JDK_IMAGE_DIR)/db && $(MV) db-derby-*-bin/* . && $(RM) -r db-derby-*-bin
$(MKDIR) -p $(@D)
$(TOUCH) $@
$(JDK_IMAGE_DIR)/db/README-JDK.html: $(JDK_TOPDIR)/src/closed/share/db/README-JDK.html
$(ECHO) $(LOG_INFO) Copying '$(patsubst $(OUTPUT_ROOT)/%,%,$@)'
- $(install-file)
+ $(CAT) $< | $(SED) "s/XXXX/$(shell cat $(JDK_TOPDIR)/src/closed/share/db/COPYRIGHTYEAR)/" > $@
+
+ $(JDK_IMAGE_DIR)/db/3RDPARTY: $(JDK_TOPDIR)/src/closed/share/db/3RDPARTY
+ $(ECHO) $(LOG_INFO) Copying '$(patsubst $(OUTPUT_ROOT)/%,%,$@)'
+ $(CAT) $< | $(SED) "s/XXXX/$(shell cat $(JDK_TOPDIR)/src/closed/share/db/COPYRIGHTYEAR)/" > $@
JDK_DB_TARGETS := $(patsubst $(JDK_TOPDIR)/src/closed/share/db/%,$(IMAGES_OUTPUTDIR)/_unzip/%.unzipped,\
- $(call not-containing,demo,$(wildcard $(JDK_TOPDIR)/src/closed/share/db/*.zip))) \
- $(JDK_IMAGE_DIR)/db/README-JDK.html
+ $(wildcard $(JDK_TOPDIR)/src/closed/share/db/*.zip)) \
+ $(JDK_IMAGE_DIR)/db/README-JDK.html $(JDK_IMAGE_DIR)/db/3RDPARTY
endif
diff --git a/jdk/makefiles/mapfiles/libawt/mapfile-vers b/jdk/makefiles/mapfiles/libawt/mapfile-vers
index 924a2827a99..8af9d14dd57 100644
--- a/jdk/makefiles/mapfiles/libawt/mapfile-vers
+++ b/jdk/makefiles/mapfiles/libawt/mapfile-vers
@@ -86,6 +86,7 @@ SUNWprivate_1.1 {
Java_sun_java2d_pipe_ShapeSpanIterator_setRule;
Java_sun_java2d_pipe_ShapeSpanIterator_skipDownTo;
+ Java_java_awt_Choice_initIDs;
Java_java_awt_Dimension_initIDs;
Java_java_awt_event_MouseEvent_initIDs;
Java_java_awt_image_DataBufferInt_initIDs;
diff --git a/jdk/makefiles/mapfiles/libawt/mapfile-vers-linux b/jdk/makefiles/mapfiles/libawt/mapfile-vers-linux
index 2514670ea3e..b0bfb1ca91a 100644
--- a/jdk/makefiles/mapfiles/libawt/mapfile-vers-linux
+++ b/jdk/makefiles/mapfiles/libawt/mapfile-vers-linux
@@ -86,6 +86,7 @@ SUNWprivate_1.1 {
Java_sun_java2d_pipe_ShapeSpanIterator_setRule;
Java_sun_java2d_pipe_ShapeSpanIterator_skipDownTo;
+ Java_java_awt_Choice_initIDs;
Java_java_awt_Dimension_initIDs;
Java_java_awt_event_MouseEvent_initIDs;
Java_java_awt_image_DataBufferInt_initIDs;
diff --git a/jdk/makefiles/profile-rtjar-includes.txt b/jdk/makefiles/profile-rtjar-includes.txt
index a90af142db1..d740e01abe8 100644
--- a/jdk/makefiles/profile-rtjar-includes.txt
+++ b/jdk/makefiles/profile-rtjar-includes.txt
@@ -57,6 +57,7 @@ PROFILE_1_RTJAR_INCLUDE_PACKAGES := \
java/time \
java/util \
javax/net \
+ javax/script \
javax/security \
jdk \
sun/invoke \
@@ -111,7 +112,6 @@ PROFILE_3_RTJAR_INCLUDE_PACKAGES := \
com/sun/nio/sctp \
com/sun/org/apache/xml/internal/security \
com/sun/rowset \
- com/sun/script \
com/sun/security/auth \
com/sun/security/jgss \
com/sun/security/ntlm \
@@ -125,7 +125,6 @@ PROFILE_3_RTJAR_INCLUDE_PACKAGES := \
javax/lang/model \
javax/management \
javax/naming \
- javax/script \
javax/security/auth/kerberos \
javax/security/sasl \
javax/smartcardio \
@@ -140,7 +139,6 @@ PROFILE_3_RTJAR_INCLUDE_PACKAGES := \
sun/net/www/protocol/http/ntlm \
sun/net/www/protocol/http/spnego \
sun/nio/ch/sctp \
- sun/org/mozilla \
sun/security/acl \
sun/security/jgss \
sun/security/krb5 \
@@ -161,10 +159,6 @@ PROFILE_3_RTJAR_EXCLUDE_TYPES := \
javax/management/remote/rmi/_RMIServerImpl_Tie.class \
javax/management/remote/rmi/_RMIServer_Stub.class
-PROFILE_3_INCLUDE_METAINF_SERVICES := \
- META-INF/services/javax.script.ScriptEngineFactory
-
-
FULL_JRE_RTJAR_INCLUDE_PACKAGES := \
com/oracle \
com/sun/accessibility/internal/resources \
diff --git a/jdk/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java
index dff48a4caa3..f5cb0d576e6 100644
--- a/jdk/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java
+++ b/jdk/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java
@@ -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
@@ -56,6 +56,8 @@ final class LWScrollBarPeer extends LWComponentPeer
void initializeImpl() {
super.initializeImpl();
final Scrollbar target = getTarget();
+ setLineIncrement(target.getUnitIncrement());
+ setPageIncrement(target.getBlockIncrement());
setValues(target.getValue(), target.getVisibleAmount(),
target.getMinimum(), target.getMaximum());
diff --git a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java
index cad6e4353ba..6ff3530db76 100644
--- a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java
+++ b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java
@@ -53,7 +53,12 @@ public abstract class LWToolkit extends SunToolkit implements Runnable {
private Clipboard clipboard;
private MouseInfoPeer mouseInfoPeer;
- public LWToolkit() {
+ /**
+ * Dynamic Layout Resize client code setting.
+ */
+ private volatile boolean dynamicLayoutSetting = true;
+
+ protected LWToolkit() {
}
/*
@@ -561,4 +566,37 @@ public abstract class LWToolkit extends SunToolkit implements Runnable {
((LWWindowPeer)w.getPeer()).ungrab(false);
}
}
+
+ @Override
+ protected final Object lazilyLoadDesktopProperty(final String name) {
+ if (name.equals("awt.dynamicLayoutSupported")) {
+ return isDynamicLayoutSupported();
+ }
+ return super.lazilyLoadDesktopProperty(name);
+ }
+
+ @Override
+ public final void setDynamicLayout(final boolean dynamic) {
+ dynamicLayoutSetting = dynamic;
+ }
+
+ @Override
+ protected final boolean isDynamicLayoutSet() {
+ return dynamicLayoutSetting;
+ }
+
+ @Override
+ public final boolean isDynamicLayoutActive() {
+ // "Live resizing" is active by default and user's data is ignored.
+ return isDynamicLayoutSupported();
+ }
+
+ /**
+ * Returns true if dynamic layout of Containers on resize is supported by
+ * the underlying operating system and/or window manager.
+ */
+ protected final boolean isDynamicLayoutSupported() {
+ // "Live resizing" is supported by default.
+ return true;
+ }
}
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java
index 791182c1565..e198024dd0c 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java
@@ -35,6 +35,7 @@ import java.security.PrivilegedAction;
import javax.print.*;
import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.HashPrintRequestAttributeSet;
import sun.java2d.*;
import sun.print.*;
@@ -96,6 +97,14 @@ public class CPrinterJob extends RasterPrinterJob {
return false;
}
+ if (attributes == null) {
+ attributes = new HashPrintRequestAttributeSet();
+ }
+
+ if (getPrintService() instanceof StreamPrintService) {
+ return super.printDialog(attributes);
+ }
+
return jobSetup(getPageable(), checkAllowedToPrintToFile());
}
@@ -130,6 +139,10 @@ public class CPrinterJob extends RasterPrinterJob {
return page;
}
+ if (getPrintService() instanceof StreamPrintService) {
+ return super.pageDialog(page);
+ }
+
PageFormat pageClone = (PageFormat) page.clone();
boolean doIt = pageSetup(pageClone, null);
return doIt ? pageClone : page;
diff --git a/jdk/src/macosx/native/sun/awt/AWTSurfaceLayers.m b/jdk/src/macosx/native/sun/awt/AWTSurfaceLayers.m
index 6e9fbbca5ab..d12908c83a3 100644
--- a/jdk/src/macosx/native/sun/awt/AWTSurfaceLayers.m
+++ b/jdk/src/macosx/native/sun/awt/AWTSurfaceLayers.m
@@ -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
@@ -28,6 +28,7 @@
#import "LWCToolkit.h"
#import
+#import
@implementation AWTSurfaceLayers
@@ -74,14 +75,12 @@
}
- (void) setBounds:(CGRect)rect {
- layer.anchorPoint = CGPointMake(0, 0);
-
// translates values to the coordinate system of the "root" layer
- CGFloat newY = windowLayer.bounds.size.height - rect.origin.y - rect.size.height;
- CGRect newRect = CGRectMake(rect.origin.x, newY, rect.size.width, rect.size.height);
-
- layer.frame = newRect;
-
+ rect.origin.y = windowLayer.bounds.size.height - rect.origin.y - rect.size.height;
+ [CATransaction begin];
+ [CATransaction setDisableActions:YES];
+ layer.frame = rect;
+ [CATransaction commit];
[AWTSurfaceLayers repaintLayersRecursively:layer];
}
diff --git a/jdk/src/macosx/native/sun/java2d/opengl/CGLLayer.m b/jdk/src/macosx/native/sun/java2d/opengl/CGLLayer.m
index e0074eb4ef3..f300ea404c4 100644
--- a/jdk/src/macosx/native/sun/java2d/opengl/CGLLayer.m
+++ b/jdk/src/macosx/native/sun/java2d/opengl/CGLLayer.m
@@ -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
@@ -64,11 +64,13 @@ AWT_ASSERT_APPKIT_THREAD;
//Disable CALayer's default animation
NSMutableDictionary * actions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
+ [NSNull null], @"anchorPoint",
[NSNull null], @"bounds",
[NSNull null], @"contents",
[NSNull null], @"contentsScale",
[NSNull null], @"onOrderIn",
[NSNull null], @"onOrderOut",
+ [NSNull null], @"position",
[NSNull null], @"sublayers",
nil];
self.actions = actions;
diff --git a/jdk/src/share/bin/java.c b/jdk/src/share/bin/java.c
index f08a52a9db2..73c532676b3 100644
--- a/jdk/src/share/bin/java.c
+++ b/jdk/src/share/bin/java.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -149,12 +149,15 @@ static int KnownVMIndex(const char* name);
static void FreeKnownVMs();
static jboolean IsWildCardEnabled();
-#define ARG_CHECK(n, f, a) if (n < 1) { \
- JLI_ReportErrorMessage(f, a); \
- printUsage = JNI_TRUE; \
- *pret = 1; \
- return JNI_TRUE; \
-}
+#define ARG_CHECK(AC_arg_count, AC_failure_message, AC_questionable_arg) \
+ do { \
+ if (AC_arg_count < 1) { \
+ JLI_ReportErrorMessage(AC_failure_message, AC_questionable_arg); \
+ printUsage = JNI_TRUE; \
+ *pret = 1; \
+ return JNI_TRUE; \
+ } \
+ } while (JNI_FALSE)
/*
* Running Java code in primordial thread caused many problems. We will
@@ -310,29 +313,37 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */
* mainThread.isAlive() to work as expected.
*/
#define LEAVE() \
- if ((*vm)->DetachCurrentThread(vm) != 0) { \
- JLI_ReportErrorMessage(JVM_ERROR2); \
- ret = 1; \
- } \
- (*vm)->DestroyJavaVM(vm); \
- return ret \
+ do { \
+ if ((*vm)->DetachCurrentThread(vm) != JNI_OK) { \
+ JLI_ReportErrorMessage(JVM_ERROR2); \
+ ret = 1; \
+ } \
+ if (JNI_TRUE) { \
+ (*vm)->DestroyJavaVM(vm); \
+ return ret; \
+ } \
+ } while (JNI_FALSE)
-#define CHECK_EXCEPTION_NULL_LEAVE(e) \
- if ((*env)->ExceptionOccurred(env)) { \
- JLI_ReportExceptionDescription(env); \
- LEAVE(); \
- } \
- if ((e) == NULL) { \
- JLI_ReportErrorMessage(JNI_ERROR); \
- LEAVE(); \
- }
+#define CHECK_EXCEPTION_NULL_LEAVE(CENL_exception) \
+ do { \
+ if ((*env)->ExceptionOccurred(env)) { \
+ JLI_ReportExceptionDescription(env); \
+ LEAVE(); \
+ } \
+ if ((CENL_exception) == NULL) { \
+ JLI_ReportErrorMessage(JNI_ERROR); \
+ LEAVE(); \
+ } \
+ } while (JNI_FALSE)
-#define CHECK_EXCEPTION_LEAVE(rv) \
- if ((*env)->ExceptionOccurred(env)) { \
- JLI_ReportExceptionDescription(env); \
- ret = (rv); \
- LEAVE(); \
- }
+#define CHECK_EXCEPTION_LEAVE(CEL_return_value) \
+ do { \
+ if ((*env)->ExceptionOccurred(env)) { \
+ JLI_ReportExceptionDescription(env); \
+ ret = (CEL_return_value); \
+ LEAVE(); \
+ } \
+ } while (JNI_FALSE)
int JNICALL
JavaMain(void * _args)
@@ -434,7 +445,7 @@ JavaMain(void * _args)
* consistent in the UI we need to track and report the application main class.
*/
appClass = GetApplicationClass(env);
- NULL_CHECK(appClass);
+ NULL_CHECK_RETURN_VALUE(appClass, -1);
/*
* PostJVMInit uses the class name as the application name for GUI purposes,
* for example, on OSX this sets the application name in the menu bar for
diff --git a/jdk/src/share/bin/java.h b/jdk/src/share/bin/java.h
index ad1a1ff90e0..83e97e60d9c 100644
--- a/jdk/src/share/bin/java.h
+++ b/jdk/src/share/bin/java.h
@@ -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
@@ -242,14 +242,18 @@ typedef struct {
InvocationFunctions ifn;
} JavaMainArgs;
-#define NULL_CHECK0(e) if ((e) == 0) { \
- JLI_ReportErrorMessage(JNI_ERROR); \
- return 0; \
- }
+#define NULL_CHECK_RETURN_VALUE(NCRV_check_pointer, NCRV_return_value) \
+ do { \
+ if ((NCRV_check_pointer) == NULL) { \
+ JLI_ReportErrorMessage(JNI_ERROR); \
+ return NCRV_return_value; \
+ } \
+ } while (JNI_FALSE)
-#define NULL_CHECK(e) if ((e) == 0) { \
- JLI_ReportErrorMessage(JNI_ERROR); \
- return; \
- }
+#define NULL_CHECK0(NC0_check_pointer) \
+ NULL_CHECK_RETURN_VALUE(NC0_check_pointer, 0)
+
+#define NULL_CHECK(NC_check_pointer) \
+ NULL_CHECK_RETURN_VALUE(NC_check_pointer, )
#endif /* _JAVA_H_ */
diff --git a/jdk/src/share/bin/wildcard.c b/jdk/src/share/bin/wildcard.c
index f8f664450e3..96dac738aa0 100644
--- a/jdk/src/share/bin/wildcard.c
+++ b/jdk/src/share/bin/wildcard.c
@@ -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
@@ -136,8 +136,10 @@ WildcardIterator_for(const char *wildcard)
{
WildcardIterator it = NEW_(WildcardIterator);
HANDLE handle = FindFirstFile(wildcard, &find_data);
- if (handle == INVALID_HANDLE_VALUE)
+ if (handle == INVALID_HANDLE_VALUE) {
+ JLI_MemFree(it);
return NULL;
+ }
it->handle = handle;
it->firstFile = find_data.cFileName;
return it;
diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java
index d281e11c8c8..0fbdefb8e0e 100644
--- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java
@@ -790,16 +790,12 @@ public class GIFImageReader extends ImageReader {
}
private void startPass(int pass) {
- if (updateListeners == null) {
+ if (updateListeners == null || !imageMetadata.interlaceFlag) {
return;
}
- int y = 0;
- int yStep = 1;
- if (imageMetadata.interlaceFlag) {
- y = interlaceOffset[interlacePass];
- yStep = interlaceIncrement[interlacePass];
- }
+ int y = interlaceOffset[interlacePass];
+ int yStep = interlaceIncrement[interlacePass];
int[] vals = ReaderUtil.
computeUpdatedPixels(sourceRegion,
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java
index a6033c97b14..19a7a08598e 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java
@@ -99,6 +99,7 @@ class Attribute implements Comparable {
return this == def.canon;
}
+ @Override
public int compareTo(Attribute that) {
return this.def.compareTo(that.def);
}
@@ -212,20 +213,20 @@ class Attribute implements Comparable {
// Metadata.
//
// We define metadata using similar layouts
- // for all five kinds of metadata attributes.
+ // for all five kinds of metadata attributes and 2 type metadata attributes
//
// Regular annotations are a counted list of [RSHNH[RUH(1)]][...]
// pack.method.attribute.RuntimeVisibleAnnotations=[NH[(1)]][RSHNH[RUH(1)]][TB...]
//
// Parameter annotations are a counted list of regular annotations.
- // pack.method.attribute.RuntimeVisibleParameterAnnotations=[NH[(1)]][NH[(1)]][RSHNH[RUH(1)]][TB...]
+ // pack.method.attribute.RuntimeVisibleParameterAnnotations=[NB[(1)]][NH[(1)]][RSHNH[RUH(1)]][TB...]
//
// RuntimeInvisible annotations are defined similarly...
// Non-method annotations are defined similarly...
//
// Annotation are a simple tagged value [TB...]
// pack.attribute.method.AnnotationDefault=[TB...]
- //
+
static {
String mdLayouts[] = {
Attribute.normalizeLayoutString
@@ -238,6 +239,9 @@ class Attribute implements Comparable {
+"\n # annotations :="
+"\n [ NH[(1)] ] # forward call to annotation"
+"\n "
+ ),
+ Attribute.normalizeLayoutString
+ (""
+"\n # annotation :="
+"\n [RSH"
+"\n NH[RUH (1)] # forward call to value"
@@ -259,24 +263,67 @@ class Attribute implements Comparable {
+"\n ()[] ]"
)
};
+ /*
+ * RuntimeVisibleTypeAnnotation and RuntimeInvisibleTypeAnnotatation are
+ * similar to RuntimeVisibleAnnotation and RuntimeInvisibleAnnotation,
+ * a type-annotation union and a type-path structure precedes the
+ * annotation structure
+ */
+ String typeLayouts[] = {
+ Attribute.normalizeLayoutString
+ (""
+ +"\n # type-annotations :="
+ +"\n [ NH[(1)(2)(3)] ] # forward call to type-annotations"
+ ),
+ Attribute.normalizeLayoutString
+ ( ""
+ +"\n # type-annotation :="
+ +"\n [TB"
+ +"\n (0-1) [B] # {CLASS, METHOD}_TYPE_PARAMETER"
+ +"\n (16) [FH] # CLASS_EXTENDS"
+ +"\n (17-18) [BB] # {CLASS, METHOD}_TYPE_PARAMETER_BOUND"
+ +"\n (19-21) [] # FIELD, METHOD_RETURN, METHOD_RECEIVER"
+ +"\n (22) [B] # METHOD_FORMAL_PARAMETER"
+ +"\n (23) [H] # THROWS"
+ +"\n (64-65) [NH[PHOHH]] # LOCAL_VARIABLE, RESOURCE_VARIABLE"
+ +"\n (66) [H] # EXCEPTION_PARAMETER"
+ +"\n (67-70) [PH] # INSTANCEOF, NEW, {CONSTRUCTOR, METHOD}_REFERENCE_RECEIVER"
+ +"\n (71-75) [PHB] # CAST, {CONSTRUCTOR,METHOD}_INVOCATION_TYPE_ARGUMENT, {CONSTRUCTOR, METHOD}_REFERENCE_TYPE_ARGUMENT"
+ +"\n ()[] ]"
+ ),
+ Attribute.normalizeLayoutString
+ (""
+ +"\n # type-path"
+ +"\n [ NB[BB] ]"
+ )
+ };
Map sd = standardDefs;
- String defaultLayout = mdLayouts[2];
- String annotationsLayout = mdLayouts[1] + mdLayouts[2];
+ String defaultLayout = mdLayouts[3];
+ String annotationsLayout = mdLayouts[1] + mdLayouts[2] + mdLayouts[3];
String paramsLayout = mdLayouts[0] + annotationsLayout;
+ String typesLayout = typeLayouts[0] + typeLayouts[1] +
+ typeLayouts[2] + mdLayouts[2] + mdLayouts[3];
+
for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
- if (ctype == ATTR_CONTEXT_CODE) continue;
- define(sd, ctype,
- "RuntimeVisibleAnnotations", annotationsLayout);
- define(sd, ctype,
- "RuntimeInvisibleAnnotations", annotationsLayout);
- if (ctype == ATTR_CONTEXT_METHOD) {
+ if (ctype != ATTR_CONTEXT_CODE) {
define(sd, ctype,
- "RuntimeVisibleParameterAnnotations", paramsLayout);
+ "RuntimeVisibleAnnotations", annotationsLayout);
define(sd, ctype,
- "RuntimeInvisibleParameterAnnotations", paramsLayout);
- define(sd, ctype,
- "AnnotationDefault", defaultLayout);
+ "RuntimeInvisibleAnnotations", annotationsLayout);
+
+ if (ctype == ATTR_CONTEXT_METHOD) {
+ define(sd, ctype,
+ "RuntimeVisibleParameterAnnotations", paramsLayout);
+ define(sd, ctype,
+ "RuntimeInvisibleParameterAnnotations", paramsLayout);
+ define(sd, ctype,
+ "AnnotationDefault", defaultLayout);
+ }
}
+ define(sd, ctype,
+ "RuntimeVisibleTypeAnnotations", typesLayout);
+ define(sd, ctype,
+ "RuntimeInvisibleTypeAnnotations", typesLayout);
}
}
@@ -529,6 +576,7 @@ class Attribute implements Comparable {
return canon.addContent(bytes, null);
}
+ @Override
public boolean equals(Object x) {
return ( x != null) && ( x.getClass() == Layout.class ) &&
equals((Layout)x);
@@ -538,11 +586,13 @@ class Attribute implements Comparable {
&& this.layout.equals(that.layout)
&& this.ctype == that.ctype;
}
+ @Override
public int hashCode() {
return (((17 + name.hashCode())
* 37 + layout.hashCode())
* 37 + ctype);
}
+ @Override
public int compareTo(Layout that) {
int r;
r = this.name.compareTo(that.name);
@@ -551,6 +601,7 @@ class Attribute implements Comparable {
if (r != 0) return r;
return this.ctype - that.ctype;
}
+ @Override
public String toString() {
String str = contextName(ctype)+"."+name+"["+layout+"]";
// If -ea, print out more informative strings!
@@ -698,11 +749,14 @@ class Attribute implements Comparable {
// References (to a local cpMap) are embedded in the bytes.
def.parse(holder, bytes, 0, bytes.length,
new ValueStream() {
+ @Override
public void putInt(int bandIndex, int value) {
}
+ @Override
public void putRef(int bandIndex, Entry ref) {
refs.add(ref);
}
+ @Override
public int encodeBCI(int bci) {
return bci;
}
@@ -716,6 +770,7 @@ class Attribute implements Comparable {
return def.unparse(in, out);
}
+ @Override
public String toString() {
return def
+"{"+(bytes == null ? -1 : size())+"}"
@@ -1309,7 +1364,7 @@ class Attribute implements Comparable {
}
out.putRef(bandIndex, globalRef);
break;
- default: assert(false); continue;
+ default: assert(false);
}
}
return pos;
@@ -1416,8 +1471,7 @@ class Attribute implements Comparable {
int localRef;
if (globalRef != null) {
// It's a one-element array, really an lvalue.
- fixups[0] = Fixups.add(fixups[0], null, out.size(),
- Fixups.U2_FORMAT, globalRef);
+ fixups[0] = Fixups.addRefWithLoc(fixups[0], out.size(), globalRef);
localRef = 0; // placeholder for fixups
} else {
localRef = 0; // fixed null value
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java
index 322e2c33326..1152aa73f0c 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java
@@ -48,6 +48,7 @@ import java.util.List;
import java.util.Map;
import java.util.jar.Pack200;
import static com.sun.java.util.jar.pack.Constants.*;
+import java.util.LinkedList;
/**
* Define the structure and ordering of "bands" in a packed file.
@@ -495,6 +496,7 @@ class BandStructure {
}
protected int lengthForDebug = -1; // DEBUG ONLY
+ @Override
public String toString() { // DEBUG ONLY
int length = (lengthForDebug != -1 ? lengthForDebug : length());
String str = name;
@@ -518,20 +520,24 @@ class BandStructure {
super(name, regularCoding);
}
+ @Override
public int capacity() {
return values == null ? -1 : values.length;
}
/** Declare predicted or needed capacity. */
+ @Override
protected void setCapacity(int cap) {
assert(length <= cap);
if (cap == -1) { values = null; return; }
values = realloc(values, cap);
}
+ @Override
public int length() {
return length;
}
+ @Override
protected int valuesRemainingForDebug() {
return length - valuesDisbursed;
}
@@ -583,6 +589,7 @@ class BandStructure {
return true;
}
+ @Override
protected void chooseBandCodings() throws IOException {
boolean canVary = canVaryCoding();
if (!canVary || !shouldVaryCoding()) {
@@ -653,6 +660,7 @@ class BandStructure {
}
}
+ @Override
protected long computeOutputSize() {
outputSize = getCodingChooser().computeByteSize(bandCoding,
values, 0, length);
@@ -668,6 +676,7 @@ class BandStructure {
return regularCoding.setD(0).getLength(X);
}
+ @Override
protected void writeDataTo(OutputStream out) throws IOException {
if (length == 0) return; // nothing to write
long len0 = 0;
@@ -691,6 +700,7 @@ class BandStructure {
if (optDumpBands) dumpBand();
}
+ @Override
protected void readDataFrom(InputStream in) throws IOException {
length = valuesExpected();
if (length == 0) return; // nothing to read
@@ -707,7 +717,6 @@ class BandStructure {
if (XB < 0) {
// Do not consume this value. No alternate coding.
in.reset();
- XB = _meta_default;
bandCoding = regularCoding;
metaCoding = noMetaCoding;
} else if (XB == _meta_default) {
@@ -733,6 +742,7 @@ class BandStructure {
if (optDumpBands) dumpBand();
}
+ @Override
public void doneDisbursing() {
super.doneDisbursing();
values = null; // for GC
@@ -763,7 +773,10 @@ class BandStructure {
/** Disburse one value. */
protected int getValue() {
assert(phase() == DISBURSE_PHASE);
- assert(valuesDisbursed < length);
+ // when debugging return a zero if lengths are zero
+ if (optDebugBands && length == 0 && valuesDisbursed == length)
+ return 0;
+ assert(valuesDisbursed <= length);
return values[valuesDisbursed++];
}
@@ -784,9 +797,11 @@ class BandStructure {
super(name, BYTE1);
}
+ @Override
public int capacity() {
return bytes == null ? -1 : Integer.MAX_VALUE;
}
+ @Override
protected void setCapacity(int cap) {
assert(bytes == null); // do this just once
bytes = new ByteArrayOutputStream(cap);
@@ -796,27 +811,32 @@ class BandStructure {
bytes = null;
}
+ @Override
public int length() {
return bytes == null ? -1 : bytes.size();
}
public void reset() {
bytes.reset();
}
+ @Override
protected int valuesRemainingForDebug() {
return (bytes == null) ? -1 : ((ByteArrayInputStream)in).available();
}
+ @Override
protected void chooseBandCodings() throws IOException {
// No-op.
assert(decodeEscapeValue(regularCoding.min(), regularCoding) < 0);
assert(decodeEscapeValue(regularCoding.max(), regularCoding) < 0);
}
+ @Override
protected long computeOutputSize() {
// do not cache
return bytes.size();
}
+ @Override
public void writeDataTo(OutputStream out) throws IOException {
if (length() == 0) return;
bytes.writeTo(out);
@@ -834,6 +854,7 @@ class BandStructure {
}
}
+ @Override
public void readDataFrom(InputStream in) throws IOException {
int vex = valuesExpected();
if (vex == 0) return;
@@ -852,11 +873,13 @@ class BandStructure {
if (optDumpBands) dumpBand();
}
+ @Override
public void readyToDisburse() {
in = new ByteArrayInputStream(bytes.toByteArray());
super.readyToDisburse();
}
+ @Override
public void doneDisbursing() {
super.doneDisbursing();
if (optDumpBands
@@ -882,11 +905,13 @@ class BandStructure {
// Tap the stream.
bytesForDump = new ByteArrayOutputStream();
this.in = new FilterInputStream(in) {
+ @Override
public int read() throws IOException {
int ch = in.read();
if (ch >= 0) bytesForDump.write(ch);
return ch;
}
+ @Override
public int read(byte b[], int off, int len) throws IOException {
int nr = in.read(b, off, len);
if (nr >= 0) bytesForDump.write(b, off, nr);
@@ -917,6 +942,7 @@ class BandStructure {
assert(b == (b & 0xFF));
collectorStream().write(b);
}
+ @Override
public String toString() {
return "byte "+super.toString();
}
@@ -1184,6 +1210,7 @@ class BandStructure {
super(name, regularCoding);
}
+ @Override
public Band init() {
super.init();
// This is all just to keep the asserts happy:
@@ -1259,12 +1286,17 @@ class BandStructure {
int bandCount() { return bandCount; }
private int cap = -1;
+ @Override
public int capacity() { return cap; }
+ @Override
public void setCapacity(int cap) { this.cap = cap; }
+ @Override
public int length() { return 0; }
+ @Override
public int valuesRemainingForDebug() { return 0; }
+ @Override
protected void chooseBandCodings() throws IOException {
// coding decision pass
for (int i = 0; i < bandCount; i++) {
@@ -1273,6 +1305,7 @@ class BandStructure {
}
}
+ @Override
protected long computeOutputSize() {
// coding decision pass
long sum = 0;
@@ -1286,6 +1319,7 @@ class BandStructure {
return sum;
}
+ @Override
protected void writeDataTo(OutputStream out) throws IOException {
long preCount = 0;
if (outputCounter != null) preCount = outputCounter.getCount();
@@ -1303,6 +1337,7 @@ class BandStructure {
}
}
+ @Override
protected void readDataFrom(InputStream in) throws IOException {
assert(false); // not called?
for (int i = 0; i < bandCount; i++) {
@@ -1314,6 +1349,7 @@ class BandStructure {
}
}
+ @Override
public String toString() {
return "{"+bandCount()+" bands: "+super.toString()+"}";
}
@@ -1335,14 +1371,17 @@ class BandStructure {
public long getCount() { return count; }
public void setCount(long c) { count = c; }
+ @Override
public void write(int b) throws IOException {
count++;
if (out != null) out.write(b);
}
+ @Override
public void write(byte b[], int off, int len) throws IOException {
count += len;
if (out != null) out.write(b, off, len);
}
+ @Override
public String toString() {
return String.valueOf(getCount());
}
@@ -1490,6 +1529,7 @@ class BandStructure {
CPRefBand field_ConstantValue_KQ = field_attr_bands.newCPRefBand("field_ConstantValue_KQ", CONSTANT_FieldSpecific);
CPRefBand field_Signature_RS = field_attr_bands.newCPRefBand("field_Signature_RS", CONSTANT_Signature);
MultiBand field_metadata_bands = field_attr_bands.newMultiBand("(field_metadata_bands)", UNSIGNED5);
+ MultiBand field_type_metadata_bands = field_attr_bands.newMultiBand("(field_type_metadata_bands)", UNSIGNED5);
CPRefBand method_descr = class_bands.newCPRefBand("method_descr", MDELTA5, CONSTANT_NameandType);
MultiBand method_attr_bands = class_bands.newMultiBand("(method_attr_bands)", UNSIGNED5);
@@ -1507,6 +1547,7 @@ class BandStructure {
IntBand method_MethodParameters_NB = method_attr_bands.newIntBand("method_MethodParameters_NB", BYTE1);
CPRefBand method_MethodParameters_name_RUN = method_attr_bands.newCPRefBand("method_MethodParameters_name_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK);
IntBand method_MethodParameters_flag_FH = method_attr_bands.newIntBand("method_MethodParameters_flag_FH");
+ MultiBand method_type_metadata_bands = method_attr_bands.newMultiBand("(method_type_metadata_bands)", UNSIGNED5);
MultiBand class_attr_bands = class_bands.newMultiBand("(class_attr_bands)", UNSIGNED5);
IntBand class_flags_hi = class_attr_bands.newIntBand("class_flags_hi");
@@ -1527,6 +1568,7 @@ class BandStructure {
CPRefBand class_InnerClasses_name_RUN = class_attr_bands.newCPRefBand("class_InnerClasses_name_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK);
IntBand class_ClassFile_version_minor_H = class_attr_bands.newIntBand("class_ClassFile_version_minor_H");
IntBand class_ClassFile_version_major_H = class_attr_bands.newIntBand("class_ClassFile_version_major_H");
+ MultiBand class_type_metadata_bands = class_attr_bands.newMultiBand("(class_type_metadata_bands)", UNSIGNED5);
MultiBand code_bands = class_bands.newMultiBand("(code_bands)", UNSIGNED5);
ByteBand code_headers = code_bands.newByteBand("code_headers"); //BYTE1
@@ -1545,7 +1587,7 @@ class BandStructure {
IntBand code_attr_indexes = code_attr_bands.newIntBand("code_attr_indexes");
IntBand code_attr_calls = code_attr_bands.newIntBand("code_attr_calls");
- MultiBand stackmap_bands = code_attr_bands.newMultiBand("StackMapTable_bands", UNSIGNED5);
+ MultiBand stackmap_bands = code_attr_bands.newMultiBand("(StackMapTable_bands)", UNSIGNED5);
IntBand code_StackMapTable_N = stackmap_bands.newIntBand("code_StackMapTable_N");
IntBand code_StackMapTable_frame_T = stackmap_bands.newIntBand("code_StackMapTable_frame_T",BYTE1);
IntBand code_StackMapTable_local_N = stackmap_bands.newIntBand("code_StackMapTable_local_N");
@@ -1573,6 +1615,7 @@ class BandStructure {
CPRefBand code_LocalVariableTypeTable_name_RU = code_attr_bands.newCPRefBand("code_LocalVariableTypeTable_name_RU", CONSTANT_Utf8);
CPRefBand code_LocalVariableTypeTable_type_RS = code_attr_bands.newCPRefBand("code_LocalVariableTypeTable_type_RS", CONSTANT_Signature);
IntBand code_LocalVariableTypeTable_slot = code_attr_bands.newIntBand("code_LocalVariableTypeTable_slot");
+ MultiBand code_type_metadata_bands = code_attr_bands.newMultiBand("(code_type_metadata_bands)", UNSIGNED5);
// bands for bytecodes
MultiBand bc_bands = all_bands.newMultiBand("(byte_codes)", UNSIGNED5);
@@ -1678,6 +1721,14 @@ class BandStructure {
metadataBands[ATTR_CONTEXT_FIELD] = field_metadata_bands;
metadataBands[ATTR_CONTEXT_METHOD] = method_metadata_bands;
}
+ // Table of bands which contains type_metadata (TypeAnnotations)
+ protected MultiBand[] typeMetadataBands = new MultiBand[ATTR_CONTEXT_LIMIT];
+ {
+ typeMetadataBands[ATTR_CONTEXT_CLASS] = class_type_metadata_bands;
+ typeMetadataBands[ATTR_CONTEXT_FIELD] = field_type_metadata_bands;
+ typeMetadataBands[ATTR_CONTEXT_METHOD] = method_type_metadata_bands;
+ typeMetadataBands[ATTR_CONTEXT_CODE] = code_type_metadata_bands;
+ }
// Attribute layouts.
public static final int ADH_CONTEXT_MASK = 0x3; // (ad_hdr & ADH_CONTEXT_MASK)
@@ -1793,36 +1844,47 @@ class BandStructure {
for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
MultiBand xxx_metadata_bands = metadataBands[ctype];
- if (xxx_metadata_bands == null)
- continue; // no code attrs
+ if (ctype != ATTR_CONTEXT_CODE) {
+ // These arguments cause the bands to be built
+ // automatically for this complicated layout:
+ predefineAttribute(X_ATTR_RuntimeVisibleAnnotations,
+ ATTR_CONTEXT_NAME[ctype]+"_RVA_",
+ xxx_metadata_bands,
+ Attribute.lookup(null, ctype,
+ "RuntimeVisibleAnnotations"));
+ predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations,
+ ATTR_CONTEXT_NAME[ctype]+"_RIA_",
+ xxx_metadata_bands,
+ Attribute.lookup(null, ctype,
+ "RuntimeInvisibleAnnotations"));
- // These arguments cause the bands to be built
- // automatically for this complicated layout:
- predefineAttribute(X_ATTR_RuntimeVisibleAnnotations,
- ATTR_CONTEXT_NAME[ctype]+"_RVA_",
- xxx_metadata_bands,
- Attribute.lookup(null, ctype,
- "RuntimeVisibleAnnotations"));
- predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations,
- ATTR_CONTEXT_NAME[ctype]+"_RIA_",
- xxx_metadata_bands,
- Attribute.lookup(null, ctype,
- "RuntimeInvisibleAnnotations"));
- if (ctype != ATTR_CONTEXT_METHOD)
- continue;
-
- predefineAttribute(METHOD_ATTR_RuntimeVisibleParameterAnnotations,
- "method_RVPA_", xxx_metadata_bands,
- Attribute.lookup(null, ctype,
- "RuntimeVisibleParameterAnnotations"));
- predefineAttribute(METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
- "method_RIPA_", xxx_metadata_bands,
- Attribute.lookup(null, ctype,
- "RuntimeInvisibleParameterAnnotations"));
- predefineAttribute(METHOD_ATTR_AnnotationDefault,
- "method_AD_", xxx_metadata_bands,
- Attribute.lookup(null, ctype,
- "AnnotationDefault"));
+ if (ctype == ATTR_CONTEXT_METHOD) {
+ predefineAttribute(METHOD_ATTR_RuntimeVisibleParameterAnnotations,
+ "method_RVPA_", xxx_metadata_bands,
+ Attribute.lookup(null, ctype,
+ "RuntimeVisibleParameterAnnotations"));
+ predefineAttribute(METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
+ "method_RIPA_", xxx_metadata_bands,
+ Attribute.lookup(null, ctype,
+ "RuntimeInvisibleParameterAnnotations"));
+ predefineAttribute(METHOD_ATTR_AnnotationDefault,
+ "method_AD_", xxx_metadata_bands,
+ Attribute.lookup(null, ctype,
+ "AnnotationDefault"));
+ }
+ }
+ // All contexts have these
+ MultiBand xxx_type_metadata_bands = typeMetadataBands[ctype];
+ predefineAttribute(X_ATTR_RuntimeVisibleTypeAnnotations,
+ ATTR_CONTEXT_NAME[ctype] + "_RVTA_",
+ xxx_type_metadata_bands,
+ Attribute.lookup(null, ctype,
+ "RuntimeVisibleTypeAnnotations"));
+ predefineAttribute(X_ATTR_RuntimeInvisibleTypeAnnotations,
+ ATTR_CONTEXT_NAME[ctype] + "_RITA_",
+ xxx_type_metadata_bands,
+ Attribute.lookup(null, ctype,
+ "RuntimeInvisibleTypeAnnotations"));
}
@@ -2053,8 +2115,7 @@ class BandStructure {
Attribute.Layout def = attr.layout();
int ctype = def.ctype();
return predefineAttribute(index, ctype,
- makeNewAttributeBands(bandPrefix, def,
- addHere),
+ makeNewAttributeBands(bandPrefix, def, addHere),
def.name(), def.layout());
}
@@ -2539,7 +2600,7 @@ class BandStructure {
return true;
}
- // DEBUG ONLY: Validate next input band.
+ // DEBUG ONLY: Validate next input band, ensure bands are read in sequence
private boolean assertReadyToReadFrom(Band b, InputStream in) throws IOException {
Band p = prevForAssertMap.get(b);
// Any previous band must be done reading before this one starts.
@@ -2547,30 +2608,19 @@ class BandStructure {
Utils.log.warning("Previous band not done reading.");
Utils.log.info(" Previous band: "+p);
Utils.log.info(" Next band: "+b);
- Thread.dumpStack();
assert(verbose > 0); // die unless verbose is true
}
String name = b.name;
if (optDebugBands && !name.startsWith("(")) {
+ assert(bandSequenceList != null);
// Verify synchronization between reader & writer:
- StringBuilder buf = new StringBuilder();
- int ch;
- while ((ch = in.read()) > 0)
- buf.append((char)ch);
- String inName = buf.toString();
+ String inName = bandSequenceList.removeFirst();
+ // System.out.println("Reading: " + name);
if (!inName.equals(name)) {
- StringBuilder sb = new StringBuilder();
- sb.append("Expected "+name+" but read: ");
- inName += (char)ch;
- while (inName.length() < 10) {
- inName += (char) in.read();
- }
- for (int i = 0; i < inName.length(); i++) {
- sb.append(inName.charAt(i));
- }
- Utils.log.warning(sb.toString());
+ Utils.log.warning("Expected " + name + " but read: " + inName);
return false;
}
+ Utils.log.info("Read band in sequence: " + name);
}
return true;
}
@@ -2590,7 +2640,12 @@ class BandStructure {
return true;
}
- // DEBUG ONLY: Maybe write a debugging cookie to next output band.
+ /*
+ * DEBUG ONLY: write the bands to a list and read back the list in order,
+ * this works perfectly if we use the java packer and unpacker, typically
+ * this will work with --repack or if they are in the same jvm instance.
+ */
+ static LinkedList bandSequenceList = null;
private boolean assertReadyToWriteTo(Band b, OutputStream out) throws IOException {
Band p = prevForAssertMap.get(b);
// Any previous band must be done writing before this one starts.
@@ -2598,16 +2653,15 @@ class BandStructure {
Utils.log.warning("Previous band not done writing.");
Utils.log.info(" Previous band: "+p);
Utils.log.info(" Next band: "+b);
- Thread.dumpStack();
assert(verbose > 0); // die unless verbose is true
}
String name = b.name;
if (optDebugBands && !name.startsWith("(")) {
+ if (bandSequenceList == null)
+ bandSequenceList = new LinkedList<>();
// Verify synchronization between reader & writer:
- for (int j = 0; j < name.length(); j++) {
- out.write((byte)name.charAt(j));
- }
- out.write((byte)0);
+ bandSequenceList.add(name);
+ // System.out.println("Writing: " + b);
}
return true;
}
@@ -2664,7 +2718,7 @@ class BandStructure {
buf.append("\\r");
} else {
String str = "000"+Integer.toHexString(ch);
- buf.append("\\u"+str.substring(str.length()-4));
+ buf.append("\\u").append(str.substring(str.length()-4));
}
}
ps.println(buf);
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Code.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Code.java
index e84cdaa59a0..423b0d7f779 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Code.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Code.java
@@ -146,7 +146,6 @@ class Code extends Attribute.Holder {
int verbose = getPackage().verbose;
if (verbose > 2)
System.out.println("Reference scan "+this);
- Class cls = thisClass();
refs.addAll(Arrays.asList(handler_class));
if (fixups != null) {
fixups.visitRefs(refs);
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java
index 1ede29134b0..4f64ef41b7a 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java
@@ -785,53 +785,55 @@ class ConstantPool {
return new String(sig);
}
- static private int skipClassNameChars(String sig, int i) {
- int len = sig.length();
- for (; i < len; i++) {
- char ch = sig.charAt(i);
- if (ch <= ' ') break;
- if (ch >= ';' && ch <= '@') break;
- }
- return i;
+ static private int skipTo(char semi, String sig, int i) {
+ i = sig.indexOf(semi, i);
+ return (i >= 0) ? i : sig.length();
}
static String[] structureSignature(String sig) {
- sig = sig.intern();
-
- int formLen = 0;
- int nparts = 1;
- for (int i = 0; i < sig.length(); i++) {
- char ch = sig.charAt(i);
- formLen++;
- if (ch == 'L') {
- nparts++;
- int i2 = skipClassNameChars(sig, i+1);
- i = i2-1; // keep the semicolon in the form
- int i3 = sig.indexOf('<', i+1);
- if (i3 > 0 && i3 < i2)
- i = i3-1;
- }
- }
- char[] form = new char[formLen];
- if (nparts == 1) {
+ int firstl = sig.indexOf('L');
+ if (firstl < 0) {
String[] parts = { sig };
return parts;
}
- String[] parts = new String[nparts];
- int j = 0;
- int k = 1;
- for (int i = 0; i < sig.length(); i++) {
- char ch = sig.charAt(i);
- form[j++] = ch;
- if (ch == 'L') {
- int i2 = skipClassNameChars(sig, i+1);
- parts[k++] = sig.substring(i+1, i2);
- i = i2;
- --i; // keep the semicolon in the form
+ // Segment the string like sig.split("L\\([^;<]*\\)").
+ // N.B.: Previous version of this code did a more complex match,
+ // to next ch < ' ' or ch in [';'..'@']. The only important
+ // characters are ';' and '<', since they are part of the
+ // signature syntax.
+ // Examples:
+ // "(Ljava/lang/Object;IJLLoo;)V" => {"(L;IJL;)V", "java/lang/Object", "Loo"}
+ // "Ljava/util/List;" => {"L;", "java/util/List", "java/lang/String"}
+ char[] form = null;
+ String[] parts = null;
+ for (int pass = 0; pass <= 1; pass++) {
+ // pass 0 is a sizing pass, pass 1 packs the arrays
+ int formPtr = 0;
+ int partPtr = 1;
+ int nextsemi = 0, nextangl = 0; // next ';' or '<', or zero, or sigLen
+ int lastj = 0;
+ for (int i = firstl + 1, j; i > 0; i = sig.indexOf('L', j) + 1) {
+ // sig[i-1] is 'L', while sig[j] will be the first ';' or '<' after it
+ // each part is in sig[i .. j-1]
+ if (nextsemi < i) nextsemi = skipTo(';', sig, i);
+ if (nextangl < i) nextangl = skipTo('<', sig, i);
+ j = (nextsemi < nextangl ? nextsemi : nextangl);
+ if (pass != 0) {
+ sig.getChars(lastj, i, form, formPtr);
+ parts[partPtr] = sig.substring(i, j);
+ }
+ formPtr += (i - lastj);
+ partPtr += 1;
+ lastj = j;
}
+ if (pass != 0) {
+ sig.getChars(lastj, sig.length(), form, formPtr);
+ break;
+ }
+ formPtr += (sig.length() - lastj);
+ form = new char[formPtr];
+ parts = new String[partPtr];
}
- assert(j == formLen);
- assert(k == parts.length);
parts[0] = new String(form);
//assert(flattenSignature(parts).equals(sig));
return parts;
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java
index 5059bc07967..15991700f25 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java
@@ -45,6 +45,7 @@ class Constants {
1.5 to 1.5.X 49,0
1.6 to 1.5.x 50,0
1.7 to 1.6.x 51,0
+ 1.8 to 1.7.x 52,0
*/
public final static Package.Version JAVA_MIN_CLASS_VERSION =
@@ -161,7 +162,9 @@ class Constants {
METHOD_ATTR_RuntimeInvisibleParameterAnnotations = 24,
CLASS_ATTR_ClassFile_version = 24,
METHOD_ATTR_AnnotationDefault = 25,
- METHOD_ATTR_MethodParameters = 26,
+ METHOD_ATTR_MethodParameters = 26, // JDK8
+ X_ATTR_RuntimeVisibleTypeAnnotations = 27, // JDK8
+ X_ATTR_RuntimeInvisibleTypeAnnotations = 28, // JDK8
CODE_ATTR_StackMapTable = 0, // new in Java 6
CODE_ATTR_LineNumberTable = 1,
CODE_ATTR_LocalVariableTable = 2,
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java
index 0c99351222a..647d1dbc413 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, 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
@@ -30,6 +30,7 @@ import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
+import java.util.Objects;
/**
* Collection of relocatable constant pool references.
@@ -77,8 +78,9 @@ final class Fixups extends AbstractCollection {
private static final int MINBIGSIZE = 1;
// cleverly share empty bigDescs:
- private static int[] noBigDescs = {MINBIGSIZE};
+ private static final int[] noBigDescs = {MINBIGSIZE};
+ @Override
public int size() {
return size;
}
@@ -105,6 +107,7 @@ final class Fixups extends AbstractCollection {
}
}
+ @Override
public void clear() {
if (bytes != null) {
// Clean the bytes:
@@ -141,16 +144,16 @@ final class Fixups extends AbstractCollection {
assert(old.equals(new ArrayList<>(this)));
}
- static final int LOC_SHIFT = 1;
- static final int FMT_MASK = 0x1;
- static final byte UNUSED_BYTE = 0;
- static final byte OVERFLOW_BYTE = -1;
+ private static final int LOC_SHIFT = 1;
+ private static final int FMT_MASK = 0x1;
+ private static final byte UNUSED_BYTE = 0;
+ private static final byte OVERFLOW_BYTE = -1;
// fill pointer of bigDescs array is in element [0]
- static final int BIGSIZE = 0;
+ private static final int BIGSIZE = 0;
// Format values:
- public static final int U2_FORMAT = 0;
- public static final int U1_FORMAT = 1;
+ private static final int U2_FORMAT = 0;
+ private static final int U1_FORMAT = 1;
// Special values for the static methods.
private static final int SPECIAL_LOC = 0;
@@ -232,6 +235,14 @@ final class Fixups extends AbstractCollection {
}
}
+ void addU1(int pc, Entry ref) {
+ add(pc, U1_FORMAT, ref);
+ }
+
+ void addU2(int pc, Entry ref) {
+ add(pc, U2_FORMAT, ref);
+ }
+
/** Simple and necessary tuple to present each fixup. */
public static
class Fixup implements Comparable {
@@ -248,15 +259,25 @@ final class Fixups extends AbstractCollection {
public int location() { return descLoc(desc); }
public int format() { return descFmt(desc); }
public Entry entry() { return entry; }
+ @Override
public int compareTo(Fixup that) {
// Ordering depends only on location.
return this.location() - that.location();
}
+ @Override
public boolean equals(Object x) {
if (!(x instanceof Fixup)) return false;
Fixup that = (Fixup) x;
return this.desc == that.desc && this.entry == that.entry;
}
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 59 * hash + this.desc;
+ hash = 59 * hash + Objects.hashCode(this.entry);
+ return hash;
+ }
+ @Override
public String toString() {
return "@"+location()+(format()==U1_FORMAT?".1":"")+"="+entry;
}
@@ -267,8 +288,11 @@ final class Fixups extends AbstractCollection {
int index = 0; // index into entries
int bigIndex = BIGSIZE+1; // index into bigDescs
int next = head; // desc pointing to next fixup
+ @Override
public boolean hasNext() { return index < size; }
+ @Override
public void remove() { throw new UnsupportedOperationException(); }
+ @Override
public Fixup next() {
int thisIndex = index;
return new Fixup(nextDesc(), entries[thisIndex]);
@@ -293,17 +317,20 @@ final class Fixups extends AbstractCollection {
}
}
+ @Override
public Iterator iterator() {
return new Itr();
}
public void add(int location, int format, Entry entry) {
addDesc(makeDesc(location, format), entry);
}
+ @Override
public boolean add(Fixup f) {
addDesc(f.desc, f.entry);
return true;
}
+ @Override
public boolean addAll(Collection extends Fixup> c) {
if (c instanceof Fixups) {
// Use knowledge of Itr structure to avoid building little structs.
@@ -367,7 +394,13 @@ final class Fixups extends AbstractCollection {
}
/// Static methods that optimize the use of this class.
- public static
+ static Object addRefWithBytes(Object f, byte[] bytes, Entry e) {
+ return add(f, bytes, 0, U2_FORMAT, e);
+ }
+ static Object addRefWithLoc(Object f, int loc, Entry entry) {
+ return add(f, null, loc, U2_FORMAT, entry);
+ }
+ private static
Object add(Object prevFixups,
byte[] bytes, int loc, int fmt,
Entry e) {
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java
index 64f9db5c309..af78754e06b 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.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
@@ -259,7 +259,7 @@ class Package {
byte[] bytes = new byte[2];
sfName = getRefString(obvious);
Object f = null;
- f = Fixups.add(f, bytes, 0, Fixups.U2_FORMAT, sfName);
+ f = Fixups.addRefWithBytes(f, bytes, sfName);
a = attrSourceFileSpecial.addContent(bytes, f);
}
} else if (obvious.equals(sfName.stringValue())) {
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java
index b42dda30eb4..000a643f873 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java
@@ -116,7 +116,7 @@ class PackageReader extends BandStructure {
int nr = super.read(b, off, len);
servedPos = pos;
if (nr >= 0) served += nr;
- assert(served <= limit || limit == -1);
+ //assert(served <= limit || limit == -1);
return nr;
}
public long skip(long n) throws IOException {
@@ -1500,6 +1500,7 @@ class PackageReader extends BandStructure {
// ic_local_bands
// *class_ClassFile_version_minor_H :UNSIGNED5
// *class_ClassFile_version_major_H :UNSIGNED5
+ // class_type_metadata_bands
//
// field_attr_bands:
// *field_flags :UNSIGNED5
@@ -1509,6 +1510,7 @@ class PackageReader extends BandStructure {
// *field_Signature_RS :UNSIGNED5 (cp_Signature)
// field_metadata_bands
// *field_ConstantValue_KQ :UNSIGNED5 (cp_Int, etc.; see note)
+ // field_type_metadata_bands
//
// method_attr_bands:
// *method_flags :UNSIGNED5
@@ -1522,6 +1524,7 @@ class PackageReader extends BandStructure {
// *method_MethodParameters_NB: BYTE1
// *method_MethodParameters_RUN: UNSIGNED5 (cp_Utf8)
// *method_MethodParameters_FH: UNSIGNED5 (flag)
+ // method_type_metadata_bands
//
// code_attr_bands:
// *code_flags :UNSIGNED5
@@ -1537,6 +1540,7 @@ class PackageReader extends BandStructure {
// *code_LocalVariableTable_name_RU :UNSIGNED5 (cp_Utf8)
// *code_LocalVariableTable_type_RS :UNSIGNED5 (cp_Signature)
// *code_LocalVariableTable_slot :UNSIGNED5
+ // code_type_metadata_bands
countAttrs(ctype, holders);
readAttrs(ctype, holders);
@@ -1703,8 +1707,9 @@ class PackageReader extends BandStructure {
class_InnerClasses_outer_RCN.readFrom(in);
class_InnerClasses_name_RUN.expectLength(tupleCount);
class_InnerClasses_name_RUN.readFrom(in);
- } else if (totalCount == 0) {
- // Expect no elements at all. Skip quickly.
+ } else if (!optDebugBands && totalCount == 0) {
+ // Expect no elements at all. Skip quickly. however if we
+ // are debugging bands, read all bands regardless
for (int j = 0; j < ab.length; j++) {
ab[j].doneWithUnusedBand();
}
@@ -1723,11 +1728,17 @@ class PackageReader extends BandStructure {
assert(cbles[j].kind == Attribute.EK_CBLE);
int entryCount = forwardCounts[j];
forwardCounts[j] = -1; // No more, please!
- if (cbles[j].flagTest(Attribute.EF_BACK))
+ if (totalCount > 0 && cbles[j].flagTest(Attribute.EF_BACK))
entryCount += xxx_attr_calls.getInt();
readAttrBands(cbles[j].body, entryCount, forwardCounts, ab);
}
}
+ // mark them read, to satisfy asserts
+ if (optDebugBands && totalCount == 0) {
+ for (int j = 0; j < ab.length; j++) {
+ ab[j].doneDisbursing();
+ }
+ }
}
}
if (!predef) break;
@@ -2154,11 +2165,10 @@ class PackageReader extends BandStructure {
if (size == 1) ldcRefSet.add(ref);
int fmt;
switch (size) {
- case 1: fmt = Fixups.U1_FORMAT; break;
- case 2: fmt = Fixups.U2_FORMAT; break;
+ case 1: fixupBuf.addU1(pc, ref); break;
+ case 2: fixupBuf.addU2(pc, ref); break;
default: assert(false); fmt = 0;
}
- fixupBuf.add(pc, fmt, ref);
buf[pc+0] = buf[pc+1] = 0;
pc += size;
}
@@ -2193,7 +2203,7 @@ class PackageReader extends BandStructure {
int coding = bc_initref.getInt();
// Find the nth overloading of in classRef.
MemberEntry ref = pkg.cp.getOverloadingForIndex(CONSTANT_Methodref, classRef, "", coding);
- fixupBuf.add(pc, Fixups.U2_FORMAT, ref);
+ fixupBuf.addU2(pc, ref);
buf[pc+0] = buf[pc+1] = 0;
pc += 2;
assert(Instruction.opLength(origBC) == (pc - curPC));
@@ -2226,7 +2236,7 @@ class PackageReader extends BandStructure {
insnMap[numInsns++] = curPC;
}
buf[pc++] = (byte) origBC;
- fixupBuf.add(pc, Fixups.U2_FORMAT, ref);
+ fixupBuf.addU2(pc, ref);
buf[pc+0] = buf[pc+1] = 0;
pc += 2;
assert(Instruction.opLength(origBC) == (pc - curPC));
@@ -2289,11 +2299,10 @@ class PackageReader extends BandStructure {
buf[pc++] = (byte) origBC;
int fmt;
switch (size) {
- case 1: fmt = Fixups.U1_FORMAT; break;
- case 2: fmt = Fixups.U2_FORMAT; break;
+ case 1: fixupBuf.addU1(pc, ref); break;
+ case 2: fixupBuf.addU2(pc, ref); break;
default: assert(false); fmt = 0;
}
- fixupBuf.add(pc, fmt, ref);
buf[pc+0] = buf[pc+1] = 0;
pc += size;
if (origBC == _multianewarray) {
diff --git a/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java b/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java
index 24f7343ac70..3c0b6a53137 100644
--- a/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java
+++ b/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java
@@ -102,7 +102,7 @@ public class DnsContext extends ComponentDirContext {
this.domain = new DnsName(domain.endsWith(".")
? domain
: domain + ".");
- this.servers = servers;
+ this.servers = (servers == null) ? null : servers.clone();
this.environment = (Hashtable