# HG changeset patch # User prr # Date 1411150778 25200 # Node ID 00b27213d86c2f36abb124f213c014b234a801aa # Parent 66228a695a62d84841abe1a96d9f865313f40664# Parent 2aa1709a8043fd81f554b25cf76ce13f96d59688 Merge diff -r 66228a695a62 -r 00b27213d86c .hgtags --- a/.hgtags Fri Sep 19 11:13:27 2014 -0700 +++ b/.hgtags Fri Sep 19 11:19:38 2014 -0700 @@ -273,3 +273,4 @@ f4269e8f454eb77763ecee228a88ae102a9aef6e jdk9-b28 c36c0092693707a8255561433647e8c3cd724ccd jdk9-b29 b2287cac7813c70ed7f679d9a46fe774bd4005f8 jdk9-b30 +9d0e6639a4d71b63507dd94b1a028e963b27e798 jdk9-b31 diff -r 66228a695a62 -r 00b27213d86c .hgtags-top-repo --- a/.hgtags-top-repo Fri Sep 19 11:13:27 2014 -0700 +++ b/.hgtags-top-repo Fri Sep 19 11:19:38 2014 -0700 @@ -273,3 +273,4 @@ ea2f7981236f3812436958748ab3d26e80a35130 jdk9-b28 9e6581aeda388a23fbee021fc33e6aa152a60657 jdk9-b29 36e9bc875325813ac9c44ac0c617a463091fa9f5 jdk9-b30 +69a84c16d9c28e0e3d504b9c8766c24bafcd58f6 jdk9-b31 diff -r 66228a695a62 -r 00b27213d86c Makefile --- a/Makefile Fri Sep 19 11:13:27 2014 -0700 +++ b/Makefile Fri Sep 19 11:19:38 2014 -0700 @@ -70,8 +70,8 @@ # Run the makefile with an arbitrary SPEC using -p -q (quiet dry-run and dump rules) to find # available PHONY targets. Use this list as valid targets to pass on to the repeated calls. all_phony_targets := $(sort $(filter-out $(global_targets), $(strip $(shell \ - cd $(root_dir)/make && $(MAKE) -f Main.gmk -p -q FRC SPEC=$(firstword $(SPEC)) | \ - grep "^.PHONY:" | head -n 1 | cut -d " " -f 2-)))) + cd $(root_dir)/make && $(MAKE) -f Main.gmk -p -q FRC SPEC=$(firstword $(SPEC)) \ + -I $(root_dir)/make/common | grep "^.PHONY:" | head -n 1 | cut -d " " -f 2-)))) # Loop through the configurations and call the main-wrapper for each one. The wrapper # target will execute with a single configuration loaded. @@ -115,12 +115,12 @@ main-wrapper: ifneq ($(SEQUENTIAL_TARGETS), ) - (cd $(root_dir)/make && $(MAKE) -f Main.gmk SPEC=$(SPEC) -j 1 \ + (cd $(SRC_ROOT)/make && $(MAKE) -f Main.gmk SPEC=$(SPEC) -j 1 \ $(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) $(SEQUENTIAL_TARGETS)) endif ifneq ($(PARALLEL_TARGETS), ) @$(call AtMakeStart) - (cd $(root_dir)/make && $(BUILD_LOG_WRAPPER) $(MAKE) -f Main.gmk SPEC=$(SPEC) -j $(JOBS) \ + (cd $(SRC_ROOT)/make && $(BUILD_LOG_WRAPPER) $(MAKE) -f Main.gmk SPEC=$(SPEC) -j $(JOBS) \ $(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) $(PARALLEL_TARGETS) \ $(if $(filter true, $(OUTPUT_SYNC_SUPPORTED)), -O$(OUTPUT_SYNC))) @$(call AtMakeEnd) diff -r 66228a695a62 -r 00b27213d86c common/autoconf/generated-configure.sh --- a/common/autoconf/generated-configure.sh Fri Sep 19 11:13:27 2014 -0700 +++ b/common/autoconf/generated-configure.sh Fri Sep 19 11:19:38 2014 -0700 @@ -4327,7 +4327,7 @@ #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1410377275 +DATE_WHEN_GENERATED=1410791401 ############################################################################### # @@ -14642,7 +14642,7 @@ FASTDEBUG="false" DEBUG_CLASSFILES="true" BUILD_VARIANT_RELEASE="-debug" - HOTSPOT_DEBUG_LEVEL="jvmg" + HOTSPOT_DEBUG_LEVEL="debug" HOTSPOT_EXPORT="debug" ;; optimized ) diff -r 66228a695a62 -r 00b27213d86c common/autoconf/hotspot-spec.gmk.in --- a/common/autoconf/hotspot-spec.gmk.in Fri Sep 19 11:13:27 2014 -0700 +++ b/common/autoconf/hotspot-spec.gmk.in Fri Sep 19 11:19:38 2014 -0700 @@ -97,8 +97,6 @@ endif HOTSPOT_MAKE_ARGS:=@HOTSPOT_MAKE_ARGS@ @STATIC_CXX_SETTING@ -# This is used from the libjvm build for C/C++ code. -HOTSPOT_BUILD_JOBS:=$(JOBS) # Control wether Hotspot runs Queens test after building TEST_IN_BUILD=@TEST_IN_BUILD@ diff -r 66228a695a62 -r 00b27213d86c common/autoconf/jdk-options.m4 --- a/common/autoconf/jdk-options.m4 Fri Sep 19 11:13:27 2014 -0700 +++ b/common/autoconf/jdk-options.m4 Fri Sep 19 11:19:38 2014 -0700 @@ -234,7 +234,7 @@ FASTDEBUG="false" DEBUG_CLASSFILES="true" BUILD_VARIANT_RELEASE="-debug" - HOTSPOT_DEBUG_LEVEL="jvmg" + HOTSPOT_DEBUG_LEVEL="debug" HOTSPOT_EXPORT="debug" ;; optimized ) diff -r 66228a695a62 -r 00b27213d86c common/autoconf/spec.gmk.in --- a/common/autoconf/spec.gmk.in Fri Sep 19 11:13:27 2014 -0700 +++ b/common/autoconf/spec.gmk.in Fri Sep 19 11:19:38 2014 -0700 @@ -245,6 +245,7 @@ NASHORN_OUTPUTDIR=$(BUILD_OUTPUT)/nashorn IMAGES_OUTPUTDIR=$(BUILD_OUTPUT)/images TESTMAKE_OUTPUTDIR=$(BUILD_OUTPUT)/testmake +MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/make-support LANGTOOLS_DIST=$(LANGTOOLS_OUTPUTDIR)/dist CORBA_DIST=$(CORBA_OUTPUTDIR)/dist diff -r 66228a695a62 -r 00b27213d86c common/bin/unshuffle_list.txt --- a/common/bin/unshuffle_list.txt Fri Sep 19 11:13:27 2014 -0700 +++ b/common/bin/unshuffle_list.txt Fri Sep 19 11:19:38 2014 -0700 @@ -1216,14 +1216,13 @@ jdk/src/java.security.acl/share/classes/sun/security/acl : jdk/src/share/classes/sun/security/acl jdk/src/java.security.jgss/macosx/native/libosxkrb5/nativeccache.c : jdk/src/share/native/sun/security/krb5/nativeccache.c jdk/src/java.security.jgss/macosx/native/libosxkrb5/SCDynamicStoreConfig.m : jdk/src/macosx/native/sun/security/krb5/SCDynamicStoreConfig.m -jdk/src/java.security.jgss/share/classes/com/sun/security/jgss : jdk/src/share/classes/com/sun/security/jgss -jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb : jdk/src/share/classes/com/sun/security/sasl/gsskerb jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos : jdk/src/share/classes/javax/security/auth/kerberos jdk/src/java.security.jgss/share/classes/jgss-overview.html : jdk/src/share/classes/com/sun/security/jgss/jgss-overview.html jdk/src/java.security.jgss/share/classes/org/ietf/jgss : jdk/src/share/classes/org/ietf/jgss jdk/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego : jdk/src/share/classes/sun/net/www/protocol/http/spnego jdk/src/java.security.jgss/share/classes/sun/security/jgss : jdk/src/share/classes/sun/security/jgss jdk/src/java.security.jgss/share/classes/sun/security/krb5 : jdk/src/share/classes/sun/security/krb5 +jdk/src/java.security.jgss/windows/classes/sun/security/krb5 : jdk/src/windows/classes/sun/security/krb5 jdk/src/java.security.jgss/share/classes/sun/security/ssl/krb5 : jdk/src/share/classes/sun/security/ssl/krb5 jdk/src/java.security.jgss/share/native/libj2gss : jdk/src/share/native/sun/security/jgss/wrapper jdk/src/java.security.jgss/unix/native/libj2gss : jdk/src/solaris/native/sun/security/jgss/wrapper @@ -1477,6 +1476,8 @@ jdk/src/jdk.security.auth/share/classes/jaas-overview.html : jdk/src/share/classes/com/sun/security/auth/jaas-overview.html jdk/src/jdk.security.auth/unix/native/libjaas : jdk/src/solaris/native/com/sun/security/auth/module jdk/src/jdk.security.auth/windows/native/libjaas : jdk/src/windows/native/com/sun/security/auth/module +jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss : jdk/src/share/classes/com/sun/security/jgss +jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb : jdk/src/share/classes/com/sun/security/sasl/gsskerb jdk/src/jdk.snmp/share/classes/com/sun/jmx/snmp : jdk/src/share/classes/com/sun/jmx/snmp jdk/src/jdk.snmp/share/classes/sun/management/snmp : jdk/src/share/classes/sun/management/snmp jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs : jdk/src/share/classes/jdk/nio/zipfs diff -r 66228a695a62 -r 00b27213d86c corba/.hgtags --- a/corba/.hgtags Fri Sep 19 11:13:27 2014 -0700 +++ b/corba/.hgtags Fri Sep 19 11:19:38 2014 -0700 @@ -273,3 +273,4 @@ a00b04ef067e39f50b9a0fea6f1904e35d632a73 jdk9-b28 163a9cd806fd09970baf1f5f42b92a3cfe7ee945 jdk9-b29 98967ae6ae53ebf15615e07cd5a6b1ae04dfd84c jdk9-b30 +c432b80aadd0cb2b2361b02add4d671957d4cec9 jdk9-b31 diff -r 66228a695a62 -r 00b27213d86c hotspot/.hgtags --- a/hotspot/.hgtags Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/.hgtags Fri Sep 19 11:19:38 2014 -0700 @@ -433,3 +433,4 @@ 657294869d7ff063e055f5492cab7ce5612ca851 jdk9-b28 deb29e92f68ace2808a36ecfa18c7d61dcb645bb jdk9-b29 5c722dffbc0f34eb8d903dca7b261e52248fa17e jdk9-b30 +9f7d155d28e519f3e4645dc21cf185c25f3176ed jdk9-b31 diff -r 66228a695a62 -r 00b27213d86c hotspot/agent/src/os/win32/windbg/sawindbg.cpp --- a/hotspot/agent/src/os/win32/windbg/sawindbg.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/agent/src/os/win32/windbg/sawindbg.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -112,7 +112,9 @@ return;} static void throwNewDebuggerException(JNIEnv* env, const char* errMsg) { - env->ThrowNew(env->FindClass("sun/jvm/hotspot/debugger/DebuggerException"), errMsg); + jclass clazz = env->FindClass("sun/jvm/hotspot/debugger/DebuggerException"); + CHECK_EXCEPTION; + env->ThrowNew(clazz, errMsg); } /* @@ -310,15 +312,18 @@ static bool setImageAndSymbolPath(JNIEnv* env, jobject obj) { jboolean isCopy; jclass clazz = env->GetObjectClass(obj); + CHECK_EXCEPTION_(false); jstring path; const char* buf; path = (jstring) env->GetStaticObjectField(clazz, imagePath_ID); + CHECK_EXCEPTION_(false); buf = env->GetStringUTFChars(path, &isCopy); CHECK_EXCEPTION_(false); AutoJavaString imagePath(env, path, buf); path = (jstring) env->GetStaticObjectField(clazz, symbolPath_ID); + CHECK_EXCEPTION_(false); buf = env->GetStringUTFChars(path, &isCopy); CHECK_EXCEPTION_(false); AutoJavaString symbolPath(env, path, buf); diff -r 66228a695a62 -r 00b27213d86c hotspot/make/Makefile --- a/hotspot/make/Makefile Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/make/Makefile Fri Sep 19 11:19:38 2014 -0700 @@ -95,6 +95,7 @@ COMMON_VM_PRODUCT_TARGETS=product product1 docs export_product COMMON_VM_FASTDEBUG_TARGETS=fastdebug fastdebug1 docs export_fastdebug COMMON_VM_DEBUG_TARGETS=debug debug1 docs export_debug +COMMON_VM_OPTIMIZED_TARGETS=optimized optimized1 docs export_optimized # JDK directory list JDK_DIRS=bin include jre lib demo @@ -111,20 +112,21 @@ all_product: product1 docs export_product all_fastdebug: fastdebug1 docs export_fastdebug all_debug: debug1 docs export_debug +all_optimized: optimized1 docs export_optimized else ifeq ($(MACOSX_UNIVERSAL),true) all_product: universal_product all_fastdebug: universal_fastdebug all_debug: universal_debug +all_optimized: universal_optimized else all_product: $(COMMON_VM_PRODUCT_TARGETS) all_fastdebug: $(COMMON_VM_FASTDEBUG_TARGETS) all_debug: $(COMMON_VM_DEBUG_TARGETS) +all_optimized: $(COMMON_VM_OPTIMIZED_TARGETS) endif endif -all_optimized: optimized optimized1 docs export_optimized - allzero: all_productzero all_fastdebugzero all_productzero: productzero docs export_product all_fastdebugzero: fastdebugzero docs export_fastdebug @@ -890,3 +892,5 @@ create_jdk copy_jdk update_jdk test_jdk \ copy_product_jdk copy_fastdebug_jdk copy_debug_jdk \ $(HS_ALT_MAKE)/Makefile.make remove_old_debuginfo + +.NOTPARALLEL: diff -r 66228a695a62 -r 00b27213d86c hotspot/make/aix/Makefile --- a/hotspot/make/aix/Makefile Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/make/aix/Makefile Fri Sep 19 11:19:38 2014 -0700 @@ -256,36 +256,36 @@ $(SUBDIRS_TIERED): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=tiered + +$(BUILDTREE) VARIANT=tiered $(SUBDIRS_C2): $(BUILDTREE_MAKE) ifeq ($(FORCE_TIERED),1) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=tiered FORCE_TIERED=1 + +$(BUILDTREE) VARIANT=tiered FORCE_TIERED=1 else $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=compiler2 + +$(BUILDTREE) VARIANT=compiler2 endif $(SUBDIRS_C1): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=compiler1 + +$(BUILDTREE) VARIANT=compiler1 $(SUBDIRS_CORE): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=core + +$(BUILDTREE) VARIANT=core $(SUBDIRS_ZERO): $(BUILDTREE_MAKE) platform_zero $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH) + +$(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH) $(SUBDIRS_SHARK): $(BUILDTREE_MAKE) platform_zero $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH) + +$(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH) $(SUBDIRS_MINIMAL1): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=minimal1 + +$(BUILDTREE) VARIANT=minimal1 platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in @@ -379,3 +379,5 @@ .PHONY: all compiler1 compiler2 core zero shark .PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark docs clean_docs .PHONY: checks check_os_version check_j2se_version + +.NOTPARALLEL: diff -r 66228a695a62 -r 00b27213d86c hotspot/make/aix/makefiles/buildtree.make --- a/hotspot/make/aix/makefiles/buildtree.make Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/make/aix/makefiles/buildtree.make Fri Sep 19 11:19:38 2014 -0700 @@ -173,7 +173,7 @@ # Run make in each subdirectory recursively. $(SUBMAKE_DIRS): $(SIMPLE_DIRS) FORCE $(QUIETLY) [ -d $@ ] || { mkdir -p $@; } - $(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F) + +$(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F) $(QUIETLY) touch $@ $(SIMPLE_DIRS): @@ -364,3 +364,5 @@ FORCE: .PHONY: all FORCE + +.NOTPARALLEL: diff -r 66228a695a62 -r 00b27213d86c hotspot/make/aix/makefiles/top.make --- a/hotspot/make/aix/makefiles/top.make Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/make/aix/makefiles/top.make Fri Sep 19 11:19:38 2014 -0700 @@ -69,7 +69,13 @@ # Wierd argument adjustment for "gnumake -j..." adjust-mflags = $(GENERATED)/adjust-mflags -MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"` +# If SPEC is set, it's from configure and it's already controlling concurrency +# for us. Skip setting -j with HOTSPOT_BUILD_JOBS. +ifeq ($(SPEC), ) + MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"` +else + MFLAGS-adjusted = -r $(MFLAGS) +endif # default target: update lists, make vm @@ -116,7 +122,7 @@ @+mv $@+ $@ the_vm: vm_build_preliminaries $(adjust-mflags) - @$(UpdatePCH) + +@$(UpdatePCH) @$(MAKE) -f vm.make $(MFLAGS-adjusted) install gamma: the_vm @@ -125,7 +131,7 @@ # next rules support "make foo.[ois]" %.o %.i %.s: - $(UpdatePCH) + +$(UpdatePCH) $(MAKE) -f vm.make $(MFLAGS) $@ #$(MAKE) -f vm.make $@ @@ -142,3 +148,5 @@ .PHONY: default vm_build_preliminaries .PHONY: lists ad_stuff jvmti_stuff sa_stuff the_vm clean realclean .PHONY: checks check_os_version install + +.NOTPARALLEL: diff -r 66228a695a62 -r 00b27213d86c hotspot/make/bsd/Makefile --- a/hotspot/make/bsd/Makefile Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/make/bsd/Makefile Fri Sep 19 11:19:38 2014 -0700 @@ -250,36 +250,36 @@ $(SUBDIRS_TIERED): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=tiered + +$(BUILDTREE) VARIANT=tiered $(SUBDIRS_C2): $(BUILDTREE_MAKE) ifeq ($(FORCE_TIERED),1) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=tiered FORCE_TIERED=1 + +$(BUILDTREE) VARIANT=tiered FORCE_TIERED=1 else $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=compiler2 + +$(BUILDTREE) VARIANT=compiler2 endif $(SUBDIRS_C1): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=compiler1 + +$(BUILDTREE) VARIANT=compiler1 $(SUBDIRS_CORE): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=core + +$(BUILDTREE) VARIANT=core $(SUBDIRS_ZERO): $(BUILDTREE_MAKE) platform_zero $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH) + +$(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH) $(SUBDIRS_SHARK): $(BUILDTREE_MAKE) platform_zero $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH) + +$(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH) $(SUBDIRS_MINIMAL1): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=minimal1 + +$(BUILDTREE) VARIANT=minimal1 platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in $(SED) 's/@ZERO_ARCHDEF@/$(ZERO_ARCHDEF)/g;s/@ZERO_LIBARCH@/$(ZERO_LIBARCH)/g;' < $< > $@ @@ -392,3 +392,5 @@ .PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark docs clean_docs .PHONY: checks check_os_version check_j2se_version .PHONY: $(HS_ALT_MAKE)/$(OSNAME)/Makefile.make + +.NOTPARALLEL: diff -r 66228a695a62 -r 00b27213d86c hotspot/make/bsd/makefiles/buildtree.make --- a/hotspot/make/bsd/makefiles/buildtree.make Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/make/bsd/makefiles/buildtree.make Fri Sep 19 11:19:38 2014 -0700 @@ -178,7 +178,7 @@ # Run make in each subdirectory recursively. $(SUBMAKE_DIRS): $(SIMPLE_DIRS) FORCE $(QUIETLY) [ -d $@ ] || { mkdir -p $@; } - $(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F) + +$(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F) $(QUIETLY) touch $@ $(SIMPLE_DIRS): @@ -378,3 +378,5 @@ FORCE: .PHONY: all FORCE + +.NOTPARALLEL: diff -r 66228a695a62 -r 00b27213d86c hotspot/make/bsd/makefiles/top.make --- a/hotspot/make/bsd/makefiles/top.make Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/make/bsd/makefiles/top.make Fri Sep 19 11:19:38 2014 -0700 @@ -69,7 +69,13 @@ # Wierd argument adjustment for "gnumake -j..." adjust-mflags = $(GENERATED)/adjust-mflags -MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"` +# If SPEC is set, it's from configure and it's already controlling concurrency +# for us. Skip setting -j with HOTSPOT_BUILD_JOBS. +ifeq ($(SPEC), ) + MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"` +else + MFLAGS-adjusted = -r $(MFLAGS) +endif # default target: update lists, make vm @@ -125,7 +131,7 @@ @+mv $@+ $@ the_vm: vm_build_preliminaries $(adjust-mflags) - @$(UpdatePCH) + +@$(UpdatePCH) @$(MAKE) -f vm.make $(MFLAGS-adjusted) install : the_vm @@ -134,7 +140,7 @@ # next rules support "make foo.[ois]" %.o %.i %.s: - $(UpdatePCH) + +$(UpdatePCH) $(MAKE) -f vm.make $(MFLAGS) $@ #$(MAKE) -f vm.make $@ @@ -151,3 +157,5 @@ .PHONY: default vm_build_preliminaries .PHONY: lists ad_stuff jvmti_stuff sa_stuff the_vm clean realclean .PHONY: checks check_os_version install + +.NOTPARALLEL: diff -r 66228a695a62 -r 00b27213d86c hotspot/make/bsd/makefiles/universal.gmk --- a/hotspot/make/bsd/makefiles/universal.gmk Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/make/bsd/makefiles/universal.gmk Fri Sep 19 11:19:38 2014 -0700 @@ -25,6 +25,8 @@ # macosx universal builds universal_product: $(MAKE) MACOSX_UNIVERSAL=true all_product_universal +universal_optimized: + $(MAKE) MACOSX_UNIVERSAL=true all_optimized_universal universal_fastdebug: $(MAKE) MACOSX_UNIVERSAL=true all_fastdebug_universal universal_debug: @@ -36,6 +38,10 @@ # $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 $(COMMON_VM_PRODUCT_TARGETS) $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 $(COMMON_VM_PRODUCT_TARGETS) $(QUIETLY) $(MAKE) BUILD_FLAVOR=product EXPORT_SUBDIR= universalize +all_optimized_universal: +# $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 $(COMMON_VM_OPTIMIZED_TARGETS) + $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 $(COMMON_VM_OPTIMIZED_TARGETS) + $(QUIETLY) $(MAKE) BUILD_FLAVOR=optimized EXPORT_SUBDIR=/optimized universalize all_fastdebug_universal: # $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 $(COMMON_VM_FASTDEBUG_TARGETS) $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 $(COMMON_VM_FASTDEBUG_TARGETS) @@ -98,13 +104,15 @@ export_product_jdk:: $(MAKE) EXPORT_SUBDIR= export_universal export_optimized_jdk:: - $(MAKE) EXPORT_SUBDIR= export_universal + $(MAKE) EXPORT_SUBDIR=/optimized export_universal export_fastdebug_jdk:: $(MAKE) EXPORT_SUBDIR=/fastdebug export_universal export_debug_jdk:: $(MAKE) EXPORT_SUBDIR=/debug export_universal copy_product_jdk:: $(MAKE) COPY_SUBDIR= copy_universal +copy_optimized_jdk:: + $(MAKE) COPY_SUBDIR=/optimized copy_universal copy_fastdebug_jdk:: $(MAKE) COPY_SUBDIR=/fastdebug copy_universal copy_debug_jdk:: @@ -112,5 +120,6 @@ .PHONY: universal_product universal_fastdebug universal_debug \ all_product_universal all_fastdebug_universal all_debug_universal \ + universal_optimized all_optimized_universal \ universalize export_universal copy_universal \ $(UNIVERSAL_LIPO_LIST) $(UNIVERSAL_COPY_LIST) diff -r 66228a695a62 -r 00b27213d86c hotspot/make/linux/Makefile --- a/hotspot/make/linux/Makefile Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/make/linux/Makefile Fri Sep 19 11:19:38 2014 -0700 @@ -256,36 +256,36 @@ $(SUBDIRS_TIERED): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=tiered + +$(BUILDTREE) VARIANT=tiered $(SUBDIRS_C2): $(BUILDTREE_MAKE) ifeq ($(FORCE_TIERED),1) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=tiered FORCE_TIERED=1 + +$(BUILDTREE) VARIANT=tiered FORCE_TIERED=1 else $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=compiler2 + +$(BUILDTREE) VARIANT=compiler2 endif $(SUBDIRS_C1): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=compiler1 + +$(BUILDTREE) VARIANT=compiler1 $(SUBDIRS_CORE): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=core + +$(BUILDTREE) VARIANT=core $(SUBDIRS_ZERO): $(BUILDTREE_MAKE) platform_zero $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH) + +$(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH) $(SUBDIRS_SHARK): $(BUILDTREE_MAKE) platform_zero $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH) + +$(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH) $(SUBDIRS_MINIMAL1): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=minimal1 + +$(BUILDTREE) VARIANT=minimal1 platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in @@ -399,3 +399,5 @@ .PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark docs clean_docs .PHONY: checks check_os_version check_j2se_version .PHONY: $(HS_ALT_MAKE)/$(OSNAME)/Makefile.make + +.NOTPARALLEL: diff -r 66228a695a62 -r 00b27213d86c hotspot/make/linux/makefiles/buildtree.make --- a/hotspot/make/linux/makefiles/buildtree.make Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/make/linux/makefiles/buildtree.make Fri Sep 19 11:19:38 2014 -0700 @@ -172,7 +172,7 @@ # Run make in each subdirectory recursively. $(SUBMAKE_DIRS): $(SIMPLE_DIRS) FORCE $(QUIETLY) [ -d $@ ] || { mkdir -p $@; } - $(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F) + +$(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F) $(QUIETLY) touch $@ $(SIMPLE_DIRS): @@ -377,3 +377,5 @@ FORCE: .PHONY: all FORCE + +.NOTPARALLEL: diff -r 66228a695a62 -r 00b27213d86c hotspot/make/linux/makefiles/top.make --- a/hotspot/make/linux/makefiles/top.make Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/make/linux/makefiles/top.make Fri Sep 19 11:19:38 2014 -0700 @@ -69,7 +69,13 @@ # Wierd argument adjustment for "gnumake -j..." adjust-mflags = $(GENERATED)/adjust-mflags -MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"` +# If SPEC is set, it's from configure and it's already controlling concurrency +# for us. Skip setting -j with HOTSPOT_BUILD_JOBS. +ifeq ($(SPEC), ) + MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"` +else + MFLAGS-adjusted = -r $(MFLAGS) +endif # default target: update lists, make vm @@ -119,7 +125,7 @@ @+mv $@+ $@ the_vm: vm_build_preliminaries $(adjust-mflags) - @$(UpdatePCH) + +@$(UpdatePCH) @$(MAKE) -f vm.make $(MFLAGS-adjusted) install: the_vm @@ -128,7 +134,7 @@ # next rules support "make foo.[ois]" %.o %.i %.s: - $(UpdatePCH) + +$(UpdatePCH) $(MAKE) -f vm.make $(MFLAGS) $@ #$(MAKE) -f vm.make $@ @@ -145,3 +151,5 @@ .PHONY: default vm_build_preliminaries .PHONY: lists ad_stuff jvmti_stuff sa_stuff the_vm clean realclean .PHONY: checks check_os_version install + +.NOTPARALLEL: diff -r 66228a695a62 -r 00b27213d86c hotspot/make/solaris/Makefile --- a/hotspot/make/solaris/Makefile Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/make/solaris/Makefile Fri Sep 19 11:19:38 2014 -0700 @@ -200,24 +200,24 @@ $(SUBDIRS_TIERED): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=tiered + +$(BUILDTREE) VARIANT=tiered $(SUBDIRS_C2): $(BUILDTREE_MAKE) ifeq ($(FORCE_TIERED),1) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=tiered FORCE_TIERED=1 + +$(BUILDTREE) VARIANT=tiered FORCE_TIERED=1 else $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=compiler2 + +$(BUILDTREE) VARIANT=compiler2 endif $(SUBDIRS_C1): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=compiler1 + +$(BUILDTREE) VARIANT=compiler1 $(SUBDIRS_CORE): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks - $(BUILDTREE) VARIANT=core + +$(BUILDTREE) VARIANT=core # Define INSTALL=y at command line to automatically copy JVM into JAVA_HOME @@ -292,3 +292,5 @@ .PHONY: all compiler1 compiler2 core .PHONY: clean clean_compiler1 clean_compiler2 clean_core docs clean_docs .PHONY: checks check_os_version check_j2se_version + +.NOTPARALLEL: diff -r 66228a695a62 -r 00b27213d86c hotspot/make/solaris/makefiles/buildtree.make --- a/hotspot/make/solaris/makefiles/buildtree.make Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/make/solaris/makefiles/buildtree.make Fri Sep 19 11:19:38 2014 -0700 @@ -165,7 +165,7 @@ # Run make in each subdirectory recursively. $(SUBMAKE_DIRS): $(SIMPLE_DIRS) FORCE $(QUIETLY) [ -d $@ ] || { mkdir -p $@; } - $(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F) + +$(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F) $(QUIETLY) touch $@ $(SIMPLE_DIRS): @@ -364,3 +364,5 @@ FORCE: .PHONY: all FORCE + +.NOTPARALLEL: diff -r 66228a695a62 -r 00b27213d86c hotspot/make/solaris/makefiles/top.make --- a/hotspot/make/solaris/makefiles/top.make Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/make/solaris/makefiles/top.make Fri Sep 19 11:19:38 2014 -0700 @@ -62,7 +62,13 @@ # Wierd argument adjustment for "gnumake -j..." adjust-mflags = $(GENERATED)/adjust-mflags -MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"` +# If SPEC is set, it's from configure and it's already controlling concurrency +# for us. Skip setting -j with HOTSPOT_BUILD_JOBS. +ifeq ($(SPEC), ) + MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"` +else + MFLAGS-adjusted = -r $(MFLAGS) +endif # default target: update lists, make vm @@ -136,3 +142,5 @@ .PHONY: default vm_build_preliminaries .PHONY: lists ad_stuff jvmti_stuff trace_stuff sa_stuff the_vm clean realclean .PHONY: checks check_os_version install + +.NOTPARALLEL: diff -r 66228a695a62 -r 00b27213d86c hotspot/make/solaris/makefiles/vm.make --- a/hotspot/make/solaris/makefiles/vm.make Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/make/solaris/makefiles/vm.make Fri Sep 19 11:19:38 2014 -0700 @@ -143,7 +143,7 @@ LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc -ldemangle endif # sparcWorks -LIBS += -lkstat +LIBS += -lkstat -lpicl # By default, link the *.o into the library, not the executable. LINK_INTO$(LINK_INTO) = LIBJVM diff -r 66228a695a62 -r 00b27213d86c hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -32,6 +32,7 @@ int VM_Version::_features = VM_Version::unknown_m; const char* VM_Version::_features_str = ""; +unsigned int VM_Version::_L2_cache_line_size = 0; void VM_Version::initialize() { _features = determine_features(); @@ -192,7 +193,7 @@ } assert(BlockZeroingLowLimit > 0, "invalid value"); - if (has_block_zeroing()) { + if (has_block_zeroing() && cache_line_size > 0) { if (FLAG_IS_DEFAULT(UseBlockZeroing)) { FLAG_SET_DEFAULT(UseBlockZeroing, true); } @@ -202,7 +203,7 @@ } assert(BlockCopyLowLimit > 0, "invalid value"); - if (has_block_zeroing()) { // has_blk_init() && is_T4(): core's local L2 cache + if (has_block_zeroing() && cache_line_size > 0) { // has_blk_init() && is_T4(): core's local L2 cache if (FLAG_IS_DEFAULT(UseBlockCopy)) { FLAG_SET_DEFAULT(UseBlockCopy, true); } @@ -252,49 +253,6 @@ // buf is started with ", " or is empty _features_str = os::strdup(strlen(buf) > 2 ? buf + 2 : buf); - // There are three 64-bit SPARC families that do not overlap, e.g., - // both is_ultra3() and is_sparc64() cannot be true at the same time. - // Within these families, there can be more than one chip, e.g., - // is_T4() and is_T7() machines are also is_niagara(). - if (is_ultra3()) { - assert(_L1_data_cache_line_size == 0, "overlap with Ultra3 family"); - // Ref: UltraSPARC III Cu Processor - _L1_data_cache_line_size = 64; - } - if (is_niagara()) { - assert(_L1_data_cache_line_size == 0, "overlap with niagara family"); - // All Niagara's are sun4v's, but not all sun4v's are Niagaras, e.g., - // Fujitsu SPARC64 is sun4v, but we don't want it in this block. - // - // Ref: UltraSPARC T1 Supplement to the UltraSPARC Architecture 2005 - // Appendix F.1.3.1 Cacheable Accesses - // -> 16-byte L1 cache line size - // - // Ref: UltraSPARC T2: A Highly-Threaded, Power-Efficient, SPARC SOC - // Section III: SPARC Processor Core - // -> 16-byte L1 cache line size - // - // Ref: Oracle's SPARC T4-1, SPARC T4-2, SPARC T4-4, and SPARC T4-1B Server Architecture - // Section SPARC T4 Processor Cache Architecture - // -> 32-byte L1 cache line size (no longer see that info on this ref) - // - // XXX - still need a T7 reference here - // - if (is_T7()) { // T7 or newer - _L1_data_cache_line_size = 64; - } else if (is_T4()) { // T4 or newer (until T7) - _L1_data_cache_line_size = 32; - } else { // T1 or newer (until T4) - _L1_data_cache_line_size = 16; - } - } - if (is_sparc64()) { - guarantee(_L1_data_cache_line_size == 0, "overlap with SPARC64 family"); - // Ref: Fujitsu SPARC64 VII Processor - // Section 4 Cache System - _L1_data_cache_line_size = 64; - } - // UseVIS is set to the smallest of what hardware supports and what // the command line requires. I.e., you cannot set UseVIS to 3 on // older UltraSparc which do not support it. @@ -401,6 +359,7 @@ #ifndef PRODUCT if (PrintMiscellaneous && Verbose) { tty->print_cr("L1 data cache line size: %u", L1_data_cache_line_size()); + tty->print_cr("L2 cache line size: %u", L2_cache_line_size()); tty->print("Allocation"); if (AllocatePrefetchStyle <= 0) { tty->print_cr(": no prefetching"); diff -r 66228a695a62 -r 00b27213d86c hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp --- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -96,6 +96,9 @@ static int _features; static const char* _features_str; + static unsigned int _L2_cache_line_size; + static unsigned int L2_cache_line_size() { return _L2_cache_line_size; } + static void print_features(); static int determine_features(); static int platform_features(int features); @@ -167,9 +170,8 @@ static const char* cpu_features() { return _features_str; } - static intx prefetch_data_size() { - return is_T4() && !is_T7() ? 32 : 64; // default prefetch block size on sparc - } + // default prefetch block size on sparc + static intx prefetch_data_size() { return L2_cache_line_size(); } // Prefetch static intx prefetch_copy_interval_in_bytes() { diff -r 66228a695a62 -r 00b27213d86c hotspot/src/cpu/x86/vm/assembler_x86.hpp --- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -26,6 +26,7 @@ #define CPU_X86_VM_ASSEMBLER_X86_HPP #include "asm/register.hpp" +#include "vm_version_x86.hpp" class BiasedLockingCounters; @@ -1292,14 +1293,34 @@ if (order_constraint & StoreLoad) { // All usable chips support "locked" instructions which suffice // as barriers, and are much faster than the alternative of - // using cpuid instruction. We use here a locked add [esp],0. + // using cpuid instruction. We use here a locked add [esp-C],0. // This is conveniently otherwise a no-op except for blowing - // flags. + // flags, and introducing a false dependency on target memory + // location. We can't do anything with flags, but we can avoid + // memory dependencies in the current method by locked-adding + // somewhere else on the stack. Doing [esp+C] will collide with + // something on stack in current method, hence we go for [esp-C]. + // It is convenient since it is almost always in data cache, for + // any small C. We need to step back from SP to avoid data + // dependencies with other things on below SP (callee-saves, for + // example). Without a clear way to figure out the minimal safe + // distance from SP, it makes sense to step back the complete + // cache line, as this will also avoid possible second-order effects + // with locked ops against the cache line. Our choice of offset + // is bounded by x86 operand encoding, which should stay within + // [-128; +127] to have the 8-byte displacement encoding. + // // Any change to this code may need to revisit other places in // the code where this idiom is used, in particular the // orderAccess code. + + int offset = -VM_Version::L1_line_size(); + if (offset < -128) { + offset = -128; + } + lock(); - addl(Address(rsp, 0), 0);// Assert the lock# signal here + addl(Address(rsp, offset), 0);// Assert the lock# signal here } } } diff -r 66228a695a62 -r 00b27213d86c hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp --- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -820,14 +820,10 @@ } address InterpreterGenerator::generate_native_entry(bool synchronized) { - assert(synchronized == false, "should be"); - return generate_entry((address) CppInterpreter::native_entry); } address InterpreterGenerator::generate_normal_entry(bool synchronized) { - assert(synchronized == false, "should be"); - return generate_entry((address) CppInterpreter::normal_entry); } diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os/bsd/vm/os_bsd.cpp --- a/hotspot/src/os/bsd/vm/os_bsd.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -1644,8 +1644,20 @@ return true; } +int _print_dll_info_cb(const char * name, address base_address, address top_address, void * param) { + outputStream * out = (outputStream *) param; + out->print_cr(PTR_FORMAT " \t%s", base_address, name); + return 0; +} + void os::print_dll_info(outputStream *st) { st->print_cr("Dynamic libraries:"); + if (get_loaded_modules_info(_print_dll_info_cb, (void *)st)) { + st->print_cr("Error: Cannot print dynamic libraries."); + } +} + +int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) { #ifdef RTLD_DI_LINKMAP Dl_info dli; void *handle; @@ -1654,36 +1666,41 @@ if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 || dli.dli_fname == NULL) { - st->print_cr("Error: Cannot print dynamic libraries."); - return; + return 1; } handle = dlopen(dli.dli_fname, RTLD_LAZY); if (handle == NULL) { - st->print_cr("Error: Cannot print dynamic libraries."); - return; + return 1; } dlinfo(handle, RTLD_DI_LINKMAP, &map); if (map == NULL) { - st->print_cr("Error: Cannot print dynamic libraries."); - return; + dlclose(handle); + return 1; } while (map->l_prev != NULL) map = map->l_prev; while (map != NULL) { - st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name); + // Value for top_address is returned as 0 since we don't have any information about module size + if (callback(map->l_name, (address)map->l_addr, (address)0, param)) { + dlclose(handle); + return 1; + } map = map->l_next; } dlclose(handle); #elif defined(__APPLE__) for (uint32_t i = 1; i < _dyld_image_count(); i++) { - st->print_cr(PTR_FORMAT " \t%s", _dyld_get_image_header(i), - _dyld_get_image_name(i)); + // Value for top_address is returned as 0 since we don't have any information about module size + if (callback(_dyld_get_image_name(i), (address)_dyld_get_image_header(i), (address)0, param)) { + return 1; + } } + return 0; #else - st->print_cr("Error: Cannot print dynamic libraries."); + return 1; #endif } diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os/linux/vm/os_linux.cpp --- a/hotspot/src/os/linux/vm/os_linux.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -2120,6 +2120,40 @@ } } +int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) { + FILE *procmapsFile = NULL; + + // Open the procfs maps file for the current process + if ((procmapsFile = fopen("/proc/self/maps", "r")) != NULL) { + // Allocate PATH_MAX for file name plus a reasonable size for other fields. + char line[PATH_MAX + 100]; + + // Read line by line from 'file' + while (fgets(line, sizeof(line), procmapsFile) != NULL) { + u8 base, top, offset, inode; + char permissions[5]; + char device[6]; + char name[PATH_MAX + 1]; + + // Parse fields from line + sscanf(line, "%lx-%lx %4s %lx %5s %ld %s", &base, &top, permissions, &offset, device, &inode, name); + + // Filter by device id '00:00' so that we only get file system mapped files. + if (strcmp(device, "00:00") != 0) { + + // Call callback with the fields of interest + if(callback(name, (address)base, (address)top, param)) { + // Oops abort, callback aborted + fclose(procmapsFile); + return 1; + } + } + } + fclose(procmapsFile); + } + return 0; +} + void os::print_os_info_brief(outputStream* st) { os::Linux::print_distro_info(st); diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os/posix/vm/os_posix.cpp --- a/hotspot/src/os/posix/vm/os_posix.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os/posix/vm/os_posix.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -215,6 +215,9 @@ struct utsname name; uname(&name); st->print("%s ", name.sysname); +#ifdef ASSERT + st->print("%s ", name.nodename); +#endif st->print("%s ", name.release); st->print("%s ", name.version); st->print("%s", name.machine); diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os/solaris/vm/os_solaris.cpp --- a/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -1722,41 +1722,54 @@ return false; } -// Prints the names and full paths of all opened dynamic libraries -// for current process -void os::print_dll_info(outputStream * st) { +int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) { Dl_info dli; - void *handle; + // Sanity check? + if (dladdr(CAST_FROM_FN_PTR(void *, os::get_loaded_modules_info), &dli) == 0 || + dli.dli_fname == NULL) { + return 1; + } + + void * handle = dlopen(dli.dli_fname, RTLD_LAZY); + if (handle == NULL) { + return 1; + } + Link_map *map; - Link_map *p; - - st->print_cr("Dynamic libraries:"); st->flush(); - - if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 || - dli.dli_fname == NULL) { - st->print_cr("Error: Cannot print dynamic libraries."); - return; - } - handle = dlopen(dli.dli_fname, RTLD_LAZY); - if (handle == NULL) { - st->print_cr("Error: Cannot print dynamic libraries."); - return; - } dlinfo(handle, RTLD_DI_LINKMAP, &map); if (map == NULL) { - st->print_cr("Error: Cannot print dynamic libraries."); - return; - } - - while (map->l_prev != NULL) + dlclose(handle); + return 1; + } + + while (map->l_prev != NULL) { map = map->l_prev; + } while (map != NULL) { - st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name); + // Iterate through all map entries and call callback with fields of interest + if(callback(map->l_name, (address)map->l_addr, (address)0, param)) { + dlclose(handle); + return 1; + } map = map->l_next; } dlclose(handle); + return 0; +} + +int _print_dll_info_cb(const char * name, address base_address, address top_address, void * param) { + outputStream * out = (outputStream *) param; + out->print_cr(PTR_FORMAT " \t%s", base_address, name); + return 0; +} + +void os::print_dll_info(outputStream * st) { + st->print_cr("Dynamic libraries:"); st->flush(); + if (get_loaded_modules_info(_print_dll_info_cb, (void *)st)) { + st->print_cr("Error: Cannot print dynamic libraries."); + } } // Loads .dll/.so and diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os/windows/vm/os_windows.cpp --- a/hotspot/src/os/windows/vm/os_windows.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -1301,120 +1301,6 @@ } #endif - -// Enumerate all modules for a given process ID -// -// Notice that Windows 95/98/Me and Windows NT/2000/XP have -// different API for doing this. We use PSAPI.DLL on NT based -// Windows and ToolHelp on 95/98/Me. - -// Callback function that is called by enumerate_modules() on -// every DLL module. -// Input parameters: -// int pid, -// char* module_file_name, -// address module_base_addr, -// unsigned module_size, -// void* param -typedef int (*EnumModulesCallbackFunc)(int, char *, address, unsigned, void *); - -// enumerate_modules for Windows NT, using PSAPI -static int _enumerate_modules_winnt( int pid, EnumModulesCallbackFunc func, void * param) -{ - HANDLE hProcess; - -# define MAX_NUM_MODULES 128 - HMODULE modules[MAX_NUM_MODULES]; - static char filename[MAX_PATH]; - int result = 0; - - if (!os::PSApiDll::PSApiAvailable()) { - return 0; - } - - hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, - FALSE, pid); - if (hProcess == NULL) return 0; - - DWORD size_needed; - if (!os::PSApiDll::EnumProcessModules(hProcess, modules, - sizeof(modules), &size_needed)) { - CloseHandle(hProcess); - return 0; - } - - // number of modules that are currently loaded - int num_modules = size_needed / sizeof(HMODULE); - - for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) { - // Get Full pathname: - if (!os::PSApiDll::GetModuleFileNameEx(hProcess, modules[i], - filename, sizeof(filename))) { - filename[0] = '\0'; - } - - MODULEINFO modinfo; - if (!os::PSApiDll::GetModuleInformation(hProcess, modules[i], - &modinfo, sizeof(modinfo))) { - modinfo.lpBaseOfDll = NULL; - modinfo.SizeOfImage = 0; - } - - // Invoke callback function - result = func(pid, filename, (address)modinfo.lpBaseOfDll, - modinfo.SizeOfImage, param); - if (result) break; - } - - CloseHandle(hProcess); - return result; -} - - -// enumerate_modules for Windows 95/98/ME, using TOOLHELP -static int _enumerate_modules_windows( int pid, EnumModulesCallbackFunc func, void *param) -{ - HANDLE hSnapShot; - static MODULEENTRY32 modentry; - int result = 0; - - if (!os::Kernel32Dll::HelpToolsAvailable()) { - return 0; - } - - // Get a handle to a Toolhelp snapshot of the system - hSnapShot = os::Kernel32Dll::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); - if (hSnapShot == INVALID_HANDLE_VALUE) { - return FALSE; - } - - // iterate through all modules - modentry.dwSize = sizeof(MODULEENTRY32); - bool not_done = os::Kernel32Dll::Module32First( hSnapShot, &modentry ) != 0; - - while (not_done) { - // invoke the callback - result=func(pid, modentry.szExePath, (address)modentry.modBaseAddr, - modentry.modBaseSize, param); - if (result) break; - - modentry.dwSize = sizeof(MODULEENTRY32); - not_done = os::Kernel32Dll::Module32Next( hSnapShot, &modentry ) != 0; - } - - CloseHandle(hSnapShot); - return result; -} - -int enumerate_modules( int pid, EnumModulesCallbackFunc func, void * param ) -{ - // Get current process ID if caller doesn't provide it. - if (!pid) pid = os::current_process_id(); - - if (os::win32::is_nt()) return _enumerate_modules_winnt (pid, func, param); - else return _enumerate_modules_windows(pid, func, param); -} - struct _modinfo { address addr; char* full_path; // point to a char buffer @@ -1422,13 +1308,13 @@ address base_addr; }; -static int _locate_module_by_addr(int pid, char * mod_fname, address base_addr, - unsigned size, void * param) { +static int _locate_module_by_addr(const char * mod_fname, address base_addr, + address top_address, void * param) { struct _modinfo *pmod = (struct _modinfo *)param; if (!pmod) return -1; - if (base_addr <= pmod->addr && - base_addr+size > pmod->addr) { + if (base_addr <= pmod->addr && + top_address > pmod->addr) { // if a buffer is provided, copy path name to the buffer if (pmod->full_path) { jio_snprintf(pmod->full_path, pmod->buflen, "%s", mod_fname); @@ -1453,8 +1339,7 @@ mi.addr = addr; mi.full_path = buf; mi.buflen = buflen; - int pid = os::current_process_id(); - if (enumerate_modules(pid, _locate_module_by_addr, (void *)&mi)) { + if (get_loaded_modules_info(_locate_module_by_addr, (void *)&mi)) { // buf already contains path name if (offset) *offset = addr - mi.base_addr; return true; @@ -1479,14 +1364,14 @@ } // save the start and end address of jvm.dll into param[0] and param[1] -static int _locate_jvm_dll(int pid, char* mod_fname, address base_addr, - unsigned size, void * param) { +static int _locate_jvm_dll(const char* mod_fname, address base_addr, + address top_address, void * param) { if (!param) return -1; - if (base_addr <= (address)_locate_jvm_dll && - base_addr+size > (address)_locate_jvm_dll) { + if (base_addr <= (address)_locate_jvm_dll && + top_address > (address)_locate_jvm_dll) { ((address*)param)[0] = base_addr; - ((address*)param)[1] = base_addr + size; + ((address*)param)[1] = top_address; return 1; } return 0; @@ -1497,8 +1382,7 @@ // check if addr is inside jvm.dll bool os::address_is_in_vm(address addr) { if (!vm_lib_location[0] || !vm_lib_location[1]) { - int pid = os::current_process_id(); - if (!enumerate_modules(pid, _locate_jvm_dll, (void *)vm_lib_location)) { + if (!get_loaded_modules_info(_locate_jvm_dll, (void *)vm_lib_location)) { assert(false, "Can't find jvm module."); return false; } @@ -1508,14 +1392,13 @@ } // print module info; param is outputStream* -static int _print_module(int pid, char* fname, address base, - unsigned size, void* param) { +static int _print_module(const char* fname, address base_address, + address top_address, void* param) { if (!param) return -1; outputStream* st = (outputStream*)param; - address end_addr = base + size; - st->print(PTR_FORMAT " - " PTR_FORMAT " \t%s\n", base, end_addr, fname); + st->print(PTR_FORMAT " - " PTR_FORMAT " \t%s\n", base_address, top_address, fname); return 0; } @@ -1644,11 +1527,60 @@ return NULL; } - void os::print_dll_info(outputStream *st) { - int pid = os::current_process_id(); st->print_cr("Dynamic libraries:"); - enumerate_modules(pid, _print_module, (void *)st); + get_loaded_modules_info(_print_module, (void *)st); +} + +int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) { + HANDLE hProcess; + +# define MAX_NUM_MODULES 128 + HMODULE modules[MAX_NUM_MODULES]; + static char filename[MAX_PATH]; + int result = 0; + + if (!os::PSApiDll::PSApiAvailable()) { + return 0; + } + + int pid = os::current_process_id(); + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, + FALSE, pid); + if (hProcess == NULL) return 0; + + DWORD size_needed; + if (!os::PSApiDll::EnumProcessModules(hProcess, modules, + sizeof(modules), &size_needed)) { + CloseHandle(hProcess); + return 0; + } + + // number of modules that are currently loaded + int num_modules = size_needed / sizeof(HMODULE); + + for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) { + // Get Full pathname: + if (!os::PSApiDll::GetModuleFileNameEx(hProcess, modules[i], + filename, sizeof(filename))) { + filename[0] = '\0'; + } + + MODULEINFO modinfo; + if (!os::PSApiDll::GetModuleInformation(hProcess, modules[i], + &modinfo, sizeof(modinfo))) { + modinfo.lpBaseOfDll = NULL; + modinfo.SizeOfImage = 0; + } + + // Invoke callback function + result = callback(filename, (address)modinfo.lpBaseOfDll, + (address)((u8)modinfo.lpBaseOfDll + (u8)modinfo.SizeOfImage), param); + if (result) break; + } + + CloseHandle(hProcess); + return result; } void os::print_os_info_brief(outputStream* st) { @@ -1656,8 +1588,17 @@ } void os::print_os_info(outputStream* st) { - st->print("OS:"); - +#ifdef ASSERT + char buffer[1024]; + DWORD size = sizeof(buffer); + st->print(" HostName: "); + if (GetComputerNameEx(ComputerNameDnsHostname, buffer, &size)) { + st->print("%s", buffer); + } else { + st->print("N/A"); + } +#endif + st->print(" OS:"); os::win32::print_windows_version(st); } diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp --- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -563,3 +563,8 @@ assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); } #endif + +int os::extra_bang_size_in_bytes() { + // PPC does not require the additional stack bang. + return 0; +} diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp --- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -1030,3 +1030,8 @@ void os::verify_stack_alignment() { } #endif + +int os::extra_bang_size_in_bytes() { + // JDK-8050147 requires the full cache line bang for x86. + return VM_Version::L1_line_size(); +} diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp --- a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -465,3 +465,8 @@ void os::verify_stack_alignment() { } #endif + +int os::extra_bang_size_in_bytes() { + // Zero does not require an additional stack bang. + return 0; +} diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp --- a/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -612,3 +612,8 @@ assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); } #endif + +int os::extra_bang_size_in_bytes() { + // PPC does not require the additional stack bang. + return 0; +} diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp --- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -752,3 +752,8 @@ void os::verify_stack_alignment() { } #endif + +int os::extra_bang_size_in_bytes() { + // SPARC does not require the additional stack bang. + return 0; +} diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp --- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -930,3 +930,8 @@ // keep the page mapped so CS limit isn't reduced. #endif } + +int os::extra_bang_size_in_bytes() { + // JDK-8050147 requires the full cache line bang for x86. + return VM_Version::L1_line_size(); +} diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp --- a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -495,3 +495,8 @@ void os::verify_stack_alignment() { } #endif + +int os::extra_bang_size_in_bytes() { + // Zero does not require an additional stack banging. + return 0; +} diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp --- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -774,3 +774,8 @@ void os::verify_stack_alignment() { } #endif + +int os::extra_bang_size_in_bytes() { + // SPARC does not require an additional stack bang. + return 0; +} diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp --- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -28,10 +28,140 @@ #include "runtime/os.hpp" #include "vm_version_sparc.hpp" -# include -# include -# include -# include +#include +#include +#include +#include +#include + +extern "C" static int PICL_get_l1_data_cache_line_size_helper(picl_nodehdl_t nodeh, void *result); +extern "C" static int PICL_get_l2_cache_line_size_helper(picl_nodehdl_t nodeh, void *result); + +class PICL { + // Get a value of the integer property. The value in the tree can be either 32 or 64 bit + // depending on the platform. The result is converted to int. + static int get_int_property(picl_nodehdl_t nodeh, const char* name, int* result) { + picl_propinfo_t pinfo; + picl_prophdl_t proph; + if (picl_get_prop_by_name(nodeh, name, &proph) != PICL_SUCCESS || + picl_get_propinfo(proph, &pinfo) != PICL_SUCCESS) { + return PICL_FAILURE; + } + + if (pinfo.type != PICL_PTYPE_INT && pinfo.type != PICL_PTYPE_UNSIGNED_INT) { + assert(false, "Invalid property type"); + return PICL_FAILURE; + } + if (pinfo.size == sizeof(int64_t)) { + int64_t val; + if (picl_get_propval(proph, &val, sizeof(int64_t)) != PICL_SUCCESS) { + return PICL_FAILURE; + } + *result = static_cast(val); + } else if (pinfo.size == sizeof(int32_t)) { + int32_t val; + if (picl_get_propval(proph, &val, sizeof(int32_t)) != PICL_SUCCESS) { + return PICL_FAILURE; + } + *result = static_cast(val); + } else { + assert(false, "Unexpected integer property size"); + return PICL_FAILURE; + } + return PICL_SUCCESS; + } + + // Visitor and a state machine that visits integer properties and verifies that the + // values are the same. Stores the unique value observed. + class UniqueValueVisitor { + enum { + INITIAL, // Start state, no assignments happened + ASSIGNED, // Assigned a value + INCONSISTENT // Inconsistent value seen + } _state; + int _value; + public: + UniqueValueVisitor() : _state(INITIAL) { } + int value() { + assert(_state == ASSIGNED, "Precondition"); + return _value; + } + void set_value(int value) { + assert(_state == INITIAL, "Precondition"); + _value = value; + _state = ASSIGNED; + } + bool is_initial() { return _state == INITIAL; } + bool is_assigned() { return _state == ASSIGNED; } + bool is_inconsistent() { return _state == INCONSISTENT; } + void set_inconsistent() { _state = INCONSISTENT; } + + static int visit(picl_nodehdl_t nodeh, const char* name, void *arg) { + UniqueValueVisitor *state = static_cast(arg); + assert(!state->is_inconsistent(), "Precondition"); + int curr; + if (PICL::get_int_property(nodeh, name, &curr) == PICL_SUCCESS) { + if (!state->is_assigned()) { // first iteration + state->set_value(curr); + } else if (curr != state->value()) { // following iterations + state->set_inconsistent(); + } + } + if (state->is_inconsistent()) { + return PICL_WALK_TERMINATE; + } + return PICL_WALK_CONTINUE; + } + }; + + int _L1_data_cache_line_size; + int _L2_cache_line_size; +public: + static int get_l1_data_cache_line_size(picl_nodehdl_t nodeh, void *state) { + return UniqueValueVisitor::visit(nodeh, "l1-dcache-line-size", state); + } + static int get_l2_cache_line_size(picl_nodehdl_t nodeh, void *state) { + return UniqueValueVisitor::visit(nodeh, "l2-cache-line-size", state); + } + + PICL() : _L1_data_cache_line_size(0), _L2_cache_line_size(0) { + if (picl_initialize() == PICL_SUCCESS) { + picl_nodehdl_t rooth; + if (picl_get_root(&rooth) == PICL_SUCCESS) { + UniqueValueVisitor L1_state; + // Visit all "cpu" class instances + picl_walk_tree_by_class(rooth, "cpu", &L1_state, PICL_get_l1_data_cache_line_size_helper); + if (L1_state.is_initial()) { // Still initial, iteration found no values + // Try walk all "core" class instances, it might be a Fujitsu machine + picl_walk_tree_by_class(rooth, "core", &L1_state, PICL_get_l1_data_cache_line_size_helper); + } + if (L1_state.is_assigned()) { // Is there a value? + _L1_data_cache_line_size = L1_state.value(); + } + + UniqueValueVisitor L2_state; + picl_walk_tree_by_class(rooth, "cpu", &L2_state, PICL_get_l2_cache_line_size_helper); + if (L2_state.is_initial()) { + picl_walk_tree_by_class(rooth, "core", &L2_state, PICL_get_l2_cache_line_size_helper); + } + if (L2_state.is_assigned()) { + _L2_cache_line_size = L2_state.value(); + } + } + picl_shutdown(); + } + } + + unsigned int L1_data_cache_line_size() const { return _L1_data_cache_line_size; } + unsigned int L2_cache_line_size() const { return _L2_cache_line_size; } +}; + +extern "C" static int PICL_get_l1_data_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) { + return PICL::get_l1_data_cache_line_size(nodeh, result); +} +extern "C" static int PICL_get_l2_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) { + return PICL::get_l2_cache_line_size(nodeh, result); +} // We need to keep these here as long as we have to build on Solaris // versions before 10. @@ -211,5 +341,10 @@ kstat_close(kc); } + // Figure out cache line sizes using PICL + PICL picl; + _L1_data_cache_line_size = picl.L1_data_cache_line_size(); + _L2_cache_line_size = picl.L2_cache_line_size(); + return features; } diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp --- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -918,3 +918,8 @@ #endif } #endif + +int os::extra_bang_size_in_bytes() { + // JDK-8050147 requires the full cache line bang for x86. + return VM_Version::L1_line_size(); +} diff -r 66228a695a62 -r 00b27213d86c hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp --- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -639,3 +639,8 @@ #endif } #endif + +int os::extra_bang_size_in_bytes() { + // JDK-8050147 requires the full cache line bang for x86. + return VM_Version::L1_line_size(); +} diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/c1/c1_LIRAssembler.cpp --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -170,7 +170,7 @@ // removes the need to bang the stack in the deoptimization blob which // in turn simplifies stack overflow handling. int LIR_Assembler::bang_size_in_bytes() const { - return MAX2(initial_frame_size_in_bytes(), _compilation->interpreter_frame_size()); + return MAX2(initial_frame_size_in_bytes() + os::extra_bang_size_in_bytes(), _compilation->interpreter_frame_size()); } void LIR_Assembler::emit_exception_entries(ExceptionInfoList* info_list) { diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/ci/ciEnv.cpp --- a/hotspot/src/share/vm/ci/ciEnv.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/ci/ciEnv.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -926,7 +926,7 @@ #ifdef ASSERT if (!counter_changed && !PrintCompilation) { // Print out the compile task that failed - _task->print_line(); + _task->print_tty(); } #endif assert(counter_changed, "failed dependencies, but counter didn't change"); diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/classfile/classLoader.cpp --- a/hotspot/src/share/vm/classfile/classLoader.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/classfile/classLoader.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -1528,7 +1528,7 @@ if (TieredCompilation && TieredStopAtLevel >= CompLevel_full_optimization) { // Clobber the first compile and force second tier compilation nmethod* nm = m->code(); - if (nm != NULL) { + if (nm != NULL && !m->is_method_handle_intrinsic()) { // Throw out the code so that the code cache doesn't fill up nm->make_not_entrant(); m->clear_code(); @@ -1547,7 +1547,7 @@ } nmethod* nm = m->code(); - if (nm != NULL) { + if (nm != NULL && !m->is_method_handle_intrinsic()) { // Throw out the code so that the code cache doesn't fill up nm->make_not_entrant(); m->clear_code(); diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/classfile/classLoaderData.cpp --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -746,7 +746,7 @@ // mark metadata seen on the stack and code cache so we can delete // unneeded entries. bool has_redefined_a_class = JvmtiExport::has_redefined_a_class(); - MetadataOnStackMark md_on_stack; + MetadataOnStackMark md_on_stack(has_redefined_a_class); if (has_redefined_a_class) { // purge_previous_versions also cleans weak method links. Because // one method's MDO can reference another method from another diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/classfile/metadataOnStackMark.cpp --- a/hotspot/src/share/vm/classfile/metadataOnStackMark.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/classfile/metadataOnStackMark.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ // Walk metadata on the stack and mark it so that redefinition doesn't delete // it. Class unloading also walks the previous versions and might try to // delete it, so this class is used by class unloading also. -MetadataOnStackMark::MetadataOnStackMark() { +MetadataOnStackMark::MetadataOnStackMark(bool has_redefined_a_class) { assert(SafepointSynchronize::is_at_safepoint(), "sanity check"); NOT_PRODUCT(_is_active = true;) if (_marked_objects == NULL) { @@ -49,7 +49,7 @@ } Threads::metadata_do(Metadata::mark_on_stack); - if (JvmtiExport::has_redefined_a_class()) { + if (has_redefined_a_class) { CodeCache::alive_nmethods_do(nmethod::mark_on_stack); } CompileBroker::mark_on_stack(); diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/classfile/metadataOnStackMark.hpp --- a/hotspot/src/share/vm/classfile/metadataOnStackMark.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/classfile/metadataOnStackMark.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ class MetadataOnStackMark : public StackObj { NOT_PRODUCT(static bool _is_active;) public: - MetadataOnStackMark(); + MetadataOnStackMark(bool has_redefined_a_class); ~MetadataOnStackMark(); static void record(Metadata* m); }; diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/classfile/systemDictionary.cpp --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -52,6 +52,7 @@ #include "oops/typeArrayKlass.hpp" #include "prims/jvmtiEnvBase.hpp" #include "prims/methodHandles.hpp" +#include "runtime/arguments.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/fieldType.hpp" #include "runtime/handles.inline.hpp" @@ -2274,7 +2275,11 @@ m = Method::make_method_handle_intrinsic(iid, signature, CHECK_(empty)); CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_highest_tier, methodHandle(), CompileThreshold, "MH", CHECK_(empty)); - + // Check if we need to have compiled code but we don't. + if (!Arguments::is_interpreter_only() && !m->has_compiled_code()) { + THROW_MSG_(vmSymbols::java_lang_VirtualMachineError(), + "out of space in CodeCache for method handle intrinsic", empty); + } // Now grab the lock. We might have to throw away the new method, // if a racing thread has managed to install one at the same time. { @@ -2288,6 +2293,9 @@ } assert(spe != NULL && spe->method() != NULL, ""); + assert(Arguments::is_interpreter_only() || (spe->method()->has_compiled_code() && + spe->method()->code()->entry_point() == spe->method()->from_compiled_entry()), + "MH intrinsic invariant"); return spe->method(); } diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/code/codeCache.cpp --- a/hotspot/src/share/vm/code/codeCache.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/code/codeCache.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -249,6 +249,7 @@ #define FOR_ALL_BLOBS(var) for (CodeBlob *var = first() ; var != NULL; var = next(var) ) #define FOR_ALL_ALIVE_BLOBS(var) for (CodeBlob *var = alive(first()); var != NULL; var = alive(next(var))) #define FOR_ALL_ALIVE_NMETHODS(var) for (nmethod *var = alive_nmethod(first()); var != NULL; var = alive_nmethod(next(var))) +#define FOR_ALL_NMETHODS(var) for (nmethod *var = first_nmethod(); var != NULL; var = next_nmethod(var)) bool CodeCache::contains(void *p) { @@ -687,7 +688,9 @@ void CodeCache::mark_all_nmethods_for_deoptimization() { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); FOR_ALL_ALIVE_NMETHODS(nm) { - nm->mark_for_deoptimization(); + if (!nm->method()->is_method_handle_intrinsic()) { + nm->mark_for_deoptimization(); + } } } @@ -967,6 +970,25 @@ } } +void CodeCache::print_codelist(outputStream* st) { + assert_locked_or_safepoint(CodeCache_lock); + + FOR_ALL_NMETHODS(p) { + ResourceMark rm; + char *method_name = p->method()->name_and_sig_as_C_string(); + st->print_cr("%d %d %s ["INTPTR_FORMAT", "INTPTR_FORMAT" - "INTPTR_FORMAT"]", + p->compile_id(), p->comp_level(), method_name, (intptr_t)p->header_begin(), + (intptr_t)p->code_begin(), (intptr_t)p->code_end()); + } +} + +void CodeCache::print_layout(outputStream* st) { + assert_locked_or_safepoint(CodeCache_lock); + ResourceMark rm; + + print_summary(st, true); +} + void CodeCache::log_state(outputStream* st) { st->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'" " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/code/codeCache.hpp --- a/hotspot/src/share/vm/code/codeCache.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/code/codeCache.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -152,6 +152,10 @@ static void print_summary(outputStream* st, bool detailed = true); // Prints a summary of the code cache usage static void log_state(outputStream* st); + // Dcmd (Diagnostic commands) + static void print_codelist(outputStream* st); + static void print_layout(outputStream* st); + // The full limits of the codeCache static address low_bound() { return (address) _heap->low_boundary(); } static address high_bound() { return (address) _heap->high_boundary(); } diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/code/compiledIC.cpp --- a/hotspot/src/share/vm/code/compiledIC.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/code/compiledIC.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -595,6 +595,7 @@ } else { // Callee is interpreted code. In any case entering the interpreter // puts a converter-frame on the stack to save arguments. + assert(!m->is_method_handle_intrinsic(), "Compiled code should never call interpreter MH intrinsics"); info._to_interpreter = true; info._entry = m()->get_c2i_entry(); } diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/code/nmethod.cpp --- a/hotspot/src/share/vm/code/nmethod.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/code/nmethod.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -2062,7 +2062,7 @@ "metadata must be found in exactly one place"); if (r->metadata_is_immediate() && r->metadata_value() != NULL) { Metadata* md = r->metadata_value(); - f(md); + if (md != _method) f(md); } } else if (iter.type() == relocInfo::virtual_call_type) { // Check compiledIC holders associated with this nmethod diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/code/nmethod.hpp --- a/hotspot/src/share/vm/code/nmethod.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/code/nmethod.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -448,7 +448,10 @@ // alive. It is used when an uncommon trap happens. Returns true // if this thread changed the state of the nmethod or false if // another thread performed the transition. - bool make_not_entrant() { return make_not_entrant_or_zombie(not_entrant); } + bool make_not_entrant() { + assert(!method()->is_method_handle_intrinsic(), "Cannot make MH intrinsic not entrant"); + return make_not_entrant_or_zombie(not_entrant); + } bool make_zombie() { return make_not_entrant_or_zombie(zombie); } // used by jvmti to track if the unload event has been reported diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/compiler/compileBroker.cpp --- a/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -166,7 +166,7 @@ StringLogMessage lm; stringStream sstr = lm.stream(); // msg.time_stamp().update_to(tty->time_stamp().ticks()); - task->print_compilation(&sstr, NULL, true); + task->print_compilation(&sstr, NULL, true, false); log(thread, "%s", (const char*)lm); } @@ -328,7 +328,6 @@ if (nm == NULL) _code_handle = NULL; // drop the handle also } - void CompileTask::mark_on_stack() { // Mark these methods as something redefine classes cannot remove. _method->set_on_stack(true); @@ -338,18 +337,6 @@ } // ------------------------------------------------------------------ -// CompileTask::print -void CompileTask::print() { - tty->print("print("method="); - _method->print_name(tty); - tty->print_cr(" osr_bci=%d is_blocking=%s is_complete=%s is_success=%s>", - _osr_bci, bool_to_str(_is_blocking), - bool_to_str(_is_complete), bool_to_str(_is_success)); -} - - -// ------------------------------------------------------------------ // CompileTask::print_line_on_error // // This function is called by fatal error handler when the thread @@ -367,19 +354,18 @@ // ------------------------------------------------------------------ // CompileTask::print_line -void CompileTask::print_line() { +void CompileTask::print_tty() { ttyLocker ttyl; // keep the following output all in one block // print compiler name if requested if (CIPrintCompilerName) tty->print("%s:", CompileBroker::compiler_name(comp_level())); - print_compilation(); + print_compilation(tty); } - // ------------------------------------------------------------------ // CompileTask::print_compilation_impl void CompileTask::print_compilation_impl(outputStream* st, Method* method, int compile_id, int comp_level, bool is_osr_method, int osr_bci, bool is_blocking, - const char* msg, bool short_form) { + const char* msg, bool short_form, bool cr) { if (!short_form) { st->print("%7d ", (int) st->time_stamp().milliseconds()); // print timestamp } @@ -428,7 +414,7 @@ if (msg != NULL) { st->print(" %s", msg); } - if (!short_form) { + if (cr) { st->cr(); } } @@ -494,9 +480,9 @@ // ------------------------------------------------------------------ // CompileTask::print_compilation -void CompileTask::print_compilation(outputStream* st, const char* msg, bool short_form) { +void CompileTask::print_compilation(outputStream* st, const char* msg, bool short_form, bool cr) { bool is_osr_method = osr_bci() != InvocationEntryBci; - print_compilation_impl(st, method(), compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), msg, short_form); + print_compilation_impl(st, method(), compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), msg, short_form, cr); } // ------------------------------------------------------------------ @@ -621,7 +607,9 @@ // Mark the method as being in the compile queue. task->method()->set_queued_for_compilation(); - NOT_PRODUCT(print();) + if (CIPrintCompileQueue) { + print_tty(); + } if (LogCompilation && xtty != NULL) { task->log_task_queued(); @@ -786,24 +774,40 @@ } } -#ifndef PRODUCT -/** - * Print entire compilation queue. - */ -void CompileQueue::print() { - if (CIPrintCompileQueue) { - ttyLocker ttyl; - tty->print_cr("Contents of %s", name()); - tty->print_cr("----------------------"); - CompileTask* task = _first; + +CompileQueue* CompileBroker::compile_queue(int comp_level) { + if (is_c2_compile(comp_level)) return _c2_compile_queue; + if (is_c1_compile(comp_level)) return _c1_compile_queue; + return NULL; +} + + +void CompileBroker::print_compile_queues(outputStream* st) { + _c1_compile_queue->print(st); + _c2_compile_queue->print(st); +} + + +void CompileQueue::print(outputStream* st) { + assert_locked_or_safepoint(lock()); + st->print_cr("Contents of %s", name()); + st->print_cr("----------------------------"); + CompileTask* task = _first; + if (task == NULL) { + st->print_cr("Empty");; + } else { while (task != NULL) { - task->print_line(); + task->print_compilation(st, NULL, true, true); task = task->next(); } - tty->print_cr("----------------------"); } + st->print_cr("----------------------------"); } -#endif // PRODUCT + +void CompileQueue::print_tty() { + ttyLocker ttyl; + print(tty); +} CompilerCounters::CompilerCounters(const char* thread_name, int instance, TRAPS) { @@ -1068,11 +1072,11 @@ #endif // !ZERO && !SHARK // Initialize the compilation queue if (c2_compiler_count > 0) { - _c2_compile_queue = new CompileQueue("C2 CompileQueue", MethodCompileQueue_lock); + _c2_compile_queue = new CompileQueue("C2 compile queue", MethodCompileQueue_lock); _compilers[1]->set_num_compiler_threads(c2_compiler_count); } if (c1_compiler_count > 0) { - _c1_compile_queue = new CompileQueue("C1 CompileQueue", MethodCompileQueue_lock); + _c1_compile_queue = new CompileQueue("C1 compile queue", MethodCompileQueue_lock); _compilers[0]->set_num_compiler_threads(c1_compiler_count); } @@ -1892,7 +1896,7 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) { if (PrintCompilation) { ResourceMark rm; - task->print_line(); + task->print_tty(); } elapsedTimer time; diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/compiler/compileBroker.hpp --- a/hotspot/src/share/vm/compiler/compileBroker.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/compiler/compileBroker.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -111,14 +111,14 @@ private: static void print_compilation_impl(outputStream* st, Method* method, int compile_id, int comp_level, bool is_osr_method = false, int osr_bci = -1, bool is_blocking = false, - const char* msg = NULL, bool short_form = false); + const char* msg = NULL, bool short_form = false, bool cr = true); public: - void print_compilation(outputStream* st = tty, const char* msg = NULL, bool short_form = false); - static void print_compilation(outputStream* st, const nmethod* nm, const char* msg = NULL, bool short_form = false) { + void print_compilation(outputStream* st = tty, const char* msg = NULL, bool short_form = false, bool cr = true); + static void print_compilation(outputStream* st, const nmethod* nm, const char* msg = NULL, bool short_form = false, bool cr = true) { print_compilation_impl(st, nm->method(), nm->compile_id(), nm->comp_level(), nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false, - msg, short_form); + msg, short_form, cr); } static void print_inlining(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg = NULL); @@ -131,8 +131,7 @@ static void print_inline_indent(int inline_level, outputStream* st = tty); - void print(); - void print_line(); + void print_tty(); void print_line_on_error(outputStream* st, char* buf, int buflen); void log_task(xmlStream* log); @@ -234,7 +233,8 @@ // Redefine Classes support void mark_on_stack(); void free_all(); - NOT_PRODUCT (void print();) + void print_tty(); + void print(outputStream* st = tty); ~CompileQueue() { assert (is_empty(), " Compile Queue must be empty"); @@ -341,7 +341,7 @@ static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count); static bool compilation_is_complete (methodHandle method, int osr_bci, int comp_level); static bool compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level); - static bool is_compile_blocking (); + static bool is_compile_blocking(); static void preload_classes (methodHandle method, TRAPS); static CompileTask* create_compile_task(CompileQueue* queue, @@ -369,11 +369,8 @@ int hot_count, const char* comment, Thread* thread); - static CompileQueue* compile_queue(int comp_level) { - if (is_c2_compile(comp_level)) return _c2_compile_queue; - if (is_c1_compile(comp_level)) return _c1_compile_queue; - return NULL; - } + + static CompileQueue* compile_queue(int comp_level); static bool init_compiler_runtime(); static void shutdown_compiler_runtime(AbstractCompiler* comp, CompilerThread* thread); @@ -390,6 +387,7 @@ } static bool compilation_is_in_queue(methodHandle method); + static void print_compile_queues(outputStream* st); static int queue_size(int comp_level) { CompileQueue *q = compile_queue(comp_level); return q != NULL ? q->size() : 0; diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -369,33 +369,45 @@ #endif } -bool -G1BlockOffsetArray::verify_for_object(HeapWord* obj_start, - size_t word_size) const { - size_t first_card = _array->index_for(obj_start); - size_t last_card = _array->index_for(obj_start + word_size - 1); - if (!_array->is_card_boundary(obj_start)) { - // If the object is not on a card boundary the BOT entry of the - // first card should point to another object so we should not - // check that one. - first_card += 1; - } - for (size_t card = first_card; card <= last_card; card += 1) { - HeapWord* card_addr = _array->address_for_index(card); - HeapWord* block_start = block_start_const(card_addr); - if (block_start != obj_start) { - gclog_or_tty->print_cr("block start: "PTR_FORMAT" is incorrect - " - "card index: "SIZE_FORMAT" " - "card addr: "PTR_FORMAT" BOT entry: %u " - "obj: "PTR_FORMAT" word size: "SIZE_FORMAT" " - "cards: ["SIZE_FORMAT","SIZE_FORMAT"]", - p2i(block_start), card, p2i(card_addr), - _array->offset_array(card), - p2i(obj_start), word_size, first_card, last_card); - return false; +void G1BlockOffsetArray::verify() const { + assert(gsp()->bottom() < gsp()->top(), "Only non-empty regions should be verified."); + size_t start_card = _array->index_for(gsp()->bottom()); + size_t end_card = _array->index_for(gsp()->top() - 1); + + for (size_t current_card = start_card; current_card < end_card; current_card++) { + u_char entry = _array->offset_array(current_card); + if (entry < N_words) { + // The entry should point to an object before the current card. Verify that + // it is possible to walk from that object in to the current card by just + // iterating over the objects following it. + HeapWord* card_address = _array->address_for_index(current_card); + HeapWord* obj_end = card_address - entry; + while (obj_end < card_address) { + HeapWord* obj = obj_end; + size_t obj_size = block_size(obj); + obj_end = obj + obj_size; + guarantee(obj_end > obj && obj_end <= gsp()->top(), + err_msg("Invalid object end. obj: " PTR_FORMAT " obj_size: " SIZE_FORMAT " obj_end: " PTR_FORMAT " top: " PTR_FORMAT, + p2i(obj), obj_size, p2i(obj_end), p2i(gsp()->top()))); + } + } else { + // Because we refine the BOT based on which cards are dirty there is not much we can verify here. + // We need to make sure that we are going backwards and that we don't pass the start of the + // corresponding heap region. But that is about all we can verify. + size_t backskip = BlockOffsetArray::entry_to_cards_back(entry); + guarantee(backskip >= 1, "Must be going back at least one card."); + + size_t max_backskip = current_card - start_card; + guarantee(backskip <= max_backskip, + err_msg("Going backwards beyond the start_card. start_card: " SIZE_FORMAT " current_card: " SIZE_FORMAT " backskip: " SIZE_FORMAT, + start_card, current_card, backskip)); + + HeapWord* backskip_address = _array->address_for_index(current_card - backskip); + guarantee(backskip_address >= gsp()->bottom(), + err_msg("Going backwards beyond bottom of the region: bottom: " PTR_FORMAT ", backskip_address: " PTR_FORMAT, + p2i(gsp()->bottom()), p2i(backskip_address))); } } - return true; } #ifndef PRODUCT diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -304,13 +304,9 @@ virtual HeapWord* block_start_unsafe(const void* addr); virtual HeapWord* block_start_unsafe_const(const void* addr) const; - // Used by region verification. Checks that the contents of the - // BOT reflect that there's a single object that spans the address - // range [obj_start, obj_start + word_size); returns true if this is - // the case, returns false if it's not. - bool verify_for_object(HeapWord* obj_start, size_t word_size) const; + void check_all_cards(size_t left_card, size_t right_card) const; - void check_all_cards(size_t left_card, size_t right_card) const; + void verify() const; virtual void print_on(outputStream* out) PRODUCT_RETURN; }; diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -48,6 +48,7 @@ return hash ^ (hash >> 7); // code heap blocks are 128byte aligned } + void remove_entry(Entry* e, Entry* previous); Entry* new_entry(nmethod* nm); public: @@ -67,7 +68,7 @@ void nmethods_do(CodeBlobClosure* blk); template - void remove_if(CB& should_remove); + int remove_if(CB& should_remove); static void purge_list_append(CodeRootSetTable* tbl); static void purge(); @@ -91,6 +92,18 @@ return entry; } +void CodeRootSetTable::remove_entry(Entry* e, Entry* previous) { + int index = hash_to_index(e->hash()); + assert((e == bucket(index)) == (previous == NULL), "if e is the first entry then previous should be null"); + + if (previous == NULL) { + set_entry(index, e->next()); + } else { + previous->set_next(e->next()); + } + free_entry(e); +} + CodeRootSetTable::~CodeRootSetTable() { for (int index = 0; index < table_size(); ++index) { for (Entry* e = bucket(index); e != NULL; ) { @@ -133,12 +146,7 @@ Entry* previous = NULL; for (Entry* e = bucket(index); e != NULL; previous = e, e = e->next()) { if (e->literal() == nm) { - if (previous != NULL) { - previous->set_next(e->next()); - } else { - set_entry(index, e->next()); - } - free_entry(e); + remove_entry(e, previous); return true; } } @@ -163,25 +171,23 @@ } template -void CodeRootSetTable::remove_if(CB& should_remove) { +int CodeRootSetTable::remove_if(CB& should_remove) { + int num_removed = 0; for (int index = 0; index < table_size(); ++index) { Entry* previous = NULL; Entry* e = bucket(index); while (e != NULL) { Entry* next = e->next(); if (should_remove(e->literal())) { - if (previous != NULL) { - previous->set_next(next); - } else { - set_entry(index, next); - } - free_entry(e); + remove_entry(e, previous); + ++num_removed; } else { previous = e; } e = next; } } + return num_removed; } G1CodeRootSet::~G1CodeRootSet() { @@ -320,14 +326,19 @@ bool operator() (nmethod* nm) { _detector._points_into = false; _blobs.do_code_blob(nm); - return _detector._points_into; + return !_detector._points_into; } }; void G1CodeRootSet::clean(HeapRegion* owner) { CleanCallback should_clean(owner); if (_table != NULL) { - _table->remove_if(should_clean); + int removed = _table->remove_if(should_clean); + assert((size_t)removed <= _length, "impossible"); + _length -= removed; + } + if (_length == 0) { + clear(); } } diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -861,7 +861,6 @@ HeapWord* prev_p = NULL; VerifyLiveClosure vl_cl(g1, vo); bool is_humongous = isHumongous(); - bool do_bot_verify = !is_young(); size_t object_num = 0; while (p < top()) { oop obj = oop(p); @@ -878,15 +877,6 @@ return; } - // If it returns false, verify_for_object() will output the - // appropriate message. - if (do_bot_verify && - !g1->is_obj_dead(obj, this) && - !_offsets.verify_for_object(p, obj_size)) { - *failures = true; - return; - } - if (!g1->is_obj_dead_cond(obj, this, vo)) { if (obj->is_oop()) { Klass* klass = obj->klass(); @@ -924,6 +914,10 @@ p += obj_size; } + if (!is_young() && !is_empty()) { + _offsets.verify(); + } + if (p != top()) { gclog_or_tty->print_cr("end of last object "PTR_FORMAT" " "does not match top "PTR_FORMAT, p, top()); diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/memory/universe.cpp diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/oops/instanceKlass.cpp --- a/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -460,6 +460,8 @@ oop InstanceKlass::init_lock() const { // return the init lock from the mirror oop lock = java_lang_Class::init_lock(java_mirror()); + // Prevent reordering with any access of initialization state + OrderAccess::loadload(); assert((oop)lock != NULL || !is_not_initialized(), // initialized or in_error state "only fully initialized state can have a null lock"); return lock; @@ -2437,16 +2439,6 @@ assert(breakpoints() == 0x0, "should have cleared breakpoints"); } - // deallocate information about previous versions - if (_previous_versions != NULL) { - for (int i = _previous_versions->length() - 1; i >= 0; i--) { - PreviousVersionNode * pv_node = _previous_versions->at(i); - delete pv_node; - } - delete _previous_versions; - _previous_versions = NULL; - } - // deallocate the cached class file if (_cached_class_file != NULL) { os::free(_cached_class_file, mtClass); @@ -3020,16 +3012,17 @@ st->print(BULLET"field type annotations: "); fields_type_annotations()->print_value_on(st); st->cr(); { bool have_pv = false; - PreviousVersionWalker pvw(Thread::current(), (InstanceKlass*)this); - for (PreviousVersionNode * pv_node = pvw.next_previous_version(); - pv_node != NULL; pv_node = pvw.next_previous_version()) { + // previous versions are linked together through the InstanceKlass + for (InstanceKlass* pv_node = _previous_versions; + pv_node != NULL; + pv_node = pv_node->previous_versions()) { if (!have_pv) st->print(BULLET"previous version: "); have_pv = true; - pv_node->prev_constant_pool()->print_value_on(st); + pv_node->constants()->print_value_on(st); } if (have_pv) st->cr(); - } // pvw is cleaned up + } if (generic_signature() != NULL) { st->print(BULLET"generic signature: "); @@ -3443,92 +3436,92 @@ // RedefineClasses() support for previous versions: // Purge previous versions -static void purge_previous_versions_internal(InstanceKlass* ik, int emcp_method_count) { +void InstanceKlass::purge_previous_versions(InstanceKlass* ik) { if (ik->previous_versions() != NULL) { // This klass has previous versions so see what we can cleanup // while it is safe to do so. int deleted_count = 0; // leave debugging breadcrumbs int live_count = 0; - ClassLoaderData* loader_data = ik->class_loader_data() == NULL ? - ClassLoaderData::the_null_class_loader_data() : - ik->class_loader_data(); + ClassLoaderData* loader_data = ik->class_loader_data(); + assert(loader_data != NULL, "should never be null"); // RC_TRACE macro has an embedded ResourceMark - RC_TRACE(0x00000200, ("purge: %s: previous version length=%d", - ik->external_name(), ik->previous_versions()->length())); - - for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) { - // check the previous versions array - PreviousVersionNode * pv_node = ik->previous_versions()->at(i); - ConstantPool* cp_ref = pv_node->prev_constant_pool(); - assert(cp_ref != NULL, "cp ref was unexpectedly cleared"); - - ConstantPool* pvcp = cp_ref; + RC_TRACE(0x00000200, ("purge: %s: previous versions", ik->external_name())); + + // previous versions are linked together through the InstanceKlass + InstanceKlass* pv_node = ik->previous_versions(); + InstanceKlass* last = ik; + int version = 0; + + // check the previous versions list + for (; pv_node != NULL; ) { + + ConstantPool* pvcp = pv_node->constants(); + assert(pvcp != NULL, "cp ref was unexpectedly cleared"); + if (!pvcp->on_stack()) { // If the constant pool isn't on stack, none of the methods - // are executing. Delete all the methods, the constant pool and - // and this previous version node. - GrowableArray* method_refs = pv_node->prev_EMCP_methods(); - if (method_refs != NULL) { - for (int j = method_refs->length() - 1; j >= 0; j--) { - Method* method = method_refs->at(j); - assert(method != NULL, "method ref was unexpectedly cleared"); - method_refs->remove_at(j); - // method will be freed with associated class. - } - } - // Remove the constant pool - delete pv_node; - // Since we are traversing the array backwards, we don't have to - // do anything special with the index. - ik->previous_versions()->remove_at(i); + // are executing. Unlink this previous_version. + // The previous version InstanceKlass is on the ClassLoaderData deallocate list + // so will be deallocated during the next phase of class unloading. + pv_node = pv_node->previous_versions(); + last->link_previous_versions(pv_node); deleted_count++; + version++; continue; } else { - RC_TRACE(0x00000200, ("purge: previous version @%d is alive", i)); + RC_TRACE(0x00000200, ("purge: previous version " INTPTR_FORMAT " is alive", + pv_node)); assert(pvcp->pool_holder() != NULL, "Constant pool with no holder"); guarantee (!loader_data->is_unloading(), "unloaded classes can't be on the stack"); live_count++; } - // At least one method is live in this previous version, clean out - // the others or mark them as obsolete. - GrowableArray* method_refs = pv_node->prev_EMCP_methods(); + // At least one method is live in this previous version so clean its MethodData. + // Reset dead EMCP methods not to get breakpoints. + // All methods are deallocated when all of the methods for this class are no + // longer running. + Array* method_refs = pv_node->methods(); if (method_refs != NULL) { RC_TRACE(0x00000200, ("purge: previous methods length=%d", method_refs->length())); - for (int j = method_refs->length() - 1; j >= 0; j--) { + for (int j = 0; j < method_refs->length(); j++) { Method* method = method_refs->at(j); - assert(method != NULL, "method ref was unexpectedly cleared"); - - // Remove the emcp method if it's not executing - // If it's been made obsolete by a redefinition of a non-emcp - // method, mark it as obsolete but leave it to clean up later. + if (!method->on_stack()) { - method_refs->remove_at(j); - } else if (emcp_method_count == 0) { - method->set_is_obsolete(); + // no breakpoints for non-running methods + if (method->is_running_emcp()) { + method->set_running_emcp(false); + } } else { + assert (method->is_obsolete() || method->is_running_emcp(), + "emcp method cannot run after emcp bit is cleared"); // RC_TRACE macro has an embedded ResourceMark RC_TRACE(0x00000200, ("purge: %s(%s): prev method @%d in version @%d is alive", method->name()->as_C_string(), - method->signature()->as_C_string(), j, i)); + method->signature()->as_C_string(), j, version)); if (method->method_data() != NULL) { - // Clean out any weak method links + // Clean out any weak method links for running methods + // (also should include not EMCP methods) method->method_data()->clean_weak_method_links(); } } } } + // next previous version + last = pv_node; + pv_node = pv_node->previous_versions(); + version++; } - assert(ik->previous_versions()->length() == live_count, "sanity check"); RC_TRACE(0x00000200, ("purge: previous version stats: live=%d, deleted=%d", live_count, deleted_count)); } + // Clean MethodData of this class's methods so they don't refer to + // old methods that are no longer running. Array* methods = ik->methods(); int num_methods = methods->length(); for (int index2 = 0; index2 < num_methods; ++index2) { @@ -3538,122 +3531,30 @@ } } -// External interface for use during class unloading. -void InstanceKlass::purge_previous_versions(InstanceKlass* ik) { - // Call with >0 emcp methods since they are not currently being redefined. - purge_previous_versions_internal(ik, 1); -} - - -// Potentially add an information node that contains pointers to the -// interesting parts of the previous version of the_class. -// This is also where we clean out any unused references. -// Note that while we delete nodes from the _previous_versions -// array, we never delete the array itself until the klass is -// unloaded. The has_been_redefined() query depends on that fact. -// -void InstanceKlass::add_previous_version(instanceKlassHandle ikh, - BitMap* emcp_methods, int emcp_method_count) { - assert(Thread::current()->is_VM_thread(), - "only VMThread can add previous versions"); - - if (_previous_versions == NULL) { - // This is the first previous version so make some space. - // Start with 2 elements under the assumption that the class - // won't be redefined much. - _previous_versions = new (ResourceObj::C_HEAP, mtClass) - GrowableArray(2, true); - } - - ConstantPool* cp_ref = ikh->constants(); - - // RC_TRACE macro has an embedded ResourceMark - RC_TRACE(0x00000400, ("adding previous version ref for %s @%d, EMCP_cnt=%d " - "on_stack=%d", - ikh->external_name(), _previous_versions->length(), emcp_method_count, - cp_ref->on_stack())); - - // If the constant pool for this previous version of the class - // is not marked as being on the stack, then none of the methods - // in this previous version of the class are on the stack so - // we don't need to create a new PreviousVersionNode. However, - // we still need to examine older previous versions below. - Array* old_methods = ikh->methods(); - - if (cp_ref->on_stack()) { - PreviousVersionNode * pv_node = NULL; - if (emcp_method_count == 0) { - // non-shared ConstantPool gets a reference - pv_node = new PreviousVersionNode(cp_ref, NULL); - RC_TRACE(0x00000400, - ("add: all methods are obsolete; flushing any EMCP refs")); - } else { - int local_count = 0; - GrowableArray* method_refs = new (ResourceObj::C_HEAP, mtClass) - GrowableArray(emcp_method_count, true); - for (int i = 0; i < old_methods->length(); i++) { - if (emcp_methods->at(i)) { - // this old method is EMCP. Save it only if it's on the stack - Method* old_method = old_methods->at(i); - if (old_method->on_stack()) { - method_refs->append(old_method); - } - if (++local_count >= emcp_method_count) { - // no more EMCP methods so bail out now - break; - } - } - } - // non-shared ConstantPool gets a reference - pv_node = new PreviousVersionNode(cp_ref, method_refs); - } - // append new previous version. - _previous_versions->append(pv_node); - } - - // Since the caller is the VMThread and we are at a safepoint, this - // is a good time to clear out unused references. - - RC_TRACE(0x00000400, ("add: previous version length=%d", - _previous_versions->length())); - - // Purge previous versions not executing on the stack - purge_previous_versions_internal(this, emcp_method_count); - +void InstanceKlass::mark_newly_obsolete_methods(Array* old_methods, + int emcp_method_count) { int obsolete_method_count = old_methods->length() - emcp_method_count; if (emcp_method_count != 0 && obsolete_method_count != 0 && - _previous_versions->length() > 0) { + _previous_versions != NULL) { // We have a mix of obsolete and EMCP methods so we have to // clear out any matching EMCP method entries the hard way. int local_count = 0; for (int i = 0; i < old_methods->length(); i++) { - if (!emcp_methods->at(i)) { + Method* old_method = old_methods->at(i); + if (old_method->is_obsolete()) { // only obsolete methods are interesting - Method* old_method = old_methods->at(i); Symbol* m_name = old_method->name(); Symbol* m_signature = old_method->signature(); - // we might not have added the last entry - for (int j = _previous_versions->length() - 1; j >= 0; j--) { - // check the previous versions array for non executing obsolete methods - PreviousVersionNode * pv_node = _previous_versions->at(j); - - GrowableArray* method_refs = pv_node->prev_EMCP_methods(); - if (method_refs == NULL) { - // We have run into a PreviousVersion generation where - // all methods were made obsolete during that generation's - // RedefineClasses() operation. At the time of that - // operation, all EMCP methods were flushed so we don't - // have to go back any further. - // - // A NULL method_refs is different than an empty method_refs. - // We cannot infer any optimizations about older generations - // from an empty method_refs for the current generation. - break; - } - - for (int k = method_refs->length() - 1; k >= 0; k--) { + // previous versions are linked together through the InstanceKlass + int j = 0; + for (InstanceKlass* prev_version = _previous_versions; + prev_version != NULL; + prev_version = prev_version->previous_versions(), j++) { + + Array* method_refs = prev_version->methods(); + for (int k = 0; k < method_refs->length(); k++) { Method* method = method_refs->at(k); if (!method->is_obsolete() && @@ -3661,14 +3562,11 @@ method->signature() == m_signature) { // The current RedefineClasses() call has made all EMCP // versions of this method obsolete so mark it as obsolete - // and remove the reference. RC_TRACE(0x00000400, ("add: %s(%s): flush obsolete method @%d in version @%d", m_name->as_C_string(), m_signature->as_C_string(), k, j)); method->set_is_obsolete(); - // Leave obsolete methods on the previous version list to - // clean up later. break; } } @@ -3676,9 +3574,9 @@ // The previous loop may not find a matching EMCP method, but // that doesn't mean that we can optimize and not go any // further back in the PreviousVersion generations. The EMCP - // method for this generation could have already been deleted, + // method for this generation could have already been made obsolete, // but there still may be an older EMCP method that has not - // been deleted. + // been made obsolete. } if (++local_count >= obsolete_method_count) { @@ -3688,15 +3586,69 @@ } } } +} + +// Save the scratch_class as the previous version if any of the methods are running. +// The previous_versions are used to set breakpoints in EMCP methods and they are +// also used to clean MethodData links to redefined methods that are no longer running. +void InstanceKlass::add_previous_version(instanceKlassHandle scratch_class, + int emcp_method_count) { + assert(Thread::current()->is_VM_thread(), + "only VMThread can add previous versions"); + + // RC_TRACE macro has an embedded ResourceMark + RC_TRACE(0x00000400, ("adding previous version ref for %s, EMCP_cnt=%d", + scratch_class->external_name(), emcp_method_count)); + + // Clean out old previous versions + purge_previous_versions(this); + + // Mark newly obsolete methods in remaining previous versions. An EMCP method from + // a previous redefinition may be made obsolete by this redefinition. + Array* old_methods = scratch_class->methods(); + mark_newly_obsolete_methods(old_methods, emcp_method_count); + + // If the constant pool for this previous version of the class + // is not marked as being on the stack, then none of the methods + // in this previous version of the class are on the stack so + // we don't need to add this as a previous version. + ConstantPool* cp_ref = scratch_class->constants(); + if (!cp_ref->on_stack()) { + RC_TRACE(0x00000400, ("add: scratch class not added; no methods are running")); + return; + } + + if (emcp_method_count != 0) { + // At least one method is still running, check for EMCP methods + for (int i = 0; i < old_methods->length(); i++) { + Method* old_method = old_methods->at(i); + if (!old_method->is_obsolete() && old_method->on_stack()) { + // if EMCP method (not obsolete) is on the stack, mark as EMCP so that + // we can add breakpoints for it. + + // We set the method->on_stack bit during safepoints for class redefinition and + // class unloading and use this bit to set the is_running_emcp bit. + // After the safepoint, the on_stack bit is cleared and the running emcp + // method may exit. If so, we would set a breakpoint in a method that + // is never reached, but this won't be noticeable to the programmer. + old_method->set_running_emcp(true); + RC_TRACE(0x00000400, ("add: EMCP method %s is on_stack " INTPTR_FORMAT, + old_method->name_and_sig_as_C_string(), old_method)); + } else if (!old_method->is_obsolete()) { + RC_TRACE(0x00000400, ("add: EMCP method %s is NOT on_stack " INTPTR_FORMAT, + old_method->name_and_sig_as_C_string(), old_method)); + } + } + } + + // Add previous version if any methods are still running. + RC_TRACE(0x00000400, ("add: scratch class added; one of its methods is on_stack")); + assert(scratch_class->previous_versions() == NULL, "shouldn't have a previous version"); + scratch_class->link_previous_versions(previous_versions()); + link_previous_versions(scratch_class()); } // end add_previous_version() -// Determine if InstanceKlass has a previous version. -bool InstanceKlass::has_previous_version() const { - return (_previous_versions != NULL && _previous_versions->length() > 0); -} // end has_previous_version() - - Method* InstanceKlass::method_with_idnum(int idnum) { Method* m = NULL; if (idnum < methods()->length()) { @@ -3722,61 +3674,3 @@ unsigned char * InstanceKlass::get_cached_class_file_bytes() { return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file); } - - -// Construct a PreviousVersionNode entry for the array hung off -// the InstanceKlass. -PreviousVersionNode::PreviousVersionNode(ConstantPool* prev_constant_pool, - GrowableArray* prev_EMCP_methods) { - - _prev_constant_pool = prev_constant_pool; - _prev_EMCP_methods = prev_EMCP_methods; -} - - -// Destroy a PreviousVersionNode -PreviousVersionNode::~PreviousVersionNode() { - if (_prev_constant_pool != NULL) { - _prev_constant_pool = NULL; - } - - if (_prev_EMCP_methods != NULL) { - delete _prev_EMCP_methods; - } -} - -// Construct a helper for walking the previous versions array -PreviousVersionWalker::PreviousVersionWalker(Thread* thread, InstanceKlass *ik) { - _thread = thread; - _previous_versions = ik->previous_versions(); - _current_index = 0; - _current_p = NULL; - _current_constant_pool_handle = constantPoolHandle(thread, ik->constants()); -} - - -// Return the interesting information for the next previous version -// of the klass. Returns NULL if there are no more previous versions. -PreviousVersionNode* PreviousVersionWalker::next_previous_version() { - if (_previous_versions == NULL) { - // no previous versions so nothing to return - return NULL; - } - - _current_p = NULL; // reset to NULL - _current_constant_pool_handle = NULL; - - int length = _previous_versions->length(); - - while (_current_index < length) { - PreviousVersionNode * pv_node = _previous_versions->at(_current_index++); - - // Save a handle to the constant pool for this previous version, - // which keeps all the methods from being deallocated. - _current_constant_pool_handle = constantPoolHandle(_thread, pv_node->prev_constant_pool()); - _current_p = pv_node; - return pv_node; - } - - return NULL; -} // end next_previous_version() diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/oops/instanceKlass.hpp --- a/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -59,7 +59,6 @@ class fieldDescriptor; class DepChange; class nmethodBucket; -class PreviousVersionNode; class JvmtiCachedClassFieldMap; class MemberNameTable; @@ -205,7 +204,8 @@ _misc_should_verify_class = 1 << 2, // allow caching of preverification _misc_is_anonymous = 1 << 3, // has embedded _host_klass field _misc_is_contended = 1 << 4, // marked with contended annotation - _misc_has_default_methods = 1 << 5 // class/superclass/implemented interfaces has default methods + _misc_has_default_methods = 1 << 5, // class/superclass/implemented interfaces has default methods + _misc_has_been_redefined = 1 << 6 // class has been redefined }; u2 _misc_flags; u2 _minor_version; // minor version number of class file @@ -220,9 +220,8 @@ nmethodBucket* _dependencies; // list of dependent nmethods nmethod* _osr_nmethods_head; // Head of list of on-stack replacement nmethods for this class BreakpointInfo* _breakpoints; // bpt lists, managed by Method* - // Array of interesting part(s) of the previous version(s) of this - // InstanceKlass. See PreviousVersionWalker below. - GrowableArray* _previous_versions; + // Linked instanceKlasses of previous versions + InstanceKlass* _previous_versions; // JVMTI fields can be moved to their own structure - see 6315920 // JVMTI: cached class file, before retransformable agent modified it in CFLH JvmtiCachedClassFileData* _cached_class_file; @@ -608,19 +607,20 @@ } // RedefineClasses() support for previous versions: - void add_previous_version(instanceKlassHandle ikh, BitMap *emcp_methods, - int emcp_method_count); - // If the _previous_versions array is non-NULL, then this klass - // has been redefined at least once even if we aren't currently - // tracking a previous version. - bool has_been_redefined() const { return _previous_versions != NULL; } - bool has_previous_version() const; + void add_previous_version(instanceKlassHandle ikh, int emcp_method_count); + + InstanceKlass* previous_versions() const { return _previous_versions; } + + bool has_been_redefined() const { + return (_misc_flags & _misc_has_been_redefined) != 0; + } + void set_has_been_redefined() { + _misc_flags |= _misc_has_been_redefined; + } + void init_previous_versions() { _previous_versions = NULL; } - GrowableArray* previous_versions() const { - return _previous_versions; - } static void purge_previous_versions(InstanceKlass* ik); @@ -1042,6 +1042,10 @@ // Free CHeap allocated fields. void release_C_heap_structures(); + + // RedefineClasses support + void link_previous_versions(InstanceKlass* pv) { _previous_versions = pv; } + void mark_newly_obsolete_methods(Array* old_methods, int emcp_method_count); public: // CDS support - remove and restore oops from metadata. Oops are not shared. virtual void remove_unshareable_info(); @@ -1141,62 +1145,6 @@ }; -// If breakpoints are more numerous than just JVMTI breakpoints, -// consider compressing this data structure. -// It is currently a simple linked list defined in method.hpp. - -class BreakpointInfo; - - -// A collection point for interesting information about the previous -// version(s) of an InstanceKlass. A GrowableArray of PreviousVersionNodes -// is attached to the InstanceKlass as needed. See PreviousVersionWalker below. -class PreviousVersionNode : public CHeapObj { - private: - ConstantPool* _prev_constant_pool; - - // If the previous version of the InstanceKlass doesn't have any - // EMCP methods, then _prev_EMCP_methods will be NULL. If all the - // EMCP methods have been collected, then _prev_EMCP_methods can - // have a length of zero. - GrowableArray* _prev_EMCP_methods; - -public: - PreviousVersionNode(ConstantPool* prev_constant_pool, - GrowableArray* prev_EMCP_methods); - ~PreviousVersionNode(); - ConstantPool* prev_constant_pool() const { - return _prev_constant_pool; - } - GrowableArray* prev_EMCP_methods() const { - return _prev_EMCP_methods; - } -}; - - -// Helper object for walking previous versions. -class PreviousVersionWalker : public StackObj { - private: - Thread* _thread; - GrowableArray* _previous_versions; - int _current_index; - - // A pointer to the current node object so we can handle the deletes. - PreviousVersionNode* _current_p; - - // The constant pool handle keeps all the methods in this class from being - // deallocated from the metaspace during class unloading. - constantPoolHandle _current_constant_pool_handle; - - public: - PreviousVersionWalker(Thread* thread, InstanceKlass *ik); - - // Return the interesting information for the next previous version - // of the klass. Returns NULL if there are no more previous versions. - PreviousVersionNode* next_previous_version(); -}; - - // // nmethodBucket is used to record dependent nmethods for // deoptimization. nmethod dependencies are actually diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/oops/method.cpp --- a/hotspot/src/share/vm/oops/method.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/oops/method.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -1635,34 +1635,34 @@ } int Method::highest_comp_level() const { - const MethodData* mdo = method_data(); - if (mdo != NULL) { - return mdo->highest_comp_level(); + const MethodCounters* mcs = method_counters(); + if (mcs != NULL) { + return mcs->highest_comp_level(); } else { return CompLevel_none; } } int Method::highest_osr_comp_level() const { - const MethodData* mdo = method_data(); - if (mdo != NULL) { - return mdo->highest_osr_comp_level(); + const MethodCounters* mcs = method_counters(); + if (mcs != NULL) { + return mcs->highest_osr_comp_level(); } else { return CompLevel_none; } } void Method::set_highest_comp_level(int level) { - MethodData* mdo = method_data(); - if (mdo != NULL) { - mdo->set_highest_comp_level(level); + MethodCounters* mcs = method_counters(); + if (mcs != NULL) { + mcs->set_highest_comp_level(level); } } void Method::set_highest_osr_comp_level(int level) { - MethodData* mdo = method_data(); - if (mdo != NULL) { - mdo->set_highest_osr_comp_level(level); + MethodCounters* mcs = method_counters(); + if (mcs != NULL) { + mcs->set_highest_osr_comp_level(level); } } diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/oops/method.hpp --- a/hotspot/src/share/vm/oops/method.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/oops/method.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -80,7 +80,8 @@ _caller_sensitive = 1 << 1, _force_inline = 1 << 2, _dont_inline = 1 << 3, - _hidden = 1 << 4 + _hidden = 1 << 4, + _running_emcp = 1 << 5 }; u1 _flags; @@ -688,6 +689,21 @@ void set_is_obsolete() { _access_flags.set_is_obsolete(); } bool is_deleted() const { return access_flags().is_deleted(); } void set_is_deleted() { _access_flags.set_is_deleted(); } + + bool is_running_emcp() const { + // EMCP methods are old but not obsolete or deleted. Equivalent + // Modulo Constant Pool means the method is equivalent except + // the constant pool and instructions that access the constant + // pool might be different. + // If a breakpoint is set in a redefined method, its EMCP methods that are + // still running must have a breakpoint also. + return (_flags & _running_emcp) != 0; + } + + void set_running_emcp(bool x) { + _flags = x ? (_flags | _running_emcp) : (_flags & ~_running_emcp); + } + bool on_stack() const { return access_flags().on_stack(); } void set_on_stack(const bool value); diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/oops/methodCounters.cpp --- a/hotspot/src/share/vm/oops/methodCounters.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/oops/methodCounters.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -35,4 +35,40 @@ set_interpreter_throwout_count(0); set_interpreter_invocation_count(0); set_nmethod_age(INT_MAX); +#ifdef TIERED + set_prev_time(0); + set_rate(0); + set_highest_comp_level(0); + set_highest_osr_comp_level(0); +#endif } + + +int MethodCounters::highest_comp_level() const { +#ifdef TIERED + return _highest_comp_level; +#else + return CompLevel_none; +#endif +} + +void MethodCounters::set_highest_comp_level(int level) { +#ifdef TIERED + _highest_comp_level = level; +#endif +} + +int MethodCounters::highest_osr_comp_level() const { +#ifdef TIERED + return _highest_osr_comp_level; +#else + return CompLevel_none; +#endif +} + +void MethodCounters::set_highest_osr_comp_level(int level) { +#ifdef TIERED + _highest_osr_comp_level = level; +#endif +} + diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/oops/methodCounters.hpp --- a/hotspot/src/share/vm/oops/methodCounters.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/oops/methodCounters.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -49,6 +49,8 @@ #ifdef TIERED float _rate; // Events (invocation and backedge counter increments) per millisecond jlong _prev_time; // Previous time the rate was acquired + u1 _highest_comp_level; // Highest compile level this method has ever seen. + u1 _highest_osr_comp_level; // Same for OSR level #endif MethodCounters() : _interpreter_invocation_count(0), @@ -57,7 +59,9 @@ _nmethod_age(INT_MAX) #ifdef TIERED , _rate(0), - _prev_time(0) + _prev_time(0), + _highest_comp_level(0), + _highest_osr_comp_level(0) #endif { invocation_counter()->init(); @@ -114,6 +118,11 @@ void set_rate(float rate) { _rate = rate; } #endif + int highest_comp_level() const; + void set_highest_comp_level(int level); + int highest_osr_comp_level() const; + void set_highest_osr_comp_level(int level); + // invocation counter InvocationCounter* invocation_counter() { return &_invocation_counter; } InvocationCounter* backedge_counter() { return &_backedge_counter; } diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/oops/methodData.cpp --- a/hotspot/src/share/vm/oops/methodData.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/oops/methodData.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -1134,8 +1134,6 @@ _tenure_traps = 0; _num_loops = 0; _num_blocks = 0; - _highest_comp_level = 0; - _highest_osr_comp_level = 0; _would_profile = true; #if INCLUDE_RTM_OPT diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/oops/methodData.hpp --- a/hotspot/src/share/vm/oops/methodData.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/oops/methodData.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -2095,10 +2095,6 @@ // time with C1. It is used to determine if method is trivial. short _num_loops; short _num_blocks; - // Highest compile level this method has ever seen. - u1 _highest_comp_level; - // Same for OSR level - u1 _highest_osr_comp_level; // Does this method contain anything worth profiling? bool _would_profile; @@ -2277,11 +2273,6 @@ void set_would_profile(bool p) { _would_profile = p; } bool would_profile() const { return _would_profile; } - int highest_comp_level() const { return _highest_comp_level; } - void set_highest_comp_level(int level) { _highest_comp_level = level; } - int highest_osr_comp_level() const { return _highest_osr_comp_level; } - void set_highest_osr_comp_level(int level) { _highest_osr_comp_level = level; } - int num_loops() const { return _num_loops; } void set_num_loops(int n) { _num_loops = n; } int num_blocks() const { return _num_blocks; } diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/opto/compile.cpp --- a/hotspot/src/share/vm/opto/compile.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/opto/compile.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -430,7 +430,7 @@ // removes the need to bang the stack in the deoptimization blob which // in turn simplifies stack overflow handling. int Compile::bang_size_in_bytes() const { - return MAX2(_interpreter_frame_size, frame_size_in_bytes()); + return MAX2(frame_size_in_bytes() + os::extra_bang_size_in_bytes(), _interpreter_frame_size); } // ============================================================================ diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/opto/library_call.cpp --- a/hotspot/src/share/vm/opto/library_call.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/opto/library_call.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -4968,7 +4968,8 @@ // Allocate the result array Node* zlen = _gvn.transform(new AddINode(xlen, ylen)); - Node* klass_node = makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_INT))); + ciKlass* klass = ciTypeArrayKlass::make(T_INT); + Node* klass_node = makecon(TypeKlassPtr::make(klass)); IdealKit ideal(this); @@ -5002,7 +5003,8 @@ sync_kit(ideal); z = __ value(z_alloc); - _gvn.set_type(z, TypeAryPtr::INTS); + // Can't use TypeAryPtr::INTS which uses Bottom offset. + _gvn.set_type(z, TypeOopPtr::make_from_klass(klass)); // Final sync IdealKit and GraphKit. final_sync(ideal); #undef __ diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/prims/jvmtiImpl.cpp --- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -282,39 +282,22 @@ void JvmtiBreakpoint::each_method_version_do(method_action meth_act) { ((Method*)_method->*meth_act)(_bci); - // add/remove breakpoint to/from versions of the method that - // are EMCP. Directly or transitively obsolete methods are - // not saved in the PreviousVersionNodes. + // add/remove breakpoint to/from versions of the method that are EMCP. Thread *thread = Thread::current(); instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder()); Symbol* m_name = _method->name(); Symbol* m_signature = _method->signature(); // search previous versions if they exist - PreviousVersionWalker pvw(thread, (InstanceKlass *)ikh()); - for (PreviousVersionNode * pv_node = pvw.next_previous_version(); - pv_node != NULL; pv_node = pvw.next_previous_version()) { - GrowableArray* methods = pv_node->prev_EMCP_methods(); - - if (methods == NULL) { - // We have run into a PreviousVersion generation where - // all methods were made obsolete during that generation's - // RedefineClasses() operation. At the time of that - // operation, all EMCP methods were flushed so we don't - // have to go back any further. - // - // A NULL methods array is different than an empty methods - // array. We cannot infer any optimizations about older - // generations from an empty methods array for the current - // generation. - break; - } + for (InstanceKlass* pv_node = ikh->previous_versions(); + pv_node != NULL; + pv_node = pv_node->previous_versions()) { + Array* methods = pv_node->methods(); for (int i = methods->length() - 1; i >= 0; i--) { Method* method = methods->at(i); - // obsolete methods that are running are not deleted from - // previous version array, but they are skipped here. - if (!method->is_obsolete() && + // Only set breakpoints in running EMCP methods. + if (method->is_running_emcp() && method->name() == m_name && method->signature() == m_signature) { RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -135,7 +135,7 @@ // Mark methods seen on stack and everywhere else so old methods are not // cleaned up if they're on the stack. - MetadataOnStackMark md_on_stack; + MetadataOnStackMark md_on_stack(true); HandleMark hm(thread); // make sure any handles created are deleted // before the stack walk again. @@ -2826,11 +2826,10 @@ } // the previous versions' constant pool caches may need adjustment - PreviousVersionWalker pvw(_thread, ik); - for (PreviousVersionNode * pv_node = pvw.next_previous_version(); - pv_node != NULL; pv_node = pvw.next_previous_version()) { - other_cp = pv_node->prev_constant_pool(); - cp_cache = other_cp->cache(); + for (InstanceKlass* pv_node = ik->previous_versions(); + pv_node != NULL; + pv_node = pv_node->previous_versions()) { + cp_cache = pv_node->constants()->cache(); if (cp_cache != NULL) { cp_cache->adjust_method_entries(_matching_old_methods, _matching_new_methods, @@ -2855,9 +2854,8 @@ } } -void VM_RedefineClasses::check_methods_and_mark_as_obsolete( - BitMap *emcp_methods, int * emcp_method_count_p) { - *emcp_method_count_p = 0; +int VM_RedefineClasses::check_methods_and_mark_as_obsolete() { + int emcp_method_count = 0; int obsolete_count = 0; int old_index = 0; for (int j = 0; j < _matching_methods_length; ++j, ++old_index) { @@ -2931,9 +2929,9 @@ // that we get from effectively overwriting the old methods // when the new methods are attached to the_class. - // track which methods are EMCP for add_previous_version() call - emcp_methods->set_bit(old_index); - (*emcp_method_count_p)++; + // Count number of methods that are EMCP. The method will be marked + // old but not obsolete if it is EMCP. + emcp_method_count++; // An EMCP method is _not_ obsolete. An obsolete method has a // different jmethodID than the current method. An EMCP method @@ -2982,10 +2980,11 @@ old_method->name()->as_C_string(), old_method->signature()->as_C_string())); } - assert((*emcp_method_count_p + obsolete_count) == _old_methods->length(), + assert((emcp_method_count + obsolete_count) == _old_methods->length(), "sanity check"); - RC_TRACE(0x00000100, ("EMCP_cnt=%d, obsolete_cnt=%d", *emcp_method_count_p, + RC_TRACE(0x00000100, ("EMCP_cnt=%d, obsolete_cnt=%d", emcp_method_count, obsolete_count)); + return emcp_method_count; } // This internal class transfers the native function registration from old methods @@ -3379,11 +3378,8 @@ old_constants->set_pool_holder(scratch_class()); #endif - // track which methods are EMCP for add_previous_version() call below - BitMap emcp_methods(_old_methods->length()); - int emcp_method_count = 0; - emcp_methods.clear(); // clears 0..(length() - 1) - check_methods_and_mark_as_obsolete(&emcp_methods, &emcp_method_count); + // track number of methods that are EMCP for add_previous_version() call below + int emcp_method_count = check_methods_and_mark_as_obsolete(); transfer_old_native_function_registrations(the_class); // The class file bytes from before any retransformable agents mucked @@ -3471,9 +3467,10 @@ scratch_class->enclosing_method_method_index()); scratch_class->set_enclosing_method_indices(old_class_idx, old_method_idx); + the_class->set_has_been_redefined(); + // keep track of previous versions of this class - the_class->add_previous_version(scratch_class, &emcp_methods, - emcp_method_count); + the_class->add_previous_version(scratch_class, emcp_method_count); RC_TIMER_STOP(_timer_rsc_phase1); RC_TIMER_START(_timer_rsc_phase2); diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -403,14 +403,9 @@ // Change jmethodIDs to point to the new methods void update_jmethod_ids(); - // In addition to marking methods as obsolete, this routine - // records which methods are EMCP (Equivalent Module Constant - // Pool) in the emcp_methods BitMap and returns the number of - // EMCP methods via emcp_method_count_p. This information is - // used when information about the previous version of the_class - // is squirreled away. - void check_methods_and_mark_as_obsolete(BitMap *emcp_methods, - int * emcp_method_count_p); + // In addition to marking methods as old and/or obsolete, this routine + // counts the number of methods that are EMCP (Equivalent Module Constant Pool). + int check_methods_and_mark_as_obsolete(); void transfer_old_native_function_registrations(instanceKlassHandle the_class); // Install the redefinition of a class diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/runtime/arguments.hpp --- a/hotspot/src/share/vm/runtime/arguments.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/runtime/arguments.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -590,7 +590,9 @@ static void fix_appclasspath(); // Operation modi - static Mode mode() { return _mode; } + static Mode mode() { return _mode; } + static bool is_interpreter_only() { return mode() == _int; } + // Utility: copies src into buf, replacing "%%" with "%" and "%p" with pid. static bool copy_expand_pid(const char* src, size_t srclen, char* buf, size_t buflen); diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/runtime/globals.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -2473,7 +2473,7 @@ develop(bool, CIPrintCompilerName, false, \ "when CIPrint is active, print the name of the active compiler") \ \ - develop(bool, CIPrintCompileQueue, false, \ + diagnostic(bool, CIPrintCompileQueue, false, \ "display the contents of the compile queue whenever a " \ "compilation is enqueued") \ \ diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/runtime/os.cpp --- a/hotspot/src/share/vm/runtime/os.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/runtime/os.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -53,6 +53,7 @@ #include "runtime/vm_version.hpp" #include "services/attachListener.hpp" #include "services/nmtCommon.hpp" +#include "services/mallocTracker.hpp" #include "services/memTracker.hpp" #include "services/threadService.hpp" #include "utilities/defaultStream.hpp" @@ -570,6 +571,17 @@ NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1)); NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size)); +#if INCLUDE_NMT + // NMT can not track malloc allocation size > MAX_MALLOC_SIZE, which is + // (1GB - 1) on 32-bit system. It is not an issue on 64-bit system, where + // MAX_MALLOC_SIZE = ((1 << 62) - 1). + // VM code does not have such large malloc allocation. However, it can come + // Unsafe call. + if (MemTracker::tracking_level() >= NMT_summary && size > MAX_MALLOC_SIZE) { + return NULL; + } +#endif + #ifdef ASSERT // checking for the WatcherThread and crash_protection first // since os::malloc can be called when the libjvm.{dll,so} is @@ -640,6 +652,13 @@ } void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, const NativeCallStack& stack) { +#if INCLUDE_NMT + // See comments in os::malloc() above + if (MemTracker::tracking_level() >= NMT_summary && size > MAX_MALLOC_SIZE) { + return NULL; + } +#endif + #ifndef ASSERT NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1)); NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size)); diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/runtime/os.hpp --- a/hotspot/src/share/vm/runtime/os.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/runtime/os.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -557,6 +557,16 @@ // Unload library static void dll_unload(void *lib); + // Callback for loaded module information + // Input parameters: + // char* module_file_name, + // address module_base_addr, + // address module_top_addr, + // void* param + typedef int (*LoadedModulesCallbackFunc)(const char *, address, address, void *); + + static int get_loaded_modules_info(LoadedModulesCallbackFunc callback, void *param); + // Return the handle of this process static void* get_default_process_handle(); @@ -761,6 +771,9 @@ // Hook for os specific jvm options that we don't want to abort on seeing static bool obsolete_option(const JavaVMOption *option); + // Amount beyond the callee frame size that we bang the stack. + static int extra_bang_size_in_bytes(); + // Extensions #include "runtime/os_ext.hpp" diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/runtime/sweeper.cpp --- a/hotspot/src/share/vm/runtime/sweeper.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/runtime/sweeper.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -618,7 +618,7 @@ if (mc == NULL) { // Sometimes we can get here without MethodCounters. For example if we run with -Xcomp. // Try to allocate them. - mc = Method::build_method_counters(nm->method(), Thread::current()); + mc = nm->method()->get_method_counters(Thread::current()); } if (mc != NULL) { // Snapshot the value as it's changed concurrently diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/runtime/vm_operations.cpp --- a/hotspot/src/share/vm/runtime/vm_operations.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/runtime/vm_operations.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -470,3 +470,15 @@ ShouldNotReachHere(); } } + +void VM_PrintCompileQueue::doit() { + CompileBroker::print_compile_queues(_out); +} + +void VM_PrintCodeList::doit() { + CodeCache::print_codelist(_out); +} + +void VM_PrintCodeCache::doit() { + CodeCache::print_layout(_out); +} diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/runtime/vm_operations.hpp --- a/hotspot/src/share/vm/runtime/vm_operations.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/runtime/vm_operations.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -99,6 +99,9 @@ template(RotateGCLog) \ template(WhiteBoxOperation) \ template(ClassLoaderStatsOperation) \ + template(PrintCompileQueue) \ + template(PrintCodeList) \ + template(PrintCodeCache) \ class VM_Operation: public CHeapObj { public: @@ -413,4 +416,35 @@ void doit() { gclog_or_tty->rotate_log(true, _out); } }; +class VM_PrintCompileQueue: public VM_Operation { + private: + outputStream* _out; + + public: + VM_PrintCompileQueue(outputStream* st) : _out(st) {} + VMOp_Type type() const { return VMOp_PrintCompileQueue; } + void doit(); +}; + +class VM_PrintCodeList: public VM_Operation { + private: + outputStream* _out; + + public: + VM_PrintCodeList(outputStream* st) : _out(st) {} + VMOp_Type type() const { return VMOp_PrintCodeList; } + void doit(); +}; + +class VM_PrintCodeCache: public VM_Operation { + private: + outputStream* _out; + + public: + VM_PrintCodeCache(outputStream* st) : _out(st) {} + VMOp_Type type() const { return VMOp_PrintCodeCache; } + void doit(); +}; + + #endif // SHARE_VM_RUNTIME_VM_OPERATIONS_HPP diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/services/diagnosticCommand.cpp --- a/hotspot/src/share/vm/services/diagnosticCommand.cpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp Fri Sep 19 11:19:38 2014 -0700 @@ -60,6 +60,9 @@ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); // Enhanced JMX Agent Support // These commands won't be exported via the DiagnosticCommandMBean until an @@ -674,3 +677,18 @@ } } +void CompileQueueDCmd::execute(DCmdSource source, TRAPS) { + VM_PrintCompileQueue printCompileQueueOp(output()); + VMThread::execute(&printCompileQueueOp); +} + +void CodeListDCmd::execute(DCmdSource source, TRAPS) { + VM_PrintCodeList printCodeListOp(output()); + VMThread::execute(&printCodeListOp); +} + +void CodeCacheDCmd::execute(DCmdSource source, TRAPS) { + VM_PrintCodeCache printCodeCacheOp(output()); + VMThread::execute(&printCodeCacheOp); +} + diff -r 66228a695a62 -r 00b27213d86c hotspot/src/share/vm/services/diagnosticCommand.hpp --- a/hotspot/src/share/vm/services/diagnosticCommand.hpp Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp Fri Sep 19 11:19:38 2014 -0700 @@ -399,4 +399,68 @@ } }; +class CompileQueueDCmd : public DCmd { +public: + CompileQueueDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} + static const char* name() { + return "Compiler.queue"; + } + static const char* description() { + return "Print methods queued for compilation."; + } + static const char* impact() { + return "Low"; + } + static const JavaPermission permission() { + JavaPermission p = {"java.lang.management.ManagementPermission", + "monitor", NULL}; + return p; + } + static int num_arguments() { return 0; } + virtual void execute(DCmdSource source, TRAPS); +}; + +class CodeListDCmd : public DCmd { +public: + CodeListDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} + static const char* name() { + return "Compiler.codelist"; + } + static const char* description() { + return "Print all compiled methods in code cache."; + } + static const char* impact() { + return "Medium"; + } + static const JavaPermission permission() { + JavaPermission p = {"java.lang.management.ManagementPermission", + "monitor", NULL}; + return p; + } + static int num_arguments() { return 0; } + virtual void execute(DCmdSource source, TRAPS); +}; + + +class CodeCacheDCmd : public DCmd { +public: + CodeCacheDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} + static const char* name() { + return "Compiler.codecache"; + } + static const char* description() { + return "Print code cache layout and bounds."; + } + static const char* impact() { + return "Low"; + } + static const JavaPermission permission() { + JavaPermission p = {"java.lang.management.ManagementPermission", + "monitor", NULL}; + return p; + } + static int num_arguments() { return 0; } + virtual void execute(DCmdSource source, TRAPS); +}; + #endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP diff -r 66228a695a62 -r 00b27213d86c hotspot/test/TEST.groups --- a/hotspot/test/TEST.groups Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/test/TEST.groups Fri Sep 19 11:19:38 2014 -0700 @@ -80,6 +80,7 @@ runtime/NMT/MallocSiteHashOverflow.java \ runtime/NMT/MallocStressTest.java \ runtime/NMT/MallocTestType.java \ + runtime/NMT/MallocTrackingVerify.java \ runtime/NMT/ReleaseCommittedMemory.java \ runtime/NMT/ReleaseNoCommit.java \ runtime/NMT/ShutdownTwice.java \ @@ -87,6 +88,7 @@ runtime/NMT/SummarySanityCheck.java \ runtime/NMT/ThreadedMallocTestType.java \ runtime/NMT/ThreadedVirtualAllocTestType.java \ + runtime/NMT/UnsafeMallocLimit.java \ runtime/NMT/VirtualAllocCommitUncommitRecommit.java \ runtime/NMT/VirtualAllocTestType.java \ runtime/RedefineObject/TestRedefineObject.java \ diff -r 66228a695a62 -r 00b27213d86c hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java --- a/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java Fri Sep 19 11:19:38 2014 -0700 @@ -22,7 +22,7 @@ */ /* - * @ignore 8027915 + * @ignore 8049864 * @test TestParallelHeapSizeFlags * @key gc * @bug 8006088 diff -r 66228a695a62 -r 00b27213d86c hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java --- a/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java Fri Sep 19 11:19:38 2014 -0700 @@ -22,7 +22,6 @@ */ /* - * @ignore 8025645 * @test TestUseCompressedOopsErgo * @key gc * @bug 8010722 diff -r 66228a695a62 -r 00b27213d86c hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java --- a/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java Fri Sep 19 11:19:38 2014 -0700 @@ -22,7 +22,7 @@ */ /** - * @ignore 8042051 + * @ignore 8019361 * @test TestDynShrinkHeap * @bug 8016479 * @summary Verify that the heap shrinks after full GC according to the current values of the Min/MaxHeapFreeRatio flags diff -r 66228a695a62 -r 00b27213d86c hotspot/test/runtime/NMT/MallocTrackingVerify.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/NMT/MallocTrackingVerify.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8054836 + * @summary Test to verify correctness of malloc tracking + * @key nmt jcmd + * @library /testlibrary /testlibrary/whitebox + * @build MallocTrackingVerify + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocTrackingVerify + * + */ + +import java.util.ArrayList; +import java.util.Random; + +import com.oracle.java.testlibrary.*; + +import sun.hotspot.WhiteBox; + +public class MallocTrackingVerify { + private static int MAX_ALLOC = 4 * 1024; + + static ArrayList mallocd_memory = new ArrayList(); + static long mallocd_total = 0; + public static WhiteBox wb = WhiteBox.getWhiteBox(); + + public static void main(String args[]) throws Exception { + OutputAnalyzer output; + + // Grab my own PID + String pid = Integer.toString(ProcessTools.getProcessId()); + ProcessBuilder pb = new ProcessBuilder(); + + Random random = new Random(); + // Allocate small amounts of memory with random pseudo call stack + while (mallocd_total < MAX_ALLOC) { + int size = random.nextInt(31) + 1; + long addr = wb.NMTMallocWithPseudoStack(size, random.nextInt()); + if (addr != 0) { + MallocMemory mem = new MallocMemory(addr, size); + mallocd_memory.add(mem); + mallocd_total += size; + } else { + System.out.println("Out of malloc memory"); + break; + } + } + + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary" }); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("Test (reserved=4KB, committed=4KB)"); + + // Free + for (MallocMemory mem : mallocd_memory) { + wb.NMTFree(mem.addr()); + } + + // Run 'jcmd VM.native_memory summary', check for expected output + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, + "VM.native_memory", "summary" }); + output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("Test (reserved="); + } + + static class MallocMemory { + private long addr; + private int size; + + MallocMemory(long addr, int size) { + this.addr = addr; + this.size = size; + } + + long addr() { + return this.addr; + } + + int size() { + return this.size; + } + } +} diff -r 66228a695a62 -r 00b27213d86c hotspot/test/runtime/NMT/UnsafeMallocLimit.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/NMT/UnsafeMallocLimit.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8055289 + * @library /testlibrary + * @build UnsafeMallocLimit + * @run main/othervm -Xmx32m -XX:NativeMemoryTracking=summary UnsafeMallocLimit + */ + +import com.oracle.java.testlibrary.*; +import sun.misc.Unsafe; + +public class UnsafeMallocLimit { + + public static void main(String args[]) throws Exception { + if (Platform.is32bit()) { + Unsafe unsafe = Utils.getUnsafe(); + try { + unsafe.allocateMemory(1 << 30); + throw new RuntimeException("Did not get expected OOME"); + } catch (OutOfMemoryError e) { + // Expected exception + } + } else { + System.out.println("Test only valid on 32-bit platforms"); + } + } +} diff -r 66228a695a62 -r 00b27213d86c hotspot/test/runtime/RedefineFinalizer/RedefineFinalizer.java --- a/hotspot/test/runtime/RedefineFinalizer/RedefineFinalizer.java Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 6904403 - * @summary Don't assert if we redefine finalize method - * @library /testlibrary - * @build RedefineClassHelper - * @run main RedefineClassHelper - * @run main/othervm -javaagent:redefineagent.jar RedefineFinalizer - */ - -/* - * Regression test for hitting: - * - * assert(f == k->has_finalizer()) failed: inconsistent has_finalizer - * - * when redefining finalizer method - */ -public class RedefineFinalizer { - - public static String newB = - "class RedefineFinalizer$B {" + - " protected void finalize() { " + - " System.out.println(\"Finalizer called\");" + - " }" + - "}"; - - public static void main(String[] args) throws Exception { - RedefineClassHelper.redefineClass(B.class, newB); - - A a = new A(); - } - - static class A extends B { - } - - static class B { - protected void finalize() { - // should be empty - } - } -} diff -r 66228a695a62 -r 00b27213d86c hotspot/test/runtime/RedefineTests/RedefineFinalizer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/RedefineTests/RedefineFinalizer.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6904403 + * @summary Don't assert if we redefine finalize method + * @library /testlibrary + * @build RedefineClassHelper + * @run main RedefineClassHelper + * @run main/othervm -javaagent:redefineagent.jar RedefineFinalizer + */ + +/* + * Regression test for hitting: + * + * assert(f == k->has_finalizer()) failed: inconsistent has_finalizer + * + * when redefining finalizer method + */ +public class RedefineFinalizer { + + public static String newB = + "class RedefineFinalizer$B {" + + " protected void finalize() { " + + " System.out.println(\"Finalizer called\");" + + " }" + + "}"; + + public static void main(String[] args) throws Exception { + RedefineClassHelper.redefineClass(B.class, newB); + + A a = new A(); + } + + static class A extends B { + } + + static class B { + protected void finalize() { + // should be empty + } + } +} diff -r 66228a695a62 -r 00b27213d86c hotspot/test/runtime/RedefineTests/RedefineRunningMethods.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/RedefineTests/RedefineRunningMethods.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8055008 + * @summary Redefine EMCP and non-EMCP methods that are running in an infinite loop + * @library /testlibrary + * @build RedefineClassHelper + * @run main RedefineClassHelper + * @run main/othervm -javaagent:redefineagent.jar -XX:TraceRedefineClasses=0x600 RedefineRunningMethods + */ +public class RedefineRunningMethods { + + public static String newB = + "class RedefineRunningMethods$B {" + + " static int count1 = 0;" + + " static int count2 = 0;" + + " public static volatile boolean stop = false;" + + " static void localSleep() { " + + " try{ " + + " Thread.currentThread().sleep(10);" + + " } catch(InterruptedException ie) { " + + " } " + + " } " + + " public static void infinite() { " + + " System.out.println(\"infinite called\");" + + " }" + + " public static void infinite_emcp() { " + + " while (!stop) { count2++; localSleep(); }" + + " }" + + "}"; + + public static String evenNewerB = + "class RedefineRunningMethods$B {" + + " static int count1 = 0;" + + " static int count2 = 0;" + + " public static volatile boolean stop = false;" + + " static void localSleep() { " + + " try{ " + + " Thread.currentThread().sleep(1);" + + " } catch(InterruptedException ie) { " + + " } " + + " } " + + " public static void infinite() { }" + + " public static void infinite_emcp() { " + + " System.out.println(\"infinite_emcp now obsolete called\");" + + " }" + + "}"; + + static class B { + static int count1 = 0; + static int count2 = 0; + public static volatile boolean stop = false; + static void localSleep() { + try{ + Thread.currentThread().sleep(10);//sleep for 10 ms + } catch(InterruptedException ie) { + } + } + + public static void infinite() { + while (!stop) { count1++; localSleep(); } + } + public static void infinite_emcp() { + while (!stop) { count2++; localSleep(); } + } + } + + + public static void main(String[] args) throws Exception { + + new Thread() { + public void run() { + B.infinite(); + } + }.start(); + + new Thread() { + public void run() { + B.infinite_emcp(); + } + }.start(); + + RedefineClassHelper.redefineClass(B.class, newB); + + System.gc(); + + B.infinite(); + + // Start a thread with the second version of infinite_emcp running + new Thread() { + public void run() { + B.infinite_emcp(); + } + }.start(); + + for (int i = 0; i < 20 ; i++) { + String s = new String("some garbage"); + System.gc(); + } + + RedefineClassHelper.redefineClass(B.class, evenNewerB); + System.gc(); + + for (int i = 0; i < 20 ; i++) { + B.infinite(); + String s = new String("some garbage"); + System.gc(); + } + + B.infinite_emcp(); + + // purge should clean everything up. + B.stop = true; + + for (int i = 0; i < 20 ; i++) { + B.infinite(); + String s = new String("some garbage"); + System.gc(); + } + } +} diff -r 66228a695a62 -r 00b27213d86c hotspot/test/runtime/SharedArchiveFile/ArchiveDoesNotExist.java --- a/hotspot/test/runtime/SharedArchiveFile/ArchiveDoesNotExist.java Fri Sep 19 11:13:27 2014 -0700 +++ b/hotspot/test/runtime/SharedArchiveFile/ArchiveDoesNotExist.java Fri Sep 19 11:19:38 2014 -0700 @@ -61,7 +61,7 @@ "-version"); output = new OutputAnalyzer(pb.start()); - output.shouldContain("java version"); + output.shouldMatch("(java|openjdk) version"); output.shouldNotContain("sharing"); output.shouldHaveExitValue(0); } diff -r 66228a695a62 -r 00b27213d86c hotspot/test/serviceability/dcmd/CodeCacheTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/CodeCacheTest.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test CodeCacheTest + * @bug 8054889 + * @build DcmdUtil CodeCacheTest + * @run main CodeCacheTest + * @summary Test of diagnostic command Compiler.codecache + */ + +import java.io.BufferedReader; +import java.io.StringReader; +import java.lang.reflect.Method; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CodeCacheTest { + + /** + * This test calls Jcmd (diagnostic command tool) Compiler.codecache and then parses the output, + * making sure that all number look ok + * + * + * Expected output: + * + * CodeCache: size=245760Kb used=4680Kb max_used=4680Kb free=241079Kb + * bounds [0x00007f5bd9000000, 0x00007f5bd94a0000, 0x00007f5be8000000] + * total_blobs=575 nmethods=69 adapters=423 + * compilation: enabled + */ + + static Pattern line1 = Pattern.compile("CodeCache: size=(\\p{Digit}*)Kb used=(\\p{Digit}*)Kb max_used=(\\p{Digit}*)Kb free=(\\p{Digit}*)Kb"); + static Pattern line2 = Pattern.compile(" bounds \\[0x(\\p{XDigit}*), 0x(\\p{XDigit}*), 0x(\\p{XDigit}*)\\]"); + static Pattern line3 = Pattern.compile(" total_blobs=(\\p{Digit}*) nmethods=(\\p{Digit}*) adapters=(\\p{Digit}*)"); + static Pattern line4 = Pattern.compile(" compilation: (\\w*)"); + + public static void main(String arg[]) throws Exception { + + // Get output from dcmd (diagnostic command) + String result = DcmdUtil.executeDcmd("Compiler.codecache"); + BufferedReader r = new BufferedReader(new StringReader(result)); + + // Validate first line + String line; + line = r.readLine(); + Matcher m = line1.matcher(line); + if (m.matches()) { + for(int i = 1; i <= 4; i++) { + int val = Integer.parseInt(m.group(i)); + if (val < 0) { + throw new Exception("Failed parsing dcmd codecache output"); + } + } + } else { + throw new Exception("Regexp 1 failed"); + } + + // Validate second line + line = r.readLine(); + m = line2.matcher(line); + if (m.matches()) { + long start = Long.parseLong(m.group(1), 16); + if (start < 0) { + throw new Exception("Failed parsing dcmd codecache output"); + } + long mark = Long.parseLong(m.group(2), 16); + if (mark < 0) { + throw new Exception("Failed parsing dcmd codecache output"); + } + long top = Long.parseLong(m.group(3), 16); + if (top < 0) { + throw new Exception("Failed parsing dcmd codecache output"); + } + if (start > mark) { + throw new Exception("Failed parsing dcmd codecache output"); + } + if (mark > top) { + throw new Exception("Failed parsing dcmd codecache output"); + } + } else { + throw new Exception("Regexp 2 failed line: " + line); + } + + // Validate third line + line = r.readLine(); + m = line3.matcher(line); + if (m.matches()) { + int blobs = Integer.parseInt(m.group(1)); + if (blobs <= 0) { + throw new Exception("Failed parsing dcmd codecache output"); + } + int nmethods = Integer.parseInt(m.group(2)); + if (nmethods <= 0) { + throw new Exception("Failed parsing dcmd codecache output"); + } + int adapters = Integer.parseInt(m.group(3)); + if (adapters <= 0) { + throw new Exception("Failed parsing dcmd codecache output"); + } + if (blobs < (nmethods + adapters)) { + throw new Exception("Failed parsing dcmd codecache output"); + } + } else { + throw new Exception("Regexp 3 failed"); + } + + // Validate fourth line + line = r.readLine(); + m = line4.matcher(line); + if (m.matches()) { + if (!m.group(1).equals("enabled")) { + throw new Exception("Invalid message: '" + m.group(1) + "'"); + } + } else { + throw new Exception("Regexp 4 failed"); + } + } +} diff -r 66228a695a62 -r 00b27213d86c hotspot/test/serviceability/dcmd/CodelistTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/CodelistTest.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test CodelistTest + * @bug 8054889 + * @build DcmdUtil MethodIdentifierParser CodelistTest + * @run main CodelistTest + * @summary Test of diagnostic command Compiler.codelist + */ + +import java.io.BufferedReader; +import java.io.StringReader; +import java.lang.reflect.Method; + +public class CodelistTest { + + /** + * This test calls Jcmd (diagnostic command tool) Compiler.codelist and then parses the output, + * making sure that the first methods in the list is valid by reflection. + * + * Output example: + * + * 6 0 java.lang.System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V [0x00007f7b49200910, 0x00007f7b49200aa0 - 0x00007f7b49200d30] + * 2 3 java.lang.String.indexOf(II)I [0x00007f7b49200d90, 0x00007f7b49200f60 - 0x00007f7b49201490] + * 7 3 java.lang.Math.min(II)I [0x00007f7b4922f010, 0x00007f7b4922f180 - 0x00007f7b4922f338] + * 8 3 java.lang.String.equals(Ljava/lang/Object;)Z [0x00007f7b4922fb10, 0x00007f7b4922fd40 - 0x00007f7b49230698] + * 9 3 java.lang.AbstractStringBuilder.ensureCapacityInternal(I)V [0x00007f7b49232010, 0x00007f7b492321a0 - 0x00007f7b49232510] + * 10 1 java.lang.Object.()V [0x00007f7b49233e90, 0x00007f7b49233fe0 - 0x00007f7b49234118] + * + */ + + public static void main(String arg[]) throws Exception { + int ok = 0; + int fail = 0; + + // Get output from dcmd (diagnostic command) + String result = DcmdUtil.executeDcmd("Compiler.codelist"); + BufferedReader r = new BufferedReader(new StringReader(result)); + + // Grab a method name from the output + String line; + int count = 0; + + while((line = r.readLine()) != null) { + count++; + + String[] parts = line.split(" "); + // int compileID = Integer.parseInt(parts[0]); + // int compileLevel = Integer.parseInt(parts[1]); + String methodPrintedInLogFormat = parts[2]; + + // skip inits and clinits - they can not be reflected + if (methodPrintedInLogFormat.contains("")) { + continue; + } + if (methodPrintedInLogFormat.contains("")) { + continue; + } + + MethodIdentifierParser mf = new MethodIdentifierParser(methodPrintedInLogFormat); + Method m; + try { + m = mf.getMethod(); + } catch (NoSuchMethodException e) { + m = null; + } + if (m == null) { + throw new Exception("Test failed"); + } + if (count > 10) { + // Testing 10 entries is enough. Lets not waste time. + break; + } + } + } +} diff -r 66228a695a62 -r 00b27213d86c hotspot/test/serviceability/dcmd/CompilerQueueTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/CompilerQueueTest.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test CompilerQueueTest + * @bug 8054889 + * @build DcmdUtil CompilerQueueTest + * @run main CompilerQueueTest + * @summary Test of diagnostic command Compiler.queue + */ + +import java.io.BufferedReader; +import java.io.StringReader; + +public class CompilerQueueTest { + + /** + * This test calls Jcmd (diagnostic command tool) Compiler.queue and + * then parses the output, making sure that the output look ok. + * + * + * Output example: + * + * Contents of C1 compile queue + * ---------------------------- + * 73 3 java.lang.AbstractStringBuilder::append (50 bytes) + * 74 1 java.util.TreeMap::size (5 bytes) + * 75 3 java.lang.StringBuilder::append (8 bytes) + * 83 3 java.util.TreeMap$ValueIterator::next (8 bytes) + * 84 1 javax.management.MBeanFeatureInfo::getName (5 bytes) + * ---------------------------- + * Contents of C2 compile queue + * ---------------------------- + * Empty + * ---------------------------- + * + **/ + + public static void main(String arg[]) throws Exception { + + // Get output from dcmd (diagnostic command) + String result = DcmdUtil.executeDcmd("Compiler.queue"); + BufferedReader r = new BufferedReader(new StringReader(result)); + + String line; + match(r.readLine(), "Contents of C1 compile queue"); + match(r.readLine(), "----------------------------"); + String str = r.readLine(); + if (!str.equals("Empty")) { + while (str.charAt(0) != '-') { + validateMethodLine(str); + str = r.readLine(); + } + } else { + str = r.readLine(); + } + + match(str, "----------------------------"); + match(r.readLine(), "Contents of C2 compile queue"); + match(r.readLine(), "----------------------------"); + str = r.readLine(); + if (!str.equals("Empty")) { + while (str.charAt(0) != '-') { + validateMethodLine(str); + str = r.readLine(); + } + } else { + str = r.readLine(); + } + match(str, "----------------------------"); + } + + private static void validateMethodLine(String str) throws Exception { + String name = str.substring(19); + int sep = name.indexOf("::"); + try { + Class.forName(name.substring(0, sep)); + } catch (ClassNotFoundException e) { + throw new Exception("Failed parsing dcmd queue"); + } + } + + public static void match(String line, String str) throws Exception { + if (!line.equals(str)) { + throw new Exception("String equals: " + line + ", " + str); + } + } +} diff -r 66228a695a62 -r 00b27213d86c hotspot/test/serviceability/dcmd/MethodIdentifierParser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/MethodIdentifierParser.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.reflect.Method; +import java.util.ArrayList; + +public class MethodIdentifierParser { + + private String logString; + private String className; + private String methodName; + private String methodDescriptor; + + /** + * This is a utility class for parsing the log entries for a method. It supplies + * a few select methods for reflecting the class and method from that information. + * + * Example log entries: + * "java.util.TreeMap.successor(Ljava/util/TreeMap$Entry;)Ljava/util/TreeMap$Entry;" + */ + + public MethodIdentifierParser(String logString) { + this.logString = logString; + + int i = logString.lastIndexOf("."); // find start of method name + className = logString.substring(0, i); // classname is everything before + int i2 = logString.indexOf("("); // Signature starts with an '(' + methodName = logString.substring(i+1, i2); + methodDescriptor = logString.substring(i2, logString.length()); + + // Add sanity check for extracted fields + } + + public Method getMethod() throws NoSuchMethodException, SecurityException, ClassNotFoundException, Exception { + try { + return Class.forName(className).getDeclaredMethod(methodName, getParamenterDescriptorArray()); + } catch (UnexpectedTokenException e) { + throw new Exception("Parse failed"); + } + } + + public Class[] getParamenterDescriptorArray() throws ClassNotFoundException, UnexpectedTokenException { + ParameterDecriptorIterator s = new ParameterDecriptorIterator(methodDescriptor); + Class paramType; + ArrayList> list = new ArrayList>(); + while ((paramType = s.nextParamType()) != null) { + list.add(paramType); + } + if (list.size() > 0) { + return list.toArray(new Class[list.size()]); + } else { + return null; + } + } + + class ParameterDecriptorIterator { + + // This class uses charAt() indexing for startMark and i + // That is when i points to the last char it can be retrieved with + // charAt(i). Including the last char for a subString requires + // substring(startMark, i+1); + + private String methodDescriptor; + private int startMark; + + public ParameterDecriptorIterator(String signature) { + this.methodDescriptor = signature; + this.startMark = 0; + if (signature.charAt(0) == '(') { + this.startMark = 1; + } + } + + public Class nextParamType() throws UnexpectedTokenException { + int i = startMark; + while (methodDescriptor.length() > i) { + switch (methodDescriptor.charAt(i)) { + case 'C': + case 'B': + case 'I': + case 'J': + case 'Z': + case 'F': + case 'D': + case 'S': + // Primitive class case, but we may have gotten here with [ as first token + break; + case 'L': + // Internal class name suffixed by ';' + while (methodDescriptor.charAt(i) != ';') { + i++; + } + break; + case '[': + i++; // arrays -> do another pass + continue; + case ')': + return null; // end found + case 'V': + case ';': + default: + throw new UnexpectedTokenException(methodDescriptor, i); + } + break; + } + if (i == startMark) { + // Single char -> primitive class case + startMark++; // Update for next iteration + switch (methodDescriptor.charAt(i)) { + case 'C': + return char.class; + case 'B': + return byte.class; + case 'I': + return int.class; + case 'J': + return long.class; + case 'F': + return float.class; + case 'D': + return double.class; + case 'S': + return short.class; + case 'Z': + return boolean.class; + default: + throw new UnexpectedTokenException(methodDescriptor, i); + } + } else { + // Multi char case + String nextParam; + if (methodDescriptor.charAt(startMark) == 'L') { + // When reflecting a class the leading 'L' and trailing';' must be removed. + // (When reflecting an array of classes, they must remain...) + nextParam = methodDescriptor.substring(startMark+1, i); + } else { + // Any kind of array - simple case, use whole descriptor when reflecting. + nextParam = methodDescriptor.substring(startMark, i+1); + } + startMark = ++i; // Update for next iteration + try { + // The parameter descriptor uses JVM internal class identifier with '/' as + // package separator, but Class.forName expects '.'. + nextParam = nextParam.replace('/', '.'); + return Class.forName(nextParam); + } catch (ClassNotFoundException e) { + System.out.println("Class not Found: " + nextParam); + return null; + } + } + } + } + + class UnexpectedTokenException extends Exception { + String descriptor; + int i; + public UnexpectedTokenException(String descriptor, int i) { + this.descriptor = descriptor; + this.i = i; + } + + @Override + public String toString() { + return "Unexpected token at: " + i + " in signature: " + descriptor; + } + + private static final long serialVersionUID = 1L; + } + + public void debugPrint() { + System.out.println("mlf in: " + logString); + System.out.println("mlf class: " + className); + System.out.println("mlf method: " + methodName); + System.out.println("mlf methodDescriptor: " + methodDescriptor); + } +} diff -r 66228a695a62 -r 00b27213d86c jaxp/.hgtags --- a/jaxp/.hgtags Fri Sep 19 11:13:27 2014 -0700 +++ b/jaxp/.hgtags Fri Sep 19 11:19:38 2014 -0700 @@ -273,3 +273,4 @@ dc1e26434b3fd7e9b8eeab149103c1e30965f95c jdk9-b28 30adcd13a313ea91e81164801a2f89282756d933 jdk9-b29 d181d4002214e4914d5525bd5ee13369311c765c jdk9-b30 +292317ebc7dbaca6b3965f0bc7b38a2cee733b7a jdk9-b31 diff -r 66228a695a62 -r 00b27213d86c jaxws/.hgtags --- a/jaxws/.hgtags Fri Sep 19 11:13:27 2014 -0700 +++ b/jaxws/.hgtags Fri Sep 19 11:19:38 2014 -0700 @@ -276,3 +276,4 @@ 5282a14f131f897cc9575872c0fae72d47dc4e65 jdk9-b28 3d1a4bfb6abbf5011ba6d8896301ee3b6ef3ba72 jdk9-b29 e58d3ea638c3824f01547596b2a98aa5f77c4a5c jdk9-b30 +7af228ae847f3c02aaafb7b01cdbb3bdc2e89e77 jdk9-b31 diff -r 66228a695a62 -r 00b27213d86c jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/xjc/api/util/ApClassLoader.java --- a/jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/xjc/api/util/ApClassLoader.java Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +0,0 @@ -/* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tools.internal.xjc.api.util; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.File; -import java.net.URL; -import java.net.URLClassLoader; -import java.net.MalformedURLException; - -import com.sun.istack.internal.Nullable; - -/** - * {@link ClassLoader} that loads Annotation Processing and specified classes - * both into the same classloader, so that they can reference each other. - * - * @author Bhakti Mehta - * @since 2.0 beta - */ -public final class ApClassLoader extends URLClassLoader { - /** - * List of package prefixes we want to mask the - * parent classLoader from loading - */ - private final String[] packagePrefixes; - - /** - * - * @param packagePrefixes - * The package prefixes that are forced to resolve within this class loader. - * @param parent - * The parent class loader to delegate to. Null to indicate bootstrap classloader. - */ - public ApClassLoader(@Nullable ClassLoader parent, String[] packagePrefixes) throws ToolsJarNotFoundException { - super(getToolsJar(parent),parent); - if(getURLs().length==0) - // if tools.jar was found in our classloader, no need to create - // a parallel classes - this.packagePrefixes = new String[0]; - else - this.packagePrefixes = packagePrefixes; - } - - public Class loadClass(String className) throws ClassNotFoundException { - for( String prefix : packagePrefixes ) { - if (className.startsWith(prefix) ) { - // we need to load those classes in this class loader - // without delegation. - return findClass(className); - } - } - - return super.loadClass(className); - - } - - protected Class findClass(String name) throws ClassNotFoundException { - - StringBuilder sb = new StringBuilder(name.length() + 6); - sb.append(name.replace('.','/')).append(".class"); - - InputStream is = getResourceAsStream(sb.toString()); - if (is==null) - throw new ClassNotFoundException("Class not found" + sb); - - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buf = new byte[1024]; - int len; - while((len=is.read(buf))>=0) - baos.write(buf,0,len); - - buf = baos.toByteArray(); - - // define package if not defined yet - int i = name.lastIndexOf('.'); - if (i != -1) { - String pkgname = name.substring(0, i); - Package pkg = getPackage(pkgname); - if(pkg==null) - definePackage(pkgname, null, null, null, null, null, null, null); - } - - return defineClass(name,buf,0,buf.length); - } catch (IOException e) { - throw new ClassNotFoundException(name,e); - } finally { - try { - is.close(); - } catch (IOException ioe) { - //ignore - } - } - } - - /** - * Returns a class loader that can load classes from JDK tools.jar. - * @param parent - */ - private static URL[] getToolsJar(@Nullable ClassLoader parent) throws ToolsJarNotFoundException { - - try { - Class.forName("com.sun.tools.javac.Main", false, parent); - return new URL[0]; - // we can already load them in the parent class loader. - // so no need to look for tools.jar. - // this happens when we are run inside IDE/Ant, or - // in Mac OS. - } catch (ClassNotFoundException e) { - // otherwise try to find tools.jar - } - - File jreHome = new File(System.getProperty("java.home")); - File toolsJar = new File( jreHome.getParent(), "lib/tools.jar" ); - - if (!toolsJar.exists()) { - throw new ToolsJarNotFoundException(toolsJar); - } - - try { - return new URL[]{toolsJar.toURL()}; - } catch (MalformedURLException e) { - // impossible - throw new AssertionError(e); - } - } -} diff -r 66228a695a62 -r 00b27213d86c jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/xjc/api/util/ToolsJarNotFoundException.java --- a/jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/xjc/api/util/ToolsJarNotFoundException.java Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tools.internal.xjc.api.util; - -import java.io.File; - -/** - * Signals an error when tools.jar was not found. - * - * Simply print out the message obtained by {@link #getMessage()}. - * - * @author Kohsuke Kawaguchi - */ -public final class ToolsJarNotFoundException extends Exception { - /** - * Location where we expected to find tools.jar - */ - public final File toolsJar; - - public ToolsJarNotFoundException(File toolsJar) { - super(calcMessage(toolsJar)); - this.toolsJar = toolsJar; - } - - private static String calcMessage(File toolsJar) { - return Messages.TOOLS_JAR_NOT_FOUND.format(toolsJar.getPath()); - } -} diff -r 66228a695a62 -r 00b27213d86c jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/Invoker.java --- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/Invoker.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/Invoker.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,19 +29,16 @@ import com.sun.istack.internal.tools.ParallelWorldClassLoader; import com.sun.tools.internal.ws.resources.WscompileMessages; import com.sun.tools.internal.ws.wscompile.Options; -import com.sun.tools.internal.xjc.api.util.ToolsJarNotFoundException; import com.sun.xml.internal.bind.util.Which; import javax.xml.ws.Service; import javax.xml.ws.WebServiceFeature; import javax.xml.namespace.QName; -import java.io.File; import java.io.OutputStream; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; @@ -59,7 +56,7 @@ /** * The list of package prefixes we want the * {@link MaskingClassLoader} to prevent the parent - * classLoader from loading + * class loader from loading */ static final String[] maskedPackages = new String[]{ "com.sun.istack.internal.tools.", @@ -130,24 +127,6 @@ return -1; } - //find and load tools.jar - List urls = new ArrayList(); - findToolsJar(cl, urls); - - if(urls.size() > 0){ - List mask = new ArrayList(Arrays.asList(maskedPackages)); - - // first create a protected area so that we load JAXB/WS 2.1 API - // and everything that depends on them inside - cl = new MaskingClassLoader(cl,mask); - - // then this classloader loads the API and tools.jar - cl = new URLClassLoader(urls.toArray(new URL[urls.size()]), cl); - - // finally load the rest of the RI. The actual class files are loaded from ancestors - cl = new ParallelWorldClassLoader(cl,""); - } - } Thread.currentThread().setContextClassLoader(cl); @@ -158,8 +137,6 @@ Method runMethod = compileTool.getMethod("run",String[].class); boolean r = (Boolean)runMethod.invoke(tool,new Object[]{args}); return r ? 0 : 1; - } catch (ToolsJarNotFoundException e) { - System.err.println(e.getMessage()); } catch (InvocationTargetException e) { throw e.getCause(); } catch(ClassNotFoundException e){ @@ -167,8 +144,6 @@ }finally { Thread.currentThread().setContextClassLoader(oldcc); } - - return -1; } /** @@ -203,10 +178,10 @@ /** - * Creates a classloader that can load JAXB/WS 2.2 API and tools.jar, - * and then return a classloader that can RI classes, which can see all those APIs and tools.jar. + * Creates a class loader that can load JAXB/WS 2.2 API, + * and then return a class loader that can RI classes, which can see all those APIs. */ - public static ClassLoader createClassLoader(ClassLoader cl) throws ClassNotFoundException, IOException, ToolsJarNotFoundException { + public static ClassLoader createClassLoader(ClassLoader cl) throws ClassNotFoundException, IOException { URL[] urls = findIstack22APIs(cl); if(urls.length==0) @@ -223,7 +198,7 @@ // and everything that depends on them inside cl = new MaskingClassLoader(cl,mask); - // then this classloader loads the API and tools.jar + // then this class loader loads the API cl = new URLClassLoader(urls, cl); // finally load the rest of the RI. The actual class files are loaded from ancestors @@ -233,13 +208,13 @@ } /** - * Creates a classloader for loading JAXB/WS 2.2 jar and tools.jar + * Creates a class loader for loading JAXB/WS 2.2 jar */ - private static URL[] findIstack22APIs(ClassLoader cl) throws ClassNotFoundException, IOException, ToolsJarNotFoundException { + private static URL[] findIstack22APIs(ClassLoader cl) throws ClassNotFoundException, IOException { List urls = new ArrayList(); if(Service.class.getClassLoader()==null) { - // JAX-WS API is loaded from bootstrap classloader + // JAX-WS API is loaded from bootstrap class loader URL res = cl.getResource("javax/xml/ws/EndpointContext.class"); if(res==null) throw new ClassNotFoundException("There's no JAX-WS 2.2 API in the classpath"); @@ -250,28 +225,7 @@ urls.add(ParallelWorldClassLoader.toJarUrl(res)); } - findToolsJar(cl, urls); - return urls.toArray(new URL[urls.size()]); } - private static void findToolsJar(ClassLoader cl, List urls) throws ToolsJarNotFoundException, MalformedURLException { - try { - Class.forName("com.sun.tools.javac.Main",false,cl); - // we can already load them in the parent class loader. - // so no need to look for tools.jar. - // this happens when we are run inside IDE/Ant, or - // in Mac OS. - } catch (ClassNotFoundException e) { - // otherwise try to find tools.jar - File jreHome = new File(System.getProperty("java.home")); - File toolsJar = new File( jreHome.getParent(), "lib/tools.jar" ); - - if (!toolsJar.exists()) { - throw new ToolsJarNotFoundException(toolsJar); - } - urls.add(toolsJar.toURL()); - } - } - } diff -r 66228a695a62 -r 00b27213d86c jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/WsGen.java --- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/WsGen.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/WsGen.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,8 +35,7 @@ */ public class WsGen { /** - * CLI entry point. Use {@link Invoker} to - * load tools.jar + * CLI entry point. Use {@link Invoker} to load proper API version */ public static void main(String[] args) throws Throwable { System.exit(Invoker.invoke("com.sun.tools.internal.ws.wscompile.WsgenTool", args)); @@ -50,7 +49,7 @@ * it doesn't invoke {@link System#exit(int)}. This method * also doesn't play with classloaders. It's the caller's * responsibility to set up the classloader to load all jars - * needed to run the tool, including $JAVA_HOME/lib/tools.jar + * needed to run the tool. * * @return * 0 if the tool runs successfully. diff -r 66228a695a62 -r 00b27213d86c jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/WsImport.java --- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/WsImport.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/WsImport.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,8 +35,7 @@ */ public class WsImport { /** - * CLI entry point. Use {@link Invoker} to - * load tools.jar + * CLI entry point. Use {@link Invoker} to load proper API version */ public static void main(String[] args) throws Throwable { System.exit(Invoker.invoke("com.sun.tools.internal.ws.wscompile.WsimportTool", args)); @@ -50,7 +49,7 @@ * it doesn't invoke {@link System#exit(int)}. This method * also doesn't play with classloaders. It's the caller's * responsibility to set up the classloader to load all jars - * needed to run the tool, including $JAVA_HOME/lib/tools.jar + * needed to run the tool. * * @return * 0 if the tool runs successfully. diff -r 66228a695a62 -r 00b27213d86c jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/resources/JavacompilerMessages.java --- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/resources/JavacompilerMessages.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/resources/JavacompilerMessages.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,40 +39,16 @@ private final static LocalizableMessageFactory messageFactory = new LocalizableMessageFactory("com.sun.tools.internal.ws.resources.javacompiler"); private final static Localizer localizer = new Localizer(); - public static Localizable localizableJAVACOMPILER_CLASSPATH_ERROR(Object arg0) { - return messageFactory.getMessage("javacompiler.classpath.error", arg0); - } - - /** - * {0} is not available in the classpath, requires Sun's JDK version 5.0 or latter. - * - */ - public static String JAVACOMPILER_CLASSPATH_ERROR(Object arg0) { - return localizer.localize(localizableJAVACOMPILER_CLASSPATH_ERROR(arg0)); - } - - public static Localizable localizableJAVACOMPILER_NOSUCHMETHOD_ERROR(Object arg0) { - return messageFactory.getMessage("javacompiler.nosuchmethod.error", arg0); + public static Localizable localizableNO_JAVACOMPILER_ERROR() { + return messageFactory.getMessage("no.javacompiler.error"); } /** - * There is no such method {0} available, requires Sun's JDK version 5.0 or latter. + * No system compiler found, check your jdk. * */ - public static String JAVACOMPILER_NOSUCHMETHOD_ERROR(Object arg0) { - return localizer.localize(localizableJAVACOMPILER_NOSUCHMETHOD_ERROR(arg0)); - } - - public static Localizable localizableJAVACOMPILER_ERROR(Object arg0) { - return messageFactory.getMessage("javacompiler.error", arg0); - } - - /** - * error : {0}. - * - */ - public static String JAVACOMPILER_ERROR(Object arg0) { - return localizer.localize(localizableJAVACOMPILER_ERROR(arg0)); + public static String NO_JAVACOMPILER_ERROR() { + return localizer.localize(localizableNO_JAVACOMPILER_ERROR()); } } diff -r 66228a695a62 -r 00b27213d86c jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/resources/javacompiler.properties --- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/resources/javacompiler.properties Fri Sep 19 11:13:27 2014 -0700 +++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/resources/javacompiler.properties Fri Sep 19 11:19:38 2014 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,4 @@ # # Generic Messages # -javacompiler.classpath.error={0} is not available in the classpath, requires Sun's JDK version 5.0 or latter. -javacompiler.nosuchmethod.error=There is no such method {0} available, requires Sun's JDK version 5.0 or latter. -javacompiler.error=error : {0}. +no.javacompiler.error=No system compiler found, check your jdk. diff -r 66228a695a62 -r 00b27213d86c jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wscompile/JavaCompilerHelper.java --- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wscompile/JavaCompilerHelper.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wscompile/JavaCompilerHelper.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,14 +28,13 @@ import com.sun.istack.internal.tools.ParallelWorldClassLoader; import com.sun.tools.internal.ws.resources.JavacompilerMessages; +import javax.tools.JavaCompiler; +import javax.tools.ToolProvider; import java.io.File; import java.io.OutputStream; -import java.io.PrintWriter; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.net.URL; -import java.net.URISyntaxException; /** * A helper class to invoke javac. @@ -61,34 +60,17 @@ } static boolean compile(String[] args, OutputStream out, ErrorReceiver receiver){ - ClassLoader cl = Thread.currentThread().getContextClassLoader(); try { - /* try to use the new compiler */ - Class comSunToolsJavacMainClass = - cl.loadClass("com.sun.tools.javac.Main"); - try { - Method compileMethod = - comSunToolsJavacMainClass.getMethod( - "compile", - compileMethodSignature); - Object result = - compileMethod.invoke( - null, args, new PrintWriter(out)); - return result instanceof Integer && (Integer) result == 0; - } catch (NoSuchMethodException e2) { - receiver.error(JavacompilerMessages.JAVACOMPILER_NOSUCHMETHOD_ERROR("getMethod(\"compile\", Class[])"), e2); - } catch (IllegalAccessException e) { - receiver.error(e); - } catch (InvocationTargetException e) { - receiver.error(e); + JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); + if (comp == null) { + receiver.error(JavacompilerMessages.NO_JAVACOMPILER_ERROR(), null); + return false; } - } catch (ClassNotFoundException e) { - receiver.error(JavacompilerMessages.JAVACOMPILER_CLASSPATH_ERROR("com.sun.tools.javac.Main"), e); + return 0 == comp.run(null, out, out, args); } catch (SecurityException e) { receiver.error(e); } return false; } - private static final Class[] compileMethodSignature = {String[].class, PrintWriter.class}; } diff -r 66228a695a62 -r 00b27213d86c jdk/.hgtags --- a/jdk/.hgtags Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/.hgtags Fri Sep 19 11:19:38 2014 -0700 @@ -273,3 +273,4 @@ 1828f73b35cfe35e460e41fd6e087ab1f83e0621 jdk9-b28 2da27e8e2c865e154f0c2eb9009f011a44649b11 jdk9-b29 8d24fb4493f13d380a2adf62d444e1e5a4451f37 jdk9-b30 +71e99dae28f9791287b88d46e16a266b564f22be jdk9-b31 diff -r 66228a695a62 -r 00b27213d86c jdk/make/CreateJars.gmk --- a/jdk/make/CreateJars.gmk Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/make/CreateJars.gmk Fri Sep 19 11:19:38 2014 -0700 @@ -220,7 +220,6 @@ sun/tools/serialver \ sun/tools/tree \ sun/tools/util \ - sun/util/cldr/CLDRLocaleDataMetaInfo.class \ sun/util/resources/provider/NonEnLocaleDataMetaInfo.class \ META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo \ sun/util/resources/cldr \ @@ -452,11 +451,9 @@ $(eval $(call SetupArchive,BUILD_CLDRDATA_JAR, \ $(CLDR_METAINF_SERVICES), \ SRCS := $(JDK_OUTPUTDIR)/modules/jdk.localedata \ - $(JDK_OUTPUTDIR)/modules/java.base \ $(CLDR_SERVICES_DIR), \ SUFFIXES := .class, \ INCLUDES := sun/text/resources/cldr \ - sun/util/cldr/CLDRLocaleDataMetaInfo.class \ sun/util/resources/cldr, \ EXTRA_FILES := META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo, \ JAR := $(CLDRDATA_JAR_DST), \ diff -r 66228a695a62 -r 00b27213d86c jdk/make/gensrc/Gensrc-java.base.gmk --- a/jdk/make/gensrc/Gensrc-java.base.gmk Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/make/gensrc/Gensrc-java.base.gmk Fri Sep 19 11:19:38 2014 -0700 @@ -29,14 +29,13 @@ include GensrcProperties.gmk GENSRC_JAVA_BASE += $(GENSRC_PROPERTIES) -include GensrcLocaleDataMetaInfo.gmk +include GensrcLocaleData.gmk include GensrcCharacterData.gmk include GensrcMisc.gmk include GensrcCharsetMapping.gmk include GensrcCharsetCoder.gmk include GensrcBuffer.gmk include GensrcExceptions.gmk -include GensrcCLDR.gmk java.base: $(GENSRC_JAVA_BASE) diff -r 66228a695a62 -r 00b27213d86c jdk/make/gensrc/Gensrc-jdk.attach.gmk --- a/jdk/make/gensrc/Gensrc-jdk.attach.gmk Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -# -# 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 -# 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. -# - -include GensrcCommon.gmk - -include GensrcProviders.gmk - -jdk.attach: $(GENSRC_JDK_ATTACH) - -all: jdk.attach - -.PHONY: all jdk.attach diff -r 66228a695a62 -r 00b27213d86c jdk/make/gensrc/Gensrc-jdk.charsets.gmk --- a/jdk/make/gensrc/Gensrc-jdk.charsets.gmk Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/make/gensrc/Gensrc-jdk.charsets.gmk Fri Sep 19 11:19:38 2014 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -25,10 +25,60 @@ include GensrcCommon.gmk -include GensrcCharsetMapping.gmk +################################################################################ +# +# Generate files using the charsetmapping tool +# +CHARSET_DATA_DIR := $(JDK_TOPDIR)/make/data/charsetmapping +CHARSET_GENSRC_JAVA_DIR_CS := $(JDK_OUTPUTDIR)/gensrc/jdk.charsets/sun/nio/cs/ext +CHARSET_DONE_CS := $(CHARSET_GENSRC_JAVA_DIR_CS)/_the.charsetmapping +CHARSET_COPYRIGHT_HEADER := $(JDK_TOPDIR)/make/src/classes/build/tools/charsetmapping +CHARSET_TEMPLATES := \ + $(CHARSET_DATA_DIR)/SingleByte-X.java.template \ + $(CHARSET_DATA_DIR)/DoubleByte-X.java.template + +$(CHARSET_DONE_CS)-extsbcs: $(CHARSET_DATA_DIR)/extsbcs \ + $(CHARSET_TEMPLATES) $(BUILD_TOOLS_JDK) + $(MKDIR) -p $(@D) + $(TOOL_CHARSETMAPPING) $(CHARSET_DATA_DIR) $(CHARSET_GENSRC_JAVA_DIR_CS) extsbcs + $(TOUCH) '$@' + +$(CHARSET_DONE_CS)-dbcs: $(CHARSET_DATA_DIR)/dbcs \ + $(CHARSET_TEMPLATES) $(BUILD_TOOLS_JDK) + $(MKDIR) -p $(@D) + $(TOOL_CHARSETMAPPING) $(CHARSET_DATA_DIR) $(CHARSET_GENSRC_JAVA_DIR_CS) dbcs + $(TOUCH) '$@' + +$(CHARSET_DONE_CS)-hkscs: $(CHARSET_COPYRIGHT_HEADER)/HKSCS.java \ + $(BUILD_TOOLS_JDK) + $(MKDIR) -p $(@D) + $(TOOL_CHARSETMAPPING) $(CHARSET_DATA_DIR) $(CHARSET_GENSRC_JAVA_DIR_CS) hkscs '$<' + $(TOUCH) '$@' + +$(CHARSET_DONE_CS)-euctw: $(CHARSET_COPYRIGHT_HEADER)/EUC_TW.java \ + $(BUILD_TOOLS_JDK) + $(MKDIR) -p $(@D) + $(TOOL_CHARSETMAPPING) $(CHARSET_DATA_DIR) $(CHARSET_GENSRC_JAVA_DIR_CS) euctw '$<' + $(TOUCH) '$@' + +$(CHARSET_GENSRC_JAVA_DIR_CS)/sjis0213.dat: $(CHARSET_DATA_DIR)/sjis0213.map \ + $(BUILD_TOOLS_JDK) + $(MKDIR) -p $(@D) + $(TOOL_CHARSETMAPPING) '$<' '$@' sjis0213 + +GENSRC_JDK_CHARSETS += \ + $(CHARSET_DONE_CS)-extsbcs \ + $(CHARSET_DONE_CS)-dbcs \ + $(CHARSET_DONE_CS)-hkscs \ + $(CHARSET_DONE_CS)-euctw \ + $(CHARSET_GENSRC_JAVA_DIR_CS)/sjis0213.dat \ + # + +################################################################################ jdk.charsets: $(GENSRC_JDK_CHARSETS) all: jdk.charsets .PHONY: all jdk.charsets + diff -r 66228a695a62 -r 00b27213d86c jdk/make/gensrc/Gensrc-jdk.jdi.gmk --- a/jdk/make/gensrc/Gensrc-jdk.jdi.gmk Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/make/gensrc/Gensrc-jdk.jdi.gmk Fri Sep 19 11:19:38 2014 -0700 @@ -25,8 +25,49 @@ include GensrcCommon.gmk -include GensrcJDWP.gmk -include GensrcProviders.gmk +################################################################################ +# Translate the Java debugger wire protocol (jdwp.spec) file into a JDWP.java file +# and a JDWPCommands.h C-header file. + +JDWP_SPEC_FILE := $(JDK_TOPDIR)/make/data/jdwp/jdwp.spec + +$(JDK_OUTPUTDIR)/gensrc_jdwp_headers/JDWPCommands.h: $(JDWP_SPEC_FILE) + +$(JDK_OUTPUTDIR)/gensrc/jdk.jdi/com/sun/tools/jdi/JDWP.java: \ + $(JDWP_SPEC_FILE) $(BUILD_TOOLS_JDK) + $(MKDIR) -p $(@D) + $(MKDIR) -p $(JDK_OUTPUTDIR)/gensrc_jdwp_headers + $(RM) $@ $(JDK_OUTPUTDIR)/gensrc_jdwp_headers/JDWPCommands.h + $(ECHO) $(LOG_INFO) Creating JDWP.java and JDWPCommands.h from jdwp.spec + $(TOOL_JDWPGEN) $< -jdi $@ -include $(JDK_OUTPUTDIR)/gensrc_jdwp_headers/JDWPCommands.h + +$(JDK_OUTPUTDIR)/gensrc_jdwp_doc/jdwp-protocol.html: $(JDWP_SPEC_FILE) \ + $(BUILD_TOOLS_JDK) + $(MKDIR) -p $(@D) + $(RM) $@ + $(ECHO) $(LOG_INFO) Creating $(@F) from jdwp.spec + $(TOOL_JDWPGEN) $< -doc $@ + +GENSRC_JDWP := $(JDK_OUTPUTDIR)/gensrc/jdk.jdi/com/sun/tools/jdi/JDWP.java \ + $(JDK_OUTPUTDIR)/gensrc_jdwp_headers/JDWPCommands.h \ + $(JDK_OUTPUTDIR)/gensrc_jdwp_doc/jdwp-protocol.html +GENSRC_JDK_JDI += $(GENSRC_JDWP) + +################################################################################ + +define process-provider + $(MKDIR) -p $(@D) + $(CAT) $^ | $(SED) -e "s/^#\[$(OPENJDK_TARGET_OS)\]//" > $@ +endef + +# Filter com.sun.jdi.connect.Connector +$(JDK_OUTPUTDIR)/gensrc/jdk.jdi/META-INF/services/com.sun.jdi.connect.Connector: \ + $(JDK_TOPDIR)/src/jdk.jdi/share/classes/META-INF/services/com.sun.jdi.connect.Connector + $(process-provider) + +GENSRC_JDK_JDI += $(JDK_OUTPUTDIR)/gensrc/jdk.jdi/META-INF/services/com.sun.jdi.connect.Connector + +################################################################################ jdk.jdi: $(GENSRC_JDK_JDI) diff -r 66228a695a62 -r 00b27213d86c jdk/make/gensrc/Gensrc-jdk.localedata.gmk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/gensrc/Gensrc-jdk.localedata.gmk Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,38 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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. +# + +include GensrcCommon.gmk + +# Hook to include the corresponding custom file, if present. +$(eval $(call IncludeCustomExtension, jdk, gensrc/Gensrc-jdk.localedata.gmk)) + +include GensrcLocaleData.gmk +include GensrcCLDR.gmk + +jdk.localedata: $(GENSRC_JDK_LOCALEDATA) + +all: jdk.localedata + +.PHONY: all jdk.localedata diff -r 66228a695a62 -r 00b27213d86c jdk/make/gensrc/GensrcCLDR.gmk --- a/jdk/make/gensrc/GensrcCLDR.gmk Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/make/gensrc/GensrcCLDR.gmk Fri Sep 19 11:19:38 2014 -0700 @@ -27,9 +27,8 @@ CLDRSRCDIR := $(JDK_TOPDIR)/src/jdk.localedata/share/classes/sun/util/cldr/resources/$(subst .,_,$(CLDRVERSION)) GENSRC_DIR := $(JDK_OUTPUTDIR)/gensrc/jdk.localedata -BASE_GENSRC_DIR := $(JDK_OUTPUTDIR)/gensrc/java.base -CLDR_METAINFO_FILE := $(BASE_GENSRC_DIR)/sun/util/cldr/CLDRLocaleDataMetaInfo.java +CLDR_METAINFO_FILE := $(GENSRC_DIR)/sun/util/resources/cldr/provider/CLDRLocaleDataMetaInfo.java $(CLDR_METAINFO_FILE): $(wildcard $(CLDRSRCDIR)/common/dtd/*.dtd) \ $(wildcard $(CLDRSRCDIR)/common/main/*.xml) \ @@ -37,16 +36,6 @@ $(BUILD_TOOLS_JDK) $(MKDIR) -p $(GENSRC_DIR) $(TOOL_CLDRCONVERTER) -base $(CLDRSRCDIR) -o $(GENSRC_DIR) - $(MKDIR) -p $(BASE_GENSRC_DIR)/sun/text/resources/cldr - $(MKDIR) -p $(BASE_GENSRC_DIR)/sun/util/resources/cldr - $(RM) -r $(BASE_GENSRC_DIR)/sun/text/resources/cldr/en \ - $(BASE_GENSRC_DIR)/sun/util/resources/cldr/en - $(MV) $(GENSRC_DIR)/sun/text/resources/cldr/en $(BASE_GENSRC_DIR)/sun/text/resources/cldr/en - $(MV) $(GENSRC_DIR)/sun/util/resources/cldr/en $(BASE_GENSRC_DIR)/sun/util/resources/cldr/en - $(MV) $(GENSRC_DIR)/sun/text/resources/cldr/*.java $(BASE_GENSRC_DIR)/sun/text/resources/cldr - $(MV) $(GENSRC_DIR)/sun/util/resources/cldr/*.java $(BASE_GENSRC_DIR)/sun/util/resources/cldr - $(MKDIR) -p $(@D) - $(MV) $(GENSRC_DIR)/sun/util/cldr/CLDRLocaleDataMetaInfo.java $@ GENSRC_CLDR := $(CLDR_METAINFO_FILE) -GENSRC_JAVA_BASE += $(GENSRC_CLDR) +GENSRC_JDK_LOCALEDATA += $(GENSRC_CLDR) diff -r 66228a695a62 -r 00b27213d86c jdk/make/gensrc/GensrcCharsetMapping.gmk --- a/jdk/make/gensrc/GensrcCharsetMapping.gmk Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/make/gensrc/GensrcCharsetMapping.gmk Fri Sep 19 11:19:38 2014 -0700 @@ -23,71 +23,29 @@ # questions. # -GENSRC_CHARSETMAPPING := - +################################################################################ +# +# Generate files using the charsetmapping tool +# CHARSET_DATA_DIR := $(JDK_TOPDIR)/make/data/charsetmapping - -### -### Generate files using the charsetmapping tool -### - -CHARSET_GENSRC_JAVA_DIR_CS := $(JDK_OUTPUTDIR)/gensrc/jdk.charsets/sun/nio/cs/ext CHARSET_GENSRC_JAVA_DIR_BASE := $(JDK_OUTPUTDIR)/gensrc/java.base/sun/nio/cs -CHARSET_DONE_CS := $(CHARSET_GENSRC_JAVA_DIR_CS)/_the.charsetmapping CHARSET_DONE_BASE := $(CHARSET_GENSRC_JAVA_DIR_BASE)/_the.charsetmapping -CHARSET_COPYRIGHT_HEADER_BASE := $(JDK_TOPDIR)/make/src/classes/build/tools/charsetmapping CHARSET_TEMPLATES := \ $(CHARSET_DATA_DIR)/SingleByte-X.java.template \ $(CHARSET_DATA_DIR)/DoubleByte-X.java.template -# This target should be referenced using the order-only operator (|) -$(CHARSET_GENSRC_JAVA_DIR_CS): - $(ECHO) "Generating charset mappings" - $(MKDIR) -p $(CHARSET_GENSRC_JAVA_DIR_CS) - $(MKDIR) -p $(CHARSET_GENSRC_JAVA_DIR_BASE) - $(CHARSET_DONE_BASE)-sbcs: $(CHARSET_DATA_DIR)/sbcs \ - $(CHARSET_TEMPLATES) $(BUILD_TOOLS_JDK) | $(CHARSET_GENSRC_JAVA_DIR_CS) + $(CHARSET_TEMPLATES) $(BUILD_TOOLS_JDK) + $(MKDIR) -p $(@D) $(TOOL_CHARSETMAPPING) $(CHARSET_DATA_DIR) $(CHARSET_GENSRC_JAVA_DIR_BASE) sbcs $(TOUCH) '$@' -$(CHARSET_DONE_CS)-extsbcs: $(CHARSET_DATA_DIR)/extsbcs \ - $(CHARSET_DONE_BASE)-sbcs $(CHARSET_TEMPLATES) $(BUILD_TOOLS_JDK) - $(TOOL_CHARSETMAPPING) $(CHARSET_DATA_DIR) $(CHARSET_GENSRC_JAVA_DIR_CS) extsbcs - $(TOUCH) '$@' - -$(CHARSET_DONE_CS)-dbcs: $(CHARSET_DATA_DIR)/dbcs \ - $(CHARSET_DONE_BASE)-sbcs $(CHARSET_TEMPLATES) $(BUILD_TOOLS_JDK) - $(TOOL_CHARSETMAPPING) $(CHARSET_DATA_DIR) $(CHARSET_GENSRC_JAVA_DIR_CS) dbcs - $(TOUCH) '$@' - -$(CHARSET_DONE_CS)-hkscs: $(CHARSET_COPYRIGHT_HEADER_BASE)/HKSCS.java \ - $(CHARSET_DONE_BASE)-sbcs $(BUILD_TOOLS_JDK) - $(TOOL_CHARSETMAPPING) $(CHARSET_DATA_DIR) $(CHARSET_GENSRC_JAVA_DIR_CS) hkscs '$<' - $(TOUCH) '$@' +GENSRC_JAVA_BASE += $(CHARSET_DONE_BASE)-sbcs -$(CHARSET_DONE_CS)-euctw: $(CHARSET_COPYRIGHT_HEADER_BASE)/EUC_TW.java \ - $(CHARSET_DONE_BASE)-sbcs $(BUILD_TOOLS_JDK) - $(TOOL_CHARSETMAPPING) $(CHARSET_DATA_DIR) $(CHARSET_GENSRC_JAVA_DIR_CS) euctw '$<' - $(TOUCH) '$@' - -$(CHARSET_GENSRC_JAVA_DIR_CS)/sjis0213.dat: $(CHARSET_DATA_DIR)/sjis0213.map \ - $(CHARSET_DONE_BASE)-sbcs $(BUILD_TOOLS_JDK) - $(TOOL_CHARSETMAPPING) '$<' '$@' sjis0213 - -GENSRC_JAVA_BASE += $(CHARSET_DONE_BASE)-sbcs -GENSRC_JDK_CHARSETS += \ - $(CHARSET_DONE_CS)-extsbcs \ - $(CHARSET_DONE_CS)-dbcs \ - $(CHARSET_DONE_CS)-hkscs \ - $(CHARSET_DONE_CS)-euctw \ - $(CHARSET_GENSRC_JAVA_DIR_CS)/sjis0213.dat \ - # - -### -### Generate the sun/nio/cs/StandardCharsets.java file -### - +################################################################################ +# +# Generate the sun/nio/cs/StandardCharsets.java file +# CHARSET_STANDARD_GENSRC_DIR := $(JDK_OUTPUTDIR)/gensrc/standardcharsets CHARSET_STANDARD_DATA := $(CHARSET_DATA_DIR)/standard-charsets CHARSET_STANDARD_JAVA := sun/nio/cs/StandardCharsets.java diff -r 66228a695a62 -r 00b27213d86c jdk/make/gensrc/GensrcJDWP.gmk --- a/jdk/make/gensrc/GensrcJDWP.gmk Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -# -# 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 -# 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. -# - -# Translate the Java debugger wire protocol (jdwp.spec) file into a JDWP.java file -# and a JDWPCommands.h C-header file. - -JDWP_SPEC_FILE := $(JDK_TOPDIR)/make/data/jdwp/jdwp.spec - -$(JDK_OUTPUTDIR)/gensrc_jdwp_headers/JDWPCommands.h: $(JDWP_SPEC_FILE) - -$(JDK_OUTPUTDIR)/gensrc/jdk.jdi/com/sun/tools/jdi/JDWP.java: \ - $(JDWP_SPEC_FILE) $(BUILD_TOOLS_JDK) - $(MKDIR) -p $(@D) - $(MKDIR) -p $(JDK_OUTPUTDIR)/gensrc_jdwp_headers - $(RM) $@ $(JDK_OUTPUTDIR)/gensrc_jdwp_headers/JDWPCommands.h - $(ECHO) $(LOG_INFO) Creating JDWP.java and JDWPCommands.h from jdwp.spec - $(TOOL_JDWPGEN) $< -jdi $@ -include $(JDK_OUTPUTDIR)/gensrc_jdwp_headers/JDWPCommands.h - -$(JDK_OUTPUTDIR)/gensrc_jdwp_doc/jdwp-protocol.html: $(JDWP_SPEC_FILE) \ - $(BUILD_TOOLS_JDK) - $(MKDIR) -p $(@D) - $(RM) $@ - $(ECHO) $(LOG_INFO) Creating $(@F) from jdwp.spec - $(TOOL_JDWPGEN) $< -doc $@ - -GENSRC_JDWP := $(JDK_OUTPUTDIR)/gensrc/jdk.jdi/com/sun/tools/jdi/JDWP.java \ - $(JDK_OUTPUTDIR)/gensrc_jdwp_headers/JDWPCommands.h \ - $(JDK_OUTPUTDIR)/gensrc_jdwp_doc/jdwp-protocol.html -GENSRC_JDK_JDI += $(GENSRC_JDWP) diff -r 66228a695a62 -r 00b27213d86c jdk/make/gensrc/GensrcLocaleData.gmk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/gensrc/GensrcLocaleData.gmk Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,152 @@ +# +# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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. +# + +# Scan for all locale resources and extract for which locales there exists +# resources. Then put this meta information about existing (supported?) locales +# into LocaleDataMetaInfo.java + +# First go look for all locale files +LOCALE_FILES := $(shell $(FIND) $(JDK_TOPDIR)/src/java.base/share/classes \ + $(JDK_TOPDIR)/src/jdk.localedata/share/classes \ + -name "FormatData_*.java" -o -name "FormatData_*.properties" -o \ + -name "CollationData_*.java" -o -name "CollationData_*.properties" -o \ + -name "TimeZoneNames_*.java" -o -name "TimeZoneNames_*.properties" -o \ + -name "LocaleNames_*.java" -o -name "LocaleNames_*.properties" -o \ + -name "CurrencyNames_*.java" -o -name "CurrencyNames_*.properties" -o \ + -name "CalendarData_*.java" -o -name "CalendarData_*.properties" -o \ + -name "BreakIteratorInfo_*.java" -o -name "BreakIteratorRules_*.java") + +# Then translate the locale files into for example: FormatData_sv +LOCALE_RESOURCES := $(sort $(subst .properties,,$(subst .java,,$(notdir $(LOCALE_FILES))))) + +# Include the list of resources found during the previous compile. +-include $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources + +MISSING_RESOURCES := $(filter-out $(LOCALE_RESOURCES), $(PREV_LOCALE_RESOURCES)) +NEW_RESOURCES := $(filter-out $(PREV_LOCALE_RESOURCES), $(LOCALE_RESOURCES)) + +ifneq (, $(MISSING_RESOURCES)$(NEW_RESOURCES)) + # There is a difference in the number of supported resources. Trigger a regeneration. + $(shell $(RM) $(JDK_OUTPUTDIR)/gensrc/sun/util/locale/provider/LocaleDataMetaInfo.java) +endif + +# The EN locales +EN_LOCALES := en% + +# Locales that don't have any resource files should be included here. +ALL_NON_EN_LOCALES := ja-JP-JP nb-NO nn-NO th-TH-TH + +SED_ENARGS := -e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g' +SED_NONENARGS := $(SED_ENARGS) + +# Fill in the languages and package names +SED_ENARGS += -e 's/$(HASH)Lang$(HASH)/En/' \ + -e 's/$(HASH)Package$(HASH)/sun.util.locale.provider/' +SED_NONENARGS += -e 's/$(HASH)Lang$(HASH)/NonEn/' \ + -e 's/$(HASH)Package$(HASH)/sun.util.resources.provider/' + +# This macro creates a sed expression that substitues for example: +# #FormatData_ENLocales# with: en% locales. +define CaptureLocale + $1_LOCALES := $$(subst _,-,$$(filter-out $1, $$(subst $1_,,$$(filter $1_%, $(LOCALE_RESOURCES))))) + $1_EN_LOCALES := $$(filter $(EN_LOCALES), $$($1_LOCALES)) + $1_NON_EN_LOCALES := $$(filter-out $(EN_LOCALES), $$($1_LOCALES)) + + # Special handling for Chinese locales to include implicit scripts + $1_NON_EN_LOCALES := $$(subst zh-CN,zh-CN$$(SPACE)zh-Hans-CN, $$($1_NON_EN_LOCALES)) + $1_NON_EN_LOCALES := $$(subst zh-SG,zh-SG$$(SPACE)zh-Hans-SG, $$($1_NON_EN_LOCALES)) + $1_NON_EN_LOCALES := $$(subst zh-HK,zh-HK$$(SPACE)zh-Hant-HK, $$($1_NON_EN_LOCALES)) + $1_NON_EN_LOCALES := $$(subst zh-MO,zh-MO$$(SPACE)zh-Hant-MO, $$($1_NON_EN_LOCALES)) + $1_NON_EN_LOCALES := $$(subst zh-TW,zh-TW$$(SPACE)zh-Hant-TW, $$($1_NON_EN_LOCALES)) + + ALL_EN_LOCALES += $$($1_EN_LOCALES) + ALL_NON_EN_LOCALES += $$($1_NON_EN_LOCALES) + + # Don't sed in a space if there are no locales. + SED_ENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_EN_LOCALES),$$(SPACE)$$($1_EN_LOCALES),)/g' + SED_NONENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_NON_EN_LOCALES),$$(SPACE)$$($1_NON_EN_LOCALES),)/g' +endef + +#sun.text.resources.FormatData +$(eval $(call CaptureLocale,FormatData)) + +#sun.text.resources.CollationData +$(eval $(call CaptureLocale,CollationData)) + +#sun.text.resources.BreakIteratorInfo +$(eval $(call CaptureLocale,BreakIteratorInfo)) + +#sun.text.resources.BreakIteratorRules +$(eval $(call CaptureLocale,BreakIteratorRules)) + +#sun.util.resources.TimeZoneNames +$(eval $(call CaptureLocale,TimeZoneNames)) + +#sun.util.resources.LocaleNames +$(eval $(call CaptureLocale,LocaleNames)) + +#sun.util.resources.CurrencyNames +$(eval $(call CaptureLocale,CurrencyNames)) + +#sun.util.resources.CalendarData +$(eval $(call CaptureLocale,CalendarData)) + +SED_ENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_EN_LOCALES))/g' +SED_NONENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_NON_EN_LOCALES))/g' + +$(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java: \ + $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template + $(MKDIR) -p $(@D) + $(ECHO) Creating sun/util/locale/provider/EnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources. + $(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" > $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources + $(SED) $(SED_ENARGS) $< > $@ + +$(JDK_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java: \ + $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template + $(MKDIR) -p $(@D) + $(ECHO) Creating sun/util/resources/provider/NonEnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources. + $(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" > $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources + $(SED) $(SED_NONENARGS) $< > $@ + +GENSRC_BASELOCALEDATA := $(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java +GENSRC_LOCALEDATA := $(JDK_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java + +################################################################################ + +GENSRC_CRBC_DST := $(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/CoreResourceBundleControl.java +GENSRC_CRBC_CMD := $(JDK_TOPDIR)/make/scripts/localelist.sh + +JRE_NONEXIST_LOCALES := en en_US de_DE es_ES fr_FR it_IT ja_JP ko_KR sv_SE zh + +$(GENSRC_CRBC_DST): $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/CoreResourceBundleControl-XLocales.java.template \ + $(GENSRC_CRBC_CMD) + $(MKDIR) -p $(@D) + NAWK="$(NAWK)" SED="$(SED)" $(SH) $(GENSRC_CRBC_CMD) "$(JRE_NONEXIST_LOCALES)" $< $@ + +GENSRC_BASELOCALEDATA += $(GENSRC_CRBC_DST) +GENSRC_JAVA_BASE += $(GENSRC_BASELOCALEDATA) +GENSRC_JDK_LOCALEDATA += $(GENSRC_LOCALEDATA) + +################################################################################ diff -r 66228a695a62 -r 00b27213d86c jdk/make/gensrc/GensrcLocaleDataMetaInfo.gmk --- a/jdk/make/gensrc/GensrcLocaleDataMetaInfo.gmk Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -# -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. 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. -# - -# Scan for all locale resources and extract for which locales there exists -# resources. Then put this meta information about existing (supported?) locales -# into LocaleDataMetaInfo.java - -# First go look for all locale files -LOCALE_FILES := $(shell $(FIND) $(JDK_TOPDIR)/src/java.base/share/classes \ - $(JDK_TOPDIR)/src/jdk.localedata/share/classes \ - -name "FormatData_*.java" -o -name "FormatData_*.properties" -o \ - -name "CollationData_*.java" -o -name "CollationData_*.properties" -o \ - -name "TimeZoneNames_*.java" -o -name "TimeZoneNames_*.properties" -o \ - -name "LocaleNames_*.java" -o -name "LocaleNames_*.properties" -o \ - -name "CurrencyNames_*.java" -o -name "CurrencyNames_*.properties" -o \ - -name "CalendarData_*.java" -o -name "CalendarData_*.properties" -o \ - -name "BreakIteratorInfo_*.java" -o -name "BreakIteratorRules_*.java") - -# Then translate the locale files into for example: FormatData_sv -LOCALE_RESOURCES := $(sort $(subst .properties,,$(subst .java,,$(notdir $(LOCALE_FILES))))) - -# Include the list of resources found during the previous compile. --include $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources - -MISSING_RESOURCES := $(filter-out $(LOCALE_RESOURCES), $(PREV_LOCALE_RESOURCES)) -NEW_RESOURCES := $(filter-out $(PREV_LOCALE_RESOURCES), $(LOCALE_RESOURCES)) - -ifneq (, $(MISSING_RESOURCES)$(NEW_RESOURCES)) - # There is a difference in the number of supported resources. Trigger a regeneration. - $(shell $(RM) $(JDK_OUTPUTDIR)/gensrc/sun/util/locale/provider/LocaleDataMetaInfo.java) -endif - -# The EN locales -EN_LOCALES := en% - -# Locales that don't have any resource files should be included here. -ALL_NON_EN_LOCALES := ja-JP-JP nb-NO nn-NO th-TH-TH - -SED_ENARGS := -e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g' -SED_NONENARGS := $(SED_ENARGS) - -# Fill in the languages and package names -SED_ENARGS += -e 's/$(HASH)Lang$(HASH)/En/' \ - -e 's/$(HASH)Package$(HASH)/sun.util.locale.provider/' -SED_NONENARGS += -e 's/$(HASH)Lang$(HASH)/NonEn/' \ - -e 's/$(HASH)Package$(HASH)/sun.util.resources.provider/' - -# This macro creates a sed expression that substitues for example: -# #FormatData_ENLocales# with: en% locales. -define CaptureLocale - $1_LOCALES := $$(subst _,-,$$(filter-out $1, $$(subst $1_,,$$(filter $1_%, $(LOCALE_RESOURCES))))) - $1_EN_LOCALES := $$(filter $(EN_LOCALES), $$($1_LOCALES)) - $1_NON_EN_LOCALES := $$(filter-out $(EN_LOCALES), $$($1_LOCALES)) - - # Special handling for Chinese locales to include implicit scripts - $1_NON_EN_LOCALES := $$(subst zh-CN,zh-CN$$(SPACE)zh-Hans-CN, $$($1_NON_EN_LOCALES)) - $1_NON_EN_LOCALES := $$(subst zh-SG,zh-SG$$(SPACE)zh-Hans-SG, $$($1_NON_EN_LOCALES)) - $1_NON_EN_LOCALES := $$(subst zh-HK,zh-HK$$(SPACE)zh-Hant-HK, $$($1_NON_EN_LOCALES)) - $1_NON_EN_LOCALES := $$(subst zh-MO,zh-MO$$(SPACE)zh-Hant-MO, $$($1_NON_EN_LOCALES)) - $1_NON_EN_LOCALES := $$(subst zh-TW,zh-TW$$(SPACE)zh-Hant-TW, $$($1_NON_EN_LOCALES)) - - ALL_EN_LOCALES += $$($1_EN_LOCALES) - ALL_NON_EN_LOCALES += $$($1_NON_EN_LOCALES) - - # Don't sed in a space if there are no locales. - SED_ENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_EN_LOCALES),$$(SPACE)$$($1_EN_LOCALES),)/g' - SED_NONENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_NON_EN_LOCALES),$$(SPACE)$$($1_NON_EN_LOCALES),)/g' -endef - -#sun.text.resources.FormatData -$(eval $(call CaptureLocale,FormatData)) - -#sun.text.resources.CollationData -$(eval $(call CaptureLocale,CollationData)) - -#sun.text.resources.BreakIteratorInfo -$(eval $(call CaptureLocale,BreakIteratorInfo)) - -#sun.text.resources.BreakIteratorRules -$(eval $(call CaptureLocale,BreakIteratorRules)) - -#sun.util.resources.TimeZoneNames -$(eval $(call CaptureLocale,TimeZoneNames)) - -#sun.util.resources.LocaleNames -$(eval $(call CaptureLocale,LocaleNames)) - -#sun.util.resources.CurrencyNames -$(eval $(call CaptureLocale,CurrencyNames)) - -#sun.util.resources.CalendarData -$(eval $(call CaptureLocale,CalendarData)) - -SED_ENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_EN_LOCALES))/g' -SED_NONENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_NON_EN_LOCALES))/g' - -$(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java: \ - $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template - $(MKDIR) -p $(@D) - $(ECHO) Creating sun/util/locale/provider/EnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources. - $(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" > $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources - $(SED) $(SED_ENARGS) $< > $@ - -$(JDK_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java: \ - $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template - $(MKDIR) -p $(@D) - $(ECHO) Creating sun/util/resources/provider/NonEnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources. - $(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" > $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources - $(SED) $(SED_NONENARGS) $< > $@ - -GENSRC_LOCALEDATAMETAINFO := $(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java \ - $(JDK_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java - -################################################################################ - -GENSRC_CRBC_DST := $(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/CoreResourceBundleControl.java -GENSRC_CRBC_CMD := $(JDK_TOPDIR)/make/scripts/localelist.sh - -JRE_NONEXIST_LOCALES := en en_US de_DE es_ES fr_FR it_IT ja_JP ko_KR sv_SE zh - -$(GENSRC_CRBC_DST): $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/CoreResourceBundleControl-XLocales.java.template \ - $(GENSRC_CRBC_CMD) - $(MKDIR) -p $(@D) - NAWK="$(NAWK)" SED="$(SED)" $(SH) $(GENSRC_CRBC_CMD) "$(JRE_NONEXIST_LOCALES)" $< $@ - -GENSRC_LOCALEDATAMETAINFO += $(GENSRC_CRBC_DST) -GENSRC_JAVA_BASE += $(GENSRC_LOCALEDATAMETAINFO) - -################################################################################ diff -r 66228a695a62 -r 00b27213d86c jdk/make/gensrc/GensrcProviders.gmk --- a/jdk/make/gensrc/GensrcProviders.gmk Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -# -# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. 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. -# - -################################################################################ - -define process-provider - $(MKDIR) -p $(@D) - $(CAT) $^ | $(SED) -e "s/^#\[$(OPENJDK_TARGET_OS)\]//" > $@ -endef - -################################################################################ - -# Filter com.sun.jdi.connect.Connector -$(JDK_OUTPUTDIR)/gensrc/jdk.jdi/META-INF/services/com.sun.jdi.connect.Connector: \ - $(JDK_TOPDIR)/src/jdk.jdi/share/classes/META-INF/services/com.sun.jdi.connect.Connector - $(process-provider) - -GENSRC_JDK_JDI += $(JDK_OUTPUTDIR)/gensrc/jdk.jdi/META-INF/services/com.sun.jdi.connect.Connector - -################################################################################ diff -r 66228a695a62 -r 00b27213d86c jdk/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java --- a/jdk/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java Fri Sep 19 11:19:38 2014 -0700 @@ -143,8 +143,9 @@ @Override public void generateMetaInfo(Map> metaInfo) throws IOException { - String dirName = CLDRConverter.DESTINATION_DIR + File.separator + "sun" + File.separator + "util" + File.separator - + "cldr" + File.separator; + String dirName = CLDRConverter.DESTINATION_DIR + File.separator + "sun" + File.separator + "util" + + File.separator + "resources" + File.separator + "cldr" + File.separator + + "provider" + File.separator ; File dir = new File(dirName); if (!dir.exists()) { dir.mkdirs(); @@ -158,7 +159,7 @@ try (PrintWriter out = new PrintWriter(file, "us-ascii")) { out.println(CopyrightHeaders.getOpenJDKCopyright()); - out.println("package sun.util.cldr;\n\n" + out.println("package sun.util.resources.cldr.provider;\n\n" + "import java.util.ListResourceBundle;\n" + "import sun.util.locale.provider.LocaleProviderAdapter;\n" + "import sun.util.locale.provider.LocaleDataMetaInfo;\n"); diff -r 66228a695a62 -r 00b27213d86c jdk/make/src/classes/build/tools/module/GenJdepsModulesXml.java --- a/jdk/make/src/classes/build/tools/module/GenJdepsModulesXml.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/make/src/classes/build/tools/module/GenJdepsModulesXml.java Fri Sep 19 11:19:38 2014 -0700 @@ -25,29 +25,17 @@ package build.tools.module; -import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.BasicFileAttributes; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; import java.util.HashSet; -import java.util.Map; -import java.util.Objects; import java.util.Set; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import javax.xml.namespace.QName; -import javax.xml.stream.*; -import javax.xml.stream.events.Attribute; -import javax.xml.stream.events.XMLEvent; +import java.util.stream.Collectors; /** * GenJdepsModulesXml augments the input modules.xml file(s) @@ -97,14 +85,14 @@ Set modules = new HashSet<>(); for (; i < args.length; i++) { Path p = Paths.get(args[i]); - try (InputStream in = new BufferedInputStream(Files.newInputStream(p))) { - Set mods = gentool.load(in); - modules.addAll(mods); - } + modules.addAll(ModulesXmlReader.readModules(p) + .stream() + .map(gentool::buildIncludes) + .collect(Collectors.toSet())); } Files.createDirectories(outfile.getParent()); - gentool.writeXML(modules, outfile); + ModulesXmlWriter.writeModules(modules, outfile); } final Path modulepath; @@ -112,228 +100,21 @@ this.modulepath = modulepath; } - private static final String MODULES = "modules"; - private static final String MODULE = "module"; - private static final String NAME = "name"; - private static final String DEPEND = "depend"; - private static final String EXPORT = "export"; - private static final String TO = "to"; - private static final String INCLUDE = "include"; - private static final QName REEXPORTS = new QName("re-exports"); - private Set load(InputStream in) throws XMLStreamException, IOException { - Set modules = new HashSet<>(); - XMLInputFactory factory = XMLInputFactory.newInstance(); - XMLEventReader stream = factory.createXMLEventReader(in); - Module.Builder mb = null; - String modulename = null; - String pkg = null; - Set permits = new HashSet<>(); - while (stream.hasNext()) { - XMLEvent event = stream.nextEvent(); - if (event.isStartElement()) { - String startTag = event.asStartElement().getName().getLocalPart(); - switch (startTag) { - case MODULES: - break; - case MODULE: - if (mb != null) { - throw new RuntimeException("end tag for module is missing"); - } - modulename = getNextTag(stream, NAME); - mb = new Module.Builder(); - mb.name(modulename); - break; - case NAME: - throw new RuntimeException(event.toString()); - case DEPEND: - boolean reexports = false; - Attribute attr = event.asStartElement().getAttributeByName(REEXPORTS); - if (attr != null) { - String value = attr.getValue(); - if (value.equals("true") || value.equals("false")) { - reexports = Boolean.parseBoolean(value); - } else { - throw new RuntimeException("unexpected attribute " + attr.toString()); - } - } - mb.require(getData(stream), reexports); - break; - case INCLUDE: - throw new RuntimeException("unexpected " + event); - case EXPORT: - pkg = getNextTag(stream, NAME); - break; - case TO: - permits.add(getData(stream)); - break; - default: - } - } else if (event.isEndElement()) { - String endTag = event.asEndElement().getName().getLocalPart(); - switch (endTag) { - case MODULE: - buildIncludes(mb, modulename); - modules.add(mb.build()); - mb = null; - break; - case EXPORT: - if (pkg == null) { - throw new RuntimeException("export-to is malformed"); - } - mb.exportTo(pkg, permits); - pkg = null; - permits.clear(); - break; - default: - } - } else if (event.isCharacters()) { - String s = event.asCharacters().getData(); - if (!s.trim().isEmpty()) { - throw new RuntimeException("export-to is malformed"); - } - } - } - return modules; - } - - private String getData(XMLEventReader reader) throws XMLStreamException { - XMLEvent e = reader.nextEvent(); - if (e.isCharacters()) { - return e.asCharacters().getData(); - } - throw new RuntimeException(e.toString()); - } - - private String getNextTag(XMLEventReader reader, String tag) throws XMLStreamException { - XMLEvent e = reader.nextTag(); - if (e.isStartElement()) { - String t = e.asStartElement().getName().getLocalPart(); - if (!tag.equals(t)) { - throw new RuntimeException(e + " expected: " + tag); - } - return getData(reader); - } - throw new RuntimeException("export-to name is missing:" + e); - } - private void writeXML(Set modules, Path path) - throws IOException, XMLStreamException - { - XMLOutputFactory xof = XMLOutputFactory.newInstance(); - try (OutputStream out = Files.newOutputStream(path)) { - int depth = 0; - XMLStreamWriter xtw = xof.createXMLStreamWriter(out, "UTF-8"); - xtw.writeStartDocument("utf-8","1.0"); - writeStartElement(xtw, MODULES, depth); - modules.stream() - .sorted(Comparator.comparing(Module::name)) - .forEach(m -> writeModuleElement(xtw, m, depth+1)); - writeEndElement(xtw, depth); - xtw.writeCharacters("\n"); - xtw.writeEndDocument(); - xtw.flush(); - xtw.close(); - } - } - - private void writeElement(XMLStreamWriter xtw, String element, String value, int depth) { - try { - writeStartElement(xtw, element, depth); - xtw.writeCharacters(value); - xtw.writeEndElement(); - } catch (XMLStreamException e) { - throw new RuntimeException(e); - } - } - - private void writeDependElement(XMLStreamWriter xtw, Module.Dependence d, int depth) { - try { - writeStartElement(xtw, DEPEND, depth); - if (d.reexport) { - xtw.writeAttribute("re-exports", "true"); - } - xtw.writeCharacters(d.name); - xtw.writeEndElement(); - } catch (XMLStreamException e) { - throw new RuntimeException(e); - } - } - - private void writeExportElement(XMLStreamWriter xtw, String pkg, int depth) { - writeExportElement(xtw, pkg, Collections.emptySet(), depth); - } - - private void writeExportElement(XMLStreamWriter xtw, String pkg, - Set permits, int depth) { - try { - writeStartElement(xtw, EXPORT, depth); - writeElement(xtw, NAME, pkg, depth+1); - if (!permits.isEmpty()) { - permits.stream().sorted() - .forEach(m -> writeElement(xtw, TO, m, depth + 1)); - } - writeEndElement(xtw, depth); - } catch (XMLStreamException e) { - throw new RuntimeException(e); - } - } - private void writeModuleElement(XMLStreamWriter xtw, Module m, int depth) { - try { - writeStartElement(xtw, MODULE, depth); - writeElement(xtw, NAME, m.name(), depth+1); - m.requires().stream().sorted(Comparator.comparing(d -> d.name)) - .forEach(d -> writeDependElement(xtw, d, depth+1)); - m.exports().keySet().stream() - .filter(pn -> m.exports().get(pn).isEmpty()) - .sorted() - .forEach(pn -> writeExportElement(xtw, pn, depth+1)); - m.exports().entrySet().stream() - .filter(e -> !e.getValue().isEmpty()) - .sorted(Map.Entry.comparingByKey()) - .forEach(e -> writeExportElement(xtw, e.getKey(), e.getValue(), depth+1)); - m.packages().stream().sorted() - .forEach(p -> writeElement(xtw, INCLUDE, p, depth+1)); - writeEndElement(xtw, depth); - } catch (XMLStreamException e) { - throw new RuntimeException(e); - - } - } - - /** Two spaces; the default indentation. */ - public static final String DEFAULT_INDENT = " "; - - /** stack[depth] indicates what's been written into the current scope. */ - private static String[] stack = new String[] { "\n", - "\n" + DEFAULT_INDENT, - "\n" + DEFAULT_INDENT + DEFAULT_INDENT, - "\n" + DEFAULT_INDENT + DEFAULT_INDENT + DEFAULT_INDENT}; - - private void writeStartElement(XMLStreamWriter xtw, String name, int depth) - throws XMLStreamException - { - xtw.writeCharacters(stack[depth]); - xtw.writeStartElement(name); - } - - private void writeEndElement(XMLStreamWriter xtw, int depth) throws XMLStreamException { - xtw.writeCharacters(stack[depth]); - xtw.writeEndElement(); - } - - private String packageName(Path p) { + private static String packageName(Path p) { return packageName(p.toString().replace(File.separatorChar, '/')); } - private String packageName(String name) { + private static String packageName(String name) { int i = name.lastIndexOf('/'); return (i > 0) ? name.substring(0, i).replace('/', '.') : ""; } - private boolean includes(String name) { - return name.endsWith(".class") && !name.equals("module-info.class"); + private static boolean includes(String name) { + return name.endsWith(".class"); } - public void buildIncludes(Module.Builder mb, String modulename) throws IOException { - Path mclasses = modulepath.resolve(modulename); + public Module buildIncludes(Module module) { + Module.Builder mb = new Module.Builder(module); + Path mclasses = modulepath.resolve(module.name()); try { Files.find(mclasses, Integer.MAX_VALUE, (Path p, BasicFileAttributes attr) -> includes(p.getFileName().toString())) @@ -341,145 +122,9 @@ .forEach(mb::include); } catch (NoSuchFileException e) { // aggregate module may not have class - } - } - - static class Module { - static class Dependence { - final String name; - final boolean reexport; - Dependence(String name) { - this(name, false); - } - Dependence(String name, boolean reexport) { - this.name = name; - this.reexport = reexport; - } - - @Override - public int hashCode() { - int hash = 5; - hash = 11 * hash + Objects.hashCode(this.name); - hash = 11 * hash + (this.reexport ? 1 : 0); - return hash; - } - - public boolean equals(Object o) { - Dependence d = (Dependence)o; - return this.name.equals(d.name) && this.reexport == d.reexport; - } - } - private final String moduleName; - private final Set requires; - private final Map> exports; - private final Set packages; - - private Module(String name, - Set requires, - Map> exports, - Set packages) { - this.moduleName = name; - this.requires = Collections.unmodifiableSet(requires); - this.exports = Collections.unmodifiableMap(exports); - this.packages = Collections.unmodifiableSet(packages); - } - - public String name() { - return moduleName; - } - - public Set requires() { - return requires; - } - - public Map> exports() { - return exports; - } - - public Set packages() { - return packages; - } - - @Override - public boolean equals(Object ob) { - if (!(ob instanceof Module)) { - return false; - } - Module that = (Module) ob; - return (moduleName.equals(that.moduleName) - && requires.equals(that.requires) - && exports.equals(that.exports) - && packages.equals(that.packages)); + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); } - - @Override - public int hashCode() { - int hc = moduleName.hashCode(); - hc = hc * 43 + requires.hashCode(); - hc = hc * 43 + exports.hashCode(); - hc = hc * 43 + packages.hashCode(); - return hc; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("module ").append(moduleName).append(" {").append("\n"); - requires.stream().sorted().forEach(d -> - sb.append(String.format(" requires %s%s%n", d.reexport ? "public " : "", d.name))); - exports.entrySet().stream().filter(e -> e.getValue().isEmpty()) - .sorted(Map.Entry.comparingByKey()) - .forEach(e -> sb.append(String.format(" exports %s%n", e.getKey()))); - exports.entrySet().stream().filter(e -> !e.getValue().isEmpty()) - .sorted(Map.Entry.comparingByKey()) - .forEach(e -> sb.append(String.format(" exports %s to %s%n", e.getKey(), e.getValue()))); - packages.stream().sorted().forEach(pn -> sb.append(String.format(" includes %s%n", pn))); - sb.append("}"); - return sb.toString(); - } - - static class Builder { - private String name; - private final Set requires = new HashSet<>(); - private final Map> exports = new HashMap<>(); - private final Set packages = new HashSet<>(); - - public Builder() { - } - - public Builder name(String n) { - name = n; - return this; - } - - public Builder require(String d, boolean reexport) { - requires.add(new Dependence(d, reexport)); - return this; - } - - public Builder include(String p) { - packages.add(p); - return this; - } - - public Builder export(String p) { - return exportTo(p, Collections.emptySet()); - } - - public Builder exportTo(String p, Set ms) { - Objects.requireNonNull(p); - Objects.requireNonNull(ms); - if (exports.containsKey(p)) { - throw new RuntimeException(name + " already exports " + p); - } - exports.put(p, new HashSet<>(ms)); - return this; - } - - public Module build() { - Module m = new Module(name, requires, exports, packages); - return m; - } - } + return mb.build(); } } diff -r 66228a695a62 -r 00b27213d86c jdk/make/src/classes/build/tools/module/GenModulesList.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/src/classes/build/tools/module/GenModulesList.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package build.tools.module; + +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Collectors; + +/** + * $ java build.tools.module.GenModulesList \ + * -o modules.list \ + * top/modules.xml ... + */ +public final class GenModulesList { + private final static String USAGE = + "Usage: GenModulesList -o path-to-modules-xml"; + + private Set modules = new HashSet<>(); + private HashMap nameToModule = new HashMap<>(); + + public static void main(String[] args) throws Exception { + GenModulesList gen = new GenModulesList(); + gen.run(args); + } + + void run(String[] args) throws Exception { + Path outfile = null; + int i = 0; + while (i < args.length) { + String arg = args[i]; + if (arg.equals("-o")) { + outfile = Paths.get(args[i+1]); + i = i+2; + } else { + break; + } + } + if (outfile == null || i >= args.length) { + System.err.println(USAGE); + System.exit(-1); + } + + for (; i < args.length; i++) { + Path p = Paths.get(args[i]); + modules.addAll(ModulesXmlReader.readModules(p)); + } + + modules.stream() + .forEach(m -> nameToModule.put(m.name(), m)); + + Path parent = outfile.getParent(); + if (parent != null) + Files.createDirectories(parent); + + Iterable sortedModules = (new TopoSorter(modules)).result(); + try (PrintWriter writer = new PrintWriter(outfile.toFile())) { + for (Module m : sortedModules) { + if (isNotAggregator(m)) { + String deps = getModuleDependences(m).stream() + .filter(GenModulesList::isNotAggregator) + .map(Module::name) + .collect(Collectors.joining(" ")); + writer.format("%s: %s%n", m.name(), deps); + } + } + } + } + + private Module nameToModule(String name) { + return nameToModule.get(name); + } + + private Set getModuleDependences(Module m) { + return m.requires().stream() + .map(d -> d.name()) + .map(this::nameToModule) + .collect(Collectors.toSet()); + } + + static boolean isNotAggregator(Module m) { + return isNotAggregator(m.name()); + } + + static boolean isNotAggregator(String name) { + return AGGREGATORS.contains(name) ? false : true; + } + + static final List AGGREGATORS = Arrays.asList(new String[] { + "java.se", "java.compact1", "java.compact2", + "java.compact3", "jdk.compact3"}); + + class TopoSorter { + final Deque result = new LinkedList<>(); + final Deque nodes = new LinkedList<>(); + + TopoSorter(Collection nodes) { + nodes.stream() + .forEach(m -> this.nodes.add(m)); + + sort(); + } + + public Iterable result() { + return result; + } + + private void sort() { + Deque visited = new LinkedList<>(); + Deque done = new LinkedList<>(); + Module node; + while ((node = nodes.poll()) != null) { + if (!visited.contains(node)) { + visit(node, visited, done); + } + } + } + + private void visit(Module m, Deque visited, Deque done) { + if (visited.contains(m)) { + if (!done.contains(m)) { + throw new IllegalArgumentException("Cyclic detected: " + + m + " " + getModuleDependences(m)); + } + return; + } + visited.add(m); + getModuleDependences(m).stream() + .forEach(x -> visit(x, visited, done)); + done.add(m); + result.addLast(m); + } + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/make/src/classes/build/tools/module/Module.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/src/classes/build/tools/module/Module.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package build.tools.module; + +import java.util.*; + +public class Module { + static class Dependence { + final String name; + final boolean reexport; + Dependence(String name) { + this(name, false); + } + Dependence(String name, boolean reexport) { + this.name = name; + this.reexport = reexport; + } + + public String name() { + return name; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 11 * hash + Objects.hashCode(this.name); + hash = 11 * hash + (this.reexport ? 1 : 0); + return hash; + } + + public boolean equals(Object o) { + Dependence d = (Dependence)o; + return this.name.equals(d.name) && this.reexport == d.reexport; + } + } + private final String moduleName; + private final Set requires; + private final Map> exports; + private final Set packages; + + private Module(String name, + Set requires, + Map> exports, + Set packages) { + this.moduleName = name; + this.requires = Collections.unmodifiableSet(requires); + this.exports = Collections.unmodifiableMap(exports); + this.packages = Collections.unmodifiableSet(packages); + } + + public String name() { + return moduleName; + } + + public Set requires() { + return requires; + } + + public Map> exports() { + return exports; + } + + public Set packages() { + return packages; + } + + @Override + public boolean equals(Object ob) { + if (!(ob instanceof Module)) { + return false; + } + Module that = (Module) ob; + return (moduleName.equals(that.moduleName) + && requires.equals(that.requires) + && exports.equals(that.exports) + && packages.equals(that.packages)); + } + + @Override + public int hashCode() { + int hc = moduleName.hashCode(); + hc = hc * 43 + requires.hashCode(); + hc = hc * 43 + exports.hashCode(); + hc = hc * 43 + packages.hashCode(); + return hc; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("module ").append(moduleName).append(" {").append("\n"); + requires.stream().sorted().forEach(d -> + sb.append(String.format(" requires %s%s%n", d.reexport ? "public " : "", d.name))); + exports.entrySet().stream().filter(e -> e.getValue().isEmpty()) + .sorted(Map.Entry.comparingByKey()) + .forEach(e -> sb.append(String.format(" exports %s%n", e.getKey()))); + exports.entrySet().stream().filter(e -> !e.getValue().isEmpty()) + .sorted(Map.Entry.comparingByKey()) + .forEach(e -> sb.append(String.format(" exports %s to %s%n", e.getKey(), e.getValue()))); + packages.stream().sorted().forEach(pn -> sb.append(String.format(" includes %s%n", pn))); + sb.append("}"); + return sb.toString(); + } + + static class Builder { + private String name; + private final Set requires = new HashSet<>(); + private final Map> exports = new HashMap<>(); + private final Set packages = new HashSet<>(); + + public Builder() { + } + + public Builder(Module module) { + name = module.name(); + requires.addAll(module.requires()); + exports.putAll(module.exports()); + packages.addAll(module.packages()); + } + + public Builder name(String n) { + name = n; + return this; + } + + public Builder require(String d, boolean reexport) { + requires.add(new Dependence(d, reexport)); + return this; + } + + public Builder include(String p) { + packages.add(p); + return this; + } + + public Builder export(String p) { + return exportTo(p, Collections.emptySet()); + } + + public Builder exportTo(String p, Set ms) { + Objects.requireNonNull(p); + Objects.requireNonNull(ms); + if (exports.containsKey(p)) { + throw new RuntimeException(name + " already exports " + p); + } + exports.put(p, new HashSet<>(ms)); + return this; + } + + public Module build() { + Module m = new Module(name, requires, exports, packages); + return m; + } + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/make/src/classes/build/tools/module/ModulesXmlReader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/src/classes/build/tools/module/ModulesXmlReader.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package build.tools.module; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.Attribute; +import javax.xml.stream.events.XMLEvent; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashSet; +import java.util.Set; + +public class ModulesXmlReader { + + private ModulesXmlReader() {} + + public static Set readModules(Path modulesXml) + throws XMLStreamException, IOException + { + Set modules = new HashSet<>(); + try (InputStream in = new BufferedInputStream(Files.newInputStream(modulesXml))) { + Set mods = ModulesXmlReader.load(in); + modules.addAll(mods); + } + return modules; + } + + private static final String MODULES = "modules"; + private static final String MODULE = "module"; + private static final String NAME = "name"; + private static final String DEPEND = "depend"; + private static final String EXPORT = "export"; + private static final String TO = "to"; + private static final String INCLUDE = "include"; + private static final QName REEXPORTS = new QName("re-exports"); + private static Set load(InputStream in) + throws XMLStreamException, IOException + { + Set modules = new HashSet<>(); + XMLInputFactory factory = XMLInputFactory.newInstance(); + XMLEventReader stream = factory.createXMLEventReader(in); + Module.Builder mb = null; + String modulename = null; + String pkg = null; + Set permits = new HashSet<>(); + while (stream.hasNext()) { + XMLEvent event = stream.nextEvent(); + if (event.isStartElement()) { + String startTag = event.asStartElement().getName().getLocalPart(); + switch (startTag) { + case MODULES: + break; + case MODULE: + if (mb != null) { + throw new RuntimeException("end tag for module is missing"); + } + modulename = getNextTag(stream, NAME); + mb = new Module.Builder(); + mb.name(modulename); + break; + case NAME: + throw new RuntimeException(event.toString()); + case DEPEND: + boolean reexports = false; + Attribute attr = event.asStartElement().getAttributeByName(REEXPORTS); + if (attr != null) { + String value = attr.getValue(); + if (value.equals("true") || value.equals("false")) { + reexports = Boolean.parseBoolean(value); + } else { + throw new RuntimeException("unexpected attribute " + attr.toString()); + } + } + mb.require(getData(stream), reexports); + break; + case INCLUDE: + throw new RuntimeException("unexpected " + event); + case EXPORT: + pkg = getNextTag(stream, NAME); + break; + case TO: + permits.add(getData(stream)); + break; + default: + } + } else if (event.isEndElement()) { + String endTag = event.asEndElement().getName().getLocalPart(); + switch (endTag) { + case MODULE: + modules.add(mb.build()); + mb = null; + break; + case EXPORT: + if (pkg == null) { + throw new RuntimeException("export-to is malformed"); + } + mb.exportTo(pkg, permits); + pkg = null; + permits.clear(); + break; + default: + } + } else if (event.isCharacters()) { + String s = event.asCharacters().getData(); + if (!s.trim().isEmpty()) { + throw new RuntimeException("export-to is malformed"); + } + } + } + return modules; + } + + private static String getData(XMLEventReader reader) + throws XMLStreamException + { + XMLEvent e = reader.nextEvent(); + if (e.isCharacters()) + return e.asCharacters().getData(); + + throw new RuntimeException(e.toString()); + } + + private static String getNextTag(XMLEventReader reader, String tag) + throws XMLStreamException + { + XMLEvent e = reader.nextTag(); + if (e.isStartElement()) { + String t = e.asStartElement().getName().getLocalPart(); + if (!tag.equals(t)) { + throw new RuntimeException(e + " expected: " + tag); + } + return getData(reader); + } + throw new RuntimeException("export-to name is missing:" + e); + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/make/src/classes/build/tools/module/ModulesXmlWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/src/classes/build/tools/module/ModulesXmlWriter.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package build.tools.module; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; +import java.util.Comparator; +import java.util.Map; +import java.util.Set; + +public final class ModulesXmlWriter { + + private ModulesXmlWriter() {} + + public static void writeModules(Set modules, Path path) + throws IOException, XMLStreamException + { + writeXML(modules, path); + } + + private static final String MODULES = "modules"; + private static final String MODULE = "module"; + private static final String NAME = "name"; + private static final String DEPEND = "depend"; + private static final String EXPORT = "export"; + private static final String TO = "to"; + private static final String INCLUDE = "include"; + private static final QName REEXPORTS = new QName("re-exports"); + + private static void writeXML(Set modules, Path path) + throws IOException, XMLStreamException + { + XMLOutputFactory xof = XMLOutputFactory.newInstance(); + try (OutputStream out = Files.newOutputStream(path)) { + int depth = 0; + XMLStreamWriter xtw = xof.createXMLStreamWriter(out, "UTF-8"); + xtw.writeStartDocument("utf-8","1.0"); + writeStartElement(xtw, MODULES, depth); + modules.stream() + .sorted(Comparator.comparing(Module::name)) + .forEach(m -> writeModuleElement(xtw, m, depth+1)); + writeEndElement(xtw, depth); + xtw.writeCharacters("\n"); + xtw.writeEndDocument(); + xtw.flush(); + xtw.close(); + } + } + + private static void writeElement(XMLStreamWriter xtw, + String element, + String value, + int depth) { + try { + writeStartElement(xtw, element, depth); + xtw.writeCharacters(value); + xtw.writeEndElement(); + } catch (XMLStreamException e) { + throw new RuntimeException(e); + } + } + + private static void writeDependElement(XMLStreamWriter xtw, + Module.Dependence d, + int depth) { + try { + writeStartElement(xtw, DEPEND, depth); + if (d.reexport) { + xtw.writeAttribute("re-exports", "true"); + } + xtw.writeCharacters(d.name); + xtw.writeEndElement(); + } catch (XMLStreamException e) { + throw new RuntimeException(e); + } + } + + private static void writeExportElement(XMLStreamWriter xtw, + String pkg, + int depth) { + writeExportElement(xtw, pkg, Collections.emptySet(), depth); + } + + private static void writeExportElement(XMLStreamWriter xtw, + String pkg, + Set permits, + int depth) { + try { + writeStartElement(xtw, EXPORT, depth); + writeElement(xtw, NAME, pkg, depth+1); + if (!permits.isEmpty()) { + permits.stream().sorted() + .forEach(m -> writeElement(xtw, TO, m, depth + 1)); + } + writeEndElement(xtw, depth); + } catch (XMLStreamException e) { + throw new RuntimeException(e); + } + } + private static void writeModuleElement(XMLStreamWriter xtw, + Module m, + int depth) { + try { + writeStartElement(xtw, MODULE, depth); + writeElement(xtw, NAME, m.name(), depth+1); + m.requires().stream().sorted(Comparator.comparing(d -> d.name)) + .forEach(d -> writeDependElement(xtw, d, depth+1)); + m.exports().keySet().stream() + .filter(pn -> m.exports().get(pn).isEmpty()) + .sorted() + .forEach(pn -> writeExportElement(xtw, pn, depth+1)); + m.exports().entrySet().stream() + .filter(e -> !e.getValue().isEmpty()) + .sorted(Map.Entry.comparingByKey()) + .forEach(e -> writeExportElement(xtw, e.getKey(), e.getValue(), depth+1)); + m.packages().stream().sorted() + .forEach(p -> writeElement(xtw, INCLUDE, p, depth+1)); + writeEndElement(xtw, depth); + } catch (XMLStreamException e) { + throw new RuntimeException(e); + + } + } + + /** Two spaces; the default indentation. */ + public static final String DEFAULT_INDENT = " "; + + /** stack[depth] indicates what's been written into the current scope. */ + private static String[] stack = new String[] { "\n", + "\n" + DEFAULT_INDENT, + "\n" + DEFAULT_INDENT + DEFAULT_INDENT, + "\n" + DEFAULT_INDENT + DEFAULT_INDENT + DEFAULT_INDENT}; + + private static void writeStartElement(XMLStreamWriter xtw, + String name, + int depth) + throws XMLStreamException + { + xtw.writeCharacters(stack[depth]); + xtw.writeStartElement(name); + } + + private static void writeEndElement(XMLStreamWriter xtw, int depth) + throws XMLStreamException + { + xtw.writeCharacters(stack[depth]); + xtw.writeEndElement(); + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Fri Sep 19 11:19:38 2014 -0700 @@ -62,7 +62,7 @@ private static final String CLL_SIG = "(L" + CLS + ";L" + OBJ + ";)L" + OBJ + ";"; /** Name of its super class*/ - private static final String superName = LF; + private static final String superName = OBJ; /** Name of new class */ private final String className; @@ -97,7 +97,7 @@ if (DUMP_CLASS_FILES) { className = makeDumpableClassName(className); } - this.className = superName + "$" + className; + this.className = LF + "$" + className; this.sourceFile = "LambdaForm$" + className; this.lambdaForm = lambdaForm; this.invokerName = invokerName; diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Sep 19 11:19:38 2014 -0700 @@ -188,7 +188,6 @@ static MethodHandle makePairwiseConvert(MethodHandle target, MethodType srcType, boolean strict, boolean monobox) { MethodType dstType = target.type(); - assert(dstType.parameterCount() == target.type().parameterCount()); if (srcType == dstType) return target; if (USE_LAMBDA_FORM_EDITOR) { @@ -265,6 +264,7 @@ static MethodHandle makePairwiseConvertIndirect(MethodHandle target, MethodType srcType, boolean strict, boolean monobox) { + assert(target.type().parameterCount() == srcType.parameterCount()); // Calculate extra arguments (temporaries) required in the names array. Object[] convSpecs = computeValueConversions(srcType, target.type(), strict, monobox); final int INARG_COUNT = srcType.parameterCount(); diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Fri Sep 19 11:19:38 2014 -0700 @@ -2023,8 +2023,9 @@ */ public static MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) { + explicitCastArgumentsChecks(target, newType); + // use the asTypeCache when possible: MethodType oldType = target.type(); - // use the asTypeCache when possible: if (oldType == newType) return target; if (oldType.explicitCastEquivalentToAsType(newType)) { return target.asType(newType); @@ -2032,6 +2033,12 @@ return MethodHandleImpl.makePairwiseConvert(target, newType, false); } + private static void explicitCastArgumentsChecks(MethodHandle target, MethodType newType) { + if (target.type().parameterCount() != newType.parameterCount()) { + throw new WrongMethodTypeException("cannot explicitly cast " + target + " to " + newType); + } + } + /** * Produces a method handle which adapts the calling sequence of the * given method handle to a new type, by reordering the arguments. @@ -2164,7 +2171,7 @@ // dropIdx is missing from reorder; add it in at the end int oldArity = reorder.length; target = dropArguments(target, oldArity, newType.parameterType(dropIdx)); - reorder = Arrays.copyOf(reorder, oldArity+1); + reorder = Arrays.copyOf(reorder, oldArity + 1); reorder[oldArity] = dropIdx; } assert(target == originalTarget || permuteArgumentChecks(reorder, newType, target.type())); @@ -2182,9 +2189,9 @@ long mask = 0; for (int arg : reorder) { assert(arg < newArity); - mask |= (1 << arg); + mask |= (1L << arg); } - if (mask == (1 << newArity) - 1) { + if (mask == (1L << newArity) - 1) { assert(Long.numberOfTrailingZeros(Long.lowestOneBit(~mask)) == newArity); return -1; } @@ -2193,16 +2200,18 @@ int zeroPos = Long.numberOfTrailingZeros(zeroBit); assert(zeroPos < newArity); return zeroPos; + } else { + BitSet mask = new BitSet(newArity); + for (int arg : reorder) { + assert (arg < newArity); + mask.set(arg); + } + int zeroPos = mask.nextClearBit(0); + assert(zeroPos <= newArity); + if (zeroPos == newArity) + return -1; + return zeroPos; } - BitSet mask = new BitSet(newArity); - for (int arg : reorder) { - assert(arg < newArity); - mask.set(arg); - } - int zeroPos = mask.nextClearBit(0); - if (zeroPos == newArity) - return -1; - return zeroPos; } /** @@ -2218,32 +2227,42 @@ long mask = 0; for (int i = 0; i < reorder.length; i++) { int arg = reorder[i]; - if (arg >= newArity) return reorder.length; - int bit = 1 << arg; - if ((mask & bit) != 0) + if (arg >= newArity) { + return reorder.length; + } + long bit = 1L << arg; + if ((mask & bit) != 0) { return i; // >0 indicates a dup + } mask |= bit; } - if (mask == (1 << newArity) - 1) { + if (mask == (1L << newArity) - 1) { assert(Long.numberOfTrailingZeros(Long.lowestOneBit(~mask)) == newArity); return 0; } // find first zero long zeroBit = Long.lowestOneBit(~mask); int zeroPos = Long.numberOfTrailingZeros(zeroBit); - assert(zeroPos < newArity); + assert(zeroPos <= newArity); + if (zeroPos == newArity) { + return 0; + } return ~zeroPos; } else { // same algorithm, different bit set BitSet mask = new BitSet(newArity); for (int i = 0; i < reorder.length; i++) { int arg = reorder[i]; - if (arg >= newArity) return reorder.length; - if (mask.get(arg)) + if (arg >= newArity) { + return reorder.length; + } + if (mask.get(arg)) { return i; // >0 indicates a dup + } mask.set(arg); } int zeroPos = mask.nextClearBit(0); + assert(zeroPos <= newArity); if (zeroPos == newArity) { return 0; } @@ -2479,6 +2498,7 @@ MethodHandle dropArguments(MethodHandle target, int pos, List> valueTypes) { MethodType oldType = target.type(); // get NPE int dropped = dropArgumentChecks(oldType, pos, valueTypes); + MethodType newType = oldType.insertParameterTypes(pos, valueTypes); if (dropped == 0) return target; BoundMethodHandle result = target.rebind(); LambdaForm lform = result.form; @@ -2490,7 +2510,6 @@ } else { lform = lform.addArguments(pos, valueTypes); } - MethodType newType = oldType.insertParameterTypes(pos, valueTypes); result = result.copyWith(newType, lform); return result; } diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Fri Sep 19 11:19:38 2014 -0700 @@ -869,9 +869,7 @@ if (dstTypes == srcTypes) { return true; } - if (dstTypes.length != srcTypes.length) { - return false; - } + assert(dstTypes.length == srcTypes.length); for (int i = 0; i < dstTypes.length; i++) { if (!explicitCastEquivalentToAsType(srcTypes[i], dstTypes[i])) { return false; diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.base/share/classes/java/math/MutableBigInteger.java --- a/jdk/src/java.base/share/classes/java/math/MutableBigInteger.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/math/MutableBigInteger.java Fri Sep 19 11:19:38 2014 -0700 @@ -1261,19 +1261,20 @@ int sigma = (int) Math.max(0, n32 - b.bitLength()); // step 3: sigma = max{T | (2^T)*B < beta^n} MutableBigInteger bShifted = new MutableBigInteger(b); bShifted.safeLeftShift(sigma); // step 4a: shift b so its length is a multiple of n - safeLeftShift(sigma); // step 4b: shift this by the same amount + MutableBigInteger aShifted = new MutableBigInteger (this); + aShifted.safeLeftShift(sigma); // step 4b: shift a by the same amount - // step 5: t is the number of blocks needed to accommodate this plus one additional bit - int t = (int) ((bitLength()+n32) / n32); + // step 5: t is the number of blocks needed to accommodate a plus one additional bit + int t = (int) ((aShifted.bitLength()+n32) / n32); if (t < 2) { t = 2; } - // step 6: conceptually split this into blocks a[t-1], ..., a[0] - MutableBigInteger a1 = getBlock(t-1, t, n); // the most significant block of this + // step 6: conceptually split a into blocks a[t-1], ..., a[0] + MutableBigInteger a1 = aShifted.getBlock(t-1, t, n); // the most significant block of a // step 7: z[t-2] = [a[t-1], a[t-2]] - MutableBigInteger z = getBlock(t-2, t, n); // the second to most significant block + MutableBigInteger z = aShifted.getBlock(t-2, t, n); // the second to most significant block z.addDisjoint(a1, n); // z[t-2] // do schoolbook division on blocks, dividing 2-block numbers by 1-block numbers @@ -1284,7 +1285,7 @@ ri = z.divide2n1n(bShifted, qi); // step 8b: z = [ri, a[i-1]] - z = getBlock(i-1, t, n); // a[i-1] + z = aShifted.getBlock(i-1, t, n); // a[i-1] z.addDisjoint(ri, n); quotient.addShifted(qi, i*n); // update q (part of step 9) } @@ -1292,7 +1293,7 @@ ri = z.divide2n1n(bShifted, qi); quotient.add(qi); - ri.rightShift(sigma); // step 9: this and b were shifted, so shift back + ri.rightShift(sigma); // step 9: a and b were shifted, so shift back return ri; } } diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.base/share/classes/java/security/spec/EncodedKeySpec.java --- a/jdk/src/java.base/share/classes/java/security/spec/EncodedKeySpec.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/security/spec/EncodedKeySpec.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,13 +43,14 @@ public abstract class EncodedKeySpec implements KeySpec { private byte[] encodedKey; + private String algorithmName; /** - * Creates a new EncodedKeySpec with the given encoded key. + * Creates a new {@code EncodedKeySpec} with the given encoded key. * * @param encodedKey the encoded key. The contents of the * array are copied to protect against subsequent modification. - * @exception NullPointerException if {@code encodedKey} + * @throws NullPointerException if {@code encodedKey} * is null. */ public EncodedKeySpec(byte[] encodedKey) { @@ -57,6 +58,48 @@ } /** + * Creates a new {@code EncodedKeySpec} with the given encoded key. + * This constructor is useful when subsequent callers of the + * {@code EncodedKeySpec} object might not know the algorithm + * of the key. + * + * @param encodedKey the encoded key. The contents of the + * array are copied to protect against subsequent modification. + * @param algorithm the algorithm name of the encoded key + * See the KeyFactory section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * @throws NullPointerException if {@code encodedKey} + * or {@code algorithm} is null. + * @throws IllegalArgumentException if {@code algorithm} is + * the empty string {@code ""} + * @since 1.9 + */ + protected EncodedKeySpec(byte[] encodedKey, String algorithm) { + if (algorithm == null) { + throw new NullPointerException("algorithm name may not be null"); + } + if (algorithm.isEmpty()) { + throw new IllegalArgumentException("algorithm name " + + "may not be empty"); + } + this.encodedKey = encodedKey.clone(); + this.algorithmName = algorithm; + + } + + /** + * Returns the name of the algorithm of the encoded key. + * + * @return the name of the algorithm, or null if not specified + * @since 1.9 + */ + public String getAlgorithm() { + return algorithmName; + } + + /** * Returns the encoded key. * * @return the encoded key. Returns a new array each time diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.base/share/classes/java/security/spec/PKCS8EncodedKeySpec.java --- a/jdk/src/java.base/share/classes/java/security/spec/PKCS8EncodedKeySpec.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/security/spec/PKCS8EncodedKeySpec.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,12 +62,12 @@ public class PKCS8EncodedKeySpec extends EncodedKeySpec { /** - * Creates a new PKCS8EncodedKeySpec with the given encoded key. + * Creates a new {@code PKCS8EncodedKeySpec} with the given encoded key. * * @param encodedKey the key, which is assumed to be * encoded according to the PKCS #8 standard. The contents of * the array are copied to protect against subsequent modification. - * @exception NullPointerException if {@code encodedKey} + * @throws NullPointerException if {@code encodedKey} * is null. */ public PKCS8EncodedKeySpec(byte[] encodedKey) { @@ -75,6 +75,30 @@ } /** + * Creates a new {@code PKCS8EncodedKeySpec} with the given encoded key and + * algorithm. This constructor is useful when subsequent callers of + * the {@code PKCS8EncodedKeySpec} object might not know the + * algorithm of the private key. + * + * @param encodedKey the key, which is assumed to be + * encoded according to the PKCS #8 standard. The contents of + * the array are copied to protect against subsequent modification. + * @param algorithm the algorithm name of the encoded private key + * See the KeyFactory section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * @throws NullPointerException if {@code encodedKey} + * or {@algorithm} is null. + * @throws IllegalArgumentException if {@code algorithm} is + * the empty string {@code ""} + * @since 1.9 + */ + public PKCS8EncodedKeySpec(byte[] encodedKey, String algorithm) { + super(encodedKey, algorithm); + } + + /** * Returns the key bytes, encoded according to the PKCS #8 standard. * * @return the PKCS #8 encoding of the key. Returns a new array diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.base/share/classes/java/security/spec/X509EncodedKeySpec.java --- a/jdk/src/java.base/share/classes/java/security/spec/X509EncodedKeySpec.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/security/spec/X509EncodedKeySpec.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,12 +52,12 @@ public class X509EncodedKeySpec extends EncodedKeySpec { /** - * Creates a new X509EncodedKeySpec with the given encoded key. + * Creates a new {@code X509EncodedKeySpec} with the given encoded key. * * @param encodedKey the key, which is assumed to be * encoded according to the X.509 standard. The contents of the * array are copied to protect against subsequent modification. - * @exception NullPointerException if {@code encodedKey} + * @throws NullPointerException if {@code encodedKey} * is null. */ public X509EncodedKeySpec(byte[] encodedKey) { @@ -65,6 +65,30 @@ } /** + * Creates a new {@code X509EncodedKeySpec} with the given encoded key. + * This constructor is useful when subsequent callers of the + * {@code X509EncodedKeySpec} object might not know the algorithm + * of the key. + * + * @param encodedKey the key, which is assumed to be + * encoded according to the X.509 standard. The contents of the + * array are copied to protect against subsequent modification. + * @param algorithm the algorithm name of the encoded public key + * See the KeyFactory section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * @throws NullPointerException if {@code encodedKey} + * or {@code algorithm} is null. + * @throws IllegalArgumentException if {@code algorithm} is + * the empty string {@code ""} + * @since 1.9 + */ + public X509EncodedKeySpec(byte[] encodedKey, String algorithm) { + super(encodedKey, algorithm); + } + + /** * Returns the key bytes, encoded according to the X.509 standard. * * @return the X.509 encoding of the key. Returns a new array diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.base/share/classes/java/util/TimerTask.java --- a/jdk/src/java.base/share/classes/java/util/TimerTask.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.base/share/classes/java/util/TimerTask.java Fri Sep 19 11:19:38 2014 -0700 @@ -26,10 +26,14 @@ package java.util; /** - * A task that can be scheduled for one-time or repeated execution by a Timer. + * A task that can be scheduled for one-time or repeated execution by a + * {@link Timer}. + * + *

A timer task is not reusable. Once a task has been scheduled + * for execution on a {@code Timer} or cancelled, subsequent attempts to + * schedule it for execution will throw {@code IllegalStateException}. * * @author Josh Bloch - * @see Timer * @since 1.3 */ diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java --- a/jdk/src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,6 +60,9 @@ // the "encryptionAlgorithm" field private AlgorithmId algid; + // the algorithm name of the encrypted private key + private String keyAlg; + // the "encryptedData" field private byte[] encryptedData; @@ -255,7 +258,7 @@ throw new InvalidKeySpecException( "Cannot retrieve the PKCS8EncodedKeySpec", ex); } - return new PKCS8EncodedKeySpec(encoded); + return new PKCS8EncodedKeySpec(encoded, keyAlg); } private PKCS8EncodedKeySpec getKeySpecImpl(Key decryptKey, @@ -280,7 +283,7 @@ throw new InvalidKeyException( "Cannot retrieve the PKCS8EncodedKeySpec", ex); } - return new PKCS8EncodedKeySpec(encoded); + return new PKCS8EncodedKeySpec(encoded, keyAlg); } /** @@ -405,7 +408,7 @@ } @SuppressWarnings("fallthrough") - private static void checkPKCS8Encoding(byte[] encodedKey) + private void checkPKCS8Encoding(byte[] encodedKey) throws IOException { DerInputStream in = new DerInputStream(encodedKey); DerValue[] values = in.getSequence(3); @@ -416,11 +419,7 @@ /* fall through */ case 3: checkTag(values[0], DerValue.tag_Integer, "version"); - DerInputStream algid = values[1].toDerInputStream(); - algid.getOID(); - if (algid.available() != 0) { - algid.getDerValue(); - } + keyAlg = AlgorithmId.parse(values[1]).getName(); checkTag(values[2], DerValue.tag_OctetString, "privateKey"); break; default: diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java --- a/jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.security.jgss; - -/** - * Kerberos 5 AuthorizationData entry. - */ -@jdk.Exported -public final class AuthorizationDataEntry { - - private final int type; - private final byte[] data; - - /** - * Create an AuthorizationDataEntry object. - * @param type the ad-type - * @param data the ad-data, a copy of the data will be saved - * inside the object. - */ - public AuthorizationDataEntry(int type, byte[] data) { - this.type = type; - this.data = data.clone(); - } - - /** - * Get the ad-type field. - * @return ad-type - */ - public int getType() { - return type; - } - - /** - * Get a copy of the ad-data field. - * @return ad-data - */ - public byte[] getData() { - return data.clone(); - } - - public String toString() { - return "AuthorizationDataEntry: type="+type+", data=" + - data.length + " bytes:\n" + - new sun.misc.HexDumpEncoder().encodeBuffer(data); - } -} diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContext.java --- a/jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContext.java Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.security.jgss; - -import org.ietf.jgss.*; - -/** - * The extended GSSContext interface for supporting additional - * functionalities not defined by {@code org.ietf.jgss.GSSContext}, - * such as querying context-specific attributes. - */ -@jdk.Exported -public interface ExtendedGSSContext extends GSSContext { - /** - * Return the mechanism-specific attribute associated with {@code type}. - *

- * If there is a security manager, an {@link InquireSecContextPermission} - * with the name {@code type.mech} must be granted. Otherwise, this could - * result in a {@link SecurityException}.

- * - * Example: - *

-     *      GSSContext ctxt = m.createContext(...)
-     *      // Establishing the context
-     *      if (ctxt instanceof ExtendedGSSContext) {
-     *          ExtendedGSSContext ex = (ExtendedGSSContext)ctxt;
-     *          try {
-     *              Key key = (key)ex.inquireSecContext(
-     *                      InquireType.KRB5_GET_SESSION_KEY);
-     *              // read key info
-     *          } catch (GSSException gsse) {
-     *              // deal with exception
-     *          }
-     *      }
-     * 
- * @param type the type of the attribute requested - * @return the attribute, see the method documentation for details. - * @throws GSSException containing the following - * major error codes: - * {@link GSSException#BAD_MECH GSSException.BAD_MECH} if the mechanism - * does not support this method, - * {@link GSSException#UNAVAILABLE GSSException.UNAVAILABLE} if the - * type specified is not supported, - * {@link GSSException#NO_CONTEXT GSSException.NO_CONTEXT} if the - * security context is invalid, - * {@link GSSException#FAILURE GSSException.FAILURE} for other - * unspecified failures. - * @throws SecurityException if a security manager exists and a proper - * {@link InquireSecContextPermission} is not granted. - * @see InquireSecContextPermission - * @see InquireType - */ - public Object inquireSecContext(InquireType type) - throws GSSException; - - /** - * Requests that the delegation policy be respected. When a true value is - * requested, the underlying context would use the delegation policy - * defined by the environment as a hint to determine whether credentials - * delegation should be performed. This request can only be made on the - * context initiator's side and it has to be done prior to the first - * call to initSecContext. - *

- * When this flag is false, delegation will only be tried when the - * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag} - * is true. - *

- * When this flag is true but the - * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag} - * is false, delegation will be only tried if the delegation policy permits - * delegation. - *

- * When both this flag and the - * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag} - * are true, delegation will be always tried. However, if the delegation - * policy does not permit delegation, the value of - * {@link #getDelegPolicyState} will be false, even - * if delegation is performed successfully. - *

- * In any case, if the delegation is not successful, the value returned - * by {@link GSSContext#getCredDelegState()} is false, and the value - * returned by {@link #getDelegPolicyState()} is also false. - *

- * Not all mechanisms support delegation policy. Therefore, the - * application should check to see if the request was honored with the - * {@link #getDelegPolicyState() getDelegPolicyState} method. When - * delegation policy is not supported, requestDelegPolicy - * should return silently without throwing an exception. - *

- * Note: for the Kerberos 5 mechanism, the delegation policy is expressed - * through the OK-AS-DELEGATE flag in the service ticket. When it's true, - * the KDC permits delegation to the target server. In a cross-realm - * environment, in order for delegation be permitted, all cross-realm TGTs - * on the authentication path must also have the OK-AS-DELAGATE flags set. - * @param state true if the policy should be respected - * @throws GSSException containing the following - * major error codes: - * {@link GSSException#FAILURE GSSException.FAILURE} - */ - public void requestDelegPolicy(boolean state) throws GSSException; - - /** - * Returns the delegation policy response. Called after a security context - * is established. This method can be only called on the initiator's side. - * See {@link ExtendedGSSContext#requestDelegPolicy}. - * @return the delegation policy response - */ - public boolean getDelegPolicyState(); -} diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSCredential.java --- a/jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSCredential.java Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.security.jgss; - -import org.ietf.jgss.*; - -/** - * The extended GSSCredential interface for supporting additional - * functionalities not defined by {@code org.ietf.jgss.GSSCredential}. - * @since 1.8 - */ -@jdk.Exported -public interface ExtendedGSSCredential extends GSSCredential { - /** - * Impersonates a principal. In Kerberos, this can be implemented - * using the Microsoft S4U2self extension. - *

- * A {@link GSSException#NO_CRED GSSException.NO_CRED} will be thrown if the - * impersonation fails. A {@link GSSException#FAILURE GSSException.FAILURE} - * will be thrown if the impersonation method is not available to this - * credential object. - * @param name the name of the principal to impersonate - * @return a credential for that principal - * @throws GSSException containing the following - * major error codes: - * {@link GSSException#NO_CRED GSSException.NO_CRED} - * {@link GSSException#FAILURE GSSException.FAILURE} - */ - public GSSCredential impersonate(GSSName name) throws GSSException; -} diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/GSSUtil.java --- a/jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/GSSUtil.java Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.security.jgss; - -import javax.security.auth.Subject; -import org.ietf.jgss.GSSName; -import org.ietf.jgss.GSSCredential; - -/** - * GSS-API Utilities for using in conjunction with Sun Microsystem's - * implementation of Java GSS-API. - */ -@jdk.Exported -public class GSSUtil { - - /** - * Use this method to convert a GSSName and GSSCredential into a - * Subject. Typically this would be done by a server that wants to - * impersonate a client thread at the Java level by setting a client - * Subject in the current access control context. If the server is merely - * interested in using a principal based policy in its local JVM, then - * it only needs to provide the GSSName of the client. - * - * The elements from the GSSName are placed in the principals set of this - * Subject and those from the GSSCredential are placed in the private - * credentials set of the Subject. Any Kerberos specific elements that - * are added to the subject will be instances of the standard Kerberos - * implementation classes defined in javax.security.auth.kerberos. - * - * @return a Subject with the entries that contain elements from the - * given GSSName and GSSCredential. - * - * @param principals a GSSName containing one or more mechanism specific - * representations of the same entity. These mechanism specific - * representations will be populated in the returned Subject's principal - * set. - * - * @param credentials a GSSCredential containing one or more mechanism - * specific credentials for the same entity. These mechanism specific - * credentials will be populated in the returned Subject's private - * credential set. Passing in a value of null will imply that the private - * credential set should be left empty. - */ - public static Subject createSubject(GSSName principals, - GSSCredential credentials) { - - return sun.security.jgss.GSSUtil.getSubject(principals, - credentials); - } -} diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/InquireSecContextPermission.java --- a/jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/InquireSecContextPermission.java Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.security.jgss; - -import java.security.BasicPermission; - -/** - * This class is used to protect various attributes of an established - * GSS security context that can be accessed using the - * {@link com.sun.security.jgss.ExtendedGSSContext#inquireSecContext} - * method. - * - *

The target name is the {@link InquireType} allowed. - */ -@jdk.Exported -public final class InquireSecContextPermission extends BasicPermission { - private static final long serialVersionUID = -7131173349668647297L; - - /** - * Constructs a new {@code InquireSecContextPermission} object with - * the specified name. The name is the symbolic name of the - * {@link InquireType} allowed. - * - * @param name the {@link InquireType} allowed by this - * permission. "*" means all {@link InquireType}s are allowed. - * - * @throws NullPointerException if name is null. - * @throws IllegalArgumentException if name is empty. - */ - public InquireSecContextPermission(String name) { - super(name); - } -} diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/InquireType.java --- a/jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/InquireType.java Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.security.jgss; - -/** - * Attribute types that can be specified as an argument of - * {@link com.sun.security.jgss.ExtendedGSSContext#inquireSecContext} - */ -@jdk.Exported -public enum InquireType { - /** - * Attribute type for retrieving the session key of an established - * Kerberos 5 security context. The returned object is an instance of - * {@link java.security.Key}, which has the following properties: - *

    - *
  • Algorithm: enctype as a string, where - * enctype is defined in RFC 3961, section 8. - *
  • Format: "RAW" - *
  • Encoded form: the raw key bytes, not in any ASN.1 encoding - *
- * @deprecated as of 1.9, replaced by {@link #KRB5_GET_SESSION_KEY_EX} - * which returns an instance of - * {@link javax.security.auth.kerberos.EncryptionKey} - * that implements the {@link javax.crypto.SecretKey} interface and - * has similar methods with {@link javax.security.auth.kerberos.KerberosKey}. - */ - @Deprecated - KRB5_GET_SESSION_KEY, - /** - * Attribute type for retrieving the session key of an - * established Kerberos 5 security context. The return value is an - * instance of {@link javax.security.auth.kerberos.EncryptionKey}. - * - * @since 1.9 - */ - KRB5_GET_SESSION_KEY_EX, - /** - * Attribute type for retrieving the service ticket flags of an - * established Kerberos 5 security context. The returned object is - * a boolean array for the service ticket flags, which is long enough - * to contain all true bits. This means if the user wants to get the - * n'th bit but the length of the returned array is less than - * n, it is regarded as false. - */ - KRB5_GET_TKT_FLAGS, - /** - * Attribute type for retrieving the authorization data in the - * service ticket of an established Kerberos 5 security context. - * Only supported on the acceptor side. - */ - KRB5_GET_AUTHZ_DATA, - /** - * Attribute type for retrieving the authtime in the service ticket - * of an established Kerberos 5 security context. The returned object - * is a String object in the standard KerberosTime format defined in - * RFC 4120 Section 5.2.3. - */ - KRB5_GET_AUTHTIME, - /** - * Attribute type for retrieving the KRB_CRED message that an initiator - * is about to send to an acceptor. The return type is an instance of - * {@link javax.security.auth.kerberos.KerberosCredMessage}. - * - * @since 1.9 - */ - KRB5_GET_KRB_CRED, -} diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/package-info.java --- a/jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/package-info.java Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * 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. 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. - */ - -@jdk.Exported -package com.sun.security.jgss; diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/FactoryImpl.java --- a/jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/FactoryImpl.java Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.security.sasl.gsskerb; - -import javax.security.sasl.*; -import com.sun.security.sasl.util.PolicyUtils; - -import java.util.Map; -import javax.security.auth.callback.CallbackHandler; - -/** - * Client/server factory for GSSAPI (Kerberos V5) SASL client/server mechs. - * See GssKrb5Client/GssKrb5Server for input requirements. - * - * @author Rosanna Lee - */ -public final class FactoryImpl implements SaslClientFactory, SaslServerFactory { - private static final String myMechs[] = { - "GSSAPI"}; - - private static final int mechPolicies[] = { - PolicyUtils.NOPLAINTEXT|PolicyUtils.NOANONYMOUS|PolicyUtils.NOACTIVE - }; - - private static final int GSS_KERB_V5 = 0; - - public FactoryImpl() { - } - - public SaslClient createSaslClient(String[] mechs, - String authorizationId, - String protocol, - String serverName, - Map props, - CallbackHandler cbh) throws SaslException { - - for (int i = 0; i < mechs.length; i++) { - if (mechs[i].equals(myMechs[GSS_KERB_V5]) - && PolicyUtils.checkPolicy(mechPolicies[GSS_KERB_V5], props)) { - return new GssKrb5Client( - authorizationId, - protocol, - serverName, - props, - cbh); - } - } - return null; - }; - - public SaslServer createSaslServer(String mech, - String protocol, - String serverName, - Map props, - CallbackHandler cbh) throws SaslException { - if (mech.equals(myMechs[GSS_KERB_V5]) - && PolicyUtils.checkPolicy(mechPolicies[GSS_KERB_V5], props)) { - if (cbh == null) { - throw new SaslException( - "Callback handler with support for AuthorizeCallback required"); - } - return new GssKrb5Server( - protocol, - serverName, - props, - cbh); - } - return null; - }; - - public String[] getMechanismNames(Map props) { - return PolicyUtils.filterMechs(myMechs, mechPolicies, props); - } -} diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java --- a/jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - -package com.sun.security.sasl.gsskerb; - -import java.util.Locale; -import java.util.Map; -import java.util.logging.Level; -import javax.security.sasl.*; -import com.sun.security.sasl.util.AbstractSaslImpl; -import org.ietf.jgss.*; -import com.sun.security.jgss.ExtendedGSSContext; -import com.sun.security.jgss.InquireType; - -abstract class GssKrb5Base extends AbstractSaslImpl { - - private static final String KRB5_OID_STR = "1.2.840.113554.1.2.2"; - protected static Oid KRB5_OID; - protected static final byte[] EMPTY = new byte[0]; - - static { - try { - KRB5_OID = new Oid(KRB5_OID_STR); - } catch (GSSException ignore) {} - } - - protected GSSContext secCtx = null; - protected static final int JGSS_QOP = 0; // unrelated to SASL QOP mask - - protected GssKrb5Base(Map props, String className) - throws SaslException { - super(props, className); - } - - /** - * Retrieves this mechanism's name. - * - * @return The string "GSSAPI". - */ - public String getMechanismName() { - return "GSSAPI"; - } - - @Override - public Object getNegotiatedProperty(String propName) { - if (!completed) { - throw new IllegalStateException("Authentication incomplete"); - } - String xprefix = "com.sun.security.jgss.inquiretype."; - if (propName.startsWith(xprefix)) { - String type = propName.substring(xprefix.length()); - if (logger.isLoggable(Level.FINEST)) { - logger.logp(Level.FINE, "GssKrb5Base", - "getNegotiatedProperty", propName); - } - for (InquireType t: InquireType.values()) { - if (t.name().toLowerCase(Locale.US).equals(type)) { - try { - return ((ExtendedGSSContext)secCtx).inquireSecContext(t); - } catch (GSSException e) { - if (logger.isLoggable(Level.FINEST)) { - logger.log(Level.WARNING, "inquireSecContext error", e); - } - return null; - } - } - } - // No such InquireType. Although not likely to be defined - // as a property in a parent class, still try it. - } - return super.getNegotiatedProperty(propName); - } - - public byte[] unwrap(byte[] incoming, int start, int len) - throws SaslException { - if (!completed) { - throw new IllegalStateException("GSSAPI authentication not completed"); - } - - // integrity will be true if either privacy or integrity negotiated - if (!integrity) { - throw new IllegalStateException("No security layer negotiated"); - } - - try { - MessageProp msgProp = new MessageProp(JGSS_QOP, privacy); - byte[] answer = secCtx.unwrap(incoming, start, len, msgProp); - if (logger.isLoggable(Level.FINEST)) { - traceOutput(myClassName, "KRB501:Unwrap", "incoming: ", - incoming, start, len); - traceOutput(myClassName, "KRB502:Unwrap", "unwrapped: ", - answer, 0, answer.length); - } - return answer; - } catch (GSSException e) { - throw new SaslException("Problems unwrapping SASL buffer", e); - } - } - - public byte[] wrap(byte[] outgoing, int start, int len) throws SaslException { - if (!completed) { - throw new IllegalStateException("GSSAPI authentication not completed"); - } - - // integrity will be true if either privacy or integrity negotiated - if (!integrity) { - throw new IllegalStateException("No security layer negotiated"); - } - - // Generate GSS token - try { - MessageProp msgProp = new MessageProp(JGSS_QOP, privacy); - byte[] answer = secCtx.wrap(outgoing, start, len, msgProp); - if (logger.isLoggable(Level.FINEST)) { - traceOutput(myClassName, "KRB503:Wrap", "outgoing: ", - outgoing, start, len); - traceOutput(myClassName, "KRB504:Wrap", "wrapped: ", - answer, 0, answer.length); - } - return answer; - - } catch (GSSException e) { - throw new SaslException("Problem performing GSS wrap", e); - } - } - - public void dispose() throws SaslException { - if (secCtx != null) { - try { - secCtx.dispose(); - } catch (GSSException e) { - throw new SaslException("Problem disposing GSS context", e); - } - secCtx = null; - } - } - - protected void finalize() throws Throwable { - dispose(); - } -} diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java --- a/jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,329 +0,0 @@ -/* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.security.sasl.gsskerb; - -import java.io.IOException; -import java.util.Map; -import java.util.logging.Level; -import javax.security.sasl.*; - -// JAAS -import javax.security.auth.callback.CallbackHandler; - -// JGSS -import org.ietf.jgss.*; - -/** - * Implements the GSSAPI SASL client mechanism for Kerberos V5. - * (RFC 2222, - * draft-ietf-cat-sasl-gssapi-04.txt). - * It uses the Java Bindings for GSSAPI - * (RFC 2853) - * for getting GSSAPI/Kerberos V5 support. - * - * The client/server interactions are: - * C0: bind (GSSAPI, initial response) - * S0: sasl-bind-in-progress, challenge 1 (output of accept_sec_context or []) - * C1: bind (GSSAPI, response 1 (output of init_sec_context or [])) - * S1: sasl-bind-in-progress challenge 2 (security layer, server max recv size) - * C2: bind (GSSAPI, response 2 (security layer, client max recv size, authzid)) - * S2: bind success response - * - * Expects the client's credentials to be supplied from the - * javax.security.sasl.credentials property or from the thread's Subject. - * Otherwise the underlying KRB5 mech will attempt to acquire Kerberos creds - * by logging into Kerberos (via default TextCallbackHandler). - * These creds will be used for exchange with server. - * - * Required callbacks: none. - * - * Environment properties that affect behavior of implementation: - * - * javax.security.sasl.qop - * - quality of protection; list of auth, auth-int, auth-conf; default is "auth" - * javax.security.sasl.maxbuf - * - max receive buffer size; default is 65536 - * javax.security.sasl.sendmaxbuffer - * - max send buffer size; default is 65536; (min with server max recv size) - * - * javax.security.sasl.server.authentication - * - "true" means require mutual authentication; default is "false" - * - * javax.security.sasl.credentials - * - an {@link org.ietf.jgss.GSSCredential} used for delegated authentication. - * - * @author Rosanna Lee - */ - -final class GssKrb5Client extends GssKrb5Base implements SaslClient { - // ---------------- Constants ----------------- - private static final String MY_CLASS_NAME = GssKrb5Client.class.getName(); - - private boolean finalHandshake = false; - private boolean mutual = false; // default false - private byte[] authzID; - - /** - * Creates a SASL mechanism with client credentials that it needs - * to participate in GSS-API/Kerberos v5 authentication exchange - * with the server. - */ - GssKrb5Client(String authzID, String protocol, String serverName, - Map props, CallbackHandler cbh) throws SaslException { - - super(props, MY_CLASS_NAME); - - String service = protocol + "@" + serverName; - logger.log(Level.FINE, "KRB5CLNT01:Requesting service name: {0}", - service); - - try { - GSSManager mgr = GSSManager.getInstance(); - - // Create the name for the requested service entity for Krb5 mech - GSSName acceptorName = mgr.createName(service, - GSSName.NT_HOSTBASED_SERVICE, KRB5_OID); - - // Parse properties to check for supplied credentials - GSSCredential credentials = null; - if (props != null) { - Object prop = props.get(Sasl.CREDENTIALS); - if (prop != null && prop instanceof GSSCredential) { - credentials = (GSSCredential) prop; - logger.log(Level.FINE, - "KRB5CLNT01:Using the credentials supplied in " + - "javax.security.sasl.credentials"); - } - } - - // Create a context using credentials for Krb5 mech - secCtx = mgr.createContext(acceptorName, - KRB5_OID, /* mechanism */ - credentials, /* credentials */ - GSSContext.INDEFINITE_LIFETIME); - - // Request credential delegation when credentials have been supplied - if (credentials != null) { - secCtx.requestCredDeleg(true); - } - - // Parse properties to set desired context options - if (props != null) { - // Mutual authentication - String prop = (String)props.get(Sasl.SERVER_AUTH); - if (prop != null) { - mutual = "true".equalsIgnoreCase(prop); - } - } - secCtx.requestMutualAuth(mutual); - - // Always specify potential need for integrity and confidentiality - // Decision will be made during final handshake - secCtx.requestConf(true); - secCtx.requestInteg(true); - - } catch (GSSException e) { - throw new SaslException("Failure to initialize security context", e); - } - - if (authzID != null && authzID.length() > 0) { - try { - this.authzID = authzID.getBytes("UTF8"); - } catch (IOException e) { - throw new SaslException("Cannot encode authorization ID", e); - } - } - } - - public boolean hasInitialResponse() { - return true; - } - - /** - * Processes the challenge data. - * - * The server sends a challenge data using which the client must - * process using GSS_Init_sec_context. - * As per RFC 2222, when GSS_S_COMPLETE is returned, we do - * an extra handshake to determine the negotiated security protection - * and buffer sizes. - * - * @param challengeData A non-null byte array containing the - * challenge data from the server. - * @return A non-null byte array containing the response to be - * sent to the server. - */ - public byte[] evaluateChallenge(byte[] challengeData) throws SaslException { - if (completed) { - throw new IllegalStateException( - "GSSAPI authentication already complete"); - } - - if (finalHandshake) { - return doFinalHandshake(challengeData); - } else { - - // Security context not established yet; continue with init - - try { - byte[] gssOutToken = secCtx.initSecContext(challengeData, - 0, challengeData.length); - if (logger.isLoggable(Level.FINER)) { - traceOutput(MY_CLASS_NAME, "evaluteChallenge", - "KRB5CLNT02:Challenge: [raw]", challengeData); - traceOutput(MY_CLASS_NAME, "evaluateChallenge", - "KRB5CLNT03:Response: [after initSecCtx]", gssOutToken); - } - - if (secCtx.isEstablished()) { - finalHandshake = true; - if (gssOutToken == null) { - // RFC 2222 7.2.1: Client responds with no data - return EMPTY; - } - } - - return gssOutToken; - } catch (GSSException e) { - throw new SaslException("GSS initiate failed", e); - } - } - } - - private byte[] doFinalHandshake(byte[] challengeData) throws SaslException { - try { - // Security context already established. challengeData - // should contain security layers and server's maximum buffer size - - if (logger.isLoggable(Level.FINER)) { - traceOutput(MY_CLASS_NAME, "doFinalHandshake", - "KRB5CLNT04:Challenge [raw]:", challengeData); - } - - if (challengeData.length == 0) { - // Received S0, should return [] - return EMPTY; - } - - // Received S1 (security layer, server max recv size) - - byte[] gssOutToken = secCtx.unwrap(challengeData, 0, - challengeData.length, new MessageProp(0, false)); - - // First octet is a bit-mask specifying the protections - // supported by the server - if (logger.isLoggable(Level.FINE)) { - if (logger.isLoggable(Level.FINER)) { - traceOutput(MY_CLASS_NAME, "doFinalHandshake", - "KRB5CLNT05:Challenge [unwrapped]:", gssOutToken); - } - logger.log(Level.FINE, "KRB5CLNT06:Server protections: {0}", - gssOutToken[0]); - } - - // Client selects preferred protection - // qop is ordered list of qop values - byte selectedQop = findPreferredMask(gssOutToken[0], qop); - if (selectedQop == 0) { - throw new SaslException( - "No common protection layer between client and server"); - } - - if ((selectedQop&PRIVACY_PROTECTION) != 0) { - privacy = true; - integrity = true; - } else if ((selectedQop&INTEGRITY_ONLY_PROTECTION) != 0) { - integrity = true; - } - - // 2nd-4th octets specifies maximum buffer size expected by - // server (in network byte order) - int srvMaxBufSize = networkByteOrderToInt(gssOutToken, 1, 3); - - // Determine the max send buffer size based on what the - // server is able to receive and our specified max - sendMaxBufSize = (sendMaxBufSize == 0) ? srvMaxBufSize : - Math.min(sendMaxBufSize, srvMaxBufSize); - - // Update context to limit size of returned buffer - rawSendSize = secCtx.getWrapSizeLimit(JGSS_QOP, privacy, - sendMaxBufSize); - - if (logger.isLoggable(Level.FINE)) { - logger.log(Level.FINE, -"KRB5CLNT07:Client max recv size: {0}; server max recv size: {1}; rawSendSize: {2}", - new Object[] {recvMaxBufSize, - srvMaxBufSize, - rawSendSize}); - } - - // Construct negotiated security layers and client's max - // receive buffer size and authzID - int len = 4; - if (authzID != null) { - len += authzID.length; - } - - byte[] gssInToken = new byte[len]; - gssInToken[0] = selectedQop; - - if (logger.isLoggable(Level.FINE)) { - logger.log(Level.FINE, - "KRB5CLNT08:Selected protection: {0}; privacy: {1}; integrity: {2}", - new Object[]{selectedQop, - Boolean.valueOf(privacy), - Boolean.valueOf(integrity)}); - } - - intToNetworkByteOrder(recvMaxBufSize, gssInToken, 1, 3); - if (authzID != null) { - // copy authorization id - System.arraycopy(authzID, 0, gssInToken, 4, authzID.length); - logger.log(Level.FINE, "KRB5CLNT09:Authzid: {0}", authzID); - } - - if (logger.isLoggable(Level.FINER)) { - traceOutput(MY_CLASS_NAME, "doFinalHandshake", - "KRB5CLNT10:Response [raw]", gssInToken); - } - - gssOutToken = secCtx.wrap(gssInToken, - 0, gssInToken.length, - new MessageProp(0 /* qop */, false /* privacy */)); - - if (logger.isLoggable(Level.FINER)) { - traceOutput(MY_CLASS_NAME, "doFinalHandshake", - "KRB5CLNT11:Response [after wrap]", gssOutToken); - } - - completed = true; // server authenticated - - return gssOutToken; - } catch (GSSException e) { - throw new SaslException("Final handshake failed", e); - } - } -} diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java --- a/jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,365 +0,0 @@ -/* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.security.sasl.gsskerb; - -import javax.security.sasl.*; -import java.io.*; -import java.util.Map; -import java.util.logging.Level; - -// JAAS -import javax.security.auth.callback.*; - -// JGSS -import org.ietf.jgss.*; - -/** - * Implements the GSSAPI SASL server mechanism for Kerberos V5. - * (RFC 2222, - * draft-ietf-cat-sasl-gssapi-00.txt). - * - * Expects thread's Subject to contain server's Kerberos credentials - * - If not, underlying KRB5 mech will attempt to acquire Kerberos creds - * by logging into Kerberos (via default TextCallbackHandler). - * - These creds will be used for exchange with client. - * - * Required callbacks: - * - AuthorizeCallback - * handler must verify that authid/authzids are allowed and set - * authorized ID to be the canonicalized authzid (if applicable). - * - * Environment properties that affect behavior of implementation: - * - * javax.security.sasl.qop - * - quality of protection; list of auth, auth-int, auth-conf; default is "auth" - * javax.security.sasl.maxbuf - * - max receive buffer size; default is 65536 - * javax.security.sasl.sendmaxbuffer - * - max send buffer size; default is 65536; (min with client max recv size) - * - * @author Rosanna Lee - */ -final class GssKrb5Server extends GssKrb5Base implements SaslServer { - private static final String MY_CLASS_NAME = GssKrb5Server.class.getName(); - - private int handshakeStage = 0; - private String peer; - private String me; - private String authzid; - private CallbackHandler cbh; - - // When serverName is null, the server will be unbound. We need to save and - // check the protocol name after the context is established. This value - // will be null if serverName is not null. - private final String protocolSaved; - /** - * Creates a SASL mechanism with server credentials that it needs - * to participate in GSS-API/Kerberos v5 authentication exchange - * with the client. - */ - GssKrb5Server(String protocol, String serverName, - Map props, CallbackHandler cbh) throws SaslException { - - super(props, MY_CLASS_NAME); - - this.cbh = cbh; - - String service; - if (serverName == null) { - protocolSaved = protocol; - service = null; - } else { - protocolSaved = null; - service = protocol + "@" + serverName; - } - - logger.log(Level.FINE, "KRB5SRV01:Using service name: {0}", service); - - try { - GSSManager mgr = GSSManager.getInstance(); - - // Create the name for the requested service entity for Krb5 mech - GSSName serviceName = service == null ? null: - mgr.createName(service, GSSName.NT_HOSTBASED_SERVICE, KRB5_OID); - - GSSCredential cred = mgr.createCredential(serviceName, - GSSCredential.INDEFINITE_LIFETIME, - KRB5_OID, GSSCredential.ACCEPT_ONLY); - - // Create a context using the server's credentials - secCtx = mgr.createContext(cred); - - if ((allQop&INTEGRITY_ONLY_PROTECTION) != 0) { - // Might need integrity - secCtx.requestInteg(true); - } - - if ((allQop&PRIVACY_PROTECTION) != 0) { - // Might need privacy - secCtx.requestConf(true); - } - } catch (GSSException e) { - throw new SaslException("Failure to initialize security context", e); - } - logger.log(Level.FINE, "KRB5SRV02:Initialization complete"); - } - - - /** - * Processes the response data. - * - * The client sends response data to which the server must - * process using GSS_accept_sec_context. - * As per RFC 2222, the GSS authenication completes (GSS_S_COMPLETE) - * we do an extra hand shake to determine the negotiated security protection - * and buffer sizes. - * - * @param responseData A non-null but possible empty byte array containing the - * response data from the client. - * @return A non-null byte array containing the challenge to be - * sent to the client, or null when no more data is to be sent. - */ - public byte[] evaluateResponse(byte[] responseData) throws SaslException { - if (completed) { - throw new SaslException( - "SASL authentication already complete"); - } - - if (logger.isLoggable(Level.FINER)) { - traceOutput(MY_CLASS_NAME, "evaluateResponse", - "KRB5SRV03:Response [raw]:", responseData); - } - - switch (handshakeStage) { - case 1: - return doHandshake1(responseData); - - case 2: - return doHandshake2(responseData); - - default: - // Security context not established yet; continue with accept - - try { - byte[] gssOutToken = secCtx.acceptSecContext(responseData, - 0, responseData.length); - - if (logger.isLoggable(Level.FINER)) { - traceOutput(MY_CLASS_NAME, "evaluateResponse", - "KRB5SRV04:Challenge: [after acceptSecCtx]", gssOutToken); - } - - if (secCtx.isEstablished()) { - handshakeStage = 1; - - peer = secCtx.getSrcName().toString(); - me = secCtx.getTargName().toString(); - - logger.log(Level.FINE, - "KRB5SRV05:Peer name is : {0}, my name is : {1}", - new Object[]{peer, me}); - - // me might take the form of proto@host or proto/host - if (protocolSaved != null && - !protocolSaved.equalsIgnoreCase(me.split("[/@]")[0])) { - throw new SaslException( - "GSS context targ name protocol error: " + me); - } - - if (gssOutToken == null) { - return doHandshake1(EMPTY); - } - } - - return gssOutToken; - } catch (GSSException e) { - throw new SaslException("GSS initiate failed", e); - } - } - } - - private byte[] doHandshake1(byte[] responseData) throws SaslException { - try { - // Security context already established. responseData - // should contain no data - if (responseData != null && responseData.length > 0) { - throw new SaslException( - "Handshake expecting no response data from server"); - } - - // Construct 4 octets of data: - // First octet contains bitmask specifying protections supported - // 2nd-4th octets contains max receive buffer of server - - byte[] gssInToken = new byte[4]; - gssInToken[0] = allQop; - intToNetworkByteOrder(recvMaxBufSize, gssInToken, 1, 3); - - if (logger.isLoggable(Level.FINE)) { - logger.log(Level.FINE, - "KRB5SRV06:Supported protections: {0}; recv max buf size: {1}", - new Object[]{allQop, - recvMaxBufSize}); - } - - handshakeStage = 2; // progress to next stage - - if (logger.isLoggable(Level.FINER)) { - traceOutput(MY_CLASS_NAME, "doHandshake1", - "KRB5SRV07:Challenge [raw]", gssInToken); - } - - byte[] gssOutToken = secCtx.wrap(gssInToken, 0, gssInToken.length, - new MessageProp(0 /* gop */, false /* privacy */)); - - if (logger.isLoggable(Level.FINER)) { - traceOutput(MY_CLASS_NAME, "doHandshake1", - "KRB5SRV08:Challenge [after wrap]", gssOutToken); - } - return gssOutToken; - - } catch (GSSException e) { - throw new SaslException("Problem wrapping handshake1", e); - } - } - - private byte[] doHandshake2(byte[] responseData) throws SaslException { - try { - // Expecting 4 octets from client selected protection - // and client's receive buffer size - byte[] gssOutToken = secCtx.unwrap(responseData, 0, - responseData.length, new MessageProp(0, false)); - - if (logger.isLoggable(Level.FINER)) { - traceOutput(MY_CLASS_NAME, "doHandshake2", - "KRB5SRV09:Response [after unwrap]", gssOutToken); - } - - // First octet is a bit-mask specifying the selected protection - byte selectedQop = gssOutToken[0]; - if ((selectedQop&allQop) == 0) { - throw new SaslException("Client selected unsupported protection: " - + selectedQop); - } - if ((selectedQop&PRIVACY_PROTECTION) != 0) { - privacy = true; - integrity = true; - } else if ((selectedQop&INTEGRITY_ONLY_PROTECTION) != 0) { - integrity = true; - } - - // 2nd-4th octets specifies maximum buffer size expected by - // client (in network byte order). This is the server's send - // buffer maximum. - int clntMaxBufSize = networkByteOrderToInt(gssOutToken, 1, 3); - - // Determine the max send buffer size based on what the - // client is able to receive and our specified max - sendMaxBufSize = (sendMaxBufSize == 0) ? clntMaxBufSize : - Math.min(sendMaxBufSize, clntMaxBufSize); - - // Update context to limit size of returned buffer - rawSendSize = secCtx.getWrapSizeLimit(JGSS_QOP, privacy, - sendMaxBufSize); - - if (logger.isLoggable(Level.FINE)) { - logger.log(Level.FINE, - "KRB5SRV10:Selected protection: {0}; privacy: {1}; integrity: {2}", - new Object[]{selectedQop, - Boolean.valueOf(privacy), - Boolean.valueOf(integrity)}); - logger.log(Level.FINE, -"KRB5SRV11:Client max recv size: {0}; server max send size: {1}; rawSendSize: {2}", - new Object[] {clntMaxBufSize, - sendMaxBufSize, - rawSendSize}); - } - - // Get authorization identity, if any - if (gssOutToken.length > 4) { - try { - authzid = new String(gssOutToken, 4, - gssOutToken.length - 4, "UTF-8"); - } catch (UnsupportedEncodingException uee) { - throw new SaslException ("Cannot decode authzid", uee); - } - } else { - authzid = peer; - } - logger.log(Level.FINE, "KRB5SRV12:Authzid: {0}", authzid); - - AuthorizeCallback acb = new AuthorizeCallback(peer, authzid); - - // In Kerberos, realm is embedded in peer name - cbh.handle(new Callback[] {acb}); - if (acb.isAuthorized()) { - authzid = acb.getAuthorizedID(); - completed = true; - } else { - // Authorization failed - throw new SaslException(peer + - " is not authorized to connect as " + authzid); - } - - return null; - } catch (GSSException e) { - throw new SaslException("Final handshake step failed", e); - } catch (IOException e) { - throw new SaslException("Problem with callback handler", e); - } catch (UnsupportedCallbackException e) { - throw new SaslException("Problem with callback handler", e); - } - } - - public String getAuthorizationID() { - if (completed) { - return authzid; - } else { - throw new IllegalStateException("Authentication incomplete"); - } - } - - public Object getNegotiatedProperty(String propName) { - if (!completed) { - throw new IllegalStateException("Authentication incomplete"); - } - - Object result; - switch (propName) { - case Sasl.BOUND_SERVER_NAME: - try { - // me might take the form of proto@host or proto/host - result = me.split("[/@]")[1]; - } catch (Exception e) { - result = null; - } - break; - default: - result = super.getNegotiatedProperty(propName); - } - return result; - } -} diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSContext.java --- a/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSContext.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSContext.java Fri Sep 19 11:19:38 2014 -0700 @@ -25,7 +25,6 @@ package org.ietf.jgss; -import sun.security.jgss.spi.*; import java.io.InputStream; import java.io.OutputStream; diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSName.java --- a/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSName.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSName.java Fri Sep 19 11:19:38 2014 -0700 @@ -25,10 +25,6 @@ package org.ietf.jgss; -import sun.security.jgss.spi.*; -import java.util.Vector; -import java.util.Enumeration; - /** * This interface encapsulates a single GSS-API principal entity. The * application obtains an implementation of this interface diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java --- a/jdk/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java Fri Sep 19 11:19:38 2014 -0700 @@ -25,7 +25,6 @@ package sun.net.www.protocol.http.spnego; -import com.sun.security.jgss.ExtendedGSSContext; import java.io.IOException; import org.ietf.jgss.GSSContext; @@ -36,6 +35,7 @@ import sun.net.www.protocol.http.HttpCallerInfo; import sun.net.www.protocol.http.Negotiator; import sun.security.jgss.GSSManagerImpl; +import sun.security.jgss.GSSContextImpl; import sun.security.jgss.GSSUtil; import sun.security.jgss.HttpCaller; @@ -102,8 +102,8 @@ GSSContext.DEFAULT_LIFETIME); // Always respect delegation policy in HTTP/SPNEGO. - if (context instanceof ExtendedGSSContext) { - ((ExtendedGSSContext)context).requestDelegPolicy(true); + if (context instanceof GSSContextImpl) { + ((GSSContextImpl)context).requestDelegPolicy(true); } oneToken = context.initSecContext(new byte[0], 0, 0); } diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSContextImpl.java --- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSContextImpl.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSContextImpl.java Fri Sep 19 11:19:38 2014 -0700 @@ -33,7 +33,8 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import com.sun.security.jgss.*; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; /** * This class represents the JGSS security context and its associated @@ -87,10 +88,10 @@ * per-message operations are returned in an instance of the MessageProp * class, which is used as an argument in these calls. */ -class GSSContextImpl implements ExtendedGSSContext { +public class GSSContextImpl implements GSSContext { - private final GSSManagerImpl gssManager; - private final boolean initiator; + private GSSManagerImpl gssManager; + private boolean initiator; // private flags for the context state private static final int PRE_INIT = 1; @@ -122,6 +123,22 @@ private boolean reqAnonState = false; private boolean reqDelegPolicyState = false; + public GSSContextImpl() { + // Useless + } + + // Used by new ExtendedGSSContext.ExtendedGSSContextImpl(ctxt) + protected GSSContextImpl(GSSContextImpl src) { + for (Field f: GSSContextImpl.class.getDeclaredFields()) { + if (!Modifier.isStatic(f.getModifiers())) { + try { + f.set(this, f.get(src)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + } /** * Creates a GSSContextImp on the context initiator's side. */ @@ -613,7 +630,7 @@ "No mechanism context yet!"); GSSCredentialSpi delCredElement = mechCtxt.getDelegCred(); return (delCredElement == null ? - null : new GSSCredentialImpl(gssManager, delCredElement)); + null : GSSManagerImpl.wrap(new GSSCredentialImpl(gssManager, delCredElement))); } public boolean isInitiator() throws GSSException { @@ -633,25 +650,18 @@ // ExtendedGSSContext methods: - @Override - public Object inquireSecContext(InquireType type) throws GSSException { - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(new InquireSecContextPermission(type.toString())); - } + public Object inquireSecContext(String type) throws GSSException { if (mechCtxt == null) { throw new GSSException(GSSException.NO_CONTEXT); } return mechCtxt.inquireSecContext(type); } - @Override public void requestDelegPolicy(boolean state) throws GSSException { if (mechCtxt == null && initiator) reqDelegPolicyState = state; } - @Override public boolean getDelegPolicyState() { if (mechCtxt != null) return mechCtxt.getDelegPolicyState(); diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSCredentialImpl.java --- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSCredentialImpl.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSCredentialImpl.java Fri Sep 19 11:19:38 2014 -0700 @@ -27,11 +27,11 @@ import org.ietf.jgss.*; import sun.security.jgss.spi.*; + import java.util.*; -import com.sun.security.jgss.*; import sun.security.jgss.spnego.SpNegoCredElement; -public class GSSCredentialImpl implements ExtendedGSSCredential { +public class GSSCredentialImpl implements GSSCredential { private GSSManagerImpl gssManager = null; private boolean destroyed = false; @@ -47,6 +47,18 @@ // XXX Optimization for single mech usage private GSSCredentialSpi tempCred = null; + public GSSCredentialImpl() { + // Useless + } + + // Used by new ExtendedGSSCredential.ExtendedGSSCredentialImpl(cred) + protected GSSCredentialImpl(GSSCredentialImpl src) { + this.gssManager = src.gssManager; + this.destroyed = src.destroyed; + this.hashtable = src.hashtable; + this.tempCred = src.tempCred; + } + GSSCredentialImpl(GSSManagerImpl gssManager, int usage) throws GSSException { this(gssManager, null, GSSCredential.DEFAULT_LIFETIME, @@ -140,7 +152,7 @@ ((GSSNameImpl)name).getElement(mech)); GSSCredentialSpi cred = tempCred.impersonate(nameElement); return (cred == null ? - null : new GSSCredentialImpl(gssManager, cred)); + null : GSSManagerImpl.wrap(new GSSCredentialImpl(gssManager, cred))); } public GSSName getName() throws GSSException { diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSManagerImpl.java --- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSManagerImpl.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSManagerImpl.java Fri Sep 19 11:19:38 2014 -0700 @@ -145,35 +145,35 @@ public GSSCredential createCredential(int usage) throws GSSException { - return new GSSCredentialImpl(this, usage); + return wrap(new GSSCredentialImpl(this, usage)); } public GSSCredential createCredential(GSSName aName, int lifetime, Oid mech, int usage) throws GSSException { - return new GSSCredentialImpl(this, aName, lifetime, mech, usage); + return wrap(new GSSCredentialImpl(this, aName, lifetime, mech, usage)); } public GSSCredential createCredential(GSSName aName, int lifetime, Oid mechs[], int usage) throws GSSException { - return new GSSCredentialImpl(this, aName, lifetime, mechs, usage); + return wrap(new GSSCredentialImpl(this, aName, lifetime, mechs, usage)); } public GSSContext createContext(GSSName peer, Oid mech, GSSCredential myCred, int lifetime) throws GSSException { - return new GSSContextImpl(this, peer, mech, myCred, lifetime); + return wrap(new GSSContextImpl(this, peer, mech, myCred, lifetime)); } public GSSContext createContext(GSSCredential myCred) throws GSSException { - return new GSSContextImpl(this, myCred); + return wrap(new GSSContextImpl(this, myCred)); } public GSSContext createContext(byte[] interProcessToken) throws GSSException { - return new GSSContextImpl(this, interProcessToken); + return wrap(new GSSContextImpl(this, interProcessToken)); } public void addProviderAtFront(Provider p, Oid mech) @@ -257,4 +257,20 @@ } return result; } + + static { + // Load the extended JGSS interfaces if exist + try { + Class.forName("com.sun.security.jgss.Extender"); + } catch (Exception e) { + } + } + + static GSSCredential wrap(GSSCredentialImpl cred) { + return sun.security.jgss.JgssExtender.getExtender().wrap(cred); + } + + static GSSContext wrap(GSSContextImpl ctxt) { + return sun.security.jgss.JgssExtender.getExtender().wrap(ctxt); + } } diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/sun/security/jgss/JgssExtender.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/JgssExtender.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.jgss; + +import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSCredential; + +/** + * The extending point of basic JGSS-API. + *

+ * If a module wants to extend basic JGSS-API classes, it should extends this + * class and register itself as "the extender" using the setExtender method. + * When various GSSManager.createXXX methods are called, they will call + * "the extender"'s wrap methods to create objects of extended types + * instead of basic types. + *

+ * We have only one extension now defined in com.sun.security.jgss, and the + * registering process is triggered in {@link GSSManagerImpl} by calling + * Class.forName("com.sun.security.jgss.Extender"). Only GSSContext + * and GSSCredential are extended now. + *

+ * The setExtender method should be called before any JGSS call. + */ +public class JgssExtender { + + // "The extender" + private static volatile JgssExtender theOne = new JgssExtender(); + + /** + * Gets "the extender". GSSManager calls this method so that it can + * wrap basic objects into extended objects. + * @return the extender + */ + public static JgssExtender getExtender() { + return theOne; + } + + /** + * Set "the extender" so that GSSManager can create extended objects. + */ + protected static void setExtender(JgssExtender theOne) { + JgssExtender.theOne = theOne; + } + + /** + * Wraps a plain GSSCredential object into an extended type. + */ + public GSSCredential wrap(GSSCredential cred) { + return cred; + } + + /** + * Wraps a plain GSSContext object into an extended type. + */ + public GSSContext wrap(GSSContext ctxt) { + return ctxt; + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/InitSecContextToken.java --- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/InitSecContextToken.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/InitSecContextToken.java Fri Sep 19 11:19:38 2014 -0700 @@ -25,7 +25,6 @@ package sun.security.jgss.krb5; -import com.sun.security.jgss.AuthorizationDataEntry; import org.ietf.jgss.*; import java.io.InputStream; import java.io.IOException; @@ -152,17 +151,7 @@ new KerberosTime(apReq.getCreds().getAuthTime()).toString()); context.setTktFlags(apReq.getCreds().getFlags()); AuthorizationData ad = apReq.getCreds().getAuthzData(); - if (ad == null) { - context.setAuthzData(null); - } else { - AuthorizationDataEntry[] authzData = - new AuthorizationDataEntry[ad.count()]; - for (int i=0; i dirs = newDirSet(); while ((e = zis.getNextEntry()) != null) { + entriesFound = true; if (files == null) { dirs.add(extractFile(zis, e)); } else { @@ -947,6 +966,8 @@ // instead of during, because creating a file in a directory changes // that directory's timestamp. updateLastModifiedTime(dirs); + + return entriesFound; } /** @@ -958,7 +979,6 @@ Enumeration zes = zf.entries(); while (zes.hasMoreElements()) { ZipEntry e = zes.nextElement(); - InputStream is; if (files == null) { dirs.add(extractFile(zf.getInputStream(e), e)); } else { diff -r 66228a695a62 -r 00b27213d86c jdk/src/jdk.localedata/META-INF/cldrdata-services/sun.util.locale.provider.LocaleDataMetaInfo --- a/jdk/src/jdk.localedata/META-INF/cldrdata-services/sun.util.locale.provider.LocaleDataMetaInfo Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/src/jdk.localedata/META-INF/cldrdata-services/sun.util.locale.provider.LocaleDataMetaInfo Fri Sep 19 11:19:38 2014 -0700 @@ -1,1 +1,1 @@ -sun.util.cldr.CLDRLocaleDataMetaInfo +sun.util.resources.cldr.provider.CLDRLocaleDataMetaInfo diff -r 66228a695a62 -r 00b27213d86c jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.security.jgss; + +/** + * Kerberos 5 AuthorizationData entry. + */ +@jdk.Exported +public final class AuthorizationDataEntry { + + private final int type; + private final byte[] data; + + /** + * Create an AuthorizationDataEntry object. + * @param type the ad-type + * @param data the ad-data, a copy of the data will be saved + * inside the object. + */ + public AuthorizationDataEntry(int type, byte[] data) { + this.type = type; + this.data = data.clone(); + } + + /** + * Get the ad-type field. + * @return ad-type + */ + public int getType() { + return type; + } + + /** + * Get a copy of the ad-data field. + * @return ad-data + */ + public byte[] getData() { + return data.clone(); + } + + public String toString() { + return "AuthorizationDataEntry: type="+type+", data=" + + data.length + " bytes:\n" + + new sun.misc.HexDumpEncoder().encodeBuffer(data); + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContext.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.security.jgss; + +import org.ietf.jgss.*; +import sun.security.jgss.GSSContextImpl; +import sun.security.krb5.internal.AuthorizationData; + +/** + * The extended GSSContext interface for supporting additional + * functionalities not defined by {@code org.ietf.jgss.GSSContext}, + * such as querying context-specific attributes. + */ +@jdk.Exported +public interface ExtendedGSSContext extends GSSContext { + + // The impl is almost identical to GSSContextImpl with only 2 differences: + // 1. It implements the extended interface + // 2. It translates result to data types here in inquireSecContext + static class ExtendedGSSContextImpl extends GSSContextImpl + implements ExtendedGSSContext { + + public ExtendedGSSContextImpl(GSSContextImpl old) { + super(old); + } + + @Override + public Object inquireSecContext(InquireType type) throws GSSException { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkPermission( + new InquireSecContextPermission(type.toString())); + } + Object output = super.inquireSecContext(type.name()); + if (output != null) { + if (type == InquireType.KRB5_GET_AUTHZ_DATA) { + AuthorizationData ad = (AuthorizationData) output; + AuthorizationDataEntry[] authzData = + new AuthorizationDataEntry[ad.count()]; + for (int i = 0; i < ad.count(); i++) { + authzData[i] = new AuthorizationDataEntry( + ad.item(i).adType, ad.item(i).adData); + } + output = authzData; + } + } + return output; + } + } + + /** + * Return the mechanism-specific attribute associated with {@code type}. + *

+ * If there is a security manager, an {@link InquireSecContextPermission} + * with the name {@code type.mech} must be granted. Otherwise, this could + * result in a {@link SecurityException}. + *

+ * Example: + *

+     *      GSSContext ctxt = m.createContext(...)
+     *      // Establishing the context
+     *      if (ctxt instanceof ExtendedGSSContext) {
+     *          ExtendedGSSContext ex = (ExtendedGSSContext)ctxt;
+     *          try {
+     *              Key key = (key)ex.inquireSecContext(
+     *                      InquireType.KRB5_GET_SESSION_KEY);
+     *              // read key info
+     *          } catch (GSSException gsse) {
+     *              // deal with exception
+     *          }
+     *      }
+     * 
+ * @param type the type of the attribute requested + * @return the attribute, see the method documentation for details. + * @throws GSSException containing the following + * major error codes: + * {@link GSSException#BAD_MECH GSSException.BAD_MECH} if the mechanism + * does not support this method, + * {@link GSSException#UNAVAILABLE GSSException.UNAVAILABLE} if the + * type specified is not supported, + * {@link GSSException#NO_CONTEXT GSSException.NO_CONTEXT} if the + * security context is invalid, + * {@link GSSException#FAILURE GSSException.FAILURE} for other + * unspecified failures. + * @throws SecurityException if a security manager exists and a proper + * {@link InquireSecContextPermission} is not granted. + * @see InquireSecContextPermission + * @see InquireType + */ + public Object inquireSecContext(InquireType type) + throws GSSException; + + /** + * Requests that the delegation policy be respected. When a true value is + * requested, the underlying context would use the delegation policy + * defined by the environment as a hint to determine whether credentials + * delegation should be performed. This request can only be made on the + * context initiator's side and it has to be done prior to the first + * call to initSecContext. + *

+ * When this flag is false, delegation will only be tried when the + * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag} + * is true. + *

+ * When this flag is true but the + * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag} + * is false, delegation will be only tried if the delegation policy permits + * delegation. + *

+ * When both this flag and the + * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag} + * are true, delegation will be always tried. However, if the delegation + * policy does not permit delegation, the value of + * {@link #getDelegPolicyState} will be false, even + * if delegation is performed successfully. + *

+ * In any case, if the delegation is not successful, the value returned + * by {@link GSSContext#getCredDelegState()} is false, and the value + * returned by {@link #getDelegPolicyState()} is also false. + *

+ * Not all mechanisms support delegation policy. Therefore, the + * application should check to see if the request was honored with the + * {@link #getDelegPolicyState() getDelegPolicyState} method. When + * delegation policy is not supported, requestDelegPolicy + * should return silently without throwing an exception. + *

+ * Note: for the Kerberos 5 mechanism, the delegation policy is expressed + * through the OK-AS-DELEGATE flag in the service ticket. When it's true, + * the KDC permits delegation to the target server. In a cross-realm + * environment, in order for delegation be permitted, all cross-realm TGTs + * on the authentication path must also have the OK-AS-DELAGATE flags set. + * @param state true if the policy should be respected + * @throws GSSException containing the following + * major error codes: + * {@link GSSException#FAILURE GSSException.FAILURE} + */ + public void requestDelegPolicy(boolean state) throws GSSException; + + /** + * Returns the delegation policy response. Called after a security context + * is established. This method can be only called on the initiator's side. + * See {@link ExtendedGSSContext#requestDelegPolicy}. + * @return the delegation policy response + */ + public boolean getDelegPolicyState(); +} diff -r 66228a695a62 -r 00b27213d86c jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSCredential.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSCredential.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.security.jgss; + +import org.ietf.jgss.*; +import sun.security.jgss.GSSCredentialImpl; + +/** + * The extended GSSCredential interface for supporting additional + * functionalities not defined by {@code org.ietf.jgss.GSSCredential}. + * @since 1.8 + */ +@jdk.Exported +public interface ExtendedGSSCredential extends GSSCredential { + + static class ExtendedGSSCredentialImpl extends GSSCredentialImpl + implements ExtendedGSSCredential { + + public ExtendedGSSCredentialImpl(GSSCredentialImpl old) { + super(old); + } + } + + /** + * Impersonates a principal. In Kerberos, this can be implemented + * using the Microsoft S4U2self extension. + *

+ * A {@link GSSException#NO_CRED GSSException.NO_CRED} will be thrown if the + * impersonation fails. A {@link GSSException#FAILURE GSSException.FAILURE} + * will be thrown if the impersonation method is not available to this + * credential object. + * @param name the name of the principal to impersonate + * @return a credential for that principal + * @throws GSSException containing the following + * major error codes: + * {@link GSSException#NO_CRED GSSException.NO_CRED} + * {@link GSSException#FAILURE GSSException.FAILURE} + */ + public GSSCredential impersonate(GSSName name) throws GSSException; +} diff -r 66228a695a62 -r 00b27213d86c jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/Extender.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/Extender.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.security.jgss; + +import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSCredential; +import sun.security.jgss.GSSContextImpl; +import sun.security.jgss.GSSCredentialImpl; +import sun.security.jgss.JgssExtender; + +// The com.sun.security.jgss extension to JGSS-API +class Extender extends JgssExtender { + + static { + JgssExtender.setExtender(new Extender()); + } + + public GSSCredential wrap(GSSCredential cred) { + if (cred instanceof ExtendedGSSCredential.ExtendedGSSCredentialImpl) { + return cred; + } else { + return new ExtendedGSSCredential.ExtendedGSSCredentialImpl((GSSCredentialImpl)cred); + } + } + + public GSSContext wrap(GSSContext ctxt) { + if (ctxt instanceof ExtendedGSSContext.ExtendedGSSContextImpl) { + return ctxt; + } else { + return new ExtendedGSSContext.ExtendedGSSContextImpl((GSSContextImpl)ctxt); + } + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/GSSUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/GSSUtil.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.security.jgss; + +import javax.security.auth.Subject; +import org.ietf.jgss.GSSName; +import org.ietf.jgss.GSSCredential; + +/** + * GSS-API Utilities for using in conjunction with Sun Microsystem's + * implementation of Java GSS-API. + */ +@jdk.Exported +public class GSSUtil { + + /** + * Use this method to convert a GSSName and GSSCredential into a + * Subject. Typically this would be done by a server that wants to + * impersonate a client thread at the Java level by setting a client + * Subject in the current access control context. If the server is merely + * interested in using a principal based policy in its local JVM, then + * it only needs to provide the GSSName of the client. + * + * The elements from the GSSName are placed in the principals set of this + * Subject and those from the GSSCredential are placed in the private + * credentials set of the Subject. Any Kerberos specific elements that + * are added to the subject will be instances of the standard Kerberos + * implementation classes defined in javax.security.auth.kerberos. + * + * @return a Subject with the entries that contain elements from the + * given GSSName and GSSCredential. + * + * @param principals a GSSName containing one or more mechanism specific + * representations of the same entity. These mechanism specific + * representations will be populated in the returned Subject's principal + * set. + * + * @param credentials a GSSCredential containing one or more mechanism + * specific credentials for the same entity. These mechanism specific + * credentials will be populated in the returned Subject's private + * credential set. Passing in a value of null will imply that the private + * credential set should be left empty. + */ + public static Subject createSubject(GSSName principals, + GSSCredential credentials) { + + return sun.security.jgss.GSSUtil.getSubject(principals, + credentials); + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/InquireSecContextPermission.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/InquireSecContextPermission.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.security.jgss; + +import java.security.BasicPermission; + +/** + * This class is used to protect various attributes of an established + * GSS security context that can be accessed using the + * {@link com.sun.security.jgss.ExtendedGSSContext#inquireSecContext} + * method. + * + *

The target name is the {@link InquireType} allowed. + */ +@jdk.Exported +public final class InquireSecContextPermission extends BasicPermission { + private static final long serialVersionUID = -7131173349668647297L; + + /** + * Constructs a new {@code InquireSecContextPermission} object with + * the specified name. The name is the symbolic name of the + * {@link InquireType} allowed. + * + * @param name the {@link InquireType} allowed by this + * permission. "*" means all {@link InquireType}s are allowed. + * + * @throws NullPointerException if name is null. + * @throws IllegalArgumentException if name is empty. + */ + public InquireSecContextPermission(String name) { + super(name); + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/InquireType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/InquireType.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.security.jgss; + +/** + * Attribute types that can be specified as an argument of + * {@link com.sun.security.jgss.ExtendedGSSContext#inquireSecContext} + */ +@jdk.Exported +public enum InquireType { + /** + * Attribute type for retrieving the session key of an established + * Kerberos 5 security context. The returned object is an instance of + * {@link java.security.Key}, which has the following properties: + *

    + *
  • Algorithm: enctype as a string, where + * enctype is defined in RFC 3961, section 8. + *
  • Format: "RAW" + *
  • Encoded form: the raw key bytes, not in any ASN.1 encoding + *
+ * @deprecated as of 1.9, replaced by {@link #KRB5_GET_SESSION_KEY_EX} + * which returns an instance of + * {@link javax.security.auth.kerberos.EncryptionKey} + * that implements the {@link javax.crypto.SecretKey} interface and + * has similar methods with {@link javax.security.auth.kerberos.KerberosKey}. + */ + @Deprecated + KRB5_GET_SESSION_KEY, + /** + * Attribute type for retrieving the session key of an + * established Kerberos 5 security context. The return value is an + * instance of {@link javax.security.auth.kerberos.EncryptionKey}. + * + * @since 1.9 + */ + KRB5_GET_SESSION_KEY_EX, + /** + * Attribute type for retrieving the service ticket flags of an + * established Kerberos 5 security context. The returned object is + * a boolean array for the service ticket flags, which is long enough + * to contain all true bits. This means if the user wants to get the + * n'th bit but the length of the returned array is less than + * n, it is regarded as false. + */ + KRB5_GET_TKT_FLAGS, + /** + * Attribute type for retrieving the authorization data in the + * service ticket of an established Kerberos 5 security context. + * Only supported on the acceptor side. + */ + KRB5_GET_AUTHZ_DATA, + /** + * Attribute type for retrieving the authtime in the service ticket + * of an established Kerberos 5 security context. The returned object + * is a String object in the standard KerberosTime format defined in + * RFC 4120 Section 5.2.3. + */ + KRB5_GET_AUTHTIME, + /** + * Attribute type for retrieving the KRB_CRED message that an initiator + * is about to send to an acceptor. The return type is an instance of + * {@link javax.security.auth.kerberos.KerberosCredMessage}. + * + * @since 1.9 + */ + KRB5_GET_KRB_CRED, +} diff -r 66228a695a62 -r 00b27213d86c jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/package-info.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,27 @@ +/* + * 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. 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. + */ + +@jdk.Exported +package com.sun.security.jgss; diff -r 66228a695a62 -r 00b27213d86c jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/FactoryImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/FactoryImpl.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.security.sasl.gsskerb; + +import javax.security.sasl.*; +import com.sun.security.sasl.util.PolicyUtils; + +import java.util.Map; +import javax.security.auth.callback.CallbackHandler; + +/** + * Client/server factory for GSSAPI (Kerberos V5) SASL client/server mechs. + * See GssKrb5Client/GssKrb5Server for input requirements. + * + * @author Rosanna Lee + */ +public final class FactoryImpl implements SaslClientFactory, SaslServerFactory { + private static final String myMechs[] = { + "GSSAPI"}; + + private static final int mechPolicies[] = { + PolicyUtils.NOPLAINTEXT|PolicyUtils.NOANONYMOUS|PolicyUtils.NOACTIVE + }; + + private static final int GSS_KERB_V5 = 0; + + public FactoryImpl() { + } + + public SaslClient createSaslClient(String[] mechs, + String authorizationId, + String protocol, + String serverName, + Map props, + CallbackHandler cbh) throws SaslException { + + for (int i = 0; i < mechs.length; i++) { + if (mechs[i].equals(myMechs[GSS_KERB_V5]) + && PolicyUtils.checkPolicy(mechPolicies[GSS_KERB_V5], props)) { + return new GssKrb5Client( + authorizationId, + protocol, + serverName, + props, + cbh); + } + } + return null; + }; + + public SaslServer createSaslServer(String mech, + String protocol, + String serverName, + Map props, + CallbackHandler cbh) throws SaslException { + if (mech.equals(myMechs[GSS_KERB_V5]) + && PolicyUtils.checkPolicy(mechPolicies[GSS_KERB_V5], props)) { + if (cbh == null) { + throw new SaslException( + "Callback handler with support for AuthorizeCallback required"); + } + return new GssKrb5Server( + protocol, + serverName, + props, + cbh); + } + return null; + }; + + public String[] getMechanismNames(Map props) { + return PolicyUtils.filterMechs(myMechs, mechPolicies, props); + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package com.sun.security.sasl.gsskerb; + +import java.util.Locale; +import java.util.Map; +import java.util.logging.Level; +import javax.security.sasl.*; +import com.sun.security.sasl.util.AbstractSaslImpl; +import org.ietf.jgss.*; +import com.sun.security.jgss.ExtendedGSSContext; +import com.sun.security.jgss.InquireType; + +abstract class GssKrb5Base extends AbstractSaslImpl { + + private static final String KRB5_OID_STR = "1.2.840.113554.1.2.2"; + protected static Oid KRB5_OID; + protected static final byte[] EMPTY = new byte[0]; + + static { + try { + KRB5_OID = new Oid(KRB5_OID_STR); + } catch (GSSException ignore) {} + } + + protected GSSContext secCtx = null; + protected static final int JGSS_QOP = 0; // unrelated to SASL QOP mask + + protected GssKrb5Base(Map props, String className) + throws SaslException { + super(props, className); + } + + /** + * Retrieves this mechanism's name. + * + * @return The string "GSSAPI". + */ + public String getMechanismName() { + return "GSSAPI"; + } + + @Override + public Object getNegotiatedProperty(String propName) { + if (!completed) { + throw new IllegalStateException("Authentication incomplete"); + } + String xprefix = "com.sun.security.jgss.inquiretype."; + if (propName.startsWith(xprefix)) { + String type = propName.substring(xprefix.length()); + if (logger.isLoggable(Level.FINEST)) { + logger.logp(Level.FINE, "GssKrb5Base", + "getNegotiatedProperty", propName); + } + for (InquireType t: InquireType.values()) { + if (t.name().toLowerCase(Locale.US).equals(type)) { + try { + return ((ExtendedGSSContext)secCtx).inquireSecContext(t); + } catch (GSSException e) { + if (logger.isLoggable(Level.FINEST)) { + logger.log(Level.WARNING, "inquireSecContext error", e); + } + return null; + } + } + } + // No such InquireType. Although not likely to be defined + // as a property in a parent class, still try it. + } + return super.getNegotiatedProperty(propName); + } + + public byte[] unwrap(byte[] incoming, int start, int len) + throws SaslException { + if (!completed) { + throw new IllegalStateException("GSSAPI authentication not completed"); + } + + // integrity will be true if either privacy or integrity negotiated + if (!integrity) { + throw new IllegalStateException("No security layer negotiated"); + } + + try { + MessageProp msgProp = new MessageProp(JGSS_QOP, privacy); + byte[] answer = secCtx.unwrap(incoming, start, len, msgProp); + if (logger.isLoggable(Level.FINEST)) { + traceOutput(myClassName, "KRB501:Unwrap", "incoming: ", + incoming, start, len); + traceOutput(myClassName, "KRB502:Unwrap", "unwrapped: ", + answer, 0, answer.length); + } + return answer; + } catch (GSSException e) { + throw new SaslException("Problems unwrapping SASL buffer", e); + } + } + + public byte[] wrap(byte[] outgoing, int start, int len) throws SaslException { + if (!completed) { + throw new IllegalStateException("GSSAPI authentication not completed"); + } + + // integrity will be true if either privacy or integrity negotiated + if (!integrity) { + throw new IllegalStateException("No security layer negotiated"); + } + + // Generate GSS token + try { + MessageProp msgProp = new MessageProp(JGSS_QOP, privacy); + byte[] answer = secCtx.wrap(outgoing, start, len, msgProp); + if (logger.isLoggable(Level.FINEST)) { + traceOutput(myClassName, "KRB503:Wrap", "outgoing: ", + outgoing, start, len); + traceOutput(myClassName, "KRB504:Wrap", "wrapped: ", + answer, 0, answer.length); + } + return answer; + + } catch (GSSException e) { + throw new SaslException("Problem performing GSS wrap", e); + } + } + + public void dispose() throws SaslException { + if (secCtx != null) { + try { + secCtx.dispose(); + } catch (GSSException e) { + throw new SaslException("Problem disposing GSS context", e); + } + secCtx = null; + } + } + + protected void finalize() throws Throwable { + dispose(); + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.security.sasl.gsskerb; + +import java.io.IOException; +import java.util.Map; +import java.util.logging.Level; +import javax.security.sasl.*; + +// JAAS +import javax.security.auth.callback.CallbackHandler; + +// JGSS +import org.ietf.jgss.*; + +/** + * Implements the GSSAPI SASL client mechanism for Kerberos V5. + * (RFC 2222, + * draft-ietf-cat-sasl-gssapi-04.txt). + * It uses the Java Bindings for GSSAPI + * (RFC 2853) + * for getting GSSAPI/Kerberos V5 support. + * + * The client/server interactions are: + * C0: bind (GSSAPI, initial response) + * S0: sasl-bind-in-progress, challenge 1 (output of accept_sec_context or []) + * C1: bind (GSSAPI, response 1 (output of init_sec_context or [])) + * S1: sasl-bind-in-progress challenge 2 (security layer, server max recv size) + * C2: bind (GSSAPI, response 2 (security layer, client max recv size, authzid)) + * S2: bind success response + * + * Expects the client's credentials to be supplied from the + * javax.security.sasl.credentials property or from the thread's Subject. + * Otherwise the underlying KRB5 mech will attempt to acquire Kerberos creds + * by logging into Kerberos (via default TextCallbackHandler). + * These creds will be used for exchange with server. + * + * Required callbacks: none. + * + * Environment properties that affect behavior of implementation: + * + * javax.security.sasl.qop + * - quality of protection; list of auth, auth-int, auth-conf; default is "auth" + * javax.security.sasl.maxbuf + * - max receive buffer size; default is 65536 + * javax.security.sasl.sendmaxbuffer + * - max send buffer size; default is 65536; (min with server max recv size) + * + * javax.security.sasl.server.authentication + * - "true" means require mutual authentication; default is "false" + * + * javax.security.sasl.credentials + * - an {@link org.ietf.jgss.GSSCredential} used for delegated authentication. + * + * @author Rosanna Lee + */ + +final class GssKrb5Client extends GssKrb5Base implements SaslClient { + // ---------------- Constants ----------------- + private static final String MY_CLASS_NAME = GssKrb5Client.class.getName(); + + private boolean finalHandshake = false; + private boolean mutual = false; // default false + private byte[] authzID; + + /** + * Creates a SASL mechanism with client credentials that it needs + * to participate in GSS-API/Kerberos v5 authentication exchange + * with the server. + */ + GssKrb5Client(String authzID, String protocol, String serverName, + Map props, CallbackHandler cbh) throws SaslException { + + super(props, MY_CLASS_NAME); + + String service = protocol + "@" + serverName; + logger.log(Level.FINE, "KRB5CLNT01:Requesting service name: {0}", + service); + + try { + GSSManager mgr = GSSManager.getInstance(); + + // Create the name for the requested service entity for Krb5 mech + GSSName acceptorName = mgr.createName(service, + GSSName.NT_HOSTBASED_SERVICE, KRB5_OID); + + // Parse properties to check for supplied credentials + GSSCredential credentials = null; + if (props != null) { + Object prop = props.get(Sasl.CREDENTIALS); + if (prop != null && prop instanceof GSSCredential) { + credentials = (GSSCredential) prop; + logger.log(Level.FINE, + "KRB5CLNT01:Using the credentials supplied in " + + "javax.security.sasl.credentials"); + } + } + + // Create a context using credentials for Krb5 mech + secCtx = mgr.createContext(acceptorName, + KRB5_OID, /* mechanism */ + credentials, /* credentials */ + GSSContext.INDEFINITE_LIFETIME); + + // Request credential delegation when credentials have been supplied + if (credentials != null) { + secCtx.requestCredDeleg(true); + } + + // Parse properties to set desired context options + if (props != null) { + // Mutual authentication + String prop = (String)props.get(Sasl.SERVER_AUTH); + if (prop != null) { + mutual = "true".equalsIgnoreCase(prop); + } + } + secCtx.requestMutualAuth(mutual); + + // Always specify potential need for integrity and confidentiality + // Decision will be made during final handshake + secCtx.requestConf(true); + secCtx.requestInteg(true); + + } catch (GSSException e) { + throw new SaslException("Failure to initialize security context", e); + } + + if (authzID != null && authzID.length() > 0) { + try { + this.authzID = authzID.getBytes("UTF8"); + } catch (IOException e) { + throw new SaslException("Cannot encode authorization ID", e); + } + } + } + + public boolean hasInitialResponse() { + return true; + } + + /** + * Processes the challenge data. + * + * The server sends a challenge data using which the client must + * process using GSS_Init_sec_context. + * As per RFC 2222, when GSS_S_COMPLETE is returned, we do + * an extra handshake to determine the negotiated security protection + * and buffer sizes. + * + * @param challengeData A non-null byte array containing the + * challenge data from the server. + * @return A non-null byte array containing the response to be + * sent to the server. + */ + public byte[] evaluateChallenge(byte[] challengeData) throws SaslException { + if (completed) { + throw new IllegalStateException( + "GSSAPI authentication already complete"); + } + + if (finalHandshake) { + return doFinalHandshake(challengeData); + } else { + + // Security context not established yet; continue with init + + try { + byte[] gssOutToken = secCtx.initSecContext(challengeData, + 0, challengeData.length); + if (logger.isLoggable(Level.FINER)) { + traceOutput(MY_CLASS_NAME, "evaluteChallenge", + "KRB5CLNT02:Challenge: [raw]", challengeData); + traceOutput(MY_CLASS_NAME, "evaluateChallenge", + "KRB5CLNT03:Response: [after initSecCtx]", gssOutToken); + } + + if (secCtx.isEstablished()) { + finalHandshake = true; + if (gssOutToken == null) { + // RFC 2222 7.2.1: Client responds with no data + return EMPTY; + } + } + + return gssOutToken; + } catch (GSSException e) { + throw new SaslException("GSS initiate failed", e); + } + } + } + + private byte[] doFinalHandshake(byte[] challengeData) throws SaslException { + try { + // Security context already established. challengeData + // should contain security layers and server's maximum buffer size + + if (logger.isLoggable(Level.FINER)) { + traceOutput(MY_CLASS_NAME, "doFinalHandshake", + "KRB5CLNT04:Challenge [raw]:", challengeData); + } + + if (challengeData.length == 0) { + // Received S0, should return [] + return EMPTY; + } + + // Received S1 (security layer, server max recv size) + + byte[] gssOutToken = secCtx.unwrap(challengeData, 0, + challengeData.length, new MessageProp(0, false)); + + // First octet is a bit-mask specifying the protections + // supported by the server + if (logger.isLoggable(Level.FINE)) { + if (logger.isLoggable(Level.FINER)) { + traceOutput(MY_CLASS_NAME, "doFinalHandshake", + "KRB5CLNT05:Challenge [unwrapped]:", gssOutToken); + } + logger.log(Level.FINE, "KRB5CLNT06:Server protections: {0}", + gssOutToken[0]); + } + + // Client selects preferred protection + // qop is ordered list of qop values + byte selectedQop = findPreferredMask(gssOutToken[0], qop); + if (selectedQop == 0) { + throw new SaslException( + "No common protection layer between client and server"); + } + + if ((selectedQop&PRIVACY_PROTECTION) != 0) { + privacy = true; + integrity = true; + } else if ((selectedQop&INTEGRITY_ONLY_PROTECTION) != 0) { + integrity = true; + } + + // 2nd-4th octets specifies maximum buffer size expected by + // server (in network byte order) + int srvMaxBufSize = networkByteOrderToInt(gssOutToken, 1, 3); + + // Determine the max send buffer size based on what the + // server is able to receive and our specified max + sendMaxBufSize = (sendMaxBufSize == 0) ? srvMaxBufSize : + Math.min(sendMaxBufSize, srvMaxBufSize); + + // Update context to limit size of returned buffer + rawSendSize = secCtx.getWrapSizeLimit(JGSS_QOP, privacy, + sendMaxBufSize); + + if (logger.isLoggable(Level.FINE)) { + logger.log(Level.FINE, +"KRB5CLNT07:Client max recv size: {0}; server max recv size: {1}; rawSendSize: {2}", + new Object[] {recvMaxBufSize, + srvMaxBufSize, + rawSendSize}); + } + + // Construct negotiated security layers and client's max + // receive buffer size and authzID + int len = 4; + if (authzID != null) { + len += authzID.length; + } + + byte[] gssInToken = new byte[len]; + gssInToken[0] = selectedQop; + + if (logger.isLoggable(Level.FINE)) { + logger.log(Level.FINE, + "KRB5CLNT08:Selected protection: {0}; privacy: {1}; integrity: {2}", + new Object[]{selectedQop, + Boolean.valueOf(privacy), + Boolean.valueOf(integrity)}); + } + + intToNetworkByteOrder(recvMaxBufSize, gssInToken, 1, 3); + if (authzID != null) { + // copy authorization id + System.arraycopy(authzID, 0, gssInToken, 4, authzID.length); + logger.log(Level.FINE, "KRB5CLNT09:Authzid: {0}", authzID); + } + + if (logger.isLoggable(Level.FINER)) { + traceOutput(MY_CLASS_NAME, "doFinalHandshake", + "KRB5CLNT10:Response [raw]", gssInToken); + } + + gssOutToken = secCtx.wrap(gssInToken, + 0, gssInToken.length, + new MessageProp(0 /* qop */, false /* privacy */)); + + if (logger.isLoggable(Level.FINER)) { + traceOutput(MY_CLASS_NAME, "doFinalHandshake", + "KRB5CLNT11:Response [after wrap]", gssOutToken); + } + + completed = true; // server authenticated + + return gssOutToken; + } catch (GSSException e) { + throw new SaslException("Final handshake failed", e); + } + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.security.sasl.gsskerb; + +import javax.security.sasl.*; +import java.io.*; +import java.util.Map; +import java.util.logging.Level; + +// JAAS +import javax.security.auth.callback.*; + +// JGSS +import org.ietf.jgss.*; + +/** + * Implements the GSSAPI SASL server mechanism for Kerberos V5. + * (RFC 2222, + * draft-ietf-cat-sasl-gssapi-00.txt). + * + * Expects thread's Subject to contain server's Kerberos credentials + * - If not, underlying KRB5 mech will attempt to acquire Kerberos creds + * by logging into Kerberos (via default TextCallbackHandler). + * - These creds will be used for exchange with client. + * + * Required callbacks: + * - AuthorizeCallback + * handler must verify that authid/authzids are allowed and set + * authorized ID to be the canonicalized authzid (if applicable). + * + * Environment properties that affect behavior of implementation: + * + * javax.security.sasl.qop + * - quality of protection; list of auth, auth-int, auth-conf; default is "auth" + * javax.security.sasl.maxbuf + * - max receive buffer size; default is 65536 + * javax.security.sasl.sendmaxbuffer + * - max send buffer size; default is 65536; (min with client max recv size) + * + * @author Rosanna Lee + */ +final class GssKrb5Server extends GssKrb5Base implements SaslServer { + private static final String MY_CLASS_NAME = GssKrb5Server.class.getName(); + + private int handshakeStage = 0; + private String peer; + private String me; + private String authzid; + private CallbackHandler cbh; + + // When serverName is null, the server will be unbound. We need to save and + // check the protocol name after the context is established. This value + // will be null if serverName is not null. + private final String protocolSaved; + /** + * Creates a SASL mechanism with server credentials that it needs + * to participate in GSS-API/Kerberos v5 authentication exchange + * with the client. + */ + GssKrb5Server(String protocol, String serverName, + Map props, CallbackHandler cbh) throws SaslException { + + super(props, MY_CLASS_NAME); + + this.cbh = cbh; + + String service; + if (serverName == null) { + protocolSaved = protocol; + service = null; + } else { + protocolSaved = null; + service = protocol + "@" + serverName; + } + + logger.log(Level.FINE, "KRB5SRV01:Using service name: {0}", service); + + try { + GSSManager mgr = GSSManager.getInstance(); + + // Create the name for the requested service entity for Krb5 mech + GSSName serviceName = service == null ? null: + mgr.createName(service, GSSName.NT_HOSTBASED_SERVICE, KRB5_OID); + + GSSCredential cred = mgr.createCredential(serviceName, + GSSCredential.INDEFINITE_LIFETIME, + KRB5_OID, GSSCredential.ACCEPT_ONLY); + + // Create a context using the server's credentials + secCtx = mgr.createContext(cred); + + if ((allQop&INTEGRITY_ONLY_PROTECTION) != 0) { + // Might need integrity + secCtx.requestInteg(true); + } + + if ((allQop&PRIVACY_PROTECTION) != 0) { + // Might need privacy + secCtx.requestConf(true); + } + } catch (GSSException e) { + throw new SaslException("Failure to initialize security context", e); + } + logger.log(Level.FINE, "KRB5SRV02:Initialization complete"); + } + + + /** + * Processes the response data. + * + * The client sends response data to which the server must + * process using GSS_accept_sec_context. + * As per RFC 2222, the GSS authenication completes (GSS_S_COMPLETE) + * we do an extra hand shake to determine the negotiated security protection + * and buffer sizes. + * + * @param responseData A non-null but possible empty byte array containing the + * response data from the client. + * @return A non-null byte array containing the challenge to be + * sent to the client, or null when no more data is to be sent. + */ + public byte[] evaluateResponse(byte[] responseData) throws SaslException { + if (completed) { + throw new SaslException( + "SASL authentication already complete"); + } + + if (logger.isLoggable(Level.FINER)) { + traceOutput(MY_CLASS_NAME, "evaluateResponse", + "KRB5SRV03:Response [raw]:", responseData); + } + + switch (handshakeStage) { + case 1: + return doHandshake1(responseData); + + case 2: + return doHandshake2(responseData); + + default: + // Security context not established yet; continue with accept + + try { + byte[] gssOutToken = secCtx.acceptSecContext(responseData, + 0, responseData.length); + + if (logger.isLoggable(Level.FINER)) { + traceOutput(MY_CLASS_NAME, "evaluateResponse", + "KRB5SRV04:Challenge: [after acceptSecCtx]", gssOutToken); + } + + if (secCtx.isEstablished()) { + handshakeStage = 1; + + peer = secCtx.getSrcName().toString(); + me = secCtx.getTargName().toString(); + + logger.log(Level.FINE, + "KRB5SRV05:Peer name is : {0}, my name is : {1}", + new Object[]{peer, me}); + + // me might take the form of proto@host or proto/host + if (protocolSaved != null && + !protocolSaved.equalsIgnoreCase(me.split("[/@]")[0])) { + throw new SaslException( + "GSS context targ name protocol error: " + me); + } + + if (gssOutToken == null) { + return doHandshake1(EMPTY); + } + } + + return gssOutToken; + } catch (GSSException e) { + throw new SaslException("GSS initiate failed", e); + } + } + } + + private byte[] doHandshake1(byte[] responseData) throws SaslException { + try { + // Security context already established. responseData + // should contain no data + if (responseData != null && responseData.length > 0) { + throw new SaslException( + "Handshake expecting no response data from server"); + } + + // Construct 4 octets of data: + // First octet contains bitmask specifying protections supported + // 2nd-4th octets contains max receive buffer of server + + byte[] gssInToken = new byte[4]; + gssInToken[0] = allQop; + intToNetworkByteOrder(recvMaxBufSize, gssInToken, 1, 3); + + if (logger.isLoggable(Level.FINE)) { + logger.log(Level.FINE, + "KRB5SRV06:Supported protections: {0}; recv max buf size: {1}", + new Object[]{allQop, + recvMaxBufSize}); + } + + handshakeStage = 2; // progress to next stage + + if (logger.isLoggable(Level.FINER)) { + traceOutput(MY_CLASS_NAME, "doHandshake1", + "KRB5SRV07:Challenge [raw]", gssInToken); + } + + byte[] gssOutToken = secCtx.wrap(gssInToken, 0, gssInToken.length, + new MessageProp(0 /* gop */, false /* privacy */)); + + if (logger.isLoggable(Level.FINER)) { + traceOutput(MY_CLASS_NAME, "doHandshake1", + "KRB5SRV08:Challenge [after wrap]", gssOutToken); + } + return gssOutToken; + + } catch (GSSException e) { + throw new SaslException("Problem wrapping handshake1", e); + } + } + + private byte[] doHandshake2(byte[] responseData) throws SaslException { + try { + // Expecting 4 octets from client selected protection + // and client's receive buffer size + byte[] gssOutToken = secCtx.unwrap(responseData, 0, + responseData.length, new MessageProp(0, false)); + + if (logger.isLoggable(Level.FINER)) { + traceOutput(MY_CLASS_NAME, "doHandshake2", + "KRB5SRV09:Response [after unwrap]", gssOutToken); + } + + // First octet is a bit-mask specifying the selected protection + byte selectedQop = gssOutToken[0]; + if ((selectedQop&allQop) == 0) { + throw new SaslException("Client selected unsupported protection: " + + selectedQop); + } + if ((selectedQop&PRIVACY_PROTECTION) != 0) { + privacy = true; + integrity = true; + } else if ((selectedQop&INTEGRITY_ONLY_PROTECTION) != 0) { + integrity = true; + } + + // 2nd-4th octets specifies maximum buffer size expected by + // client (in network byte order). This is the server's send + // buffer maximum. + int clntMaxBufSize = networkByteOrderToInt(gssOutToken, 1, 3); + + // Determine the max send buffer size based on what the + // client is able to receive and our specified max + sendMaxBufSize = (sendMaxBufSize == 0) ? clntMaxBufSize : + Math.min(sendMaxBufSize, clntMaxBufSize); + + // Update context to limit size of returned buffer + rawSendSize = secCtx.getWrapSizeLimit(JGSS_QOP, privacy, + sendMaxBufSize); + + if (logger.isLoggable(Level.FINE)) { + logger.log(Level.FINE, + "KRB5SRV10:Selected protection: {0}; privacy: {1}; integrity: {2}", + new Object[]{selectedQop, + Boolean.valueOf(privacy), + Boolean.valueOf(integrity)}); + logger.log(Level.FINE, +"KRB5SRV11:Client max recv size: {0}; server max send size: {1}; rawSendSize: {2}", + new Object[] {clntMaxBufSize, + sendMaxBufSize, + rawSendSize}); + } + + // Get authorization identity, if any + if (gssOutToken.length > 4) { + try { + authzid = new String(gssOutToken, 4, + gssOutToken.length - 4, "UTF-8"); + } catch (UnsupportedEncodingException uee) { + throw new SaslException ("Cannot decode authzid", uee); + } + } else { + authzid = peer; + } + logger.log(Level.FINE, "KRB5SRV12:Authzid: {0}", authzid); + + AuthorizeCallback acb = new AuthorizeCallback(peer, authzid); + + // In Kerberos, realm is embedded in peer name + cbh.handle(new Callback[] {acb}); + if (acb.isAuthorized()) { + authzid = acb.getAuthorizedID(); + completed = true; + } else { + // Authorization failed + throw new SaslException(peer + + " is not authorized to connect as " + authzid); + } + + return null; + } catch (GSSException e) { + throw new SaslException("Final handshake step failed", e); + } catch (IOException e) { + throw new SaslException("Problem with callback handler", e); + } catch (UnsupportedCallbackException e) { + throw new SaslException("Problem with callback handler", e); + } + } + + public String getAuthorizationID() { + if (completed) { + return authzid; + } else { + throw new IllegalStateException("Authentication incomplete"); + } + } + + public Object getNegotiatedProperty(String propName) { + if (!completed) { + throw new IllegalStateException("Authentication incomplete"); + } + + Object result; + switch (propName) { + case Sasl.BOUND_SERVER_NAME: + try { + // me might take the form of proto@host or proto/host + result = me.split("[/@]")[1]; + } catch (Exception e) { + result = null; + } + break; + default: + result = super.getNegotiatedProperty(propName); + } + return result; + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/test/ProblemList.txt --- a/jdk/test/ProblemList.txt Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/ProblemList.txt Fri Sep 19 11:19:38 2014 -0700 @@ -139,16 +139,6 @@ com/sun/management/OperatingSystemMXBean/GetSystemCpuLoad.java aix-all javax/management/MBeanServer/OldMBeanServerTest.java aix-all -# 8050115 -javax/management/monitor/GaugeMonitorDeadlockTest.java generic-all - -# 8042205 8057951 generic-all -javax/management/monitor/CounterMonitorTest.java -javax/management/monitor/NonComparableAttributeValueTest.java -javax/management/monitor/ReflectionExceptionTest.java -javax/management/monitor/RuntimeExceptionTest.java -javax/management/monitor/AttributeArbitraryDataTypeTest.java - ############################################################################ # jdk_math diff -r 66228a695a62 -r 00b27213d86c jdk/test/TEST.ROOT --- a/jdk/test/TEST.ROOT Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/TEST.ROOT Fri Sep 19 11:19:38 2014 -0700 @@ -8,7 +8,7 @@ othervm.dirs=java/awt java/beans javax/accessibility javax/imageio javax/sound javax/print javax/management com/sun/awt sun/awt sun/java2d sun/pisces # Tests that cannot run concurrently -exclusiveAccess.dirs=java/rmi/Naming java/util/prefs sun/management/jmxremote sun/tools/jstatd sun/security/mscapi +exclusiveAccess.dirs=java/rmi/Naming java/util/prefs sun/management/jmxremote sun/tools/jstatd sun/security/mscapi java/util/stream # Group definitions groups=TEST.groups [closed/TEST.groups] diff -r 66228a695a62 -r 00b27213d86c jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java --- a/jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java Fri Sep 19 11:19:38 2014 -0700 @@ -26,18 +26,18 @@ * @bug 8046703 * @summary Test verifies that lambda forms are garbage collected * @author kshefov + * @ignore 8057020 * @library /lib/testlibrary/jsr292 /lib/testlibrary * @build TestMethods * @build LambdaFormTestCase * @build LFGarbageCollectedTest - * @run main/othervm/timeout=600 -Djava.lang.invoke.MethodHandle.USE_LF_EDITOR=true -DtestLimit=150 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI LFGarbageCollectedTest + * @run main/othervm/timeout=600 -Djava.lang.invoke.MethodHandle.USE_LF_EDITOR=true -DtestLimit=150 LFGarbageCollectedTest */ import java.lang.invoke.MethodHandle; import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; import java.util.EnumSet; import java.util.Map; @@ -93,10 +93,16 @@ * @param args Accepts no arguments. */ public static void main(String[] args) { - // The "identity" and "constant" methods should be removed from this test, - // because their lambda forms are stored in a static filed and are not GC'ed. - // There can be only 5 such LFs for each method, so no memory leak happens. - EnumSet testMethods = EnumSet.complementOf(EnumSet.of(TestMethods.IDENTITY, TestMethods.CONSTANT)); + // The "identity", "constant", "arrayElementGetter" and "arrayElementSetter" + // methods should be removed from this test, + // because their lambda forms are stored in a static field and are not GC'ed. + // There can be only a finite number of such LFs for each method, + // so no memory leak happens. + EnumSet testMethods = EnumSet.complementOf(EnumSet.of( + TestMethods.IDENTITY, + TestMethods.CONSTANT, + TestMethods.ARRAY_ELEMENT_GETTER, + TestMethods.ARRAY_ELEMENT_SETTER)); LambdaFormTestCase.runTests(LFGarbageCollectedTest::new, testMethods); } } diff -r 66228a695a62 -r 00b27213d86c jdk/test/java/lang/invoke/lambda/LUtils.java --- a/jdk/test/java/lang/invoke/lambda/LUtils.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/java/lang/invoke/lambda/LUtils.java Fri Sep 19 11:19:38 2014 -0700 @@ -37,8 +37,6 @@ * support infrastructure to invoke a java class from the command line */ class LUtils { - static final sun.tools.jar.Main jarTool = - new sun.tools.jar.Main(System.out, System.err, "jar-tool"); static final com.sun.tools.javac.Main javac = new com.sun.tools.javac.Main(); static final File cwd = new File(".").getAbsoluteFile(); @@ -49,6 +47,10 @@ static final File JAVA_BIN_FILE = new File(JAVAHOME, "bin"); static final File JAVA_CMD = new File(JAVA_BIN_FILE, isWindows ? "java.exe" : "java"); + static final File JAR_BIN_FILE = + new File(new File(JAVAHOME).getParentFile(), "bin"); + static final File JAR_CMD = new File(JAR_BIN_FILE, + isWindows ? "jar.exe" : "jar"); protected LUtils() { } diff -r 66228a695a62 -r 00b27213d86c jdk/test/java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java --- a/jdk/test/java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java Fri Sep 19 11:19:38 2014 -0700 @@ -67,12 +67,17 @@ compile(javacArgs); File jarFile = new File("foo.jar"); String[] jargs = {"cvf", jarFile.getName(), doprivClass.getName()}; - jarTool.run(jargs); + TestResult tr = doExec(JAR_CMD.getAbsolutePath(), + "cvf", jarFile.getName(), + doprivClass.getName()); + if (tr.exitValue != 0){ + throw new RuntimeException(tr.toString()); + } doprivJava.delete(); doprivClass.delete(); - TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), - "-Xbootclasspath/p:foo.jar", - "-cp", ".", "Bar"); + tr = doExec(JAVA_CMD.getAbsolutePath(), + "-Xbootclasspath/p:foo.jar", + "-cp", ".", "Bar"); tr.assertZero("testDoPrivileged fails"); barJava.delete(); barClass.delete(); diff -r 66228a695a62 -r 00b27213d86c jdk/test/java/math/BigDecimal/ZeroScalingTests.java --- a/jdk/test/java/math/BigDecimal/ZeroScalingTests.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/java/math/BigDecimal/ZeroScalingTests.java Fri Sep 19 11:19:38 2014 -0700 @@ -23,8 +23,10 @@ /* * @test - * @bug 4902952 4905407 4916149 - * @summary Tests that the scale of zero is propagated properly and has the proper effect. + * @bug 4902952 4905407 4916149 8057793 + * @summary Tests that the scale of zero is propagated properly and has the + * proper effect and that setting the scale to zero does not mutate the + * BigDecimal. * @author Joseph D. Darcy */ @@ -445,6 +447,16 @@ return failures; } + static int setScaleDoesNotMutateTest() { + BigDecimal total = new BigDecimal("258815507198903607775511093103396443816569106750031264155319238473795838680758514810110764742309284477206138527975952150289602995045050194333030191178778772026538699925775139201970526695485362661420908248887297829319881475178467494779683293036572059595504702727301324759997409522995072582369210284334718757260859794972695026582432867589093687280300148141501712013226636373167978223780290547640482160818746599330924736802844173226042389174403401903999447463440670236056324929325189403433689" + + ".426167432065785331444814035799717606745777287606858873045971898862329763544687891847664736523584843544347118836628373041412918374550458884706686730726101338872517021688769782894793734049819222924171842793485919753186993388451909096042127903835765393729547730953942175461146061715108701615615142134282261293656760570061554783195726716403304101469782303957325142638493327692352838806741611887655695029948975509680496573999174402058593454203190963443179532640446352828089016874853634851387762579319853267317320515941105912189838719919259277721994880193541634872882180184303434360412344059435559680494807415573269199203376126242271766939666939316648575065702750502798973418978204972336924254702551350654650573582614211506856383897692911422458286912085339575875324832979140870119455620532272318122103640233069115700020760625493816902806241630788230268031695140687964931377988962507263990468276009750998066442971308866347136022907166625330623130307555914930120150437900510530537258665172619821272937026713977709974434967165159545592482710663639966781678268622620229577009317698254134914742098420792313931843709810905414336383757407675429663714210967924767434203021205270369316797752411974617662200898086335322218191674846795163102021505555508444216708745911194321674887527227200297039471799580744303346354057273540730643842091810899490590914195225087593013834388801018488174855060306804024894292757613618190472234110859436472645203753139820658279559340251226992556744343475086923568365637919479462424794554522865559888240039662899509652221329892034706445253487898044421278283079233226845124525434586324657471286953226255430662125870993375281512713207125720748163498642795960457639954616530163959004770092547297392499137383176609646505351001304840762905826237024982330597805063521162285806541220110524989649256399233792799406995068469271941269511818994954109392839548141262324660472253632382325038836831429045617036015122388070240133760858500132713255407855625837956886349324981003917084922808187223285051144454915441134217743066575863563572152133978905444998209075763950909784148142018992367290485890072303179512881131769414783097454103103347826517701720263541869335631166977965013552647906729408522950996105479525445916501155305220090853891226367184989434453290788068397817927893708837722255115237672194162924260945492012622891770365546831236789867922136747819364833843397165107825773447549885351449899330007200651144003961228091210630807333236718793283427788965479074476288255387824982443633190938302785760754436525586544523339170400053128503337395428393881357669568532722167493096151221381017320147344991331421789379785964440840684363041795410525097564979585773948558651896834067324427900848255265001498890329859444233861478388742393060996236783742654761350763876989363052609107226398858310051497856931093693697981165801539060516895227818925342535261227134364063673285588256280386915163875872231395348293505967057794409379709079685798908660258077792158532257603211711587587586356431658240229896344639704"); + if (total.setScale(0, RoundingMode.DOWN).equals(total.setScale(0, RoundingMode.DOWN))) { + return 0; + } else { + return 1; + } + } + public static void main(String argv[]) { int failures = 0; @@ -455,6 +467,7 @@ failures += setScaleTests(); failures += toEngineeringStringTests(); failures += ulpTests(); + failures += setScaleDoesNotMutateTest(); if (failures > 0 ) { throw new RuntimeException("Incurred " + failures + " failures" + diff -r 66228a695a62 -r 00b27213d86c jdk/test/java/math/BigInteger/BigIntegerTest.java --- a/jdk/test/java/math/BigInteger/BigIntegerTest.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/java/math/BigInteger/BigIntegerTest.java Fri Sep 19 11:19:38 2014 -0700 @@ -71,6 +71,7 @@ static final int BITS_TOOM_COOK_SQUARE = 6912; static final int BITS_SCHOENHAGE_BASE = 640; static final int BITS_BURNIKEL_ZIEGLER = 2560; + static final int BITS_BURNIKEL_ZIEGLER_OFFSET = 1280; static final int ORDER_SMALL = 60; static final int ORDER_MEDIUM = 100; @@ -288,19 +289,19 @@ * where {@code abs(u) > abs(v)} and {@code a > b && b > 0}, then if * {@code w/z = q1*z + r1} and {@code u/v = q2*v + r2}, then * {@code q1 = q2*pow(2,a-b)} and {@code r1 = r2*pow(2,b)}. The test - * ensures that {@code v} is just under the B-Z threshold and that {@code w} - * and {@code z} are both over the threshold. This implies that {@code u/v} - * uses the standard division algorithm and {@code w/z} uses the B-Z - * algorithm. The results of the two algorithms are then compared using the - * observation described in the foregoing and if they are not equal a - * failure is logged. + * ensures that {@code v} is just under the B-Z threshold, that {@code z} is + * over the threshold and {@code w} is much larger than {@code z}. This + * implies that {@code u/v} uses the standard division algorithm and + * {@code w/z} uses the B-Z algorithm. The results of the two algorithms + * are then compared using the observation described in the foregoing and + * if they are not equal a failure is logged. */ public static void divideLarge() { int failCount = 0; - BigInteger base = BigInteger.ONE.shiftLeft(BITS_BURNIKEL_ZIEGLER - 33); + BigInteger base = BigInteger.ONE.shiftLeft(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 33); for (int i=0; i) () -> null, acc, null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void test2() { + AccessController.doPrivileged( + (PrivilegedAction) () -> null, acc, p1, null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void test3() { + AccessController.doPrivilegedWithCombiner( + (PrivilegedAction) () -> null, acc, null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void test4() { + AccessController.doPrivilegedWithCombiner( + (PrivilegedAction) () -> null, acc, p1, null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void test5() throws PrivilegedActionException { + AccessController.doPrivileged( + (PrivilegedExceptionAction) () -> null, + acc, null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void test6() throws PrivilegedActionException { + AccessController.doPrivileged( + (PrivilegedExceptionAction) () -> null, + acc, p1, null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void test7() throws PrivilegedActionException { + AccessController.doPrivilegedWithCombiner( + (PrivilegedExceptionAction) () -> null, + acc, null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void test8() throws PrivilegedActionException { + AccessController.doPrivilegedWithCombiner( + (PrivilegedExceptionAction) () -> null, + acc, p1, null); + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/test/java/security/AccessController/LimitedDoPrivilegedWithThread.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/AccessController/LimitedDoPrivilegedWithThread.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013,2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8050281 + * @summary Test limited doprivileged action with trhead calls. + * @run main/othervm/policy=policy LimitedDoPrivilegedWithThread + */ +import java.io.FilePermission; +import java.security.AccessControlContext; +import java.security.AccessControlException; +import java.security.AccessController; +import java.security.Permission; +import java.security.PrivilegedAction; +import java.security.ProtectionDomain; +import java.util.PropertyPermission; + +public class LimitedDoPrivilegedWithThread { + + private static final Permission PROPERTYPERM + = new PropertyPermission("user.name", "read"); + private static final Permission FILEPERM + = new FilePermission("*", "read"); + private static final AccessControlContext ACC + = new AccessControlContext( + new ProtectionDomain[]{new ProtectionDomain(null, null)}); + + public static void main(String args[]) { + //parent thread without any permission + AccessController.doPrivileged( + (PrivilegedAction) () -> { + Thread ct = new Thread( + new ChildThread(PROPERTYPERM, FILEPERM)); + ct.start(); + try { + ct.join(); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + ie.printStackTrace(); + throw new RuntimeException("Unexpected InterruptedException"); + } + return null; + }, ACC); + } +} + +class ChildThread implements Runnable { + + private final Permission P1; + private final Permission P2; + private boolean catchACE = false; + + public ChildThread(Permission p1, Permission p2) { + this.P1 = p1; + this.P2 = p2; + } + + @Override + public void run() { + //Verified that child thread has permission p1, + runTest(null, P1, false, 1); + //Verified that child thread inherits parent thread's access control context + AccessControlContext childAcc = AccessController.getContext(); + runTest(childAcc, P1, true, 2); + //Verified that we can give permision p2 to limit the "privilege" of the + //class calling doprivileged action, stack walk will continue + runTest(null, P2, true, 3); + + } + + public void runTest(AccessControlContext acc, Permission perm, + boolean expectACE, int id) { + + AccessController.doPrivileged( + (PrivilegedAction) () -> { + try { + AccessController.getContext().checkPermission(P1); + } catch (AccessControlException ace) { + catchACE = true; + } + if (catchACE ^ expectACE) { + throw new RuntimeException("test" + id + " failed"); + } + return null; + }, acc, perm); + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/test/java/security/AccessController/policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/AccessController/policy Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,4 @@ +grant{ + permission java.util.PropertyPermission "user.name", "read"; + permission java.io.FilePermission "*", "read"; +}; diff -r 66228a695a62 -r 00b27213d86c jdk/test/java/security/spec/PKCS8EncodedKeySpec/Algorithm.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/spec/PKCS8EncodedKeySpec/Algorithm.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8047223 + * @summary Add algorithm parameter to PKCS8EncodedKeySpec class + */ +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Base64; +import javax.crypto.EncryptedPrivateKeyInfo; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + +public class Algorithm { + + private static String PKCS8PrivateKey = + "MIICoTAbBgkqhkiG9w0BBQMwDgQIqQMPwbNEhOgCAggABIICgCwRkeLXVGdO7S1h\n" + + "FAFUiwj1HCzqYFF2x9+FzjlXNwEWecZsor5eoKQlTtJ9dsPajQ/wFgY76lkXDQXE\n" + + "hdm8ndWFgCwqFBshmAp4TOvO9GlaAloDTnLMUg715D5FujiElcV7vqIY2V/7uB21\n" + + "YRanKUa21sZAFJGj6Hom1+5+k0Q7Xi4kHgt+ZIPNLwrNFPWVovbTJdScZuJaDp6m\n" + + "Q1DJUIQOzthV11VI+MU/v5SSKhj/uCaxizazEi5lgdmR7rRGgMz2YipOIjXIsKgu\n" + + "jKX5LYFAZ8nYq1hy8Q1JPR5VPuWMFqeyofO/teXJb8gI/4TC1ZoED8hXj07jpJqG\n" + + "2NVO1Dwqab31qSAjfjBkSYHKun63BvZPq2mT+frJF1YzvQhCDnWN1zbMKFNTZJfd\n" + + "cUaecH/fgNKwKpeKGgX7UlWxo26/lS8pBiJ5ihtbyFfMUBtlwEN5uOHqVFOeZp1Z\n" + + "DwCc0o1JA7yOcazA2TtNT9pc58tFZ8pEeyLj7ZchOgv06N0hZJsI6AiwII4ljd+K\n" + + "4WKvs/xiSZU3tcHaWzqlf+6/M5kC3Pihm9GhZbKBmvrZYiKyTlJEeVI3pFRNSqbE\n" + + "nZUJgkmgzNT/ZfM2WsUJm03Rq0eNCU/FDscIZnCWSA6Bf/DJDQWmhMhg2QmTGzQM\n" + + "hw/vy77q7jxV67s36HGxxR1oe8uoZ2zugBBxHWEdqyQyrVwZXJukdjrc2S7pvMln\n" + + "/VSleEf91MEcDhztyhPSqlX+H95vMnVmh5oY2gwY+P0oD5Eki6/9K+BHfuqgtS4S\n" + + "LIna1iSyLr17pRO1lmNtvuCMwmUjeI8w3JhLmxxx//bl/WCAekqj3nMplrJHZ7xd\n" + + "6k0Stxo="; + + private static String keyAlg = "RSA"; + private static String password = "password"; + + /* + * This test checks that a PKCS8EncodedKeySpec is properly constructed + * from an encrypted private key and that the key algorithm name can be + * retrieved as expected. + */ + public static void main(String[] argv) throws Exception { + EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo( + Base64.getMimeDecoder().decode(PKCS8PrivateKey)); + PBEKeySpec pks = new PBEKeySpec(password.toCharArray()); + SecretKeyFactory skf = SecretKeyFactory.getInstance(epki.getAlgName()); + SecretKey sk = skf.generateSecret(pks); + PKCS8EncodedKeySpec keySpec = epki.getKeySpec(sk); + + // Get the key algorithm and make sure it's what we expect + String alg = keySpec.getAlgorithm(); + if (!alg.equals(keyAlg)) { + throw new Exception("Expected: " + keyAlg + ", Got: " + alg); + } + + System.out.println("Test passed"); + } +} diff -r 66228a695a62 -r 00b27213d86c jdk/test/java/sql/test/sql/TimestampTests.java --- a/jdk/test/java/sql/test/sql/TimestampTests.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/java/sql/test/sql/TimestampTests.java Fri Sep 19 11:19:38 2014 -0700 @@ -27,14 +27,40 @@ import java.sql.Timestamp; import java.time.Instant; import java.time.LocalDateTime; +import java.time.ZoneId; import java.util.Calendar; +import java.util.TimeZone; import static org.testng.Assert.*; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import util.BaseTest; public class TimestampTests extends BaseTest { + private static TimeZone defaultTimeZone = null; + + /* + * Need to set and use a custom TimeZone which does not + * observe daylight savings time for this test. + */ + @BeforeClass + public static void setUpClass() throws Exception { + defaultTimeZone = TimeZone.getDefault(); + TimeZone tzone = TimeZone.getTimeZone("GMT+01"); + assertFalse(tzone.observesDaylightTime()); + TimeZone.setDefault(tzone); + } + + /* + * Conservatively reset the default time zone after test. + */ + @AfterClass + public static void tearDownClass() throws Exception { + TimeZone.setDefault(defaultTimeZone); + } + /* * Validate an IllegalArgumentException is thrown for an invalid Timestamp */ @@ -610,6 +636,12 @@ "Error with Nanos"); } + @Test(dataProvider = "validTimestampLongValues") + public void test52(long value, String ts) { + Timestamp ts1 = new Timestamp(value); + assertEquals(ts1.toString(), ts, "ts1.toString() != ts"); + } + /* * DataProvider used to provide Timestamps which are not valid and are used * to validate that an IllegalArgumentException will be thrown from the @@ -678,6 +710,40 @@ }; } + @DataProvider(name = "validTimestampLongValues") + private Object[][] validTimestampLongValues() { + return new Object[][]{ + {1L, "1970-01-01 01:00:00.001"}, + {-3600*1000L - 1, "1969-12-31 23:59:59.999"}, + {-(20000L*365*24*60*60*1000), "18018-08-28 01:00:00.0"}, + {Timestamp.valueOf("1961-08-30 11:22:33").getTime(), "1961-08-30 11:22:33.0"}, + {Timestamp.valueOf("1961-08-30 11:22:33.54321000").getTime(), "1961-08-30 11:22:33.543"}, // nanoprecision lost + {new Timestamp(114, 10, 10, 10, 10, 10, 100000000).getTime(), "2014-11-10 10:10:10.1"}, + {new Timestamp(0, 10, 10, 10, 10, 10, 100000).getTime(), "1900-11-10 10:10:10.0"}, // nanoprecision lost + {new Date(114, 10, 10).getTime(), "2014-11-10 00:00:00.0"}, + {new Date(0, 10, 10).getTime(), "1900-11-10 00:00:00.0"}, + {LocalDateTime.of(1960, 10, 10, 10, 10, 10, 50000).atZone(ZoneId.of("America/Los_Angeles")) + .toInstant().toEpochMilli(), "1960-10-10 19:10:10.0"}, + + // millisecond timestamps wraps around at year 1, so Long.MIN_VALUE looks similar + // Long.MAX_VALUE, while actually representing 292278994 BCE + {Long.MIN_VALUE, "292278994-08-17 08:12:55.192"}, + {Long.MAX_VALUE + 1, "292278994-08-17 08:12:55.192"}, + {Long.MAX_VALUE, "292278994-08-17 08:12:55.807"}, + {Long.MIN_VALUE - 1, "292278994-08-17 08:12:55.807"}, + + // wrap around point near 0001-01-01, test that we never get a negative year: + {-(1970L*365*24*60*60*1000), "0001-04-25 01:00:00.0"}, + {-(1970L*365*24*60*60*1000 + 115*24*60*60*1000L), "0001-12-31 01:00:00.0"}, + {-(1970L*365*24*60*60*1000 + 115*24*60*60*1000L - 23*60*60*1000L), "0001-01-01 00:00:00.0"}, + + {LocalDateTime.of(0, 1, 1, 10, 10, 10, 50000).atZone(ZoneId.of("America/Los_Angeles")) + .toInstant().toEpochMilli() - 2*24*60*60*1000L, "0001-01-01 19:03:08.0"}, // 1 BCE + {LocalDateTime.of(0, 1, 1, 10, 10, 10, 50000).atZone(ZoneId.of("America/Los_Angeles")) + .toInstant().toEpochMilli() - 3*24*60*60*1000L, "0002-12-31 19:03:08.0"} // 2 BCE + }; + } + /* * DataProvider used to provide Timestamp and Nanos values in order to * validate that the correct Nanos value is generated from the specified diff -r 66228a695a62 -r 00b27213d86c jdk/test/javax/management/monitor/AttributeArbitraryDataTypeTest.java --- a/jdk/test/javax/management/monitor/AttributeArbitraryDataTypeTest.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/javax/management/monitor/AttributeArbitraryDataTypeTest.java Fri Sep 19 11:19:38 2014 -0700 @@ -58,9 +58,9 @@ public class AttributeArbitraryDataTypeTest implements NotificationListener { // Flag to notify that a message has been received - private boolean counterMessageReceived = false; - private boolean gaugeMessageReceived = false; - private boolean stringMessageReceived = false; + private volatile boolean counterMessageReceived = false; + private volatile boolean gaugeMessageReceived = false; + private volatile boolean stringMessageReceived = false; // Match enum public enum Match { do_not_match_0, @@ -195,21 +195,33 @@ " has reached or exceeded the threshold"); echo("\t\tDerived Gauge = " + n.getDerivedGauge()); echo("\t\tTrigger = " + n.getTrigger()); - counterMessageReceived = true; + + synchronized (this) { + counterMessageReceived = true; + notifyAll(); + } } else if (type.equals(MonitorNotification. THRESHOLD_HIGH_VALUE_EXCEEDED)) { echo("\t\t" + n.getObservedAttribute() + " has reached or exceeded the high threshold"); echo("\t\tDerived Gauge = " + n.getDerivedGauge()); echo("\t\tTrigger = " + n.getTrigger()); - gaugeMessageReceived = true; + + synchronized (this) { + gaugeMessageReceived = true; + notifyAll(); + } } else if (type.equals(MonitorNotification. STRING_TO_COMPARE_VALUE_MATCHED)) { echo("\t\t" + n.getObservedAttribute() + " matches the string-to-compare value"); echo("\t\tDerived Gauge = " + n.getDerivedGauge()); echo("\t\tTrigger = " + n.getTrigger()); - stringMessageReceived = true; + + synchronized (this) { + stringMessageReceived = true; + notifyAll(); + } } else { echo("\t\tSkipping notification of type: " + type); } @@ -358,6 +370,17 @@ // Check if notification was received // + synchronized (this) { + while (!counterMessageReceived) { + try { + wait(); + } catch (InterruptedException e) { + System.err.println("Got unexpected exception: " + e); + e.printStackTrace(); + break; + } + } + } if (counterMessageReceived) { echo("\tOK: CounterMonitor notification received"); } else { @@ -525,6 +548,17 @@ // Check if notification was received // + synchronized (this) { + while (!gaugeMessageReceived) { + try { + wait(); + } catch (InterruptedException e) { + System.err.println("Got unexpected exception: " + e); + e.printStackTrace(); + break; + } + } + } if (gaugeMessageReceived) { echo("\tOK: GaugeMonitor notification received"); } else { @@ -680,6 +714,17 @@ // Check if notification was received // + synchronized (this) { + while (!stringMessageReceived) { + try { + wait(); + } catch (InterruptedException e) { + System.err.println("Got unexpected exception: " + e); + e.printStackTrace(); + break; + } + } + } if (stringMessageReceived) { echo("\tOK: StringMonitor notification received"); } else { diff -r 66228a695a62 -r 00b27213d86c jdk/test/javax/management/monitor/CounterMonitorTest.java --- a/jdk/test/javax/management/monitor/CounterMonitorTest.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/javax/management/monitor/CounterMonitorTest.java Fri Sep 19 11:19:38 2014 -0700 @@ -43,9 +43,6 @@ // modulus number private Number modulus = new Integer(7); - // offset number - private int offset = 0; - // difference mode flag private boolean differenceModeFlag = true; @@ -58,9 +55,6 @@ // counter values private int[] values = new int[] {4, 6, 9, 11}; - // time to wait for notification (in seconds) - private int timeout = 5; - // flag to notify that a message has been received private volatile boolean messageReceived = false; @@ -92,8 +86,9 @@ echo("\t\t" + n.getObservedAttribute() + " has reached or exceeded the threshold"); echo("\t\tDerived Gauge = " + n.getDerivedGauge()); - messageReceived = true; + synchronized (this) { + messageReceived = true; notifyAll(); } } else { @@ -205,22 +200,17 @@ } /* - * Wait until timeout reached + * Wait messageReceived to be true */ - void doWait() { - for (int i = 0; i < timeout; i++) { - echo("\tdoWait: Waiting for " + timeout + " seconds. " + - "i = " + i + ", messageReceived = " + messageReceived); - if (messageReceived) { + synchronized void doWait() { + while (!messageReceived) { + try { + wait(); + } catch (InterruptedException e) { + System.err.println("Got unexpected exception: " + e); + e.printStackTrace(); break; } - try { - synchronized (this) { - wait(1000); - } - } catch (InterruptedException e) { - // OK: Ignore... - } } } diff -r 66228a695a62 -r 00b27213d86c jdk/test/javax/management/monitor/GaugeMonitorDeadlockTest.java --- a/jdk/test/javax/management/monitor/GaugeMonitorDeadlockTest.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/javax/management/monitor/GaugeMonitorDeadlockTest.java Fri Sep 19 11:19:38 2014 -0700 @@ -36,8 +36,9 @@ */ import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; import java.util.concurrent.atomic.AtomicInteger; -import javax.management.Attribute; import javax.management.JMX; import javax.management.MBeanServer; import javax.management.Notification; @@ -47,10 +48,16 @@ import javax.management.monitor.GaugeMonitorMBean; public class GaugeMonitorDeadlockTest { + private static enum When {IN_GET_ATTRIBUTE, IN_NOTIFY}; + private static long checkingTime; public static void main(String[] args) throws Exception { if (args.length != 1) throw new Exception("Arg should be test number"); + double factor = Double.parseDouble(System.getProperty("test.timeout.factor", "1.0")); + checkingTime = (long)factor*1000; + System.out.println("=== checkingTime = " + checkingTime + "ms"); + int testNo = Integer.parseInt(args[0]) - 1; TestCase test = testCases[testNo]; System.out.println("Test: " + test.getDescription()); @@ -58,8 +65,6 @@ System.out.println("Test passed"); } - private static enum When {IN_GET_ATTRIBUTE, IN_NOTIFY}; - private static abstract class TestCase { TestCase(String description, When when) { this.description = description; @@ -98,16 +103,29 @@ monitorProxy.setNotifyLow(true); monitorProxy.start(); + System.out.println("=== Waiting observedProxy.getGetCount() to be " + + "changed, presumable deadlock if timeout?"); final int initGetCount = observedProxy.getGetCount(); - int getCount = initGetCount; - for (int i = 0; i < 2000; i++) { // 2000 * 10 = 20 seconds - getCount = observedProxy.getGetCount(); - if (getCount != initGetCount) - break; - Thread.sleep(10); + long checkedTime = System.currentTimeMillis(); + long nowTime; + ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); + while (observedProxy.getGetCount() == initGetCount) { + Thread.sleep(100); + + nowTime = System.currentTimeMillis(); + if (nowTime - checkedTime >= checkingTime) { + System.out.println("=== Checking deadlocked ..."); + if (threadMXBean.findDeadlockedThreads() != null) { + for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) { + System.out.println(info); + } + throw new Error("Found deadlocked threads: " + + threadMXBean.findDeadlockedThreads().length); + } + checkedTime = System.currentTimeMillis(); + } } - if (getCount <= initGetCount) - throw new Exception("Test failed: presumable deadlock"); + // This won't show up as a deadlock in CTRL-\ or in // ThreadMXBean.findDeadlockedThreads(), because they don't // see that thread A is waiting for thread B (B.join()), and @@ -117,13 +135,13 @@ // so if we want to test notify behaviour we can trigger by // exceeding the threshold. if (when == When.IN_NOTIFY) { + final Thread testedThread = new Thread(sensitiveThing); final AtomicInteger notifCount = new AtomicInteger(); final NotificationListener listener = new NotificationListener() { public void handleNotification(Notification n, Object h) { - Thread t = new Thread(sensitiveThing); - t.start(); + testedThread.start(); try { - t.join(); + testedThread.join(); } catch (InterruptedException e) { throw new RuntimeException(e); } @@ -132,12 +150,36 @@ }; mbs.addNotificationListener(monitorName, listener, null, null); observedProxy.setThing(1000); - for (int i = 0; i < 2000 && notifCount.get() == 0; i++) - Thread.sleep(10); - if (notifCount.get() == 0) - throw new Exception("Test failed: presumable deadlock"); + System.out.println("=== Waiting notifications, presumable " + + "deadlock if timeout?"); + long startTime = System.currentTimeMillis(); + checkedTime = startTime; + while (notifCount.get() == 0) { + Thread.sleep(100); + + nowTime = System.currentTimeMillis(); + if (nowTime - checkedTime >= checkingTime) { + System.out.println("=== Checking the thread state ..."); + if (testedThread.isAlive()) { + System.out.println("=== Waiting testedThread to die " + + "after " + (nowTime - startTime) + "ms"); + + ThreadInfo tinfo = threadMXBean.getThreadInfo(testedThread.getId()); + if (Thread.State.BLOCKED.equals(tinfo.getThreadState())) { + for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) { + System.out.println(info); + } + } else { + System.out.println(tinfo); + } + } else { + System.out.println("=== The testedThread is dead as wished, " + + "the test must be passed soon."); + } + checkedTime = System.currentTimeMillis(); + } + } } - } abstract void doSensitiveThing(GaugeMonitorMBean monitorProxy, diff -r 66228a695a62 -r 00b27213d86c jdk/test/javax/management/monitor/NonComparableAttributeValueTest.java --- a/jdk/test/javax/management/monitor/NonComparableAttributeValueTest.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/javax/management/monitor/NonComparableAttributeValueTest.java Fri Sep 19 11:19:38 2014 -0700 @@ -39,7 +39,7 @@ public class NonComparableAttributeValueTest implements NotificationListener { // Flag to notify that a message has been received - private boolean messageReceived = false; + private volatile boolean messageReceived = false; // MBean class public class ObservedObject implements ObservedObjectMBean { @@ -69,7 +69,11 @@ echo("\t\t" + n.getObservedAttribute() + " is null"); echo("\t\tDerived Gauge = " + n.getDerivedGauge()); echo("\t\tTrigger = " + n.getTrigger()); - messageReceived = true; + + synchronized (this) { + messageReceived = true; + notifyAll(); + } } else { echo("\t\tSkipping notification of type: " + type); } @@ -134,12 +138,9 @@ echo(">>> START the CounterMonitor"); counterMonitor.start(); - // Wait for granularity period (multiplied by 2 for sure) - // - Thread.sleep(granularityperiod * 2); - // Check if notification was received // + doWait(); if (messageReceived) { echo("\tOK: CounterMonitor notification received"); } else { @@ -212,12 +213,9 @@ echo(">>> START the GaugeMonitor"); gaugeMonitor.start(); - // Wait for granularity period (multiplied by 2 for sure) - // - Thread.sleep(granularityperiod * 2); - // Check if notification was received // + doWait(); if (messageReceived) { echo("\tOK: GaugeMonitor notification received"); } else { @@ -289,12 +287,9 @@ echo(">>> START the StringMonitor"); stringMonitor.start(); - // Wait for granularity period (multiplied by 2 for sure) - // - Thread.sleep(granularityperiod * 2); - // Check if notification was received // + doWait(); if (messageReceived) { echo("\tOK: StringMonitor notification received"); } else { @@ -334,6 +329,21 @@ } /* + * Wait messageReceived to be true + */ + synchronized void doWait() { + while (!messageReceived) { + try { + wait(); + } catch (InterruptedException e) { + System.err.println("Got unexpected exception: " + e); + e.printStackTrace(); + break; + } + } + } + + /* * Standalone entry point. * * Run the test and report to stdout. diff -r 66228a695a62 -r 00b27213d86c jdk/test/javax/management/monitor/ReflectionExceptionTest.java --- a/jdk/test/javax/management/monitor/ReflectionExceptionTest.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/javax/management/monitor/ReflectionExceptionTest.java Fri Sep 19 11:19:38 2014 -0700 @@ -87,7 +87,11 @@ echo("\tObservedAttribute: " + mn.getObservedAttribute()); echo("\tDerivedGauge: " + mn.getDerivedGauge()); echo("\tTrigger: " + mn.getTrigger()); - messageReceived = true; + + synchronized (this) { + messageReceived = true; + notifyAll(); + } } } } @@ -135,12 +139,9 @@ echo(">>> START the CounterMonitor"); counterMonitor.start(); - // Wait for granularity period (multiplied by 2 for sure) - // - Thread.sleep(granularityperiod * 2); - // Check if notification was received // + doWait(); if (messageReceived) { echo("\tOK: CounterMonitor got RUNTIME_ERROR notification!"); } else { @@ -203,12 +204,9 @@ echo(">>> START the GaugeMonitor"); gaugeMonitor.start(); - // Wait for granularity period (multiplied by 2 for sure) - // - Thread.sleep(granularityperiod * 2); - // Check if notification was received // + doWait(); if (messageReceived) { echo("\tOK: GaugeMonitor got RUNTIME_ERROR notification!"); } else { @@ -270,12 +268,9 @@ echo(">>> START the StringMonitor"); stringMonitor.start(); - // Wait for granularity period (multiplied by 2 for sure) - // - Thread.sleep(granularityperiod * 2); - // Check if notification was received // + doWait(); if (messageReceived) { echo("\tOK: StringMonitor got RUNTIME_ERROR notification!"); } else { @@ -349,8 +344,23 @@ } } + /* + * Wait messageReceived to be true + */ + synchronized void doWait() { + while (!messageReceived) { + try { + wait(); + } catch (InterruptedException e) { + System.err.println("Got unexpected exception: " + e); + e.printStackTrace(); + break; + } + } + } + // Flag to notify that a message has been received - private boolean messageReceived = false; + private volatile boolean messageReceived = false; private MBeanServer server; private ObjectName obsObjName; diff -r 66228a695a62 -r 00b27213d86c jdk/test/javax/management/monitor/RuntimeExceptionTest.java --- a/jdk/test/javax/management/monitor/RuntimeExceptionTest.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/javax/management/monitor/RuntimeExceptionTest.java Fri Sep 19 11:19:38 2014 -0700 @@ -86,7 +86,11 @@ echo("\tObservedAttribute: " + mn.getObservedAttribute()); echo("\tDerivedGauge: " + mn.getDerivedGauge()); echo("\tTrigger: " + mn.getTrigger()); - messageReceived = true; + + synchronized (this) { + messageReceived = true; + notifyAll(); + } } } } @@ -134,12 +138,9 @@ echo(">>> START the CounterMonitor"); counterMonitor.start(); - // Wait for granularity period (multiplied by 2 for sure) - // - Thread.sleep(granularityperiod * 2); - // Check if notification was received // + doWait(); if (messageReceived) { echo("\tOK: CounterMonitor got RUNTIME_ERROR notification!"); } else { @@ -202,12 +203,9 @@ echo(">>> START the GaugeMonitor"); gaugeMonitor.start(); - // Wait for granularity period (multiplied by 2 for sure) - // - Thread.sleep(granularityperiod * 2); - // Check if notification was received // + doWait(); if (messageReceived) { echo("\tOK: GaugeMonitor got RUNTIME_ERROR notification!"); } else { @@ -269,12 +267,9 @@ echo(">>> START the StringMonitor"); stringMonitor.start(); - // Wait for granularity period (multiplied by 2 for sure) - // - Thread.sleep(granularityperiod * 2); - // Check if notification was received // + doWait(); if (messageReceived) { echo("\tOK: StringMonitor got RUNTIME_ERROR notification!"); } else { @@ -347,8 +342,23 @@ } } + /* + * Wait messageReceived to be true + */ + synchronized void doWait() { + while (!messageReceived) { + try { + wait(); + } catch (InterruptedException e) { + System.err.println("Got unexpected exception: " + e); + e.printStackTrace(); + break; + } + } + } + // Flag to notify that a message has been received - private boolean messageReceived = false; + private volatile boolean messageReceived = false; private MBeanServer server; private ObjectName obsObjName; diff -r 66228a695a62 -r 00b27213d86c jdk/test/sun/awt/datatransfer/SuplementaryCharactersTransferTest.java --- a/jdk/test/sun/awt/datatransfer/SuplementaryCharactersTransferTest.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/sun/awt/datatransfer/SuplementaryCharactersTransferTest.java Fri Sep 19 11:19:38 2014 -0700 @@ -35,6 +35,7 @@ import java.awt.datatransfer.*; import sun.awt.datatransfer.*; import sun.awt.datatransfer.DataTransferer.ReencodingInputStream; +import sun.datatransfer.DataFlavorUtil; public class SuplementaryCharactersTransferTest { @@ -46,7 +47,7 @@ dataTransferer.registerTextFlavorProperties("UNICODE TEXT", "utf-16le", "\r\n", "2"); ByteTransferable transferable = new ByteTransferable(); ReencodingInputStream is = dataTransferer.new ReencodingInputStream(transferable.getByteInputStream(), TEXT_FORMAT, - DataTransferer.getTextCharset(transferable.getDataFlavor()), transferable); + DataFlavorUtil.getTextCharset(transferable.getDataFlavor()), transferable); byte[] bytes = transferable.getBytes(); byte[] result = new byte[bytes.length]; @@ -161,4 +162,5 @@ throw new UnsupportedOperationException("Not supported yet."); } } -} \ No newline at end of file +} + diff -r 66228a695a62 -r 00b27213d86c jdk/test/sun/security/krb5/auto/Context.java --- a/jdk/test/sun/security/krb5/auto/Context.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/sun/security/krb5/auto/Context.java Fri Sep 19 11:19:38 2014 -0700 @@ -22,15 +22,14 @@ */ import com.sun.security.auth.module.Krb5LoginModule; -import java.security.Key; + +import java.lang.reflect.Method; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.Arrays; -import java.util.Base64; import java.util.HashMap; import java.util.Map; import javax.security.auth.Subject; -import javax.security.auth.kerberos.KerberosCredMessage; import javax.security.auth.kerberos.KerberosKey; import javax.security.auth.kerberos.KerberosTicket; import javax.security.auth.login.LoginContext; @@ -41,10 +40,6 @@ import org.ietf.jgss.GSSName; import org.ietf.jgss.MessageProp; import org.ietf.jgss.Oid; -import com.sun.security.jgss.ExtendedGSSContext; -import com.sun.security.jgss.InquireType; -import com.sun.security.jgss.AuthorizationDataEntry; -import com.sun.security.jgss.ExtendedGSSCredential; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.security.Principal; @@ -78,7 +73,7 @@ public class Context { private Subject s; - private ExtendedGSSContext x; + private GSSContext x; private String name; private GSSCredential cred; // see static method delegated(). @@ -143,7 +138,6 @@ /** * Logins with username/password as an existing Subject. The * same subject can be used multiple times to simulate multiple logins. - * @param s existing subject */ public static Context fromUserPass(Subject s, String user, char[] pass, boolean storeKey) throws Exception { @@ -222,7 +216,7 @@ @Override public byte[] run(Context me, byte[] dummy) throws Exception { GSSManager m = GSSManager.getInstance(); - me.x = (ExtendedGSSContext)m.createContext( + me.x = m.createContext( target.indexOf('@') < 0 ? m.createName(target, null) : m.createName(target, GSSName.NT_HOSTBASED_SERVICE), @@ -267,7 +261,7 @@ asInitiator? GSSCredential.INITIATE_AND_ACCEPT: GSSCredential.ACCEPT_ONLY); - me.x = (ExtendedGSSContext)m.createContext(me.cred); + me.x = m.createContext(me.cred); return null; } }, null); @@ -285,7 +279,7 @@ * * @return the GSSContext object */ - public ExtendedGSSContext x() { + public GSSContext x() { return x; } @@ -339,7 +333,7 @@ */ public void status() throws Exception { System.out.println("STATUS OF " + name.toUpperCase()); - try { + if (x != null) { StringBuffer sb = new StringBuffer(); if (x.getAnonymityState()) { sb.append("anon, "); @@ -362,19 +356,15 @@ if (x.getSequenceDetState()) { sb.append("seq det, "); } - if (x instanceof ExtendedGSSContext) { - if (((ExtendedGSSContext)x).getDelegPolicyState()) { - sb.append("deleg policy, "); - } + System.out.println(" Context status of " + name + ": " + sb.toString()); + if (x.isProtReady() || x.isEstablished()) { + System.out.println(" " + x.getSrcName() + " -> " + x.getTargName()); } - System.out.println("Context status of " + name + ": " + sb.toString()); - System.out.println(x.getSrcName() + " -> " + x.getTargName()); - } catch (Exception e) { - ;// Don't care } + xstatus(); if (s != null) { System.out.println("====== START SUBJECT CONTENT ====="); - for (Principal p: s.getPrincipals()) { + for (Principal p : s.getPrincipals()) { System.out.println(" Principal: " + p); } for (Object o : s.getPublicCredentials()) { @@ -405,51 +395,42 @@ } System.out.println("====== END SUBJECT CONTENT ====="); } - if (x != null && x instanceof ExtendedGSSContext) { - if (x.isEstablished()) { - ExtendedGSSContext ex = (ExtendedGSSContext)x; - Key k = (Key)ex.inquireSecContext( - InquireType.KRB5_GET_SESSION_KEY); - if (k == null) { - throw new Exception("(Old) Session key cannot be null"); - } - System.out.println("(Old) Session key is: " + k); - Key k2 = (Key)ex.inquireSecContext( - InquireType.KRB5_GET_SESSION_KEY_EX); - if (k2 == null) { - throw new Exception("Session key cannot be null"); - } - System.out.println("Session key is: " + k); - boolean[] flags = (boolean[])ex.inquireSecContext( - InquireType.KRB5_GET_TKT_FLAGS); - if (flags == null) { - throw new Exception("Ticket flags cannot be null"); + } + + public void xstatus() throws Exception { + System.out.println(" Extended context status:"); + if (x != null) { + try { + Class clazz = Class.forName("com.sun.security.jgss.ExtendedGSSContext"); + if (clazz.isAssignableFrom(x.getClass())) { + if (clazz.getMethod("getDelegPolicyState").invoke(x) == Boolean.TRUE) { + System.out.println(" deleg policy"); + } + if (x.isEstablished()) { + Class inqType = Class.forName("com.sun.security.jgss.InquireType"); + Method inqMethod = clazz.getMethod("inquireSecContext", inqType); + for (Object o : inqType.getEnumConstants()) { + System.out.println(" " + o + ":"); + try { + System.out.println(" " + inqMethod.invoke(x, o)); + } catch (Exception e) { + System.out.println(e.getCause()); + } + } + } } - System.out.println("Ticket flags is: " + Arrays.toString(flags)); - String authTime = (String)ex.inquireSecContext( - InquireType.KRB5_GET_AUTHTIME); - if (authTime == null) { - throw new Exception("Auth time cannot be null"); - } - System.out.println("AuthTime is: " + authTime); - if (!x.isInitiator()) { - AuthorizationDataEntry[] ad = (AuthorizationDataEntry[])ex.inquireSecContext( - InquireType.KRB5_GET_AUTHZ_DATA); - System.out.println("AuthzData is: " + Arrays.toString(ad)); + } catch (ClassNotFoundException cnfe) { + System.out.println(" -- ExtendedGSSContext not available"); + } + } + if (cred != null) { + try { + Class clazz2 = Class.forName("com.sun.security.jgss.ExtendedGSSCredential"); + if (!clazz2.isAssignableFrom(cred.getClass())) { + throw new Exception("cred is not extended"); } - try { - KerberosCredMessage tok = (KerberosCredMessage)ex.inquireSecContext( - InquireType.KRB5_GET_KRB_CRED); - System.out.println("KRB_CRED is " + - (tok == null?"not ":"") + "available"); - if (tok != null) { - System.out.println("From " + tok.getSender() + " to " - + tok.getRecipient()); - System.out.println(Base64.getEncoder().encodeToString(tok.getEncoded())); - } - } catch (Exception e) { - System.out.println("KRB_CRED is not available: " + e); - } + } catch (ClassNotFoundException cnfe) { + System.out.println(" -- ExtendedGSSCredential not available"); } } } @@ -591,7 +572,10 @@ if (Context.this.cred == null) { Context.this.cred = m.createCredential(GSSCredential.INITIATE_ONLY); } - return ((ExtendedGSSCredential)Context.this.cred).impersonate(other); + return (GSSCredential) + Class.forName("com.sun.security.jgss.ExtendedGSSCredential") + .getMethod("impersonate", GSSName.class) + .invoke(Context.this.cred, other); } }); Context out = new Context(); diff -r 66228a695a62 -r 00b27213d86c jdk/test/sun/security/krb5/auto/NewInquireTypes.java --- a/jdk/test/sun/security/krb5/auto/NewInquireTypes.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/sun/security/krb5/auto/NewInquireTypes.java Fri Sep 19 11:19:38 2014 -0700 @@ -29,6 +29,7 @@ * @run main/othervm NewInquireTypes */ +import com.sun.security.jgss.ExtendedGSSContext; import com.sun.security.jgss.InquireType; import sun.security.jgss.GSSUtil; import sun.security.krb5.internal.KRBCred; @@ -52,10 +53,12 @@ Context.handshake(c, s); + ExtendedGSSContext ctxt = (ExtendedGSSContext)c.x(); EncryptionKey key = (EncryptionKey) - c.x().inquireSecContext(InquireType.KRB5_GET_SESSION_KEY_EX); + ctxt.inquireSecContext(InquireType.KRB5_GET_SESSION_KEY_EX); KerberosCredMessage cred = (KerberosCredMessage) - c.x().inquireSecContext(InquireType.KRB5_GET_KRB_CRED); + ctxt.inquireSecContext(InquireType.KRB5_GET_KRB_CRED); + c.status(); // Confirm the KRB_CRED message is encrypted with the session key. new KRBCred(cred.getEncoded()).encPart.decrypt( diff -r 66228a695a62 -r 00b27213d86c jdk/test/sun/security/krb5/auto/OkAsDelegate.java --- a/jdk/test/sun/security/krb5/auto/OkAsDelegate.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/sun/security/krb5/auto/OkAsDelegate.java Fri Sep 19 11:19:38 2014 -0700 @@ -48,6 +48,7 @@ * @summary Support OK-AS-DELEGATE flag */ import com.sun.security.jgss.ExtendedGSSContext; +import org.ietf.jgss.GSSContext; import org.ietf.jgss.GSSCredential; import org.ietf.jgss.GSSException; import org.ietf.jgss.Oid; @@ -102,7 +103,7 @@ cx.requestCredDeleg(requestDelegState); cx.requestDelegPolicy(requestDelegPolicyState); s.startAsServer(mech); - ExtendedGSSContext sx = (ExtendedGSSContext)s.x(); + GSSContext sx = s.x(); Context.handshake(c, s); diff -r 66228a695a62 -r 00b27213d86c jdk/test/sun/security/krb5/auto/OkAsDelegateXRealm.java --- a/jdk/test/sun/security/krb5/auto/OkAsDelegateXRealm.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/sun/security/krb5/auto/OkAsDelegateXRealm.java Fri Sep 19 11:19:38 2014 -0700 @@ -42,6 +42,8 @@ import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; + +import com.sun.security.jgss.ExtendedGSSContext; import org.ietf.jgss.GSSException; import sun.security.jgss.GSSUtil; import sun.security.krb5.Config; @@ -129,7 +131,7 @@ for (int i=0; i<2; i++) { c.startAsClient("host@host.r3.local", GSSUtil.GSS_KRB5_MECH_OID); s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); - c.x().requestDelegPolicy(true); + ((ExtendedGSSContext)c.x()).requestDelegPolicy(true); Context.handshake(c, s); boolean succeed = true; diff -r 66228a695a62 -r 00b27213d86c jdk/test/sun/security/krb5/auto/SSL.java --- a/jdk/test/sun/security/krb5/auto/SSL.java Fri Sep 19 11:13:27 2014 -0700 +++ b/jdk/test/sun/security/krb5/auto/SSL.java Fri Sep 19 11:19:38 2014 -0700 @@ -186,13 +186,13 @@ // Client checks "initiate", then server gets the name // and checks "accept". Second connection resume. if (!permChecks.equals("IA")) { - throw new Exception(); + throw new Exception(permChecks); } } else { // For bound, JAAS checks "accept" once. Server checks again, // client then checks "initiate". Second connection resume. if (!permChecks.equals("AAI")) { - throw new Exception(); + throw new Exception(permChecks); } } } diff -r 66228a695a62 -r 00b27213d86c jdk/test/tools/jar/LeadingGarbage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/jar/LeadingGarbage.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,139 @@ +/* + * Copyright 2014 Google Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import sun.tools.jar.Main; + +import jdk.testlibrary.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; + +import org.testng.annotations.Test; + +/** + * @test + * @bug 8058520 + * @summary jar tf and jar xf should work on zip files with leading garbage + * @library /lib/testlibrary + * @run testng LeadingGarbage + */ +@Test +public class LeadingGarbage { + final String jar = + Paths.get(new File(System.getProperty("java.home")).getParent(), + "bin", "jar").toString(); + final File[] files = { new File("a"), new File("b") }; + final File normalZip = new File("normal.zip"); + final File leadingGarbageZip = new File("leadingGarbage.zip"); + + void createFile(File f) throws IOException { + OutputStream fos = new FileOutputStream(f); + fos.write(f.getName().getBytes("UTF-8")); + fos.close(); + } + + void createFiles() throws IOException { + for (File file : files) + createFile(file); + } + + void deleteFiles() throws IOException { + for (File file : files) + assertTrue(file.delete()); + } + + void assertFilesExist() throws IOException { + for (File file : files) + assertTrue(file.exists()); + } + + void createNormalZip() throws Throwable { + createFiles(); + String[] cmd = { jar, "c0Mf", "normal.zip", "a", "b" }; + ProcessBuilder pb = new ProcessBuilder(cmd); + OutputAnalyzer a = ProcessTools.executeProcess(pb); + a.shouldHaveExitValue(0); + a.stdoutShouldMatch("\\A\\Z"); + a.stderrShouldMatch("\\A\\Z"); + deleteFiles(); + } + + void createZipWithLeadingGarbage() throws Throwable { + createNormalZip(); + createFile(leadingGarbageZip); + OutputStream fos = new FileOutputStream(leadingGarbageZip, true); + Files.copy(normalZip.toPath(), fos); + assertTrue(normalZip.length() < leadingGarbageZip.length()); + assertTrue(normalZip.delete()); + } + + public void test_canList() throws Throwable { + createNormalZip(); + assertCanList("normal.zip"); + } + + public void test_canListWithLeadingGarbage() throws Throwable { + createZipWithLeadingGarbage(); + assertCanList("leadingGarbage.zip"); + } + + void assertCanList(String zipFileName) throws Throwable { + String[] cmd = { jar, "tf", zipFileName }; + ProcessBuilder pb = new ProcessBuilder(cmd); + OutputAnalyzer a = ProcessTools.executeProcess(pb); + a.shouldHaveExitValue(0); + StringBuilder expected = new StringBuilder(); + for (File file : files) + expected.append(file.getName()).append('\n'); + a.stdoutShouldMatch(expected.toString()); + a.stderrShouldMatch("\\A\\Z"); + } + + public void test_canExtract() throws Throwable { + createNormalZip(); + assertCanExtract("normal.zip"); + } + + public void test_canExtractWithLeadingGarbage() throws Throwable { + createZipWithLeadingGarbage(); + assertCanExtract("leadingGarbage.zip"); + } + + void assertCanExtract(String zipFileName) throws Throwable { + String[] cmd = { jar, "xf", zipFileName }; + ProcessBuilder pb = new ProcessBuilder(cmd); + OutputAnalyzer a = ProcessTools.executeProcess(pb); + a.shouldHaveExitValue(0); + a.stdoutShouldMatch("\\A\\Z"); + a.stderrShouldMatch("\\A\\Z"); + assertFilesExist(); + } + +} diff -r 66228a695a62 -r 00b27213d86c langtools/.hgtags --- a/langtools/.hgtags Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/.hgtags Fri Sep 19 11:19:38 2014 -0700 @@ -273,3 +273,4 @@ 016786f793149135ab6b23c71087c1ca12691d77 jdk9-b28 13705e2ddeb20a78e066595a1709e61f257189e9 jdk9-b29 ef5427c13e1e741c457a2ed868e3b6d6bf717754 jdk9-b30 +0046d55383a9d873ffbc7253d7c5e28ab98c5bea jdk9-b31 diff -r 66228a695a62 -r 00b27213d86c langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Fri Sep 19 11:19:38 2014 -0700 @@ -358,11 +358,9 @@ for (Type aLowerBound : from.getBounds(InferenceBound.LOWER)) { for (Type anotherLowerBound : from.getBounds(InferenceBound.LOWER)) { if (aLowerBound != anotherLowerBound && - commonSuperWithDiffParameterization(aLowerBound, anotherLowerBound)) { - /* self comment check if any lower bound may be and undetVar, - * in that case the result of this call may be a false positive. - * Should this be restricted to non free types? - */ + !inferenceContext.free(aLowerBound) && + !inferenceContext.free(anotherLowerBound) && + commonSuperWithDiffParameterization(aLowerBound, anotherLowerBound)) { return generateReferenceToTargetConstraint(tree, from, to, resultInfo, inferenceContext); } diff -r 66228a695a62 -r 00b27213d86c langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Fri Sep 19 11:19:38 2014 -0700 @@ -397,20 +397,19 @@ Content htmlComment = new Comment(configuration.getText("doclet.New_Page")); Content head = new HtmlTree(HtmlTag.HEAD); head.addContent(getGeneratedBy(!configuration.notimestamp)); - if (configuration.charset.length() > 0) { - Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE, - configuration.charset); - head.addContent(meta); - } head.addContent(getTitle()); + Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE, + (configuration.charset.length() > 0) ? + configuration.charset : HtmlConstants.HTML_DEFAULT_CHARSET); + head.addContent(meta); if (!configuration.notimestamp) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); - Content meta = HtmlTree.META("date", dateFormat.format(new Date())); + meta = HtmlTree.META("date", dateFormat.format(new Date())); head.addContent(meta); } if (metakeywords != null) { for (String metakeyword : metakeywords) { - Content meta = HtmlTree.META("keywords", metakeyword); + meta = HtmlTree.META("keywords", metakeyword); head.addContent(meta); } } diff -r 66228a695a62 -r 00b27213d86c langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java Fri Sep 19 11:19:38 2014 -0700 @@ -90,8 +90,7 @@ * {@inheritDoc} */ public Content getPackageHeader(String heading) { - String pkgName = packageDoc.name(); - Content bodyTree = getBody(true, getWindowTitle(pkgName)); + Content bodyTree = getBody(true, getWindowTitle(utils.getPackageName(packageDoc))); addTop(bodyTree); addNavLinks(true, bodyTree); HtmlTree div = new HtmlTree(HtmlTag.DIV); diff -r 66228a695a62 -r 00b27213d86c langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageWriterImpl.java --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageWriterImpl.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageWriterImpl.java Fri Sep 19 11:19:38 2014 -0700 @@ -103,8 +103,7 @@ * {@inheritDoc} */ public Content getPackageHeader(String heading) { - String pkgName = packageDoc.name(); - Content bodyTree = getBody(true, getWindowTitle(pkgName)); + Content bodyTree = getBody(true, getWindowTitle(utils.getPackageName(packageDoc))); addTop(bodyTree); addNavLinks(true, bodyTree); HtmlTree div = new HtmlTree(HtmlTag.DIV); diff -r 66228a695a62 -r 00b27213d86c langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java Fri Sep 19 11:19:38 2014 -0700 @@ -220,4 +220,9 @@ * Html tag for the member heading. */ public static final HtmlTag MEMBER_HEADING = HtmlTag.H4; + + /** + * Default charset for HTML. + */ + public static final String HTML_DEFAULT_CHARSET = "utf-8"; } diff -r 66228a695a62 -r 00b27213d86c langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java Fri Sep 19 11:19:38 2014 -0700 @@ -311,13 +311,12 @@ Content htmlComment = new Comment(configuration.getText("doclet.New_Page")); Content head = new HtmlTree(HtmlTag.HEAD); head.addContent(getGeneratedBy(!noTimeStamp)); - if (configuration.charset.length() > 0) { - Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE, - configuration.charset); - head.addContent(meta); - } Content windowTitle = HtmlTree.TITLE(new StringContent(title)); head.addContent(windowTitle); + Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE, + (configuration.charset.length() > 0) ? + configuration.charset : HtmlConstants.HTML_DEFAULT_CHARSET); + head.addContent(meta); head.addContent(getFramesetJavaScript()); Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(), head, frameset); diff -r 66228a695a62 -r 00b27213d86c langtools/test/com/sun/javadoc/testCharset/TestCharset.java --- a/langtools/test/com/sun/javadoc/testCharset/TestCharset.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/test/com/sun/javadoc/testCharset/TestCharset.java Fri Sep 19 11:19:38 2014 -0700 @@ -23,7 +23,7 @@ /* * @test - * @bug 7052170 + * @bug 7052170 8047745 * @summary Run a test on -charset to make sure the charset gets generated as a * part of the meta tag. * @author Bhavesh Patel @@ -42,19 +42,32 @@ @Test void test() { javadoc("-d", "out", - "-charset", "UTF-8", + "-charset", "ISO-8859-1", "-sourcepath", testSrc, "pkg"); checkExit(Exit.OK); checkOutput("index.html", true, - ""); + ""); checkOutput("pkg/Foo.html", true, - ""); + ""); checkOutput("index.html", false, - ""); + ""); checkOutput("pkg/Foo.html", false, - ""); + ""); + } + + @Test + void test1() { + javadoc("-d", "out-1", + "-sourcepath", testSrc, + "pkg"); + checkExit(Exit.OK); + + checkOutput("index.html", true, + ""); + checkOutput("pkg/Foo.html", true, + ""); } } diff -r 66228a695a62 -r 00b27213d86c langtools/test/com/sun/javadoc/testUnnamedPackage/TestUnnamedPackage.java --- a/langtools/test/com/sun/javadoc/testUnnamedPackage/TestUnnamedPackage.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/test/com/sun/javadoc/testUnnamedPackage/TestUnnamedPackage.java Fri Sep 19 11:19:38 2014 -0700 @@ -23,7 +23,7 @@ /* * @test - * @bug 4904075 4774450 5015144 + * @bug 4904075 4774450 5015144 8043698 * @summary Reference unnamed package as "Unnamed", not empty string. * Generate a package summary for the unnamed package. * @author jamieh @@ -51,6 +51,9 @@ "This is a package comment for the unnamed package.", "This is a class in the unnamed package."); + checkOutput("package-summary.html", true, + "<Unnamed>"); + checkOutput("package-tree.html", true, "

Hierarchy For Package <Unnamed>

"); diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/Parens1.java --- a/langtools/test/tools/javac/Parens1.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/test/tools/javac/Parens1.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,33 +1,10 @@ /* - * Copyright (c) 2001, 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 + * @test /nodynamiccopyright/ * @bug 4391330 * @summary compiler accepted (Integer).toString(123) * @author gafter * - * @compile/fail Parens1.java + * @compile/fail/ref=Parens1.out -XDrawDiagnostics Parens1.java */ class Parens1 { diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/Parens1.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/Parens1.out Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,2 @@ +Parens1.java:12:20: compiler.err.illegal.start.of.type +1 error diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/Parens2.java --- a/langtools/test/tools/javac/Parens2.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/test/tools/javac/Parens2.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,33 +1,10 @@ /* - * Copyright (c) 2001, 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 + * @test /nodynamiccopyright/ * @bug 4408036 * @summary Compiler accepted "(i=2);" as a valid expession statement. * @author gafter * - * @compile/fail Parens2.java + * @compile/fail/ref=Parens2.out -XDrawDiagnostics Parens2.java */ class Parens2 { diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/Parens2.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/Parens2.out Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,2 @@ +Parens2.java:13:9: compiler.err.not.stmt +1 error diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/Parens3.java --- a/langtools/test/tools/javac/Parens3.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/test/tools/javac/Parens3.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,33 +1,10 @@ /* - * Copyright (c) 2001, 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 + * @test /nodynamiccopyright/ * @bug 4394546 * @summary get no err msg if label wrapped in parentheses * @author gafter * - * @compile/fail Parens3.java + * @compile/fail/ref=Parens3.out -XDrawDiagnostics Parens3.java */ class Parens3 { diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/Parens3.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/Parens3.out Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,3 @@ +Parens3.java:12:5: compiler.err.not.stmt +Parens3.java:12:10: compiler.err.expected: ';' +2 errors diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/Parens4.java --- a/langtools/test/tools/javac/Parens4.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/test/tools/javac/Parens4.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,33 +1,10 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * 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 + * @test /nodynamiccopyright/ * @bug 4933317 * @summary javac accepts parens in package names * @author gafter * - * @compile/fail Parens4.java + * @compile/fail/ref=Parens4.out -XDrawDiagnostics Parens4.java */ class Parens4 { diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/Parens4.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/Parens4.out Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,2 @@ +Parens4.java:12:16: compiler.err.illegal.start.of.type +1 error diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/ParseConditional.java --- a/langtools/test/tools/javac/ParseConditional.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/test/tools/javac/ParseConditional.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,34 +1,11 @@ /* - * Copyright (c) 1997, 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 + * @test /nodynamiccopyright/ * @bug 4092958 * @summary The compiler was too permissive in its parsing of conditional * expressions. * @author turnidge * - * @compile/fail ParseConditional.java + * @compile/fail/ref=ParseConditional.out -XDrawDiagnostics ParseConditional.java */ public class ParseConditional { @@ -38,6 +15,11 @@ int b = 2; int c = 3; int d = 4; - a = condition ? b = c : c = d; // Should get a parse error. + // The following line should give an error because the conditional ?: operator + // is higher priority than the final assignment operator, between c and d. + // As such, the correct parsing is: + // a = (condition ? b = c : c) = d; + // and it is illegal to try and assign to the value of the conditional expression. + a = condition ? b = c : c = d; } } diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/ParseConditional.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/ParseConditional.out Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,2 @@ +ParseConditional.java:23:23: compiler.err.unexpected.type: kindname.variable, kindname.value +1 error diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/StoreClass.java --- a/langtools/test/tools/javac/StoreClass.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/test/tools/javac/StoreClass.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,33 +1,10 @@ /* - * Copyright (c) 2001, 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 + * @test /nodynamiccopyright/ * @bug 4350352 * @summary InternalError: store unsupported: com.sun.tools.javac.v8.comp.Items * @author gafter * - * @compile/fail StoreClass.java + * @compile/fail/ref=StoreClass.out -XDrawDiagnostics StoreClass.java */ class StoreClass { diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/StoreClass.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/StoreClass.out Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,3 @@ +StoreClass.java:12:19: compiler.err.cant.assign.val.to.final.var: class +StoreClass.java:13:12: compiler.err.cant.assign.val.to.final.var: class +2 errors diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/SwitchScope.java --- a/langtools/test/tools/javac/SwitchScope.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/test/tools/javac/SwitchScope.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,33 +1,10 @@ /* - * Copyright (c) 2002, 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 + * @test /nodynamiccopyright/ * @bug 4725650 * @summary Restrict scope of local classes in switch-block-group * @author gafter * - * @compile/fail SwitchScope.java + * @compile/fail/ref=SwitchScope.out -XDrawDiagnostics SwitchScope.java */ public class SwitchScope { diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/SwitchScope.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/SwitchScope.out Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,2 @@ +SwitchScope.java:22:28: compiler.err.cant.resolve.location: kindname.class, Local, , , (compiler.misc.location: kindname.class, SwitchScope, null) +1 error diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/SynthName2.java --- a/langtools/test/tools/javac/SynthName2.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/test/tools/javac/SynthName2.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,38 +1,15 @@ /* - * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * 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 + * @test /nodynamiccopyright/ * @bug 4462714 * @summary using of synthetic names in local class causes ClassFormatError * @author gafter * - * @compile/fail SynthName2.java + * @compile/fail/ref=SynthName2.out -XDrawDiagnostics SynthName2.java */ import java.io.PrintStream; -class SynthName1 { +class SynthName2 { public static void main(String args[]) { run(args, System.out); } diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/SynthName2.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/SynthName2.out Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,4 @@ +SynthName2.java:33:9: compiler.err.synthetic.name.conflict: val$zzz, InnClass +SynthName2.java:34:17: compiler.err.synthetic.name.conflict: val$prm1, InnClass +SynthName2.java:35:17: compiler.err.synthetic.name.conflict: val$zzz, InnClass +3 errors diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/T6234077.java --- a/langtools/test/tools/javac/T6234077.java Fri Sep 19 11:13:27 2014 -0700 +++ b/langtools/test/tools/javac/T6234077.java Fri Sep 19 11:19:38 2014 -0700 @@ -1,30 +1,7 @@ /* - * Copyright (c) 2005, 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 /nodynamiccopyright/ + * @bug 6234077 + * @compile/fail/ref=T6234077.out -XDrawDiagnostics T6234077.java */ -/* - * @test - * @bug 6234077 - * @compile/fail T6234077.java - */ -@Deprecated /** @deprecated */ public class Foo { } diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/T6234077.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/T6234077.out Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,2 @@ +T6234077.java:7:8: compiler.err.class.public.should.be.in.file: Foo +1 error diff -r 66228a695a62 -r 00b27213d86c langtools/test/tools/javac/generics/inference/8055963/T8055963.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/inference/8055963/T8055963.java Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. 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. + */ + +/** + * @test + * @bug 8055963 + * @summary Inference failure with nested invocation + * @compile T8055963.java + */ +class T8055963 { + + static class C {} + + T choose(T first, T second) { return null; } + + void test() { + C cs = choose(new C(), new C<>()); + } +} diff -r 66228a695a62 -r 00b27213d86c make/HotspotWrapper.gmk --- a/make/HotspotWrapper.gmk Fri Sep 19 11:13:27 2014 -0700 +++ b/make/HotspotWrapper.gmk Fri Sep 19 11:19:38 2014 -0700 @@ -42,7 +42,7 @@ # not doing it breaks builds on msys. $(HOTSPOT_OUTPUTDIR)/_hotspot.timestamp: $(HOTSPOT_FILES) @$(MKDIR) -p $(HOTSPOT_OUTPUTDIR) - @($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) -j1 $(HOTSPOT_MAKE_ARGS) SPEC=$(HOTSPOT_SPEC) BASE_SPEC=$(BASE_SPEC)) + @($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) $(HOTSPOT_MAKE_ARGS) SPEC=$(HOTSPOT_SPEC) BASE_SPEC=$(BASE_SPEC)) $(TOUCH) $@ hotspot: $(HOTSPOT_OUTPUTDIR)/_hotspot.timestamp diff -r 66228a695a62 -r 00b27213d86c make/Main.gmk --- a/make/Main.gmk Fri Sep 19 11:13:27 2014 -0700 +++ b/make/Main.gmk Fri Sep 19 11:19:38 2014 -0700 @@ -298,7 +298,9 @@ # Verification targets verify-modules: + @$(call TargetEnter) +($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f CheckModules.gmk) + @$(call TargetExit) ALL_TARGETS += verify-modules @@ -400,7 +402,7 @@ main-jars: java.security.jgss-libs endif - images: jars demos samples exploded-image source-tips + images: jars demos samples exploded-image verify-modules source-tips bootcycle-images: images @@ -476,7 +478,7 @@ ################################################################################ -all: images docs verify-modules +all: images docs default: exploded-image ALL_TARGETS += default all @@ -491,7 +493,7 @@ # file. CLEAN_COMPONENTS += langtools corba hotspot jdk nashorn images \ - bootcycle-build docs docstemp test + bootcycle-build docs docstemp test make-support CLEAN_TARGETS := $(addprefix clean-, $(CLEAN_COMPONENTS)) # Remove everything, except the output from configure. diff -r 66228a695a62 -r 00b27213d86c make/common/Modules.gmk --- a/make/common/Modules.gmk Fri Sep 19 11:13:27 2014 -0700 +++ b/make/common/Modules.gmk Fri Sep 19 11:19:38 2014 -0700 @@ -26,6 +26,9 @@ ifndef _MODULES_GMK _MODULES_GMK := 1 +include JavaCompilation.gmk +include SetupJavaCompilers.gmk + ################################################################################ # Module list macros @@ -50,8 +53,32 @@ $(patsubst %,%/*/$(OPENJDK_TARGET_OS)/classes/*, $(ALL_TOP_SRC_DIRS)))))))))))) endef -MODULES_LIST_FILE := $(SRC_ROOT)/make/common/modules.list -MODULE_DEPS_MAKEFILE := $(OUTPUT_ROOT)/module-deps.gmk +# Find all modules with source for the target platform. +define FindAllModules + $(sort $(filter-out closed demo sample, $(notdir $(patsubst %/,%, $(dir \ + $(wildcard $(patsubst %, %/*/share, $(ALL_TOP_SRC_DIRS)) \ + $(patsubst %, %/*/$(OPENJDK_TARGET_OS), $(ALL_TOP_SRC_DIRS)) \ + $(patsubst %, %/*/$(OPENJDK_TARGET_OS_API_DIR), $(ALL_TOP_SRC_DIRS)))))))) +endef + +################################################################################ + +$(eval $(call SetupJavaCompilation,BUILD_GENMODULESLIST, \ + SETUP := BOOT_JAVAC, \ + SRC := $(JDK_TOPDIR)/make/src/classes, \ + INCLUDES := build/tools/module, \ + BIN := $(MAKESUPPORT_OUTPUTDIR)/bt_classes_moduleslist)) + +TOOL_GENMODULESLIST = $(JAVA_SMALL) \ + -cp "$(MAKESUPPORT_OUTPUTDIR)/bt_classes_moduleslist" \ + build.tools.module.GenModulesList + +MODULES_LIST_FILE := $(MAKESUPPORT_OUTPUTDIR)/modules.list +MODULE_DEPS_MAKEFILE := $(MAKESUPPORT_OUTPUTDIR)/module-deps.gmk + +$(MODULES_LIST_FILE): $(SRC_ROOT)/modules.xml \ + $(BUILD_GENMODULESLIST) + $(TOOL_GENMODULESLIST) -o $@ $(filter %.xml, $^) $(MODULE_DEPS_MAKEFILE): $(MODULES_LIST_FILE) $(CAT) $^ | $(SED) -e 's/^\([^:]*\):/DEPS_\1 :=/g' > $@ @@ -63,14 +90,6 @@ $(DEPS_$(strip $1)) endef -# Find all modules with source for the target platform. -define FindAllModules - $(sort $(filter-out closed demo sample, $(notdir $(patsubst %/,%, $(dir \ - $(wildcard $(patsubst %, %/*/share, $(ALL_TOP_SRC_DIRS)) \ - $(patsubst %, %/*/$(OPENJDK_TARGET_OS), $(ALL_TOP_SRC_DIRS)) \ - $(patsubst %, %/*/$(OPENJDK_TARGET_OS_API_DIR), $(ALL_TOP_SRC_DIRS)))))))) -endef - ################################################################################ # Hook to include the corresponding custom file, if present. diff -r 66228a695a62 -r 00b27213d86c make/common/SetupJavaCompilers.gmk --- a/make/common/SetupJavaCompilers.gmk Fri Sep 19 11:13:27 2014 -0700 +++ b/make/common/SetupJavaCompilers.gmk Fri Sep 19 11:19:38 2014 -0700 @@ -34,6 +34,12 @@ # make JAVAC_WARNINGS="-Xlint:all -Xmaxwarns 10000" JAVAC_WARNINGS := -Xlint:all,-deprecation -Werror +# The BOOT_JAVAC setup uses the boot jdk compiler to compile the tools +# and the interim javac, to be run by the boot jdk. +$(eval $(call SetupJavaCompiler,BOOT_JAVAC, \ + JAVAC := $(JAVAC), \ + FLAGS := -XDignore.symbol.file=true -g -Xlint:all$(COMMA)-deprecation -Werror)) + # Any java code executed during a JDK build to build other parts of the JDK must be # executed by the bootstrap JDK (probably with -Xbootclasspath/p: ) and for this # purpose must be built with -target PREVIOUS for bootstrapping purposes, which diff -r 66228a695a62 -r 00b27213d86c make/common/modules.list --- a/make/common/modules.list Fri Sep 19 11:13:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -java.base: -java.logging: java.base -java.security.sasl: java.logging java.base -java.naming: java.security.sasl java.base -java.security.acl: java.base -jdk.charsets: java.base -java.scripting: java.base -java.xml: java.base -java.sql: java.xml java.logging java.base -jdk.scripting.nashorn: java.scripting java.logging java.base -java.rmi: java.logging java.base -java.prefs: java.xml java.base -java.desktop: jdk.charsets java.prefs java.xml java.logging java.base -java.corba: java.naming java.rmi java.desktop java.logging java.base -java.compiler: java.logging java.base -jdk.compiler: java.compiler java.base -jdk.javadoc: java.compiler java.xml jdk.compiler java.base -jdk.rmic: java.corba jdk.compiler jdk.javadoc java.base -jdk.jvmstat: java.rmi java.base -jdk.attach: jdk.jvmstat java.base -jdk.jcmd: jdk.jvmstat jdk.attach java.base -jdk.jdi: jdk.attach java.base -jdk.hotspot.agent: java.rmi java.scripting java.desktop java.base jdk.jdi -jdk.hprof.agent: java.base -java.management: java.naming java.rmi java.logging java.base -jdk.jconsole: java.management jdk.jvmstat java.rmi jdk.attach java.desktop java.logging java.base -java.activation: java.desktop java.logging java.base -java.xml.bind: java.activation java.compiler java.xml java.desktop java.logging java.base -jdk.xml.bind: java.activation java.compiler java.xml.bind java.xml java.desktop java.logging jdk.compiler java.base -jdk.httpserver: java.logging java.base -java.annotations.common: java.base -java.xml.soap: java.activation java.xml.bind java.xml java.desktop java.logging java.base -java.xml.ws: java.activation java.management jdk.httpserver java.rmi java.annotations.common java.xml.bind java.xml java.desktop java.logging java.xml.soap java.base -jdk.xml.ws: jdk.xml.bind java.compiler java.rmi java.xml.ws java.xml.bind java.xml java.logging java.base -java.sql.rowset: java.naming java.sql java.xml java.logging java.base -java.instrument: java.base -java.security.jgss: java.naming java.security.sasl java.logging java.base -java.xml.crypto: java.xml java.logging java.base -jdk.localedata: java.base -jdk.crypto.ec: java.base -jdk.crypto.pkcs11: jdk.crypto.ec java.base -jdk.crypto.mscapi: java.base -jdk.naming.rmi: java.naming java.rmi java.base -jdk.zipfs: java.base -jdk.naming.dns: java.naming java.base -java.smartcardio: java.base -jdk.dev: jdk.xml.bind jdk.xml.ws java.scripting jdk.rmic java.xml jdk.compiler java.base -jdk.snmp: java.management java.security.acl java.logging java.base -jdk.jdwp.agent: java.base -jdk.security.auth: java.naming java.security.jgss java.base -jdk.sctp: java.base -jdk.runtime: java.desktop java.base -jdk.jfr: java.management java.xml java.base -jdk.deploy.osx: java.scripting java.desktop java.base diff -r 66228a695a62 -r 00b27213d86c modules.xml --- a/modules.xml Fri Sep 19 11:13:27 2014 -0700 +++ b/modules.xml Fri Sep 19 11:19:38 2014 -0700 @@ -243,6 +243,7 @@ java.rmi java.security.jgss java.security.sasl + java.sql jdk.charsets jdk.deploy.osx jdk.dev @@ -250,6 +251,7 @@ jdk.jvmstat jdk.runtime jdk.security.auth + jdk.security.jgss sun.net.dns @@ -326,6 +328,7 @@ sun.security.internal.spec + jdk.crypto.mscapi jdk.crypto.pkcs11 jdk.crypto.ucrypto @@ -730,6 +733,10 @@ javax.swing.undo + + sun.awt + oracle.accessbridge +
java.instrument @@ -900,12 +907,7 @@ java.security.jgss java.base - java.logging java.naming - java.security.sasl - - com.sun.security.jgss - javax.security.auth.kerberos @@ -924,6 +926,14 @@ sun.security.krb5.internal.ktab jdk.security.auth + + sun.security.jgss + jdk.security.jgss + + + sun.security.krb5.internal + jdk.security.jgss + java.security.sasl @@ -934,7 +944,7 @@ com.sun.security.sasl.util - java.security.jgss + jdk.security.jgss @@ -1570,6 +1580,10 @@ + jdk.crypto.mscapi + java.base + + jdk.crypto.pkcs11 java.base jdk.crypto.ec @@ -1752,6 +1766,16 @@ + jdk.security.jgss + java.base + java.logging + java.security.jgss + java.security.sasl + + com.sun.security.jgss + + + jdk.xml.bind java.activation java.base diff -r 66228a695a62 -r 00b27213d86c nashorn/.hgtags --- a/nashorn/.hgtags Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/.hgtags Fri Sep 19 11:19:38 2014 -0700 @@ -264,3 +264,4 @@ 00c31e5eaf26f9b238165157b9d1c617b03abcb6 jdk9-b28 e541ebaf2ab7038333ad0c13f4decd327c26dd15 jdk9-b29 072dbed6c5d968a6b9e156c36cd8838b4ff86ea1 jdk9-b30 +77efdecfa2a5c28672b7c7dcc2d1b52dcb90d493 jdk9-b31 diff -r 66228a695a62 -r 00b27213d86c nashorn/README diff -r 66228a695a62 -r 00b27213d86c nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java Fri Sep 19 11:19:38 2014 -0700 @@ -231,7 +231,7 @@ if (symbol != null) { if (hasArguments() && symbol.isParam()) { symbol.setFieldIndex(paramCount++); - } else { + } else if (!isValidArrayIndex(getArrayIndex(tuple.key))) { symbol.setFieldIndex(fieldCount++); } } diff -r 66228a695a62 -r 00b27213d86c nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java Fri Sep 19 11:19:38 2014 -0700 @@ -439,8 +439,8 @@ // current ScriptContext to use - can be null. private ScriptContext scontext; - // associated Property object for "context" property. - private jdk.nashorn.internal.runtime.Property scontextProperty; + // current ScriptEngine associated - can be null. + private ScriptEngine engine; /** * Set the current script context @@ -448,7 +448,6 @@ */ public void setScriptContext(final ScriptContext scontext) { this.scontext = scontext; - scontextProperty.setValue(this, this, scontext, false); } // global constants for this global - they can be replaced with MethodHandle.constant until invalidated @@ -581,6 +580,7 @@ return; } + this.engine = engine; init(engine); } @@ -917,6 +917,13 @@ } } + switch (nameStr) { + case "context": + return sctxt; + case "engine": + return global.engine; + } + if (self == UNDEFINED) { // scope access and so throw ReferenceError throw referenceError(global, "not.defined", nameStr); @@ -1789,9 +1796,6 @@ } if (engine != null) { - final int NOT_ENUMERABLE_NOT_CONFIG = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE; - scontextProperty = addOwnProperty("context", NOT_ENUMERABLE_NOT_CONFIG, null); - addOwnProperty("engine", NOT_ENUMERABLE_NOT_CONFIG, engine); // default file name addOwnProperty(ScriptEngine.FILENAME, Attribute.NOT_ENUMERABLE, null); // __noSuchProperty__ hook for ScriptContext search of missing variables diff -r 66228a695a62 -r 00b27213d86c nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java Fri Sep 19 11:19:38 2014 -0700 @@ -54,6 +54,7 @@ import static jdk.nashorn.internal.parser.TokenType.TERNARY; import static jdk.nashorn.internal.parser.TokenType.WHILE; +import java.io.Serializable; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collections; @@ -2977,11 +2978,13 @@ * Encapsulates part of the state of the parser, enough to reconstruct the state of both parser and lexer * for resuming parsing after skipping a function body. */ - private static class ParserState { + private static class ParserState implements Serializable { private final int position; private final int line; private final int linePosition; + private static final long serialVersionUID = -2382565130754093694L; + ParserState(final int position, final int line, final int linePosition) { this.position = position; this.line = line; diff -r 66228a695a62 -r 00b27213d86c nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AccessorProperty.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AccessorProperty.java Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AccessorProperty.java Fri Sep 19 11:19:38 2014 -0700 @@ -119,7 +119,7 @@ * produce different boun method handles wrapping the same access mechanism * depending on callsite */ - private MethodHandle[] GETTER_CACHE = new MethodHandle[NOOF_TYPES]; + private transient MethodHandle[] GETTER_CACHE = new MethodHandle[NOOF_TYPES]; /** * Create a new accessor property. Factory method used by nasgen generated code. diff -r 66228a695a62 -r 00b27213d86c nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java Fri Sep 19 11:19:38 2014 -0700 @@ -101,7 +101,7 @@ private final int slot; /** SwitchPoint that is invalidated when property is changed, optional */ - protected SwitchPoint changeCallback; + protected transient SwitchPoint changeCallback; private static final long serialVersionUID = 2099814273074501176L; diff -r 66228a695a62 -r 00b27213d86c nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java Fri Sep 19 11:19:38 2014 -0700 @@ -568,9 +568,7 @@ for (final Property property : otherProperties) { // This method is only safe to use with non-slotted, native getter/setter properties assert property.getSlot() == -1; - if (isValidArrayIndex(getArrayIndex(property.getKey()))) { - newMap.setContainsArrayKeys(); - } + assert !(isValidArrayIndex(getArrayIndex(property.getKey()))); } return newMap; diff -r 66228a695a62 -r 00b27213d86c nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Fri Sep 19 11:19:38 2014 -0700 @@ -125,6 +125,15 @@ @Override public Comparison compareConversion(final Class sourceType, final Class targetType1, final Class targetType2) { + if (sourceType == ConsString.class) { + if (String.class == targetType1 || CharSequence.class == targetType1) { + return Comparison.TYPE_1_BETTER; + } + + if (String.class == targetType2 || CharSequence.class == targetType2) { + return Comparison.TYPE_2_BETTER; + } + } return linkerServices.compareConversion(sourceType, targetType1, targetType2); } } diff -r 66228a695a62 -r 00b27213d86c nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java Fri Sep 19 11:19:38 2014 -0700 @@ -131,11 +131,16 @@ } return getInvocation(EMPTY_ELEM_GETTER, self, linkerServices, desc); case "setProp": - case "setElem": + case "setElem": { + final boolean strict = NashornCallSiteDescriptor.isStrict(desc); + if (strict) { + throw typeError("cant.set.property", getArgument(linkRequest), ScriptRuntime.safeToString(self)); + } if (desc.getOperand() != null) { return getInvocation(EMPTY_PROP_SETTER, self, linkerServices, desc); } return getInvocation(EMPTY_ELEM_SETTER, self, linkerServices, desc); + } default: break; } diff -r 66228a695a62 -r 00b27213d86c nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties Fri Sep 19 11:19:38 2014 -0700 @@ -92,7 +92,7 @@ # other wrong usages of property type.error.property.has.no.setter=Cannot set property "{0}" of {1} that has only a getter -type.error.cant.set.proto.to.non.object=Cannot set Object {0}'s __proto__ to be a non-object like {1} +type.error.cant.set.proto.to.non.object=Cannot set Object {0}''s __proto__ to be a non-object like {1} type.error.no.such.function={1} has no such function "{0}" type.error.no.such.java.class=No such Java class: {0} type.error.no.such.java.constructor=No such Java constructor: {0} @@ -125,10 +125,10 @@ type.error.cant.load.script=Cannot load script from {0} type.error.JSON.stringify.cyclic=JSON.stringify got a cyclic data structure type.error.cant.convert.string.to.char=Cannot convert string to character; its length must be exactly 1 -type.error.cant.convert.number.to.char=Cannot convert number to character; it's out of 0-65535 range +type.error.cant.convert.number.to.char=Cannot convert number to character; it is out of 0-65535 range type.error.cant.convert.to.java.string=Cannot convert object of type {0} to a Java argument of string type type.error.cant.convert.to.java.number=Cannot convert object of type {0} to a Java argument of number type -type.error.cant.convert.to.javascript.array=Can only convert Java arrays and lists to JavaScript arrays. Can't convert object of type {0}. +type.error.cant.convert.to.javascript.array=Can only convert Java arrays and lists to JavaScript arrays. Cannot convert object of type {0}. type.error.extend.expects.at.least.one.argument=Java.extend needs at least one argument. type.error.extend.expects.at.least.one.type.argument=Java.extend needs at least one type argument. type.error.extend.expects.java.types=Java.extend needs Java types as its arguments. @@ -141,10 +141,10 @@ type.error.extend.ERROR_FINAL_FINALIZER=Can not extend class because {0} has a final finalize method. type.error.no.constructor.matches.args=Can not construct {0} with the passed arguments; they do not match any of its constructor signatures. type.error.no.method.matches.args=Can not invoke method {0} with the passed arguments; they do not match any of its method signatures. -type.error.method.not.constructor=Java method {0} can't be used as a constructor. +type.error.method.not.constructor=Java method {0} cannot be used as a constructor. type.error.env.not.object=$ENV must be an Object. type.error.unsupported.java.to.type=Unsupported Java.to target type {0}. -type.error.constructor.requires.new=Constructor {0} requires 'new'. +type.error.constructor.requires.new=Constructor {0} requires "new". type.error.new.on.nonpublic.javatype=new cannot be used with non-public java type {0}. range.error.dataview.constructor.offset=Wrong offset or length in DataView constructor diff -r 66228a695a62 -r 00b27213d86c nashorn/test/script/basic/JDK-8043232.js --- a/nashorn/test/script/basic/JDK-8043232.js Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/test/script/basic/JDK-8043232.js Fri Sep 19 11:19:38 2014 -0700 @@ -29,14 +29,14 @@ */ // call explicit constructor -print(new (java.awt["Color(int,int,int)"])(255,0,255)); +print(new (java.lang["String(char[],int,int)"])(['a','b', 'c', 'd'], 1, 3)); // print the constructor itself -print(java.awt["Color(int,int,int)"]); +print(java.lang["String(char[],int,int)"]); // store constructor to call later -var Color = java.awt["Color(int,int,int)"]; +var Color = java.lang["String(char[],int,int)"]; // call stored constructor -print(new Color(33, 233, 2)) +print(new Color(['r','r', 'e', 'd'], 1, 3)) // check if default constructor works var obj = new (java.lang["Object()"])(); diff -r 66228a695a62 -r 00b27213d86c nashorn/test/script/basic/JDK-8043232.js.EXPECTED --- a/nashorn/test/script/basic/JDK-8043232.js.EXPECTED Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/test/script/basic/JDK-8043232.js.EXPECTED Fri Sep 19 11:19:38 2014 -0700 @@ -1,14 +1,14 @@ -java.awt.Color[r=255,g=0,b=255] -[jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] -java.awt.Color[r=33,g=233,b=2] +bcd +[jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)] +red TypeError: No such Java class: java.lang.NonExistent TypeError: No such Java constructor: Object(String) TypeError: Java constructor signature invalid: Object()xxxxx TypeError: Java constructor signature invalid: Object( TypeError: Java constructor signature invalid: Object) -TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.lang.System.getProperty] cant be used as a constructor. -TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println] cant be used as a constructor. -TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] requires new. +TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.lang.System.getProperty] cannot be used as a constructor. +TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println] cannot be used as a constructor. +TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)] requires "new". TypeError: No such Java constructor: Runnable() TypeError: No such Java constructor: Runnable(int) java.lang.InstantiationException: java.io.InputStream diff -r 66228a695a62 -r 00b27213d86c nashorn/test/script/basic/JDK-8049086.js --- a/nashorn/test/script/basic/JDK-8049086.js Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/test/script/basic/JDK-8049086.js Fri Sep 19 11:19:38 2014 -0700 @@ -58,7 +58,7 @@ // (a) Java methods (b) Java classes (as these respond to new) // (c) FunctionalInterface objects (d) JSObjects that are 'functions' -print("java.awt.Color is java function? " + Java.isJavaFunction(java.awt.Color)); +print("java.lang.String is java function? " + Java.isJavaFunction(java.lang.String)); print("java.lang.Runnable instance is java function? " + Java.isJavaFunction(new java.lang.Runnable(function() {}))); print("eval is java function? " + Java.isJavaFunction(eval)); diff -r 66228a695a62 -r 00b27213d86c nashorn/test/script/basic/JDK-8049086.js.EXPECTED --- a/nashorn/test/script/basic/JDK-8049086.js.EXPECTED Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/test/script/basic/JDK-8049086.js.EXPECTED Fri Sep 19 11:19:38 2014 -0700 @@ -13,7 +13,7 @@ Object is script object? true {} is script object? true /foo/ is script object? true -java.awt.Color is java function? true +java.lang.String is java function? true java.lang.Runnable instance is java function? true eval is java function? false println is java function? true diff -r 66228a695a62 -r 00b27213d86c nashorn/test/script/basic/JDK-8049242.js --- a/nashorn/test/script/basic/JDK-8049242.js Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/test/script/basic/JDK-8049242.js Fri Sep 19 11:19:38 2014 -0700 @@ -29,14 +29,14 @@ */ // call explicit constructor -print(new (Java.type("java.awt.Color")["(int,int,int)"])(255,0,255)); +print(new (Java.type("java.lang.String")["(char[],int,int)"])(['a', 'b', 'c'],0, 3)); // print the constructor itself -print(Java.type("java.awt.Color")["(int,int,int)"]); +print(Java.type("java.lang.String")["(char[],int,int)"]); // store constructor to call later -var Color = Java.type("java.awt.Color")["(int,int,int)"]; +var Color = Java.type("java.lang.String")["(char[],int,int)"]; // call stored constructor -print(new Color(33, 233, 2)) +print(new Color(['j', 'a', 'v', 'a'], 1, 3)) // check if default constructor works var obj = new (Java.type("java.lang.Object")["()"])(); diff -r 66228a695a62 -r 00b27213d86c nashorn/test/script/basic/JDK-8049242.js.EXPECTED --- a/nashorn/test/script/basic/JDK-8049242.js.EXPECTED Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/test/script/basic/JDK-8049242.js.EXPECTED Fri Sep 19 11:19:38 2014 -0700 @@ -1,10 +1,10 @@ -java.awt.Color[r=255,g=0,b=255] -[jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] -java.awt.Color[r=33,g=233,b=2] +abc +[jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)] +ava TypeError: null is not a function TypeError: null is not a function TypeError: null is not a function -TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] requires new. +TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)] requires "new". TypeError: null is not a function TypeError: null is not a function java.lang.InstantiationException: java.io.InputStream diff -r 66228a695a62 -r 00b27213d86c nashorn/test/script/basic/JDK-8056978.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8056978.js Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8056978: ClassCastException: cannot cast jdk.nashorn.internal.scripts.JO* + * + * @test + * @run + */ + +var obj1 = { + 'name': 'test name', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5' +}; + +var obj2 = { + 'name': 'hello' +}; + +print(obj2['name']); +print(obj2.name); + diff -r 66228a695a62 -r 00b27213d86c nashorn/test/script/basic/JDK-8056978.js.EXPECTED --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8056978.js.EXPECTED Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,2 @@ +hello +hello diff -r 66228a695a62 -r 00b27213d86c nashorn/test/script/basic/JDK-8058422.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8058422.js Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8058422: Users should be able to overwrite "context" and "engine" variables + * + * @test + * @run + */ + +var m = new javax.script.ScriptEngineManager(); +var e = m.getEngineByName("nashorn"); +e.put("foo", "hello"); +var obj = e.eval("context.getAttribute('foo')"); +if (obj != "hello") { + fail("Expected 'obj' to be 'hello'"); +} + +e.put("context", "bar"); +if (e.eval("context") != "bar") { + fail("Expected 'context' to be 'bar'"); +} + +if (e.eval("foo") != "hello") { + fail("Expected 'foo' to be 'hello'"); +} + +if (e.eval("engine") != e) { + fail("'engine' is not evaluaed to current engine"); +} + +e.put("engine", "foobar"); +if (e.eval("engine") != "foobar") { + fail("'engine' is not evalued to 'foobar'"); +} diff -r 66228a695a62 -r 00b27213d86c nashorn/test/script/basic/JDK-8058545.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8058545.js Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8058545: With strict mode, bean property assignment of a non-existent property should result in TypeError + * + * @test + * @run + */ + +'use strict'; +var File = Java.type("java.io.File"); +var f = new File("."); +try { + f.foo = 33; + fail("Should have thrown TypeError"); +} catch (e) { + if (! (e instanceof TypeError)) { + fail("Expected TypeError, got " + e); + } +} diff -r 66228a695a62 -r 00b27213d86c nashorn/test/script/basic/JDK-8058615.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8058615.js Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8058615: Overload resolution ambiguity involving ConsString + * + * @test + * @run + */ + +var strw = new java.io.StringWriter(); +var bufw = new java.io.BufferedWriter(strw); +var s = "hello "; +bufw.write(s + "world"); +bufw.close(); +print(strw.toString()); diff -r 66228a695a62 -r 00b27213d86c nashorn/test/script/basic/JDK-8058615.js.EXPECTED --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8058615.js.EXPECTED Fri Sep 19 11:19:38 2014 -0700 @@ -0,0 +1,1 @@ +hello world diff -r 66228a695a62 -r 00b27213d86c nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java --- a/nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java Fri Sep 19 11:13:27 2014 -0700 +++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java Fri Sep 19 11:19:38 2014 -0700 @@ -582,6 +582,60 @@ assertEquals(e.eval("x", newCtxt), 2); } + // @bug 8058422: Users should be able to overwrite "context" and "engine" variables + @Test + public static void contextOverwriteTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings b = new SimpleBindings(); + b.put("context", "hello"); + b.put("foo", 32); + final ScriptContext newCtxt = new SimpleScriptContext(); + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + e.setContext(newCtxt); + assertEquals(e.eval("context"), "hello"); + assertEquals(((Number)e.eval("foo")).intValue(), 32); + } + + // @bug 8058422: Users should be able to overwrite "context" and "engine" variables + @Test + public static void contextOverwriteInScriptTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + e.put("foo", 32); + + assertEquals(((Number)e.eval("foo")).intValue(), 32); + assertEquals(e.eval("context = 'bar'"), "bar"); + assertEquals(((Number)e.eval("foo")).intValue(), 32); + } + + // @bug 8058422: Users should be able to overwrite "context" and "engine" variables + @Test + public static void engineOverwriteTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings b = new SimpleBindings(); + b.put("engine", "hello"); + b.put("foo", 32); + final ScriptContext newCtxt = new SimpleScriptContext(); + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + e.setContext(newCtxt); + assertEquals(e.eval("engine"), "hello"); + assertEquals(((Number)e.eval("foo")).intValue(), 32); + } + + // @bug 8058422: Users should be able to overwrite "context" and "engine" variables + @Test + public static void engineOverwriteInScriptTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + e.put("foo", 32); + + assertEquals(((Number)e.eval("foo")).intValue(), 32); + assertEquals(e.eval("engine = 'bar'"), "bar"); + assertEquals(((Number)e.eval("foo")).intValue(), 32); + } + // @bug 8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook @Test public static void testMegamorphicGetInGlobal() throws Exception {