# HG changeset patch # User duke # Date 1499268747 -7200 # Node ID f1df068076986679ea1105532a65529d63a89060 # Parent c4808ff47e60c6b03ebf81b24e991ab0b3e59411# Parent 4d4f07f87e289caff55d49b85ba06938431b4537 Merge diff -r 4d4f07f87e28 -r f1df06807698 .hgtags-top-repo --- a/.hgtags-top-repo Wed Jul 05 17:31:42 2017 +0200 +++ b/.hgtags-top-repo Wed Jul 05 17:32:27 2017 +0200 @@ -99,3 +99,4 @@ f1591eed71f64f6eba79fb7426f5616cc4dfea73 jdk7-b122 ed6950da30cf1e8904b4bdb034d471647942271f jdk7-b123 024a6755895bf91b5a3c98984c89ee018efbf538 jdk7-b124 +5c4df7e992775c102f08e9f1c0a124b324641b70 jdk7-b125 diff -r 4d4f07f87e28 -r f1df06807698 corba/.hgtags --- a/corba/.hgtags Wed Jul 05 17:31:42 2017 +0200 +++ b/corba/.hgtags Wed Jul 05 17:32:27 2017 +0200 @@ -99,3 +99,4 @@ 1523a060032c8a5b7840198da8911abeff88118f jdk7-b122 a230c142628cea22475ab9dc5cd544266ddf2466 jdk7-b123 f90b3e014e831eb4f32ef035a1dad2b8ba87949f jdk7-b124 +1ce58c72b7892cb813eb920276c7e7f17a1b79fe jdk7-b125 diff -r 4d4f07f87e28 -r f1df06807698 hotspot/.hgtags --- a/hotspot/.hgtags Wed Jul 05 17:31:42 2017 +0200 +++ b/hotspot/.hgtags Wed Jul 05 17:32:27 2017 +0200 @@ -140,3 +140,4 @@ 9669f9b284108a9ee0a0ccbe215c37a130c9dcf5 hs20-b04 0a8e0d4345b37b71ec49dda08ee03b68c4f1b592 jdk7-b124 0a8e0d4345b37b71ec49dda08ee03b68c4f1b592 hs20-b05 +e24ab3fa6aafad3efabbe7dba9918c5f461a20b1 jdk7-b125 diff -r 4d4f07f87e28 -r f1df06807698 jaxp/.hgtags --- a/jaxp/.hgtags Wed Jul 05 17:31:42 2017 +0200 +++ b/jaxp/.hgtags Wed Jul 05 17:32:27 2017 +0200 @@ -99,3 +99,4 @@ 03ff13d19c8fa983cbab6542930a7f352e9b5b33 jdk7-b122 e2aedea6495d61557326928de20dbb2d78fdd9aa jdk7-b123 57ed1f3bec72924cdad102f9bf90f7449ea7bb83 jdk7-b124 +6c9bdee0cc3a8912acc5189cc092b8cba6851f9d jdk7-b125 diff -r 4d4f07f87e28 -r f1df06807698 jaxp/jaxp.properties --- a/jaxp/jaxp.properties Wed Jul 05 17:31:42 2017 +0200 +++ b/jaxp/jaxp.properties Wed Jul 05 17:32:27 2017 +0200 @@ -25,13 +25,13 @@ drops.master.copy.base=${drops.dir} -jaxp_src.bundle.name=jaxp-1_4_4.zip -jaxp_src.bundle.md5.checksum=2c40a758392c4abf2d59f355240df46a +jaxp_src.bundle.name=jaxp-1_4_5-dev.zip +jaxp_src.bundle.md5.checksum=84e2c26853262c9144133c6ff7ef5dc9 jaxp_src.master.bundle.dir=${drops.master.copy.base} -jaxp_src.master.bundle.url.base=https://java.net/downloads/jaxp/jdk7 +jaxp_src.master.bundle.url.base=http://download.java.net/jaxp/1.4.5/dev -#jaxp_tests.bundle.name=jaxp-unittests-1_4_4.zip -#jaxp_tests.bundle.md5.checksum=51845e38b02920cf5374d0331ab3a4ee -#jaxp_tests.master.bundle.dir=${drops.master.copy.base} -#jaxp_tests.master.bundle.url.base=https://java.net/downloads/jaxp/jdk7 +jaxp_tests.bundle.name=jaxp-1_4_5-dev-unittests.zip +jaxp_tests.bundle.md5.checksum=0377e715fa21814cb8006768c5967dc5 +jaxp_tests.master.bundle.dir=${drops.master.copy.base} +jaxp_tests.master.bundle.url.base=http://download.java.net/jaxp/1.4.5/dev diff -r 4d4f07f87e28 -r f1df06807698 jaxws/.hgtags --- a/jaxws/.hgtags Wed Jul 05 17:31:42 2017 +0200 +++ b/jaxws/.hgtags Wed Jul 05 17:32:27 2017 +0200 @@ -99,3 +99,4 @@ 17b6c48a344968880925dcef1178fec282feb335 jdk7-b122 5a8e43bcce56b7cd5576419067a929b74575ae71 jdk7-b123 86f60e5b3975840968f3147ddce047a27a9fc83e jdk7-b124 +d72eea121c3bc2b649272a37b80d9417855b7146 jdk7-b125 diff -r 4d4f07f87e28 -r f1df06807698 jaxws/jaxws.properties --- a/jaxws/jaxws.properties Wed Jul 05 17:31:42 2017 +0200 +++ b/jaxws/jaxws.properties Wed Jul 05 17:32:27 2017 +0200 @@ -25,10 +25,10 @@ drops.master.copy.base=${drops.dir} -jaxws_src.bundle.name= jdk7-jaxws2_2-2010_08_19.zip -jaxws_src.bundle.md5.checksum=8775ccefd3b4fa2dde5155ec4b7e4ceb +jaxws_src.bundle.name=jdk7-jaxws2_2_2-2010_12_14.zip +jaxws_src.bundle.md5.checksum=fee9ac72fabc96719eefc66ecaff4bc3 jaxws_src.master.bundle.dir=${drops.master.copy.base} -jaxws_src.master.bundle.url.base=https://java.net/downloads/jax-ws/JDK7 +jaxws_src.master.bundle.url.base=http://download.java.net/glassfish/components/jax-ws/openjdk/jdk7 jaf_src.bundle.name=jdk7-jaf-2010_08_19.zip jaf_src.bundle.md5.checksum=18d15dfd71117daadb332af003d08212 diff -r 4d4f07f87e28 -r f1df06807698 jdk/.hgtags --- a/jdk/.hgtags Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/.hgtags Wed Jul 05 17:32:27 2017 +0200 @@ -99,3 +99,4 @@ ac311eb325bfc763698219252bf3cee9e091f3af jdk7-b122 869190935eedee7750d955019ab2a1b80f0a13a8 jdk7-b123 1c72adc9d5f331cb882cf5354ba0dcb118a60b23 jdk7-b124 +0a56bdd709d01c1663047e55201d19152ffd3d69 jdk7-b125 diff -r 4d4f07f87e28 -r f1df06807698 jdk/make/common/shared/Defs-java.gmk --- a/jdk/make/common/shared/Defs-java.gmk Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/make/common/shared/Defs-java.gmk Wed Jul 05 17:32:27 2017 +0200 @@ -155,7 +155,7 @@ "-Xbootclasspath/p:$(JAVAC_JAR)" \ -jar $(JAVAC_JAR) $(JAVACFLAGS) JAVAH_CMD = $(BOOT_JAVA_CMD) \ - "-Xbootclasspath/p:$(JAVAH_JAR)$(CLASSPATH_SEPARATOR)$(JAVADOC_JAR)$(CLASSPATH_SEPARATOR)$(JAVAC_JAR)" \ + "-Xbootclasspath/p:$(JAVAH_JAR)$(CLASSPATH_SEPARATOR)$(JAVAC_JAR)" \ -jar $(JAVAH_JAR) $(JAVAHFLAGS) JAVADOC_CMD = $(BOOT_JAVA_CMD) \ "-Xbootclasspath/p:$(JAVADOC_JAR)$(CLASSPATH_SEPARATOR)$(JAVAC_JAR)$(CLASSPATH_SEPARATOR)$(DOCLETS_JAR)" \ diff -r 4d4f07f87e28 -r f1df06807698 jdk/make/sun/Makefile --- a/jdk/make/sun/Makefile Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/make/sun/Makefile Wed Jul 05 17:32:27 2017 +0200 @@ -42,7 +42,15 @@ ifndef OPENJDK ifeq ($(PLATFORM), solaris) ifneq ($(ARCH), amd64) - DGA_SUBDIR = jdga + # Solaris 11 does not have support for new compilation of DGA code. + OS_VERSION = $(shell uname -r) + OS_MAJOR_VERSION := $(call MajorVersion,$(OS_VERSION)) + OS_MINOR_VERSION := $(call MinorVersion,$(OS_VERSION)) + ifeq ($(shell $(EXPR) $(OS_MAJOR_VERSION) == 5), 1) + ifeq ($(shell $(EXPR) $(OS_MINOR_VERSION) \<= 10), 1) + DGA_SUBDIR = jdga + endif + endif endif endif endif diff -r 4d4f07f87e28 -r f1df06807698 jdk/make/sun/awt/Makefile --- a/jdk/make/sun/awt/Makefile Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/make/sun/awt/Makefile Wed Jul 05 17:32:27 2017 +0200 @@ -175,6 +175,10 @@ include $(BUILDDIR)/common/Mapfile-vers.gmk include $(BUILDDIR)/common/Library.gmk +COMPILEFONTCONFIG_FLAGS = +ifdef ALT_COMPILEFONTCONFIG_FLAGS + COMPILEFONTCONFIG_FLAGS += $(ALT_COMPILEFONTCONFIG_FLAGS) +endif build: fontconfigs @@ -406,7 +410,7 @@ $(LIBDIR)/%.bfc: $(FONTCONFIGS_SRC)/$(FONTCONFIGS_SRC_PREFIX)%.properties \ $(COMPILEFONTCONFIG_JARFILE) $(prep-target) - $(BOOT_JAVA_CMD) -jar $(COMPILEFONTCONFIG_JARFILE) $< $@ + $(BOOT_JAVA_CMD) -jar $(COMPILEFONTCONFIG_JARFILE) $(COMPILEFONTCONFIG_FLAGS) $< $@ $(install-module-file) $(call chmod-file, 444) @$(java-vm-cleanup) diff -r 4d4f07f87e28 -r f1df06807698 jdk/make/sun/awt/make.depend --- a/jdk/make/sun/awt/make.depend Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/make/sun/awt/make.depend Wed Jul 05 17:32:27 2017 +0200 @@ -224,7 +224,7 @@ $(OBJDIR)/DrawLine.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawLine.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h -$(OBJDIR)/DrawParallelogram.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawParallelogram.h $(CLASSHDRDIR)/sun_java2d_loops_FillParallelogram.h ../../../src/share/javavm/export/classfile_constants.h ../../../src/share/javavm/export/jni.h ../../../src/share/javavm/export/jvm.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/awt/debug/debug_assert.h ../../../src/share/native/sun/awt/debug/debug_mem.h ../../../src/share/native/sun/awt/debug/debug_trace.h ../../../src/share/native/sun/awt/debug/debug_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/LoopMacros.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/share/native/sun/java2d/Trace.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/javavm/export/jvm_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h +$(OBJDIR)/DrawParallelogram.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawParallelogram.h ../../../src/share/javavm/export/classfile_constants.h ../../../src/share/javavm/export/jni.h ../../../src/share/javavm/export/jvm.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/awt/debug/debug_assert.h ../../../src/share/native/sun/awt/debug/debug_mem.h ../../../src/share/native/sun/awt/debug/debug_trace.h ../../../src/share/native/sun/awt/debug/debug_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/ParallelogramUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/share/native/sun/java2d/Trace.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/javavm/export/jvm_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h $(OBJDIR)/DrawPath.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawPath.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/DrawPath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/ProcessPath.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h @@ -232,7 +232,7 @@ $(OBJDIR)/DrawRect.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawRect.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h -$(OBJDIR)/FillParallelogram.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_FillParallelogram.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h +$(OBJDIR)/FillParallelogram.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_FillParallelogram.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/ParallelogramUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h $(OBJDIR)/FillPath.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_FillPath.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/DrawPath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/ProcessPath.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h @@ -284,7 +284,7 @@ $(OBJDIR)/MaskBlit.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_MaskBlit.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/pipe/Region.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/awt/utility/rect.h ../../../src/windows/native/sun/java2d/j2d_md.h -$(OBJDIR)/MaskFill.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_MaskFill.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h +$(OBJDIR)/MaskFill.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_MaskFill.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/ParallelogramUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h $(OBJDIR)/MouseInfo.obj:: $(CLASSHDRDIR)/java_awt_AWTEvent.h $(CLASSHDRDIR)/java_awt_Component.h $(CLASSHDRDIR)/java_awt_Dimension.h $(CLASSHDRDIR)/java_awt_Event.h $(CLASSHDRDIR)/java_awt_event_FocusEvent.h $(CLASSHDRDIR)/java_awt_event_KeyEvent.h $(CLASSHDRDIR)/java_awt_event_MouseEvent.h $(CLASSHDRDIR)/java_awt_event_WindowEvent.h $(CLASSHDRDIR)/java_awt_Font.h $(CLASSHDRDIR)/sun_awt_FontDescriptor.h $(CLASSHDRDIR)/sun_awt_PlatformFont.h $(CLASSHDRDIR)/sun_awt_windows_WComponentPeer.h $(CLASSHDRDIR)/sun_awt_windows_WFontMetrics.h $(CLASSHDRDIR)/sun_awt_windows_WObjectPeer.h $(CLASSHDRDIR)/sun_awt_windows_WToolkit.h ../../../src/share/javavm/export/classfile_constants.h ../../../src/share/javavm/export/jni.h ../../../src/share/javavm/export/jvm.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/awt/debug/debug_assert.h ../../../src/share/native/sun/awt/debug/debug_mem.h ../../../src/share/native/sun/awt/debug/debug_trace.h ../../../src/share/native/sun/awt/debug/debug_util.h ../../../src/share/native/sun/awt/image/cvutils/img_globals.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/share/native/sun/java2d/Trace.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/javavm/export/jvm_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.h ../../../src/windows/native/sun/windows/alloc.h ../../../src/windows/native/sun/windows/awt.h ../../../src/windows/native/sun/windows/awtmsg.h ../../../src/windows/native/sun/windows/awt_Brush.h ../../../src/windows/native/sun/windows/awt_Component.h ../../../src/windows/native/sun/windows/awt_Debug.h ../../../src/windows/native/sun/windows/awt_Font.h ../../../src/windows/native/sun/windows/awt_GDIObject.h ../../../src/windows/native/sun/windows/awt_Object.h ../../../src/windows/native/sun/windows/awt_Palette.h ../../../src/windows/native/sun/windows/awt_Pen.h ../../../src/windows/native/sun/windows/awt_Toolkit.h ../../../src/windows/native/sun/windows/awt_Win32GraphicsDevice.h ../../../src/windows/native/sun/windows/colordata.h ../../../src/windows/native/sun/windows/Devices.h ../../../src/windows/native/sun/windows/GDIHashtable.h ../../../src/windows/native/sun/windows/Hashtable.h ../../../src/windows/native/sun/windows/ObjectList.h ../../../src/windows/native/sun/windows/stdhdrs.h diff -r 4d4f07f87e28 -r f1df06807698 jdk/make/sun/awt/mapfile-vers --- a/jdk/make/sun/awt/mapfile-vers Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/make/sun/awt/mapfile-vers Wed Jul 05 17:32:27 2017 +0200 @@ -118,6 +118,8 @@ Java_sun_java2d_loops_GraphicsPrimitiveMgr_registerNativeLoops; Java_sun_java2d_loops_MaskBlit_MaskBlit; Java_sun_java2d_loops_MaskFill_MaskFill; + Java_sun_java2d_loops_MaskFill_FillAAPgram; + Java_sun_java2d_loops_MaskFill_DrawAAPgram; Java_sun_java2d_loops_TransformHelper_Transform; Java_sun_java2d_pipe_Region_initIDs; Java_sun_java2d_pipe_SpanClipRenderer_initIDs; diff -r 4d4f07f87e28 -r f1df06807698 jdk/make/sun/awt/mapfile-vers-linux --- a/jdk/make/sun/awt/mapfile-vers-linux Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/make/sun/awt/mapfile-vers-linux Wed Jul 05 17:32:27 2017 +0200 @@ -115,6 +115,8 @@ Java_sun_java2d_loops_GraphicsPrimitiveMgr_registerNativeLoops; Java_sun_java2d_loops_MaskBlit_MaskBlit; Java_sun_java2d_loops_MaskFill_MaskFill; + Java_sun_java2d_loops_MaskFill_FillAAPgram; + Java_sun_java2d_loops_MaskFill_DrawAAPgram; Java_sun_java2d_pipe_BufferedRenderPipe_fillSpans; Java_sun_java2d_pipe_SpanClipRenderer_initIDs; sun_awt_image_GifImageDecoder_initIDs; diff -r 4d4f07f87e28 -r f1df06807698 jdk/make/tools/src/build/tools/javazic/Zoneinfo.java --- a/jdk/make/tools/src/build/tools/javazic/Zoneinfo.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/make/tools/src/build/tools/javazic/Zoneinfo.java Wed Jul 05 17:32:27 2017 +0200 @@ -222,6 +222,7 @@ boolean continued = false; Zone zone = null; String l; + lineNum = 0; try { while ((line = in.readLine()) != null) { diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/bin/java.c --- a/jdk/src/share/bin/java.c Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/bin/java.c Wed Jul 05 17:32:27 2017 +0200 @@ -158,8 +158,9 @@ * Running Java code in primordial thread caused many problems. We will * create a new thread to invoke JVM. See 6316197 for more information. */ -static jlong threadStackSize = 0; /* stack size of the new thread */ -static jlong heapSize = 0; /* heap size */ +static jlong threadStackSize = 0; /* stack size of the new thread */ +static jlong maxHeapSize = 0; /* max heap size */ +static jlong initialHeapSize = 0; /* inital heap size */ int JNICALL JavaMain(void * args); /* entry point */ @@ -381,7 +382,7 @@ if (showSettings != NULL) { ShowSettings(env, showSettings); - CHECK_EXCEPTION_LEAVE(0); + CHECK_EXCEPTION_LEAVE(1); } /* If the user specified neither a class name nor a JAR file */ if (printXUsage || printUsage || (jarfile == 0 && classname == 0)) { @@ -689,7 +690,14 @@ if (JLI_StrCCmp(str, "-Xmx") == 0) { jlong tmp; if (parse_size(str + 4, &tmp)) { - heapSize = tmp; + maxHeapSize = tmp; + } + } + + if (JLI_StrCCmp(str, "-Xms") == 0) { + jlong tmp; + if (parse_size(str + 4, &tmp)) { + initialHeapSize = tmp; } } } @@ -1506,12 +1514,13 @@ jstring joptString; NULL_CHECK(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper")); NULL_CHECK(showSettingsID = (*env)->GetStaticMethodID(env, cls, - "showSettings", "(ZLjava/lang/String;JJZ)V")); + "showSettings", "(ZLjava/lang/String;JJJZ)V")); joptString = (*env)->NewStringUTF(env, optString); (*env)->CallStaticVoidMethod(env, cls, showSettingsID, JNI_TRUE, joptString, - (jlong)heapSize, + (jlong)initialHeapSize, + (jlong)maxHeapSize, (jlong)threadStackSize, ServerClassMachine()); } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/AdaptiveCoding.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/AdaptiveCoding.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/AdaptiveCoding.java Wed Jul 05 17:32:27 2017 +0200 @@ -29,13 +29,14 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import static com.sun.java.util.jar.pack.Constants.*; /** * Adaptive coding. * See the section "Adaptive Encodings" in the Pack200 spec. * @author John Rose */ -class AdaptiveCoding implements Constants, CodingMethod { +class AdaptiveCoding implements CodingMethod { CodingMethod headCoding; int headLength; CodingMethod tailCoding; @@ -147,7 +148,6 @@ } if (KX == KX_MAX) return Integer.MAX_VALUE; KX += 1; - int unit2 = 1 << (KX * KX_LG2BASE); int mask2 = KB_MAX << (KX * KX_LG2BASE); K1 |= (mask & ~mask2); K1 += unit; @@ -250,7 +250,7 @@ return m.toString(); } public String toString() { - StringBuffer res = new StringBuffer(20); + StringBuilder res = new StringBuilder(20); AdaptiveCoding run = this; res.append("run("); for (;;) { diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java Wed Jul 05 17:32:27 2017 +0200 @@ -36,6 +36,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import static com.sun.java.util.jar.pack.Constants.*; /** * Represents an attribute in a class-file. @@ -44,7 +45,7 @@ * attribute layouts. * @author John Rose */ -class Attribute implements Comparable, Constants { +class Attribute implements Comparable { // Attribute instance fields. Layout def; // the name and format of this attr @@ -103,7 +104,6 @@ return this.def.compareTo(that.def); } - private static final byte[] noBytes = {}; private static final Map, List> canonLists = new HashMap<>(); private static final Map attributes = new HashMap<>(); private static final Map standardDefs = new HashMap<>(); @@ -112,7 +112,7 @@ // are used by trimToSize, in order to reduce footprint // of some common cases. (Note that Code attributes are // always zero size.) - public static List getCanonList(List al) { + public static List getCanonList(List al) { synchronized (canonLists) { List cl = canonLists.get(al); if (cl == null) { @@ -465,7 +465,9 @@ return ConstantPool.getUtf8Entry(name()); } - public boolean isEmpty() { return layout == ""; } + public boolean isEmpty() { + return layout.isEmpty(); + } public Layout(int ctype, String name, String layout) { this.ctype = ctype; @@ -479,19 +481,19 @@ } else { String[] bodies = splitBodies(layout); // Make the callables now, so they can be linked immediately. - Element[] elems = new Element[bodies.length]; - this.elems = elems; - for (int i = 0; i < elems.length; i++) { + Element[] lelems = new Element[bodies.length]; + this.elems = lelems; + for (int i = 0; i < lelems.length; i++) { Element ce = this.new Element(); ce.kind = EK_CBLE; ce.removeBand(); ce.bandIndex = NO_BAND_INDEX; ce.layout = bodies[i]; - elems[i] = ce; + lelems[i] = ce; } // Next fill them in. - for (int i = 0; i < elems.length; i++) { - Element ce = elems[i]; + for (int i = 0; i < lelems.length; i++) { + Element ce = lelems[i]; ce.body = tokenizeLayout(this, i, bodies[i]); } //System.out.println(Arrays.asList(elems)); @@ -525,11 +527,12 @@ } public boolean equals(Object x) { - return x instanceof Layout && equals((Layout)x); + return ( x != null) && ( x.getClass() == Layout.class ) && + equals((Layout)x); } public boolean equals(Layout that) { - return this.name == that.name - && this.layout == that.layout + return this.name.equals(that.name) + && this.layout.equals(that.layout) && this.ctype == that.ctype; } public int hashCode() { @@ -589,14 +592,14 @@ return str; } private String stringForDebug() { - Element[] body = this.body; + Element[] lbody = this.body; switch (kind) { case EK_CALL: - body = null; + lbody = null; break; case EK_CASE: if (flagTest(EF_BACK)) - body = null; + lbody = null; break; } return layout @@ -604,7 +607,7 @@ + "<"+ (flags==0?"":""+flags)+kind+len + (refKind==0?"":""+refKind) + ">" + (value==0?"":"("+value+")") - + (body==null?"": ""+Arrays.asList(body)); + + (lbody==null?"": ""+Arrays.asList(lbody)); } } @@ -613,16 +616,19 @@ } static private final Element[] noElems = {}; public Element[] getCallables() { - if (hasCallables()) - return elems; - else + if (hasCallables()) { + Element[] nelems = Arrays.copyOf(elems, elems.length); + return nelems; + } else return noElems; // no callables at all } public Element[] getEntryPoint() { if (hasCallables()) return elems[0].body; // body of first callable - else - return elems; // no callables; whole body + else { + Element[] nelems = Arrays.copyOf(elems, elems.length); + return nelems; // no callables; whole body + } } /** Return a sequence of tokens from the given attribute bytes. @@ -674,7 +680,7 @@ } } - void visitRefs(Holder holder, int mode, final Collection refs) { + void visitRefs(Holder holder, int mode, final Collection refs) { if (mode == VRM_CLASSIC) { refs.add(getNameRef()); } @@ -720,7 +726,7 @@ */ static public String normalizeLayoutString(String layout) { - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); for (int i = 0, len = layout.length(); i < len; ) { char ch = layout.charAt(i++); if (ch <= ' ') { @@ -832,14 +838,14 @@ */ static //private Layout.Element[] tokenizeLayout(Layout self, int curCble, String layout) { - ArrayList col = new ArrayList<>(layout.length()); + List col = new ArrayList<>(layout.length()); tokenizeLayout(self, curCble, layout, col); Layout.Element[] res = new Layout.Element[col.size()]; col.toArray(res); return res; } static //private - void tokenizeLayout(Layout self, int curCble, String layout, ArrayList col) { + void tokenizeLayout(Layout self, int curCble, String layout, List col) { boolean prevBCI = false; for (int len = layout.length(), i = 0; i < len; ) { int start = i; @@ -897,7 +903,7 @@ case 'T': // union: 'T' any_int union_case* '(' ')' '[' body ']' kind = EK_UN; i = tokenizeSInt(e, layout, i); - ArrayList cases = new ArrayList<>(); + List cases = new ArrayList<>(); for (;;) { // Keep parsing cases until we hit the default case. if (layout.charAt(i++) != '(') @@ -1051,7 +1057,7 @@ } static //private String[] splitBodies(String layout) { - ArrayList bodies = new ArrayList<>(); + List bodies = new ArrayList<>(); // Parse several independent layout bodies: "[foo][bar]...[baz]" for (int i = 0; i < layout.length(); i++) { if (layout.charAt(i++) != '[') @@ -1156,7 +1162,7 @@ String expandCaseDashNotation(String layout) { int dash = findCaseDash(layout, 0); if (dash < 0) return layout; // no dashes (the common case) - StringBuffer result = new StringBuffer(layout.length() * 3); + StringBuilder result = new StringBuilder(layout.length() * 3); int sofar = 0; // how far have we processed the layout? for (;;) { // for each dash, collect everything up to the dash diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java Wed Jul 05 17:32:27 2017 +0200 @@ -44,16 +44,17 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.jar.Pack200; +import static com.sun.java.util.jar.pack.Constants.*; /** * Define the structure and ordering of "bands" in a packed file. * @author John Rose */ abstract -class BandStructure implements Constants { +class BandStructure { static final int MAX_EFFORT = 9; static final int MIN_EFFORT = 1; static final int DEFAULT_EFFORT = 5; @@ -251,18 +252,18 @@ null }; - final private static HashMap basicCodingIndexes; + final private static Map basicCodingIndexes; static { assert(basicCodings[_meta_default] == null); assert(basicCodings[_meta_canon_min] != null); assert(basicCodings[_meta_canon_max] != null); - HashMap map = new HashMap(); + Map map = new HashMap<>(); for (int i = 0; i < basicCodings.length; i++) { Coding c = basicCodings[i]; if (c == null) continue; assert(i >= _meta_canon_min); assert(i <= _meta_canon_max); - map.put(c, new Integer(i)); + map.put(c, i); } basicCodingIndexes = map; } @@ -270,12 +271,12 @@ return i < basicCodings.length ? basicCodings[i] : null; } public static int indexOf(Coding c) { - Integer i = (Integer) basicCodingIndexes.get(c); + Integer i = basicCodingIndexes.get(c); if (i == null) return 0; return i.intValue(); } public static Coding[] getBasicCodings() { - return (Coding[]) basicCodings.clone(); + return basicCodings.clone(); } protected byte[] bandHeaderBytes; // used for input only @@ -687,7 +688,6 @@ } bandCoding.writeArrayTo(out, values, 0, length); if (out == outputCounter) { - long len1 = outputCounter.getCount(); assert(outputSize == outputCounter.getCount() - len0) : (outputSize+" != "+outputCounter.getCount()+"-"+len0); } @@ -1050,8 +1050,8 @@ // Bootstrap support for CPRefBands. These are needed to record // intended CP indexes, before the CP has been created. - private ArrayList allKQBands = new ArrayList(); - private ArrayList needPredefIndex = new ArrayList(); + private final List allKQBands = new ArrayList<>(); + private List needPredefIndex = new ArrayList<>(); int encodeRef(Entry e, Index ix) { @@ -1078,9 +1078,9 @@ && this instanceof PackageWriter) { // Twist the random state based on my first file. // This sends each segment off in a different direction. - List classes = ((PackageWriter)this).pkg.classes; + List classes = ((PackageWriter)this).pkg.classes; if (!classes.isEmpty()) { - Package.Class cls = (Package.Class) classes.get(0); + Package.Class cls = classes.get(0); codingChooser.addStressSeed(cls.getName().hashCode()); } } @@ -1619,8 +1619,7 @@ /** Given CP indexes, distribute tag-specific indexes to bands. */ protected void setBandIndexes() { // Handle prior calls to setBandIndex: - for (Iterator i = needPredefIndex.iterator(); i.hasNext(); ) { - Object[] need = (Object[]) i.next(); + for (Object[] need : needPredefIndex) { CPRefBand b = (CPRefBand) need[0]; Byte which = (Byte) need[1]; b.setIndex(getCPIndex(which.byteValue())); @@ -1633,7 +1632,7 @@ } protected void setBandIndex(CPRefBand b, byte which) { - Object[] need = { b, new Byte(which) }; + Object[] need = { b, Byte.valueOf(which) }; if (which == CONSTANT_Literal) { // I.e., attribute layouts KQ (no null) or KQN (null ok). allKQBands.add(b); @@ -1645,7 +1644,7 @@ } } - protected void setConstantValueIndex(com.sun.java.util.jar.pack.Package.Class.Field f) { + protected void setConstantValueIndex(Field f) { Index ix = null; if (f != null) { byte tag = f.getLiteralTag(); @@ -1655,8 +1654,7 @@ assert(ix != null); } // Typically, allKQBands is the singleton of field_ConstantValue_KQ. - for (Iterator i = allKQBands.iterator(); i.hasNext(); ) { - CPRefBand xxx_KQ = (CPRefBand) i.next(); + for (CPRefBand xxx_KQ : allKQBands) { xxx_KQ.setIndex(ix); } } @@ -1688,7 +1686,7 @@ protected int attrClassFileVersionMask; // Mapping from Attribute.Layout to Band[] (layout element bands). - protected HashMap attrBandTable = new HashMap(); + protected Map attrBandTable = new HashMap<>(); // Well-known attributes: protected final Attribute.Layout attrCodeEmpty; @@ -1697,15 +1695,18 @@ protected final Attribute.Layout attrConstantValue; // Mapping from Attribute.Layout to Integer (inverse of attrDefs) - HashMap attrIndexTable = new HashMap(); + Map attrIndexTable = new HashMap<>(); // Mapping from attribute index (<32 are flag bits) to attributes. - protected ArrayList[] attrDefs = new ArrayList[ATTR_CONTEXT_LIMIT]; + protected List> attrDefs = + new FixedList<>(ATTR_CONTEXT_LIMIT); { for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { assert(attrIndexLimit[i] == 0); attrIndexLimit[i] = 32; // just for the sake of predefs. - attrDefs[i] = new ArrayList(Collections.nCopies(attrIndexLimit[i], null)); + attrDefs.set(i, new ArrayList<>(Collections.nCopies( + attrIndexLimit[i], (Attribute.Layout)null))); + } // Add predefined attribute definitions: @@ -1867,9 +1868,10 @@ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { assert(attrIndexLimit[i] == 0); // decide on it now! attrIndexLimit[i] = (haveFlagsHi(i)? 63: 32); - assert(attrDefs[i].size() == 32); // all predef indexes are <32 - int addMore = attrIndexLimit[i] - attrDefs[i].size(); - attrDefs[i].addAll(Collections.nCopies(addMore, null)); + List defList = attrDefs.get(i); + assert(defList.size() == 32); // all predef indexes are <32 + int addMore = attrIndexLimit[i] - defList.size(); + defList.addAll(Collections.nCopies(addMore, (Attribute.Layout) null)); } } @@ -1890,13 +1892,13 @@ return testBit(archiveOptions, mask); } - protected ArrayList getPredefinedAttrs(int ctype) { + protected List getPredefinedAttrs(int ctype) { assert(attrIndexLimit[ctype] != 0); - ArrayList res = new ArrayList(attrIndexLimit[ctype]); + List res = new ArrayList<>(attrIndexLimit[ctype]); // Remove nulls and non-predefs. for (int ai = 0; ai < attrIndexLimit[ctype]; ai++) { if (testBit(attrDefSeen[ctype], 1L<= attrIndexLimit[ctype]) return false; // If the bit is set, it was explicitly def'd. if (testBit(attrDefSeen[ctype], 1L< defList = attrDefs.get(ctype); + Attribute.Layout def = defList.get(index); assert(def != null); defList.set(index, null); attrIndexTable.put(def, null); @@ -2059,7 +2061,7 @@ assert(index < 64); attrDefSeen[ctype] &= ~(1L< defList = attrDefs.get(ctype); if (index == ATTR_INDEX_OVERFLOW) { // Overflow attribute. index = defList.size(); defList.add(def); if (verbose > 0) Utils.log.info("Adding new attribute at "+def +": "+index); - attrIndexTable.put(def, new Integer(index)); + attrIndexTable.put(def, index); return index; } @@ -2240,7 +2241,7 @@ // Remove index binding of any previous fixed attr. attrIndexTable.put(defList.get(index), null); defList.set(index, def); - attrIndexTable.put(def, new Integer(index)); + attrIndexTable.put(def, index); return index; } @@ -2361,7 +2362,7 @@ //////////////////////////////////////////////////////////////////// static int nextSeqForDebug; - static File dumpDir; + static File dumpDir = null; static OutputStream getDumpStream(Band b, String ext) throws IOException { return getDumpStream(b.name, b.seqForDebug, ext, b); } @@ -2512,19 +2513,19 @@ +", "+cstr+", "+ixS+"),"); } - private HashMap prevForAssertMap; + private Map prevForAssertMap; // DEBUG ONLY: Record something about the band order. boolean notePrevForAssert(Band b, Band p) { if (prevForAssertMap == null) - prevForAssertMap = new HashMap(); + prevForAssertMap = new HashMap<>(); prevForAssertMap.put(b, p); return true; } // DEBUG ONLY: Validate next input band. private boolean assertReadyToReadFrom(Band b, InputStream in) throws IOException { - Band p = (Band) prevForAssertMap.get(b); + Band p = prevForAssertMap.get(b); // Any previous band must be done reading before this one starts. if (p != null && phaseCmp(p.phase(), DISBURSE_PHASE) < 0) { Utils.log.warning("Previous band not done reading."); @@ -2536,19 +2537,21 @@ String name = b.name; if (optDebugBands && !name.startsWith("(")) { // Verify synchronization between reader & writer: - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); int ch; while ((ch = in.read()) > 0) buf.append((char)ch); String inName = buf.toString(); if (!inName.equals(name)) { - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); sb.append("Expected "+name+" but read: "); inName += (char)ch; - while (inName.length() < 10) - inName += (char)in.read(); - for (int i = 0; i < inName.length(); i++) + while (inName.length() < 10) { + inName += (char) in.read(); + } + for (int i = 0; i < inName.length(); i++) { sb.append(inName.charAt(i)); + } Utils.log.warning(sb.toString()); return false; } @@ -2573,7 +2576,7 @@ // DEBUG ONLY: Maybe write a debugging cookie to next output band. private boolean assertReadyToWriteTo(Band b, OutputStream out) throws IOException { - Band p = (Band) prevForAssertMap.get(b); + Band p = prevForAssertMap.get(b); // Any previous band must be done writing before this one starts. if (p != null && phaseCmp(p.phase(), DONE_PHASE) < 0) { Utils.log.warning("Previous band not done writing."); @@ -2654,7 +2657,7 @@ protected static Object[] realloc(Object[] a) { return realloc(a, Math.max(10, a.length*2)); } - static private int[] noInts = {}; + protected static int[] realloc(int[] a, int len) { if (len == 0) return noInts; if (a == null) return new int[len]; @@ -2665,7 +2668,7 @@ protected static int[] realloc(int[] a) { return realloc(a, Math.max(10, a.length*2)); } - static private byte[] noBytes = {}; + protected static byte[] realloc(byte[] a, int len) { if (len == 0) return noBytes; if (a == null) return new byte[len]; diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java Wed Jul 05 17:32:27 2017 +0200 @@ -38,19 +38,20 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.Map; +import static com.sun.java.util.jar.pack.Constants.*; /** * Reader for a class file that is being incorporated into a package. * @author John Rose */ -class ClassReader implements Constants { +class ClassReader { int verbose; Package pkg; Class cls; long inPos; DataInputStream in; - Map attrDefs; + Map attrDefs; Map attrCommands; String unknownAttrCommand = "error";; @@ -77,7 +78,7 @@ }); } - public void setAttrDefs(Map attrDefs) { + public void setAttrDefs(Map attrDefs) { this.attrDefs = attrDefs; } @@ -211,27 +212,23 @@ break; case CONSTANT_Integer: { - Comparable val = new Integer(in.readInt()); - cpMap[i] = ConstantPool.getLiteralEntry(val); + cpMap[i] = ConstantPool.getLiteralEntry(in.readInt()); } break; case CONSTANT_Float: { - Comparable val = new Float(in.readFloat()); - cpMap[i] = ConstantPool.getLiteralEntry(val); + cpMap[i] = ConstantPool.getLiteralEntry(in.readFloat()); } break; case CONSTANT_Long: { - Comparable val = new Long(in.readLong()); - cpMap[i] = ConstantPool.getLiteralEntry(val); + cpMap[i] = ConstantPool.getLiteralEntry(in.readLong()); cpMap[++i] = null; } break; case CONSTANT_Double: { - Comparable val = new Double(in.readDouble()); - cpMap[i] = ConstantPool.getLiteralEntry(val); + cpMap[i] = ConstantPool.getLiteralEntry(in.readDouble()); cpMap[++i] = null; } break; @@ -353,17 +350,18 @@ if (attrCommands != null) { Object lkey = Attribute.keyForLookup(ctype, name); String cmd = (String) attrCommands.get(lkey); - if (cmd == "pass") { - String message = "passing attribute bitwise in "+h; - throw new Attribute.FormatException(message, ctype, name, - cmd); - } else if (cmd == "error") { - String message = "attribute not allowed in "+h; - throw new Attribute.FormatException(message, ctype, name, - cmd); - } else if (cmd == "strip") { - skip(length, name+" attribute in "+h); - continue; + if (cmd != null) { + switch (cmd) { + case "pass": + String message1 = "passing attribute bitwise in " + h; + throw new Attribute.FormatException(message1, ctype, name, cmd); + case "error": + String message2 = "attribute not allowed in " + h; + throw new Attribute.FormatException(message2, ctype, name, cmd); + case "strip": + skip(length, name + " attribute in " + h); + continue; + } } } // Find canonical instance of the requested attribute. @@ -408,7 +406,7 @@ String message = "unsupported StackMap variant in "+h; throw new Attribute.FormatException(message, ctype, name, "pass"); - } else if (unknownAttrCommand == "strip") { + } else if ("strip".equals(unknownAttrCommand)) { // Skip the unknown attribute. skip(length, "unknown "+name+" attribute in "+h); continue; @@ -422,7 +420,7 @@ a.layout() == Package.attrInnerClassesEmpty) { // These are hardwired. long pos0 = inPos; - if (a.name() == "Code") { + if ("Code".equals(a.name())) { Class.Method m = (Class.Method) h; m.code = new Code(m); try { @@ -471,7 +469,7 @@ void readInnerClasses(Class cls) throws IOException { int nc = readUnsignedShort(); - ArrayList ics = new ArrayList(nc); + ArrayList ics = new ArrayList<>(nc); for (int i = 0; i < nc; i++) { InnerClass ic = new InnerClass(readClassRef(), diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/ClassWriter.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassWriter.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassWriter.java Wed Jul 05 17:32:27 2017 +0200 @@ -38,12 +38,12 @@ import java.io.OutputStream; import java.util.Iterator; import java.util.List; - +import static com.sun.java.util.jar.pack.Constants.*; /** * Writer for a class file that is incorporated into a package. * @author John Rose */ -class ClassWriter implements Constants { +class ClassWriter { int verbose; Package pkg; @@ -196,8 +196,7 @@ return; } writeShort(h.attributes.size()); - for (Iterator i = h.attributes.iterator(); i.hasNext(); ) { - Attribute a = (Attribute) i.next(); + for (Attribute a : h.attributes) { a.finishRefs(cpIndex); writeRef(a.getNameRef()); if (a.layout() == Package.attrCodeEmpty || @@ -207,7 +206,7 @@ assert(out != bufOut); buf.reset(); out = bufOut; - if (a.name() == "Code") { + if ("Code".equals(a.name())) { Class.Method m = (Class.Method) h; writeCode(m.code); } else { @@ -246,10 +245,9 @@ } void writeInnerClasses(Class cls) throws IOException { - List ics = cls.getInnerClasses(); + List ics = cls.getInnerClasses(); writeShort(ics.size()); - for (Iterator i = ics.iterator(); i.hasNext(); ) { - InnerClass ic = (InnerClass) i.next(); + for (InnerClass ic : ics) { writeRef(ic.thisClass); writeRef(ic.outerClass); writeRef(ic.name); diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/Code.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Code.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Code.java Wed Jul 05 17:32:27 2017 +0200 @@ -29,12 +29,13 @@ import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.Collection; +import static com.sun.java.util.jar.pack.Constants.*; /** * Represents a chunk of bytecodes. * @author John Rose */ -class Code extends Attribute.Holder implements Constants { +class Code extends Attribute.Holder { Class.Method m; public Code(Class.Method m) { @@ -141,15 +142,12 @@ super.trimToSize(); } - protected void visitRefs(int mode, Collection refs) { + protected void visitRefs(int mode, Collection refs) { int verbose = getPackage().verbose; if (verbose > 2) System.out.println("Reference scan "+this); Class cls = thisClass(); - Package pkg = cls.getPackage(); - for (int i = 0; i < handler_class.length; i++) { - refs.add(handler_class[i]); - } + refs.addAll(Arrays.asList(handler_class)); if (fixups != null) { fixups.visitRefs(refs); } else { @@ -196,11 +194,8 @@ map[mapLen] = (short)(PClimit + Short.MIN_VALUE); return map; } else { - int[] map = new int[mapLen+1]; - for (int i = 0; i < mapLen; i++) { - map[i] = (int) insnMap[i]; - } - map[mapLen] = (int) PClimit; + int[] map = Arrays.copyOf(insnMap, mapLen + 1); + map[mapLen] = PClimit; return map; } } @@ -220,10 +215,7 @@ } } else { int[] map = (int[]) map0; - imap = new int[map.length-1]; - for (int i = 0; i < imap.length; i++) { - imap[i] = map[i]; - } + imap = Arrays.copyOfRange(map, 0, map.length - 1); } return imap; } @@ -266,7 +258,7 @@ } else { int[] map = (int[]) map0; len = map.length; - i = Arrays.binarySearch(map, (int)bci); + i = Arrays.binarySearch(map, bci); } assert(i != -1); assert(i != 0); @@ -322,7 +314,7 @@ len = map.length; if (bciCode < len) return map[bciCode]; - i = Arrays.binarySearch(map, (int)bciCode); + i = Arrays.binarySearch(map, bciCode); if (i < 0) i = -i-1; int key = bciCode-len; for (;; i--) { diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/Coding.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Coding.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Coding.java Wed Jul 05 17:32:27 2017 +0200 @@ -29,14 +29,15 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.HashMap; - +import java.util.Map; +import static com.sun.java.util.jar.pack.Constants.*; /** * Define the conversions between sequences of small integers and raw bytes. * This is a schema of encodings which incorporates varying lengths, * varying degrees of length variability, and varying amounts of signed-ness. * @author John Rose */ -class Coding implements Constants, Comparable, CodingMethod, Histogram.BitMetric { +class Coding implements Comparable, CodingMethod, Histogram.BitMetric { /* Coding schema for single integers, parameterized by (B,H,S): @@ -191,7 +192,9 @@ if (S == 0 || range >= (long)1<<32) return saturate32(range-1); long maxPos = range-1; - while (isNegativeCode(maxPos, S)) --maxPos; + while (isNegativeCode(maxPos, S)) { + --maxPos; + } if (maxPos < 0) return -1; // No positive codings at all. int smax = decodeSign32(maxPos, S); // check for 32-bit wraparound: @@ -213,9 +216,10 @@ if (S == 0) { return 0; } - int Smask = (1< codeMap; private static synchronized Coding of(int B, int H, int S, int del) { - if (codeMap == null) codeMap = new HashMap(); + if (codeMap == null) codeMap = new HashMap<>(); Coding x0 = new Coding(B, H, S, del); - Coding x1 = (Coding) codeMap.get(x0); + Coding x1 = codeMap.get(x0); if (x1 == null) codeMap.put(x0, x1 = x0); return x1; } @@ -462,6 +466,7 @@ // %%% use byte[] buffer for (int i = start; i < end; i++) a[i] = readFrom(in); + for (int dstep = 0; dstep < del; dstep++) { long state = 0; for (int i = start; i < end; i++) { @@ -750,14 +755,14 @@ if (len == 0) return true; if (isFullRange()) return true; // Calculate max, min: - int max = values[start]; - int min = max; + int lmax = values[start]; + int lmin = lmax; for (int i = 1; i < len; i++) { int value = values[start+i]; - if (max < value) max = value; - if (min > value) min = value; + if (lmax < value) lmax = value; + if (lmin > value) lmin = value; } - return canRepresent(min, max); + return canRepresent(lmin, lmax); } public double getBitLength(int value) { // implements BitMetric @@ -800,21 +805,20 @@ //return Coding.of(B, H, S).getLength(deltas, 0, len); values = deltas; start = 0; - end = values.length; } int sum = len; // at least 1 byte per // add extra bytes for extra-long values for (int n = 1; n <= B; n++) { // what is the coding interval [min..max] for n bytes? - int max = byteMax[n-1]; - int min = byteMin[n-1]; + int lmax = byteMax[n-1]; + int lmin = byteMin[n-1]; int longer = 0; // count of guys longer than n bytes for (int i = 0; i < len; i++) { int value = values[start+i]; if (value >= 0) { - if (value > max) longer++; + if (value > lmax) longer++; } else { - if (value < min) longer++; + if (value < lmin) longer++; } } if (longer == 0) break; // no more passes needed diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/CodingChooser.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/CodingChooser.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/CodingChooser.java Wed Jul 05 17:32:27 2017 +0200 @@ -34,15 +34,16 @@ import java.util.Iterator; import java.util.List; import java.util.Random; +import java.util.Set; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; - +import static com.sun.java.util.jar.pack.Constants.*; /** * Heuristic chooser of basic encodings. * Runs "zip" to measure the apparent information content after coding. * @author John Rose */ -class CodingChooser implements Constants { +class CodingChooser { int verbose; int effort; boolean optUseHistogram = true; @@ -124,10 +125,10 @@ = !p200.getBoolean(Utils.COM_PREFIX+"no.population.coding"); this.optUseAdaptiveCoding = !p200.getBoolean(Utils.COM_PREFIX+"no.adaptive.coding"); - int stress + int lstress = p200.getInteger(Utils.COM_PREFIX+"stress.coding"); - if (stress != 0) - this.stress = new Random(stress); + if (lstress != 0) + this.stress = new Random(lstress); } this.effort = effort; @@ -376,9 +377,9 @@ " fewer bytes than regular "+regular+ "; win="+pct(zipSize1-bestZipSize, zipSize1)); } - CodingMethod bestMethod = this.bestMethod; + CodingMethod lbestMethod = this.bestMethod; reset(null, 0, 0); // for GC - return bestMethod; + return lbestMethod; } CodingMethod choose(int[] values, int start, int end, Coding regular) { return choose(values, start, end, regular, null); @@ -742,9 +743,9 @@ // Steps 1/2/3 are interdependent, and may be iterated. // Steps 4 and 5 may be decided independently afterward. int[] LValuesCoded = PopulationCoding.LValuesCoded; - ArrayList bestFits = new ArrayList(); - ArrayList fullFits = new ArrayList(); - ArrayList longFits = new ArrayList(); + List bestFits = new ArrayList<>(); + List fullFits = new ArrayList<>(); + List longFits = new ArrayList<>(); final int PACK_TO_MAX_S = 1; if (bestPopFVC <= 255) { bestFits.add(BandStructure.BYTE1); @@ -776,16 +777,16 @@ } } // interleave all B greater than bestB with best and full fits - for (Iterator i = bestFits.iterator(); i.hasNext(); ) { - Coding c = (Coding) i.next(); + for (Iterator i = bestFits.iterator(); i.hasNext(); ) { + Coding c = i.next(); if (c.B() > bestB) { i.remove(); longFits.add(0, c); } } } - ArrayList allFits = new ArrayList(); - for (Iterator i = bestFits.iterator(), + List allFits = new ArrayList<>(); + for (Iterator i = bestFits.iterator(), j = fullFits.iterator(), k = longFits.iterator(); i.hasNext() || j.hasNext() || k.hasNext(); ) { @@ -812,8 +813,7 @@ } if (verbose > 3) Utils.log.info("allFits: "+allFits); - for (Iterator i = allFits.iterator(); i.hasNext(); ) { - Coding tc = (Coding) i.next(); + for (Coding tc : allFits) { boolean packToMax = false; if (tc.S() == PACK_TO_MAX_S) { // Kludge: setS(PACK_TO_MAX_S) means packToMax here. @@ -910,7 +910,7 @@ " tc="+pop.tokenCoding+ " uc="+pop.unfavoredCoding); //pop.hist.print("pop-hist", null, System.out); - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); sb.append("fv = {"); for (int i = 1; i <= fVlen; i++) { if ((i % 10) == 0) @@ -949,20 +949,20 @@ // run occupies too much space. ("Too much" means, say 5% more // than the average integer size of the band as a whole.) // Try to find a better coding for those segments. - int start = this.start; - int end = this.end; - int[] values = this.values; - int len = end-start; + int lstart = this.start; + int lend = this.end; + int[] lvalues = this.values; + int len = lend-lstart; if (plainCoding.isDelta()) { - values = getDeltas(0,0); //%%% not quite right! - start = 0; - end = values.length; + lvalues = getDeltas(0,0); //%%% not quite right! + lstart = 0; + lend = lvalues.length; } int[] sizes = new int[len+1]; int fillp = 0; int totalSize = 0; - for (int i = start; i < end; i++) { - int val = values[i]; + for (int i = lstart; i < lend; i++) { + int val = lvalues[i]; sizes[fillp++] = totalSize; int size = plainCoding.getLength(val); assert(size < Integer.MAX_VALUE); @@ -1013,22 +1013,23 @@ double[] fuzzes = new double[meshes.length]; for (int i = 0; i < meshes.length; i++) { int mesh = meshes[i]; - double fuzz; + double lfuzz; if (mesh < 10) - fuzz = sizeFuzz3; + lfuzz = sizeFuzz3; else if (mesh < 100) - fuzz = sizeFuzz2; + lfuzz = sizeFuzz2; else - fuzz = sizeFuzz; - fuzzes[i] = fuzz; - threshes[i] = BAND_HEADER + (int)Math.ceil(mesh * avgSize * fuzz); + lfuzz = sizeFuzz; + fuzzes[i] = lfuzz; + threshes[i] = BAND_HEADER + (int)Math.ceil(mesh * avgSize * lfuzz); } if (verbose > 1) { System.out.print("tryAdaptiveCoding ["+len+"]"+ " avgS="+avgSize+" fuzz="+sizeFuzz+ " meshes: {"); - for (int i = 0; i < meshes.length; i++) - System.out.print(" "+meshes[i]+"("+threshes[i]+")"); + for (int i = 0; i < meshes.length; i++) { + System.out.print(" " + meshes[i] + "(" + threshes[i] + ")"); + } Utils.log.info(" }"); } if (runHelper == null) { @@ -1229,20 +1230,19 @@ Histogram hist = getValueHistogram(); int fVlen = stressLen(hist.getTotalLength()); if (fVlen == 0) return coding; - List popvals = new ArrayList(); + List popvals = new ArrayList<>(); if (stress.nextBoolean()) { // Build the population from the value list. - HashSet popset = new HashSet(); + Set popset = new HashSet<>(); for (int i = start; i < end; i++) { - Integer val = new Integer(values[i]); - if (popset.add(val)) popvals.add(val); + if (popset.add(values[i])) popvals.add(values[i]); } } else { int[][] matrix = hist.getMatrix(); for (int mrow = 0; mrow < matrix.length; mrow++) { int[] row = matrix[mrow]; for (int mcol = 1; mcol < row.length; mcol++) { - popvals.add(new Integer(row[mcol])); + popvals.add(row[mcol]); } } } @@ -1269,7 +1269,7 @@ fVlen = popvals.size(); int[] fvals = new int[1+fVlen]; for (int i = 0; i < fVlen; i++) { - fvals[1+i] = ((Integer)popvals.get(i)).intValue(); + fvals[1+i] = (popvals.get(i)).intValue(); } PopulationCoding pop = new PopulationCoding(); pop.setFavoredValues(fvals, fVlen); @@ -1283,13 +1283,13 @@ } } if (pop.tokenCoding == null) { - int min = fvals[1], max = min; + int lmin = fvals[1], lmax = lmin; for (int i = 2; i <= fVlen; i++) { int val = fvals[i]; - if (min > val) min = val; - if (max < val) max = val; + if (lmin > val) lmin = val; + if (lmax < val) lmax = val; } - pop.tokenCoding = stressCoding(min, max); + pop.tokenCoding = stressCoding(lmin, lmax); } computePopSizePrivate(pop, valueCoding, valueCoding); @@ -1310,13 +1310,13 @@ try { assert(!disableRunCoding); disableRunCoding = true; // temporary, while I decide spans - int[] allValues = (int[]) values.clone(); + int[] allValues = values.clone(); CodingMethod result = null; int scan = this.end; - int start = this.start; - for (int split; scan > start; scan = split) { + int lstart = this.start; + for (int split; scan > lstart; scan = split) { int thisspan; - int rand = (scan - start < 100)? -1: stress.nextInt(); + int rand = (scan - lstart < 100)? -1: stress.nextInt(); if ((rand & 7) != 0) { thisspan = (spanlen==1? spanlen: stressLen(spanlen-1)+1); } else { @@ -1325,7 +1325,7 @@ int KB = (rand >>>= 3) & AdaptiveCoding.KB_MAX; for (;;) { thisspan = AdaptiveCoding.decodeK(KX, KB); - if (thisspan <= scan - start) break; + if (thisspan <= scan - lstart) break; // Try smaller and smaller codings: if (KB != AdaptiveCoding.KB_DEFAULT) KB = AdaptiveCoding.KB_DEFAULT; @@ -1335,11 +1335,13 @@ //System.out.println("KX="+KX+" KB="+KB+" K="+thisspan); assert(AdaptiveCoding.isCodableLength(thisspan)); } - if (thisspan > scan - start) thisspan = scan - start; - while (!AdaptiveCoding.isCodableLength(thisspan)) --thisspan; + if (thisspan > scan - lstart) thisspan = scan - lstart; + while (!AdaptiveCoding.isCodableLength(thisspan)) { + --thisspan; + } split = scan - thisspan; assert(split < scan); - assert(split >= start); + assert(split >= lstart); // Choose a coding for the span [split..scan). CodingMethod sc = choose(allValues, split, scan, plainCoding); if (result == null) { @@ -1420,7 +1422,7 @@ case StreamTokenizer.TT_EOF: throw new NoSuchElementException(); case StreamTokenizer.TT_NUMBER: - return new Integer((int) in.nval); + return Integer.valueOf((int) in.nval); default: assert(false); return null; diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java Wed Jul 05 17:32:27 2017 +0200 @@ -33,13 +33,14 @@ import java.util.ListIterator; import java.util.Map; import java.util.Set; +import static com.sun.java.util.jar.pack.Constants.*; /** * Representation of constant pool entries and indexes. * @author John Rose */ abstract -class ConstantPool implements Constants { +class ConstantPool { private ConstantPool() {} // do not instantiate static int verbose() { @@ -155,9 +156,6 @@ return null; } - public boolean sameTagAs(Object o) { - return (o instanceof Entry) && ((Entry)o).tag == tag; - } public boolean eq(Entry that) { // same reference assert(that != null); return this == that || this.equals(that); @@ -219,9 +217,9 @@ return value.hashCode(); } public boolean equals(Object o) { - if (!sameTagAs(o)) return false; // Use reference equality of interned strings: - return ((Utf8Entry)o).value == value; + return (o != null && o.getClass() == Utf8Entry.class + && ((Utf8Entry) o).value.equals(value)); } public int compareTo(Object o) { int x = superCompareTo(o); @@ -275,8 +273,9 @@ } public boolean equals(Object o) { - if (!sameTagAs(o)) return false; - return (((NumberEntry)o).value).equals(value); + return (o != null && o.getClass() == NumberEntry.class + && ((NumberEntry) o).value.equals(value)); + } public int compareTo(Object o) { int x = superCompareTo(o); @@ -310,8 +309,8 @@ return ref.hashCode() + tag; } public boolean equals(Object o) { - if (!sameTagAs(o)) return false; - return ((StringEntry)o).ref.eq(ref); + return (o != null && o.getClass() == StringEntry.class && + ((StringEntry)o).ref.eq(ref)); } public int compareTo(Object o) { int x = superCompareTo(o); @@ -342,8 +341,8 @@ hashCode(); // force computation of valueHash } public boolean equals(Object o) { - if (!sameTagAs(o)) return false; - return ((ClassEntry)o).ref.eq(ref); + return (o != null && o.getClass() == ClassEntry.class + && ((ClassEntry) o).ref.eq(ref)); } public int compareTo(Object o) { int x = superCompareTo(o); @@ -380,7 +379,9 @@ return (nameRef.hashCode() + (hc2 << 8)) ^ hc2; } public boolean equals(Object o) { - if (!sameTagAs(o)) return false; + if (o == null || o.getClass() != DescriptorEntry.class) { + return false; + } DescriptorEntry that = (DescriptorEntry)o; return this.nameRef.eq(that.nameRef) && this.typeRef.eq(that.typeRef); @@ -439,7 +440,9 @@ hashCode(); // force computation of valueHash } public boolean equals(Object o) { - if (!sameTagAs(o)) return false; + if (o == null || o.getClass() != MemberEntry.class) { + return false; + } MemberEntry that = (MemberEntry)o; return this.classRef.eq(that.classRef) && this.descRef.eq(that.descRef); @@ -511,8 +514,8 @@ } public boolean equals(Object o) { - if (!sameTagAs(o)) return false; - return ((SignatureEntry)o).value == value; + return (o != null && o.getClass() == SignatureEntry.class && + ((SignatureEntry)o).value.equals(value)); } public int compareTo(Object o) { int x = superCompareTo(o); @@ -724,7 +727,7 @@ protected static final ClassEntry[] noClassRefs = {}; /** An Index is a mapping between CP entries and small integers. */ - public static + public static final class Index extends AbstractList { protected String debugName; protected Entry[] cpMap; @@ -894,7 +897,7 @@ } public static - Index makeIndex(String debugName, Collection cpMapList) { + Index makeIndex(String debugName, Collection cpMapList) { return new Index(debugName, cpMapList); } @@ -916,7 +919,7 @@ public static Index[] partition(Index ix, int[] keys) { // %%% Should move this into class Index. - ArrayList> parts = new ArrayList<>(); + List> parts = new ArrayList<>(); Entry[] cpMap = ix.cpMap; assert(keys.length == cpMap.length); for (int i = 0; i < keys.length; i++) { @@ -1094,12 +1097,12 @@ // Inverse of getOverloadingIndex public MemberEntry getOverloadingForIndex(byte tag, ClassEntry classRef, String name, int which) { - assert(name == name.intern()); + assert(name.equals(name.intern())); Index ix = getMemberIndex(tag, classRef); int ord = 0; for (int i = 0; i < ix.cpMap.length; i++) { MemberEntry e = (MemberEntry) ix.cpMap[i]; - if (e.descRef.nameRef.stringValue() == name) { + if (e.descRef.nameRef.stringValue().equals(name)) { if (ord == which) return e; ord++; } @@ -1133,10 +1136,10 @@ public static void completeReferencesIn(Set cpRefs, boolean flattenSigs) { cpRefs.remove(null); - for (ListIterator work = - new ArrayList(cpRefs).listIterator(cpRefs.size()); + for (ListIterator work = + new ArrayList<>(cpRefs).listIterator(cpRefs.size()); work.hasPrevious(); ) { - Entry e = (Entry) work.previous(); + Entry e = work.previous(); work.remove(); // pop stack assert(e != null); if (flattenSigs && e.tag == CONSTANT_Signature) { diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java Wed Jul 05 17:32:27 2017 +0200 @@ -32,7 +32,10 @@ * Shared constants * @author John Rose */ -interface Constants { +class Constants { + + private Constants(){} + public final static int JAVA_MAGIC = 0xCAFEBABE; /* diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/Driver.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Driver.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Driver.java Wed Jul 05 17:32:27 2017 +0200 @@ -59,12 +59,11 @@ ResourceBundle.getBundle("com.sun.java.util.jar.pack.DriverResource"); public static void main(String[] ava) throws IOException { - ArrayList av = new ArrayList<>(Arrays.asList(ava)); + List av = new ArrayList<>(Arrays.asList(ava)); boolean doPack = true; boolean doUnpack = false; boolean doRepack = false; - boolean doForceRepack = false; boolean doZip = true; String logFile = null; String verboseProp = Utils.DEBUG_VERBOSE; @@ -72,17 +71,20 @@ { // Non-standard, undocumented "--unpack" switch enables unpack mode. String arg0 = av.isEmpty() ? "" : av.get(0); - if (arg0.equals("--pack")) { + switch (arg0) { + case "--pack": av.remove(0); - } else if (arg0.equals("--unpack")) { + break; + case "--unpack": av.remove(0); doPack = false; doUnpack = true; + break; } } // Collect engine properties here: - HashMap engProps = new HashMap<>(); + Map engProps = new HashMap<>(); engProps.put(verboseProp, System.getProperty(verboseProp)); String optionMap; @@ -96,7 +98,7 @@ } // Collect argument properties here: - HashMap avProps = new HashMap<>(); + Map avProps = new HashMap<>(); try { for (;;) { String state = parseCommandOptions(av, optionMap, avProps); @@ -146,7 +148,7 @@ } // See if there is any other action to take. - if (state == "--config-file=") { + if ("--config-file=".equals(state)) { String propFile = av.remove(0); InputStream propIn = new FileInputStream(propFile); Properties fileProps = new Properties(); @@ -157,10 +159,10 @@ for (Map.Entry me : fileProps.entrySet()) { engProps.put((String) me.getKey(), (String) me.getValue()); } - } else if (state == "--version") { + } else if ("--version".equals(state)) { System.out.println(MessageFormat.format(RESOURCE.getString(DriverResource.VERSION), Driver.class.getName(), "1.31, 07/05/05")); return; - } else if (state == "--help") { + } else if ("--help".equals(state)) { printUsage(doPack, true, System.out); System.exit(1); return; @@ -178,14 +180,20 @@ // Deal with remaining non-engine properties: for (String opt : avProps.keySet()) { String val = avProps.get(opt); - if (opt == "--repack") { - doRepack = true; - } else if (opt == "--no-gzip") { - doZip = (val == null); - } else if (opt == "--log-file=") { - logFile = val; - } else { - throw new InternalError(MessageFormat.format(RESOURCE.getString(DriverResource.BAD_OPTION), opt, avProps.get(opt))); + switch (opt) { + case "--repack": + doRepack = true; + break; + case "--no-gzip": + doZip = (val == null); + break; + case "--log-file=": + logFile = val; + break; + default: + throw new InternalError(MessageFormat.format( + RESOURCE.getString(DriverResource.BAD_OPTION), + opt, avProps.get(opt))); } } @@ -219,7 +227,9 @@ if (packfile.toLowerCase().endsWith(".pack") || packfile.toLowerCase().endsWith(".pac") || packfile.toLowerCase().endsWith(".gz")) { - System.err.println(MessageFormat.format(RESOURCE.getString(DriverResource.BAD_REPACK_OUTPUT),packfile)); + System.err.println(MessageFormat.format( + RESOURCE.getString(DriverResource.BAD_REPACK_OUTPUT), + packfile)); printUsage(doPack, false, System.err); System.exit(2); } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/FixedList.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/FixedList.java Wed Jul 05 17:32:27 2017 +0200 @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.java.util.jar.pack; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +/* + * @author ksrini + */ + +/* + * This class provides an ArrayList implementation which has a fixed size, + * thus all the operations which modifies the size have been rendered + * inoperative. This essentially allows us to use generified array + * lists in lieu of arrays. + */ +final class FixedList implements List { + + private final ArrayList flist; + + protected FixedList(int capacity) { + flist = new ArrayList<>(capacity); + // initialize the list to null + for (int i = 0 ; i < capacity ; i++) { + flist.add(null); + } + } + @Override + public int size() { + return flist.size(); + } + + @Override + public boolean isEmpty() { + return flist.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return flist.contains(o); + } + + @Override + public Iterator iterator() { + return flist.iterator(); + } + + @Override + public Object[] toArray() { + return flist.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return flist.toArray(a); + } + + @Override + public boolean add(E e) throws UnsupportedOperationException { + throw new UnsupportedOperationException("operation not permitted"); + } + + @Override + public boolean remove(Object o) throws UnsupportedOperationException { + throw new UnsupportedOperationException("operation not permitted"); + } + + @Override + public boolean containsAll(Collection c) { + return flist.containsAll(c); + } + + @Override + public boolean addAll(Collection c) throws UnsupportedOperationException { + throw new UnsupportedOperationException("operation not permitted"); + } + + @Override + public boolean addAll(int index, Collection c) throws UnsupportedOperationException { + throw new UnsupportedOperationException("operation not permitted"); + } + + @Override + public boolean removeAll(Collection c) throws UnsupportedOperationException { + throw new UnsupportedOperationException("operation not permitted"); + } + + @Override + public boolean retainAll(Collection c) throws UnsupportedOperationException { + throw new UnsupportedOperationException("operation not permitted"); + } + + @Override + public void clear() throws UnsupportedOperationException { + throw new UnsupportedOperationException("operation not permitted"); + } + + @Override + public E get(int index) { + return flist.get(index); + } + + @Override + public E set(int index, E element) { + return flist.set(index, element); + } + + @Override + public void add(int index, E element) throws UnsupportedOperationException { + throw new UnsupportedOperationException("operation not permitted"); + } + + @Override + public E remove(int index) throws UnsupportedOperationException { + throw new UnsupportedOperationException("operation not permitted"); + } + + @Override + public int indexOf(Object o) { + return flist.indexOf(o); + } + + @Override + public int lastIndexOf(Object o) { + return flist.lastIndexOf(o); + } + + @Override + public ListIterator listIterator() { + return flist.listIterator(); + } + + @Override + public ListIterator listIterator(int index) { + return flist.listIterator(index); + } + + @Override + public List subList(int fromIndex, int toIndex) { + return flist.subList(fromIndex, toIndex); + } + + @Override + public String toString() { + return "FixedList{" + "plist=" + flist + '}'; + } +} + diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java Wed Jul 05 17:32:27 2017 +0200 @@ -42,7 +42,7 @@ * * @author John Rose */ -class Fixups extends AbstractCollection implements Constants { +final class Fixups extends AbstractCollection { byte[] bytes; // the subject of the relocations int head; // desc locating first reloc int tail; // desc locating last reloc @@ -99,7 +99,7 @@ } } - public void visitRefs(Collection refs) { + public void visitRefs(Collection refs) { for (int i = 0; i < size; i++) { refs.add(entries[i]); } @@ -124,6 +124,7 @@ return bytes; } + @SuppressWarnings("unchecked") public void setBytes(byte[] newBytes) { if (bytes == newBytes) return; ArrayList old = null; @@ -278,7 +279,7 @@ return new Fixup(nextDesc(), entries[thisIndex]); } int nextDesc() { - int thisIndex = index++; + index++; int thisDesc = next; if (index < size) { // Fetch next desc eagerly, in case this fixup gets finalized. @@ -310,6 +311,7 @@ public boolean add(Object fixup) { return add((Fixup) fixup); } + @SuppressWarnings("unchecked") public boolean addAll(Collection c) { if (c instanceof Fixups) { // Use knowledge of Itr structure to avoid building little structs. @@ -420,7 +422,7 @@ // Iterate over all the references in this set of fixups. public static - void visitRefs(Object fixups, Collection refs) { + void visitRefs(Object fixups, Collection refs) { if (fixups == null) { } else if (!(fixups instanceof Fixups)) { // Special convention; see above. diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/Histogram.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Histogram.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Histogram.java Wed Jul 05 17:32:27 2017 +0200 @@ -34,7 +34,7 @@ * Histogram derived from an integer array of events (int[]). * @author John Rose */ -class Histogram { +final class Histogram { // Compact histogram representation: 4 bytes per distinct value, // plus 5 words per distinct count. protected final int[][] matrix; // multi-row matrix {{counti,valueij...}} @@ -304,7 +304,7 @@ public String[] getRowTitles(String name) { int totalUnique = getTotalLength(); - int totalWeight = getTotalWeight(); + int ltotalWeight = getTotalWeight(); String[] histTitles = new String[matrix.length]; int cumWeight = 0; int cumUnique = 0; @@ -314,7 +314,7 @@ int weight = getRowWeight(i); cumWeight += weight; cumUnique += unique; - long wpct = ((long)cumWeight * 100 + totalWeight/2) / totalWeight; + long wpct = ((long)cumWeight * 100 + ltotalWeight/2) / ltotalWeight; long upct = ((long)cumUnique * 100 + totalUnique/2) / totalUnique; double len = getRowBitLength(i); assert(0.1 > Math.abs(len - getBitLength(matrix[i][1]))); @@ -346,14 +346,14 @@ public void print(String name, String[] histTitles, PrintStream out) { int totalUnique = getTotalLength(); - int totalWeight = getTotalWeight(); + int ltotalWeight = getTotalWeight(); double tlen = getBitLength(); - double avgLen = tlen / totalWeight; - double avg = (double) totalWeight / totalUnique; + double avgLen = tlen / ltotalWeight; + double avg = (double) ltotalWeight / totalUnique; String title = (name +" len="+round(tlen,10) +" avgLen="+round(avgLen,10) - +" weight("+totalWeight+")" + +" weight("+ltotalWeight+")" +" unique["+totalUnique+"]" +" avgWeight("+round(avg,100)+")"); if (histTitles == null) { @@ -363,9 +363,9 @@ StringBuffer buf = new StringBuffer(); for (int i = 0; i < matrix.length; i++) { buf.setLength(0); - buf.append(" "+histTitles[i]+" {"); + buf.append(" ").append(histTitles[i]).append(" {"); for (int j = 1; j < matrix[i].length; j++) { - buf.append(" "+matrix[i][j]); + buf.append(" ").append(matrix[i][j]); } buf.append(" }"); out.println(buf); @@ -603,7 +603,7 @@ private static int[] maybeSort(int[] values) { if (!isSorted(values, 0, false)) { - values = (int[]) values.clone(); + values = values.clone(); Arrays.sort(values); } return values; diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java Wed Jul 05 17:32:27 2017 +0200 @@ -26,13 +26,15 @@ package com.sun.java.util.jar.pack; import java.io.IOException; +import java.util.Arrays; +import static com.sun.java.util.jar.pack.Constants.*; /** * A parsed bytecode instruction. * Provides accessors to various relevant bits. * @author John Rose */ -class Instruction implements Constants { +class Instruction { protected byte[] bytes; // bytecodes protected int pc; // location of this instruction protected int bc; // opcode of this instruction @@ -91,8 +93,8 @@ /** A fake instruction at this pc whose next() will be at nextpc. */ public Instruction forceNextPC(int nextpc) { - int length = nextpc - pc; - return new Instruction(bytes, pc, -1, -1, length); + int llength = nextpc - pc; + return new Instruction(bytes, pc, -1, -1, llength); } public static Instruction at(byte[] bytes, int pc) { @@ -315,12 +317,24 @@ } } - /** Two insns are equal if they have the same bytes. */ + /** Two instructions are equal if they have the same bytes. */ public boolean equals(Object o) { - return (o instanceof Instruction) && equals((Instruction)o); + return (o != null) && (o.getClass() == Instruction.class) + && equals((Instruction) o); + } + + public int hashCode() { + int hash = 3; + hash = 11 * hash + Arrays.hashCode(this.bytes); + hash = 11 * hash + this.pc; + hash = 11 * hash + this.bc; + hash = 11 * hash + this.w; + hash = 11 * hash + this.length; + return hash; } public boolean equals(Instruction that) { + if (this.pc != that.pc) return false; if (this.bc != that.bc) return false; if (this.w != that.w) return false; if (this.length != that.length) return false; diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java Wed Jul 05 17:32:27 2017 +0200 @@ -170,8 +170,8 @@ void run(InputStream inRaw, JarOutputStream jstream, ByteBuffer presetInput) throws IOException { - BufferedInputStream in = new BufferedInputStream(inRaw); - this.in = in; // for readInputFn to see + BufferedInputStream in0 = new BufferedInputStream(inRaw); + this.in = in0; // for readInputFn to see _verbose = _props.getInteger(Utils.DEBUG_VERBOSE); // Fix for BugId: 4902477, -unpack.modification.time = 1059010598000 // TODO eliminate and fix in unpack.cpp @@ -224,7 +224,7 @@ if (_verbose > 0) Utils.log.info("bytes consumed = "+consumed); if (presetInput == null && - !Utils.isPackMagic(Utils.readMagic(in))) { + !Utils.isPackMagic(Utils.readMagic(in0))) { break; } if (_verbose > 0 ) { diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java Wed Jul 05 17:32:27 2017 +0200 @@ -52,12 +52,13 @@ import java.util.Map; import java.util.Set; import java.util.jar.JarFile; +import static com.sun.java.util.jar.pack.Constants.*; /** * Define the main data structure transmitted by pack/unpack. * @author John Rose */ -class Package implements Constants { +class Package { int verbose; { PropMap pmap = Utils.currentPropMap(); @@ -109,9 +110,9 @@ public static final Attribute.Layout attrCodeEmpty; public static final Attribute.Layout attrInnerClassesEmpty; public static final Attribute.Layout attrSourceFileSpecial; - public static final Map attrDefs; + public static final Map attrDefs; static { - HashMap ad = new HashMap<>(3); + Map ad = new HashMap<>(3); attrCodeEmpty = Attribute.define(ad, ATTR_CONTEXT_METHOD, "Code", "").layout(); attrInnerClassesEmpty = Attribute.define(ad, ATTR_CONTEXT_CLASS, @@ -130,8 +131,7 @@ */ int getHighestClassVersion() { int res = 0; // initial low value - for (Iterator i = classes.iterator(); i.hasNext(); ) { - Class cls = (Class) i.next(); + for (Class cls : classes) { int ver = cls.getVersion(); if (res < ver) res = ver; } @@ -187,7 +187,7 @@ return classes; } - public + public final class Class extends Attribute.Holder implements Comparable { public Package getPackage() { return Package.this; } @@ -232,8 +232,8 @@ initFile(newStub(classFile)); } - List getFields() { return fields == null ? noFields : fields; } - List getMethods() { return methods == null ? noMethods : methods; } + List getFields() { return fields == null ? noFields : fields; } + List getMethods() { return methods == null ? noMethods : methods; } public String getName() { return thisClass.stringValue(); @@ -264,7 +264,7 @@ if (olda == null) return; // no SourceFile attr. String obvious = getObviousSourceFile(); - ArrayList ref = new ArrayList(1); + List ref = new ArrayList<>(1); olda.visitRefs(this, VRM_PACKAGE, ref); Utf8Entry sfName = (Utf8Entry) ref.get(0); Attribute a = olda; @@ -322,7 +322,7 @@ } public void setInnerClasses(Collection ics) { - innerClasses = (ics == null) ? null : new ArrayList(ics); + innerClasses = (ics == null) ? null : new ArrayList<>(ics); // Edit the attribute list, if necessary. Attribute a = getAttribute(attrInnerClassesEmpty); if (innerClasses != null && a == null) @@ -341,7 +341,7 @@ * with that of Package.this.allInnerClasses. */ public List computeGloballyImpliedICs() { - HashSet cpRefs = new HashSet<>(); + Set cpRefs = new HashSet<>(); { // This block temporarily displaces this.innerClasses. ArrayList innerClassesSaved = innerClasses; innerClasses = null; // ignore for the moment @@ -350,7 +350,7 @@ } ConstantPool.completeReferencesIn(cpRefs, true); - HashSet icRefs = new HashSet<>(); + Set icRefs = new HashSet<>(); for (Entry e : cpRefs) { // Restrict cpRefs to InnerClasses entries only. if (!(e instanceof ClassEntry)) continue; @@ -390,7 +390,7 @@ List impliedICs = computeGloballyImpliedICs(); List actualICs = getInnerClasses(); if (actualICs == null) - actualICs = Collections.EMPTY_LIST; + actualICs = Collections.emptyList(); // Symmetric difference is calculated from I, A like this: // diff = (I+A) - (I*A) @@ -409,7 +409,7 @@ // Diff is A since I is empty. } // (I*A) is non-trivial - HashSet center = new HashSet<>(actualICs); + Set center = new HashSet<>(actualICs); center.retainAll(new HashSet<>(impliedICs)); impliedICs.addAll(actualICs); impliedICs.removeAll(center); @@ -443,7 +443,7 @@ } else if (actualICs == null) { // No local IC attribute, even though some are implied. // Signal with trivial attribute. - localICs = Collections.EMPTY_LIST; + localICs = Collections.emptyList(); } else { // Transmit a non-empty diff, which will create // a local ICs attribute. @@ -588,7 +588,7 @@ } public void strip(String attrName) { - if (attrName == "Code") + if ("Code".equals(attrName)) code = null; if (code != null) code.strip(attrName); @@ -622,7 +622,7 @@ } public void strip(String attrName) { - if (attrName == "InnerClass") + if ("InnerClass".equals(attrName)) innerClasses = null; for (int isM = 0; isM <= 1; isM++) { ArrayList members = (isM == 0) ? fields : methods; @@ -639,9 +639,7 @@ if (verbose > 2) Utils.log.fine("visitRefs "+this); refs.add(thisClass); refs.add(superClass); - for (int i = 0; i < interfaces.length; i++) { - refs.add(interfaces[i]); - } + refs.addAll(Arrays.asList(interfaces)); for (int isM = 0; isM <= 1; isM++) { ArrayList members = (isM == 0) ? fields : methods; if (members == null) continue; @@ -741,7 +739,7 @@ } public List getClassStubs() { - ArrayList classStubs = new ArrayList<>(classes.size()); + List classStubs = new ArrayList<>(classes.size()); for (Class cls : classes) { assert(cls.file.isClassStub()); classStubs.add(cls.file); @@ -749,8 +747,7 @@ return classStubs; } - public - class File implements Comparable { + public final class File implements Comparable { String nameString; // true name of this file Utf8Entry name; int modtime = NO_MODTIME; @@ -792,8 +789,10 @@ // The nameString is the key. Ignore other things. // (Note: The name might be "", in the case of a trivial class stub.) public boolean equals(Object o) { + if (o == null || (o.getClass() != File.class)) + return false; File that = (File)o; - return that.nameString == this.nameString; + return that.nameString.equals(this.nameString); } public int hashCode() { return nameString.hashCode(); @@ -816,9 +815,9 @@ return getFileName(null); } public java.io.File getFileName(java.io.File parent) { - String name = this.nameString; + String lname = this.nameString; //if (name.startsWith("./")) name = name.substring(2); - String fname = name.replace('/', java.io.File.separatorChar); + String fname = lname.replace('/', java.io.File.separatorChar); return new java.io.File(parent, fname); } @@ -834,7 +833,7 @@ } public long getFileLength() { long len = 0; - if (prepend == null && append == null) return 0; + if (prepend == null || append == null) return 0; for (Iterator i = prepend.iterator(); i.hasNext(); ) { byte[] block = (byte[]) i.next(); len += block.length; @@ -843,7 +842,7 @@ return len; } public void writeTo(OutputStream out) throws IOException { - if (prepend == null && append == null) return; + if (prepend == null || append == null) return; for (Iterator i = prepend.iterator(); i.hasNext(); ) { byte[] block = (byte[]) i.next(); out.write(block); @@ -859,8 +858,8 @@ } public InputStream getInputStream() { InputStream in = new ByteArrayInputStream(append.toByteArray()); - if (prepend.size() == 0) return in; - ArrayList isa = new ArrayList<>(prepend.size()+1); + if (prepend.isEmpty()) return in; + List isa = new ArrayList<>(prepend.size()+1); for (Iterator i = prepend.iterator(); i.hasNext(); ) { byte[] bytes = (byte[]) i.next(); isa.add(new ByteArrayInputStream(bytes)); @@ -897,11 +896,11 @@ } // Is there a globally declared table of inner classes? - ArrayList allInnerClasses = new ArrayList<>(); - HashMap allInnerClassesByThis; + List allInnerClasses = new ArrayList<>(); + Map allInnerClassesByThis; public - List getAllInnerClasses() { + List getAllInnerClasses() { return allInnerClasses; } @@ -955,16 +954,17 @@ if (parse == null) return false; String pkgOuter = parse[0]; //String number = parse[1]; - String name = parse[2]; + String lname = parse[2]; String haveName = (this.name == null) ? null : this.name.stringValue(); String haveOuter = (outerClass == null) ? null : outerClass.stringValue(); - boolean predictable = (name == haveName && pkgOuter == haveOuter); + boolean lpredictable = (lname == haveName && pkgOuter == haveOuter); //System.out.println("computePredictable => "+predictable); - return predictable; + return lpredictable; } public boolean equals(Object o) { - if (o == null) return false; + if (o == null || o.getClass() != InnerClass.class) + return false; InnerClass that = (InnerClass)o; return eq(this.thisClass, that.thisClass) && eq(this.outerClass, that.outerClass) @@ -999,7 +999,7 @@ // Helper for building InnerClasses attributes. static private - void visitInnerClassRefs(Collection innerClasses, int mode, Collection refs) { + void visitInnerClassRefs(Collection innerClasses, int mode, Collection refs) { if (innerClasses == null) { return; // no attribute; nothing to do } @@ -1008,8 +1008,7 @@ } if (innerClasses.size() > 0) { // Count the entries themselves: - for (Iterator i = innerClasses.iterator(); i.hasNext(); ) { - InnerClass c = (InnerClass) i.next(); + for (InnerClass c : innerClasses) { c.visitRefs(mode, refs); } } @@ -1117,43 +1116,43 @@ // what is one of { Debug, Compile, Constant, Exceptions, InnerClasses } if (verbose > 0) Utils.log.info("Stripping "+what.toLowerCase()+" data and attributes..."); - if (what == "Debug") { - strip("SourceFile"); - strip("LineNumberTable"); - strip("LocalVariableTable"); - strip("LocalVariableTypeTable"); - } - if (what == "Compile") { - // Keep the inner classes normally. - // Although they have no effect on execution, - // the Reflection API exposes them, and JCK checks them. - // NO: // strip("InnerClasses"); - strip("Deprecated"); - strip("Synthetic"); - } - if (what == "Exceptions") { - // Keep the exceptions normally. - // Although they have no effect on execution, - // the Reflection API exposes them, and JCK checks them. - strip("Exceptions"); - } - if (what == "Constant") { - stripConstantFields(); + switch (what) { + case "Debug": + strip("SourceFile"); + strip("LineNumberTable"); + strip("LocalVariableTable"); + strip("LocalVariableTypeTable"); + break; + case "Compile": + // Keep the inner classes normally. + // Although they have no effect on execution, + // the Reflection API exposes them, and JCK checks them. + // NO: // strip("InnerClasses"); + strip("Deprecated"); + strip("Synthetic"); + break; + case "Exceptions": + // Keep the exceptions normally. + // Although they have no effect on execution, + // the Reflection API exposes them, and JCK checks them. + strip("Exceptions"); + break; + case "Constant": + stripConstantFields(); + break; } } public void trimToSize() { classes.trimToSize(); - for (Iterator i = classes.iterator(); i.hasNext(); ) { - Class c = (Class)i.next(); + for (Class c : classes) { c.trimToSize(); } files.trimToSize(); } public void strip(String attrName) { - for (Iterator i = classes.iterator(); i.hasNext(); ) { - Class c = (Class)i.next(); + for (Class c : classes) { c.strip(attrName); } } @@ -1166,10 +1165,9 @@ } public void stripConstantFields() { - for (Iterator i = classes.iterator(); i.hasNext(); ) { - Class c = (Class) i.next(); - for (Iterator j = c.fields.iterator(); j.hasNext(); ) { - Class.Field f = (Class.Field) j.next(); + for (Class c : classes) { + for (Iterator j = c.fields.iterator(); j.hasNext(); ) { + Class.Field f = j.next(); if (Modifier.isFinal(f.flags) // do not strip non-static finals: && Modifier.isStatic(f.flags) @@ -1189,8 +1187,7 @@ c.visitRefs(mode, refs); } if (mode != VRM_CLASSIC) { - for (Iterator i = files.iterator(); i.hasNext(); ) { - File f = (File)i.next(); + for (File f : files) { f.visitRefs(mode, refs); } visitInnerClassRefs(allInnerClasses, mode, refs); @@ -1202,6 +1199,7 @@ // compress better. It also moves classes to the end of the // file order. It also removes JAR directory entries, which // are useless. + @SuppressWarnings("unchecked") void reorderFiles(boolean keepClassOrder, boolean stripDirectories) { // First reorder the classes, if that is allowed. if (!keepClassOrder) { @@ -1214,9 +1212,9 @@ // modtimes and options are not transmitted, and the stub files // for class files do not need to be transmitted at all. // Also - List stubs = getClassStubs(); - for (Iterator i = files.iterator(); i.hasNext(); ) { - File file = (File) i.next(); + List stubs = getClassStubs(); + for (Iterator i = files.iterator(); i.hasNext(); ) { + File file = i.next(); if (file.isClassStub() || (stripDirectories && file.isDirectory())) { i.remove(); @@ -1259,8 +1257,8 @@ void trimStubs() { // Restore enough non-trivial stubs to carry the needed class modtimes. - for (ListIterator i = files.listIterator(files.size()); i.hasPrevious(); ) { - File file = (File) i.previous(); + for (ListIterator i = files.listIterator(files.size()); i.hasPrevious(); ) { + File file = i.previous(); if (!file.isTrivialClassStub()) { if (verbose > 1) Utils.log.fine("Keeping last non-trivial "+file); @@ -1309,7 +1307,7 @@ // Use this before writing the class files. void ensureAllClassFiles() { - HashSet fileSet = new HashSet<>(files); + Set fileSet = new HashSet<>(files); for (Class cls : classes) { // Add to the end of ths list: if (!fileSet.contains(cls.file)) @@ -1317,8 +1315,8 @@ } } - static final List noObjects = Arrays.asList(new Object[0]); - static final List noFields = Arrays.asList(new Class.Field[0]); - static final List noMethods = Arrays.asList(new Class.Method[0]); - static final List noInnerClasses = Arrays.asList(new InnerClass[0]); + static final List noObjects = Arrays.asList(new Object[0]); + static final List noFields = Arrays.asList(new Class.Field[0]); + static final List noMethods = Arrays.asList(new Class.Method[0]); + static final List noInnerClasses = Arrays.asList(new InnerClass[0]); } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java Wed Jul 05 17:32:27 2017 +0200 @@ -32,11 +32,28 @@ import com.sun.java.util.jar.pack.ConstantPool.MemberEntry; import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry; import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry; -import java.io.*; -import java.util.*; import com.sun.java.util.jar.pack.Package.Class; import com.sun.java.util.jar.pack.Package.File; import com.sun.java.util.jar.pack.Package.InnerClass; +import java.io.ByteArrayOutputStream; +import java.io.EOFException; +import java.io.PrintStream; +import java.io.FilterInputStream; +import java.io.BufferedInputStream; +import java.io.InputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Map; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Set; +import static com.sun.java.util.jar.pack.Constants.*; /** * Reader for a package file. @@ -418,7 +435,7 @@ cp_Int.readFrom(in); for (int i = 0; i < cpMap.length; i++) { int x = cp_Int.getInt(); // coding handles signs OK - cpMap[i] = ConstantPool.getLiteralEntry(new Integer(x)); + cpMap[i] = ConstantPool.getLiteralEntry(x); } cp_Int.doneDisbursing(); break; @@ -428,7 +445,7 @@ for (int i = 0; i < cpMap.length; i++) { int x = cp_Float.getInt(); float fx = Float.intBitsToFloat(x); - cpMap[i] = ConstantPool.getLiteralEntry(new Float(fx)); + cpMap[i] = ConstantPool.getLiteralEntry(fx); } cp_Float.doneDisbursing(); break; @@ -444,7 +461,7 @@ long hi = cp_Long_hi.getInt(); long lo = cp_Long_lo.getInt(); long x = (hi << 32) + ((lo << 32) >>> 32); - cpMap[i] = ConstantPool.getLiteralEntry(new Long(x)); + cpMap[i] = ConstantPool.getLiteralEntry(x); } cp_Long_hi.doneDisbursing(); cp_Long_lo.doneDisbursing(); @@ -462,7 +479,7 @@ long lo = cp_Double_lo.getInt(); long x = (hi << 32) + ((lo << 32) >>> 32); double dx = Double.longBitsToDouble(x); - cpMap[i] = ConstantPool.getLiteralEntry(new Double(dx)); + cpMap[i] = ConstantPool.getLiteralEntry(dx); } cp_Double_hi.doneDisbursing(); cp_Double_lo.doneDisbursing(); @@ -645,7 +662,7 @@ cp_Utf8_big_suffix.doneDisbursing(); } - HashMap utf8Signatures; // Utf8Entry->SignatureEntry + Map utf8Signatures; void readSignatureBands(Entry[] cpMap) throws IOException { // cp_Signature: @@ -663,7 +680,7 @@ cp_Signature_classes.expectLength(getIntTotal(numSigClasses)); cp_Signature_classes.readFrom(in); cp_Signature_classes.setIndex(getCPIndex(CONSTANT_Class)); - utf8Signatures = new HashMap(); + utf8Signatures = new HashMap<>(); for (int i = 0; i < cpMap.length; i++) { Utf8Entry formRef = (Utf8Entry) cp_Signature_form.getRef(); ClassEntry[] classRefs = new ClassEntry[numSigClasses[i]]; @@ -863,7 +880,7 @@ ic_name.expectLength(longICCount); ic_name.readFrom(in); ic_flags.resetForSecondPass(); - ArrayList icList = new ArrayList(numInnerClasses); + List icList = new ArrayList<>(numInnerClasses); for (int i = 0; i < numInnerClasses; i++) { int flags = ic_flags.getInt(); boolean longForm = (flags & ACC_IC_LONG_FORM) != 0; @@ -876,7 +893,7 @@ thisName = (Utf8Entry) ic_name.getRef(); } else { String n = thisClass.stringValue(); - String[] parse = pkg.parseInnerClassName(n); + String[] parse = Package.parseInnerClassName(n); assert(parse != null); String pkgOuter = parse[0]; //String number = parse[1]; @@ -905,7 +922,7 @@ void readLocalInnerClasses(Class cls) throws IOException { int nc = class_InnerClasses_N.getInt(); - ArrayList localICs = new ArrayList(nc); + List localICs = new ArrayList<>(nc); for (int i = 0; i < nc; i++) { ClassEntry thisClass = (ClassEntry) class_InnerClasses_RC.getRef(); int flags = class_InnerClasses_F.getInt(); @@ -994,10 +1011,8 @@ return -1; } - Comparator entryOutputOrder = new Comparator() { - public int compare(Object o0, Object o1) { - Entry e0 = (Entry) o0; - Entry e1 = (Entry) o1; + Comparator entryOutputOrder = new Comparator<>() { + public int compare(Entry e0, Entry e1) { int k0 = getOutputIndex(e0); int k1 = getOutputIndex(e1); if (k0 >= 0 && k1 >= 0) @@ -1034,9 +1049,8 @@ } Entry[] reconstructLocalCPMap(Class cls) { - HashSet ldcRefs = (HashSet) ldcRefMap.get(cls); - HashSet cpRefs = new HashSet(); - HashSet sigSet = new HashSet(); + Set ldcRefs = ldcRefMap.get(cls); + Set cpRefs = new HashSet<>(); // look for constant pool entries: cls.visitRefs(VRM_CLASSIC, cpRefs); @@ -1064,8 +1078,7 @@ // construct a local constant pool int numDoubles = 0; - for (Iterator i = cpRefs.iterator(); i.hasNext(); ) { - Entry e = (Entry) i.next(); + for (Entry e : cpRefs) { if (e.isDoubleWord()) numDoubles++; assert(e.tag != CONSTANT_Signature) : (e); } @@ -1075,8 +1088,7 @@ // Add all ldc operands first. if (ldcRefs != null) { assert(cpRefs.containsAll(ldcRefs)); - for (Iterator i = ldcRefs.iterator(); i.hasNext(); ) { - Entry e = (Entry) i.next(); + for (Entry e : ldcRefs) { cpMap[fillp++] = e; } assert(fillp == 1+ldcRefs.size()); @@ -1085,11 +1097,10 @@ } // Next add all the two-byte references. - HashSet wideRefs = cpRefs; + Set wideRefs = cpRefs; cpRefs = null; // do not use! int narrowLimit = fillp; - for (Iterator i = wideRefs.iterator(); i.hasNext(); ) { - Entry e = (Entry) i.next(); + for (Entry e : wideRefs) { cpMap[fillp++] = e; } assert(fillp == narrowLimit+wideRefs.size()); @@ -1144,7 +1155,7 @@ method_descr.expectLength(totalNM); if (verbose > 1) Utils.log.fine("expecting #fields="+totalNF+" and #methods="+totalNM+" in #classes="+numClasses); - ArrayList fields = new ArrayList(totalNF); + List fields = new ArrayList<>(totalNF); field_descr.readFrom(in); for (int i = 0; i < classes.length; i++) { Class c = classes[i]; @@ -1160,7 +1171,7 @@ countAndReadAttrs(ATTR_CONTEXT_FIELD, fields); fields = null; // release to GC - ArrayList methods = new ArrayList(totalNM); + List methods = new ArrayList<>(totalNM); method_descr.readFrom(in); for (int i = 0; i < classes.length; i++) { Class c = classes[i]; @@ -1182,13 +1193,12 @@ } Code[] allCodes; - List codesWithFlags; - HashMap ldcRefMap = new HashMap(); // HashMap> + List codesWithFlags; + Map> ldcRefMap = new HashMap<>(); - Code[] buildCodeAttrs(List methods) { - ArrayList codes = new ArrayList(methods.size()); - for (Iterator i = methods.iterator(); i.hasNext(); ) { - Class.Method m = (Class.Method) i.next(); + Code[] buildCodeAttrs(List methods) { + List codes = new ArrayList<>(methods.size()); + for (Class.Method m : methods) { if (m.getAttribute(attrCodeEmpty) != null) { m.code = new Code(m); codes.add(m.code); @@ -1211,7 +1221,7 @@ boolean attrsOK = testBit(archiveOptions, AO_HAVE_ALL_CODE_FLAGS); code_headers.expectLength(allCodes.length); code_headers.readFrom(in); - ArrayList longCodes = new ArrayList(allCodes.length / 10); + List longCodes = new ArrayList<>(allCodes.length / 10); for (int i = 0; i < allCodes.length; i++) { Code c = allCodes[i]; int sc = code_headers.getByte(); @@ -1238,8 +1248,7 @@ code_max_stack.readFrom(in); code_max_na_locals.readFrom(in); code_handler_count.readFrom(in); - for (Iterator i = longCodes.iterator(); i.hasNext(); ) { - Code c = (Code) i.next(); + for (Code c : longCodes) { c.setMaxStack( code_max_stack.getInt() ); c.setMaxNALocals( code_max_na_locals.getInt() ); c.setHandlerCount( code_handler_count.getInt() ); @@ -1386,8 +1395,9 @@ // Fetch the attribute layout definitions which govern the bands // we are about to read. - Attribute.Layout[] defs = new Attribute.Layout[attrDefs[ctype].size()]; - attrDefs[ctype].toArray(defs); + List defList = attrDefs.get(ctype); + Attribute.Layout[] defs = new Attribute.Layout[defList.size()]; + defList.toArray(defs); IntBand xxx_flags_hi = getAttrBand(xxx_attr_bands, AB_FLAGS_HI); IntBand xxx_flags_lo = getAttrBand(xxx_attr_bands, AB_FLAGS_LO); IntBand xxx_attr_count = getAttrBand(xxx_attr_bands, AB_ATTR_COUNT); @@ -1450,7 +1460,7 @@ bits -= (1L< ha = new ArrayList<>(nfa + noa); h.attributes = ha; bits = attrBits; // iterate again for (int ai = 0; bits != 0; ai++) { @@ -1516,7 +1526,7 @@ if (predef != isPredefinedAttr(ctype, ai)) continue; // wrong pass int totalCount = totalCounts[ai]; - Band[] ab = (Band[]) attrBandTable.get(def); + Band[] ab = attrBandTable.get(def); if (def == attrInnerClassesEmpty) { // Special case. // Size the bands as if using the following layout: @@ -1571,15 +1581,16 @@ ATTR_CONTEXT_NAME[ctype]+" attribute"); } + @SuppressWarnings("unchecked") void readAttrs(int ctype, Collection holders) throws IOException { // Decode band values into attributes. - HashSet sawDefs = new HashSet(); + Set sawDefs = new HashSet<>(); ByteArrayOutputStream buf = new ByteArrayOutputStream(); for (Iterator i = holders.iterator(); i.hasNext(); ) { final Attribute.Holder h = (Attribute.Holder) i.next(); if (h.attributes == null) continue; - for (ListIterator j = h.attributes.listIterator(); j.hasNext(); ) { - Attribute a = (Attribute) j.next(); + for (ListIterator j = h.attributes.listIterator(); j.hasNext(); ) { + Attribute a = j.next(); Attribute.Layout def = a.layout(); if (def.bandCount == 0) { if (def == attrInnerClassesEmpty) { @@ -1595,7 +1606,7 @@ if (isCV) setConstantValueIndex((Class.Field)h); if (verbose > 2) Utils.log.fine("read "+a+" in "+h); - final Band[] ab = (Band[]) attrBandTable.get(def); + final Band[] ab = attrBandTable.get(def); // Read one attribute of type def from ab into a byte array. buf.reset(); Object fixups = a.unparse(new Attribute.ValueStream() { @@ -1617,10 +1628,9 @@ } // Mark the bands we just used as done disbursing. - for (Iterator i = sawDefs.iterator(); i.hasNext(); ) { - Attribute.Layout def = (Attribute.Layout) i.next(); + for (Attribute.Layout def : sawDefs) { if (def == null) continue; // unused index - Band[] ab = (Band[]) attrBandTable.get(def); + Band[] ab = attrBandTable.get(def); for (int j = 0; j < ab.length; j++) { ab[j].doneDisbursing(); } @@ -1778,7 +1788,7 @@ // scratch buffer for collecting code:: byte[] buf = new byte[1<<12]; // record of all switch opcodes (these are variable-length) - ArrayList allSwitchOps = new ArrayList(); + List allSwitchOps = new ArrayList<>(); for (int k = 0; k < allCodes.length; k++) { Code c = allCodes[k]; scanOneMethod: @@ -1798,7 +1808,7 @@ case _tableswitch: case _lookupswitch: bc_case_count.expectMoreLength(1); - allSwitchOps.add(new Integer(bc)); + allSwitchOps.add(bc); break; case _iinc: bc_local.expectMoreLength(1); @@ -1866,8 +1876,8 @@ // To size instruction bands correctly, we need info on switches: bc_case_count.readFrom(in); - for (Iterator i = allSwitchOps.iterator(); i.hasNext(); ) { - int bc = ((Integer)i.next()).intValue(); + for (Integer i : allSwitchOps) { + int bc = i.intValue(); int caseCount = bc_case_count.getInt(); bc_label.expectMoreLength(1+caseCount); // default label + cases bc_case_value.expectMoreLength(bc == _tableswitch ? 1 : caseCount); @@ -1892,9 +1902,9 @@ Class curClass = code.thisClass(); - HashSet ldcRefSet = (HashSet) ldcRefMap.get(curClass); + Set ldcRefSet = ldcRefMap.get(curClass); if (ldcRefSet == null) - ldcRefMap.put(curClass, ldcRefSet = new HashSet()); + ldcRefMap.put(curClass, ldcRefSet = new HashSet<>()); ClassEntry thisClass = curClass.thisClass; ClassEntry superClass = curClass.superClass; diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java Wed Jul 05 17:32:27 2017 +0200 @@ -45,10 +45,10 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; -import java.util.ListIterator; import java.util.Map; +import java.util.Set; +import static com.sun.java.util.jar.pack.Constants.*; /** * Writer for a package file. @@ -111,12 +111,12 @@ } } - HashSet requiredEntries; // for the CP - HashMap backCountTable; // for layout callables + Set requiredEntries; // for the CP + Map backCountTable; // for layout callables int[][] attrCounts; // count attr. occurences void setup() { - requiredEntries = new HashSet(); + requiredEntries = new HashSet<>(); setArchiveOptions(); trimClassAttributes(); collectAttributeLayouts(); @@ -139,9 +139,7 @@ // Import defaults from package (deflate hint, etc.). archiveOptions |= pkg.default_options; - for (Iterator i = pkg.files.iterator(); i.hasNext(); ) { - File file = (File) i.next(); - + for (File file : pkg.files) { int modtime = file.modtime; int options = file.options; @@ -178,16 +176,15 @@ } } // Decide on default version number (majority rule). - HashMap verCounts = new HashMap(); + Map verCounts = new HashMap<>(); int bestCount = 0; int bestVersion = -1; - for (Iterator i = pkg.classes.iterator(); i.hasNext(); ) { - Class cls = (Class) i.next(); + for (Class cls : pkg.classes) { int version = cls.getVersion(); - int[] var = (int[]) verCounts.get(new Integer(version)); + int[] var = verCounts.get(version); if (var == null) { var = new int[1]; - verCounts.put(new Integer(version), var); + verCounts.put(version, var); } int count = (var[0] += 1); //System.out.println("version="+version+" count="+count); @@ -210,9 +207,7 @@ Package.versionStringOf(pkg.getHighestClassVersion())); // Now add explicit pseudo-attrs. to classes with odd versions. - for (Iterator i = pkg.classes.iterator(); i.hasNext(); ) { - Class cls = (Class) i.next(); - + for (Class cls : pkg.classes) { if (cls.getVersion() != bestVersion) { Attribute a = makeClassFileVersionAttr(cls.minver, cls.majver); if (verbose > 1) { @@ -228,8 +223,7 @@ } // Decide if we are transmitting a huge resource file: - for (Iterator i = pkg.files.iterator(); i.hasNext(); ) { - File file = (File) i.next(); + for (File file : pkg.files) { long len = file.getFileLength(); if (len != (int)len) { archiveOptions |= AO_HAVE_FILE_SIZE_HI; @@ -244,10 +238,8 @@ // we must declare unconditional presence of code flags. int cost0 = 0; int cost1 = 0; - for (Iterator i = pkg.classes.iterator(); i.hasNext(); ) { - Class cls = (Class) i.next(); - for (Iterator j = cls.getMethods().iterator(); j.hasNext(); ) { - Class.Method m = (Class.Method) j.next(); + for (Class cls : pkg.classes) { + for (Class.Method m : cls.getMethods()) { if (m.code != null) { if (m.code.attributeSize() == 0) { // cost of a useless unconditional flags byte @@ -352,7 +344,7 @@ archive_header_1.putInt(pkg.default_modtime); archive_header_1.putInt(pkg.files.size()); } else { - assert(pkg.files.size() == 0); + assert(pkg.files.isEmpty()); } if (haveSpecial) { @@ -697,8 +689,7 @@ boolean haveModtime = testBit(options, AO_HAVE_FILE_MODTIME); boolean haveOptions = testBit(options, AO_HAVE_FILE_OPTIONS); if (!haveOptions) { - for (Iterator i = pkg.files.iterator(); i.hasNext(); ) { - File file = (File) i.next(); + for (File file : pkg.files) { if (file.isClassStub()) { haveOptions = true; options |= AO_HAVE_FILE_OPTIONS; @@ -711,9 +702,7 @@ options |= AO_HAVE_FILE_HEADERS; archiveOptions = options; } - - for (Iterator i = pkg.files.iterator(); i.hasNext(); ) { - File file = (File) i.next(); + for (File file : pkg.files) { file_name.putRef(file.name); long len = file.getFileLength(); file_size_lo.putInt((int)len); @@ -731,22 +720,20 @@ Utils.log.info("Wrote "+numFiles+" resource files"); } + @SuppressWarnings("unchecked") void collectAttributeLayouts() { maxFlags = new int[ATTR_CONTEXT_LIMIT]; - allLayouts = new HashMap[ATTR_CONTEXT_LIMIT]; + allLayouts = new FixedList<>(ATTR_CONTEXT_LIMIT); for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { - allLayouts[i] = new HashMap(); + allLayouts.set(i, new HashMap()); } // Collect maxFlags and allLayouts. - for (Iterator i = pkg.classes.iterator(); i.hasNext(); ) { - Class cls = (Class) i.next(); + for (Class cls : pkg.classes) { visitAttributeLayoutsIn(ATTR_CONTEXT_CLASS, cls); - for (Iterator j = cls.getFields().iterator(); j.hasNext(); ) { - Class.Field f = (Class.Field) j.next(); + for (Class.Field f : cls.getFields()) { visitAttributeLayoutsIn(ATTR_CONTEXT_FIELD, f); } - for (Iterator j = cls.getMethods().iterator(); j.hasNext(); ) { - Class.Method m = (Class.Method) j.next(); + for (Class.Method m : cls.getMethods()) { visitAttributeLayoutsIn(ATTR_CONTEXT_METHOD, m); if (m.code != null) { visitAttributeLayoutsIn(ATTR_CONTEXT_CODE, m.code); @@ -755,7 +742,7 @@ } // If there are many species of attributes, use 63-bit flags. for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { - int nl = allLayouts[i].size(); + int nl = allLayouts.get(i).size(); boolean haveLongFlags = haveFlagsHi(i); final int TOO_MANY_ATTRS = 32 /*int flag size*/ - 12 /*typical flag bits in use*/ @@ -781,7 +768,7 @@ } // Collect counts for both predefs. and custom defs. // Decide on custom, local attribute definitions. - backCountTable = new HashMap(); + backCountTable = new HashMap<>(); attrCounts = new int[ATTR_CONTEXT_LIMIT][]; for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { // Now the remaining defs in allLayouts[i] need attr. indexes. @@ -793,11 +780,12 @@ assert(attrIndexLimit[i] < 64); // all bits fit into a Java long avHiBits &= (1L< defMap = allLayouts.get(i); + Map.Entry[] layoutsAndCounts = new Map.Entry[defMap.size()]; + defMap.entrySet().toArray(layoutsAndCounts); // Sort by count, most frequent first. // Predefs. participate in this sort, though it does not matter. - Arrays.sort(layoutsAndCounts, new Comparator() { + Arrays.sort(layoutsAndCounts, new Comparator<>() { public int compare(Object o0, Object o1) { Map.Entry e0 = (Map.Entry) o0; Map.Entry e1 = (Map.Entry) o1; @@ -814,7 +802,7 @@ Attribute.Layout def = (Attribute.Layout) e.getKey(); int count = ((int[])e.getValue())[0]; int index; - Integer predefIndex = (Integer) attrIndexTable.get(def); + Integer predefIndex = attrIndexTable.get(def); if (predefIndex != null) { // The index is already set. index = predefIndex.intValue(); @@ -872,29 +860,32 @@ // Scratch variables for processing attributes and flags. int[] maxFlags; - HashMap[] allLayouts; + List> allLayouts; void visitAttributeLayoutsIn(int ctype, Attribute.Holder h) { // Make note of which flags appear in the class file. // Set them in maxFlags. maxFlags[ctype] |= h.flags; - for (Iterator i = h.getAttributes().iterator(); i.hasNext(); ) { - Attribute a = (Attribute) i.next(); + for (Attribute a : h.getAttributes()) { Attribute.Layout def = a.layout(); - int[] count = (int[]) allLayouts[ctype].get(def); - if (count == null) - allLayouts[ctype].put(def, count = new int[1]); - if (count[0] < Integer.MAX_VALUE) + Map defMap = allLayouts.get(ctype); + int[] count = defMap.get(def); + if (count == null) { + defMap.put(def, count = new int[1]); + } + if (count[0] < Integer.MAX_VALUE) { count[0] += 1; + } } } Attribute.Layout[] attrDefsWritten; + @SuppressWarnings("unchecked") void writeAttrDefs() throws IOException { - ArrayList defList = new ArrayList(); + List defList = new ArrayList<>(); for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { - int limit = attrDefs[i].size(); + int limit = attrDefs.get(i).size(); for (int j = 0; j < limit; j++) { int header = i; // ctype if (j < attrIndexLimit[i]) { @@ -906,9 +897,9 @@ continue; } } - Attribute.Layout def = (Attribute.Layout) attrDefs[i].get(j); - defList.add(new Object[]{ new Integer(header), def }); - assert(new Integer(j).equals(attrIndexTable.get(def))); + Attribute.Layout def = attrDefs.get(i).get(j); + defList.add(new Object[]{ Integer.valueOf(header), def }); + assert(Integer.valueOf(j).equals(attrIndexTable.get(def))); } } // Sort the new attr defs into some "natural" order. @@ -934,10 +925,7 @@ attrDefsWritten = new Attribute.Layout[numAttrDefs]; PrintStream dump = !optDumpBands ? null : new PrintStream(getDumpStream(attr_definition_headers, ".def")); - int[] indexForDebug = new int[ATTR_CONTEXT_LIMIT]; - for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { - indexForDebug[i] = attrIndexLimit[i]; - } + int[] indexForDebug = Arrays.copyOf(attrIndexLimit, ATTR_CONTEXT_LIMIT); for (int i = 0; i < defs.length; i++) { int header = ((Integer)defs[i][0]).intValue(); Attribute.Layout def = (Attribute.Layout) defs[i][1]; @@ -953,7 +941,7 @@ if (debug) { int hdrIndex = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB; if (hdrIndex < 0) hdrIndex = indexForDebug[def.ctype()]++; - int realIndex = ((Integer) attrIndexTable.get(def)).intValue(); + int realIndex = (attrIndexTable.get(def)).intValue(); assert(hdrIndex == realIndex); } if (dump != null) { @@ -969,8 +957,8 @@ for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) { MultiBand xxx_attr_bands = attrBands[ctype]; IntBand xxx_attr_calls = getAttrBand(xxx_attr_bands, AB_ATTR_CALLS); - Attribute.Layout[] defs = new Attribute.Layout[attrDefs[ctype].size()]; - attrDefs[ctype].toArray(defs); + Attribute.Layout[] defs = new Attribute.Layout[attrDefs.get(ctype).size()]; + attrDefs.get(ctype).toArray(defs); for (boolean predef = true; ; predef = false) { for (int ai = 0; ai < defs.length; ai++) { Attribute.Layout def = defs[ai]; @@ -980,7 +968,7 @@ int totalCount = attrCounts[ctype][ai]; if (totalCount == 0) continue; // irrelevant - int[] bc = (int[]) backCountTable.get(def); + int[] bc = backCountTable.get(def); for (int j = 0; j < bc.length; j++) { if (bc[j] >= 0) { int backCount = bc[j]; @@ -998,8 +986,7 @@ } void trimClassAttributes() { - for (Iterator i = pkg.classes.iterator(); i.hasNext(); ) { - Class cls = (Class) i.next(); + for (Class cls : pkg.classes) { // Replace "obvious" SourceFile attrs by null. cls.minimizeSourceFile(); } @@ -1008,14 +995,12 @@ void collectInnerClasses() { // Capture inner classes, removing them from individual classes. // Irregular inner classes must stay local, though. - HashMap allICMap = new HashMap(); + Map allICMap = new HashMap<>(); // First, collect a consistent global set. - for (Iterator i = pkg.classes.iterator(); i.hasNext(); ) { - Class cls = (Class) i.next(); + for (Class cls : pkg.classes) { if (!cls.hasInnerClasses()) continue; - for (Iterator j = cls.getInnerClasses().iterator(); j.hasNext(); ) { - InnerClass ic = (InnerClass) j.next(); - InnerClass pic = (InnerClass) allICMap.put(ic.thisClass, ic); + for (InnerClass ic : cls.getInnerClasses()) { + InnerClass pic = allICMap.put(ic.thisClass, ic); if (pic != null && !pic.equals(ic) && pic.predictable) { // Different ICs. Choose the better to make global. allICMap.put(pic.thisClass, pic); @@ -1036,15 +1021,13 @@ // Next, empty out of every local set the consistent entries. // Calculate whether there is any remaining need to have a local // set, and whether it needs to be locked. - for (Iterator i = pkg.classes.iterator(); i.hasNext(); ) { - Class cls = (Class) i.next(); + for (Class cls : pkg.classes) { cls.minimizeLocalICs(); } } void writeInnerClasses() throws IOException { - for (Iterator i = pkg.getAllInnerClasses().iterator(); i.hasNext(); ) { - InnerClass ic = (InnerClass) i.next(); + for (InnerClass ic : pkg.getAllInnerClasses()) { int flags = ic.flags; assert((flags & ACC_IC_LONG_FORM) == 0); if (!ic.predictable) { @@ -1064,10 +1047,9 @@ * local attribute. This is expected to be rare. */ void writeLocalInnerClasses(Class cls) throws IOException { - List localICs = cls.getInnerClasses(); + List localICs = cls.getInnerClasses(); class_InnerClasses_N.putInt(localICs.size()); - for (Iterator i = localICs.iterator(); i.hasNext(); ) { - InnerClass ic = (InnerClass) i.next(); + for(InnerClass ic : localICs) { class_InnerClasses_RC.putRef(ic.thisClass); // Is it redundant with the global version? if (ic.equals(pkg.getGlobalInnerClass(ic.thisClass))) { @@ -1121,18 +1103,16 @@ } void writeMembers(Class cls) throws IOException { - List fields = cls.getFields(); + List fields = cls.getFields(); class_field_count.putInt(fields.size()); - for (Iterator i = fields.iterator(); i.hasNext(); ) { - Class.Field f = (Class.Field) i.next(); + for (Class.Field f : fields) { field_descr.putRef(f.getDescriptor()); writeAttrs(ATTR_CONTEXT_FIELD, f, cls); } - List methods = cls.getMethods(); + List methods = cls.getMethods(); class_method_count.putInt(methods.size()); - for (Iterator i = methods.iterator(); i.hasNext(); ) { - Class.Method m = (Class.Method) i.next(); + for (Class.Method m : methods) { method_descr.putRef(m.getDescriptor()); writeAttrs(ATTR_CONTEXT_METHOD, m, cls); assert((m.code != null) == (m.getAttribute(attrCodeEmpty) != null)); @@ -1206,11 +1186,10 @@ long flagMask = attrFlagMask[ctype]; // which flags are attr bits? long flagsToAdd = 0; int overflowCount = 0; - for (ListIterator j = h.attributes.listIterator(); j.hasNext(); ) { - Attribute a = (Attribute) j.next(); + for (Attribute a : h.attributes) { Attribute.Layout def = a.layout(); - int index = ((Integer)attrIndexTable.get(def)).intValue(); - assert(attrDefs[ctype].get(index) == def); + int index = (attrIndexTable.get(def)).intValue(); + assert(attrDefs.get(ctype).get(index) == def); if (verbose > 3) Utils.log.fine("add attr @"+index+" "+a+" in "+h); if (index < attrIndexLimit[ctype] && testBit(flagMask, 1L<".equals(ref.descRef.nameRef.stringValue()) == false) return -1; ClassEntry refClass = ref.classRef; if (refClass == curClass.thisClass) @@ -1618,14 +1597,16 @@ String count = "" + codeHist[bc]; count = " ".substring(count.length()) + count; String pct = "" + (codeHist[bc] * 10000 / totalBytes); - while (pct.length() < 4) pct = "0" + pct; + while (pct.length() < 4) { + pct = "0" + pct; + } pct = pct.substring(0, pct.length()-2) + "." + pct.substring(pct.length()-2); hist[bc] = count + " " + pct + "% " + iname; } Arrays.sort(hist); System.out.println("Bytecode histogram ["+totalBytes+"]"); for (int i = hist.length; --i >= 0; ) { - if (hist[i] == "") continue; + if ("".equals(hist[i])) continue; System.out.println(hist[i]); } for (int tag = 0; tag < ldcHist.length; tag++) { diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Wed Jul 05 17:32:27 2017 +0200 @@ -69,7 +69,8 @@ * Get the set of options for the pack and unpack engines. * @return A sorted association of option key strings to option values. */ - public SortedMap properties() { + @SuppressWarnings("unchecked") + public SortedMap properties() { return props; } @@ -155,8 +156,8 @@ // All the worker bees..... - // The packer worker. + @SuppressWarnings("unchecked") private class DoPack { final int verbose = props.getInteger(Utils.DEBUG_VERBOSE); @@ -179,11 +180,11 @@ unknownAttrCommand = uaMode.intern(); } - final HashMap attrDefs; - final HashMap attrCommands; + final Map attrDefs; + final Map attrCommands; { - HashMap attrDefs = new HashMap(); - HashMap attrCommands = new HashMap(); + Map lattrDefs = new HashMap<>(); + Map lattrCommands = new HashMap<>(); String[] keys = { Pack200.Packer.CLASS_ATTRIBUTE_PFX, Pack200.Packer.FIELD_ATTRIBUTE_PFX, @@ -198,8 +199,9 @@ }; for (int i = 0; i < ctypes.length; i++) { String pfx = keys[i]; - Map map = props.prefixMap(pfx); - for (String key : map.keySet()) { + Map map = props.prefixMap(pfx); + for (Object k : map.keySet()) { + String key = (String)k; assert(key.startsWith(pfx)); String name = key.substring(pfx.length()); String layout = props.getProperty(key); @@ -207,24 +209,18 @@ if (Pack200.Packer.STRIP.equals(layout) || Pack200.Packer.PASS.equals(layout) || Pack200.Packer.ERROR.equals(layout)) { - attrCommands.put(lkey, layout.intern()); + lattrCommands.put(lkey, layout.intern()); } else { - Attribute.define(attrDefs, ctypes[i], name, layout); + Attribute.define(lattrDefs, ctypes[i], name, layout); if (verbose > 1) { Utils.log.fine("Added layout for "+Constants.ATTR_CONTEXT_NAME[i]+" attribute "+name+" = "+layout); } - assert(attrDefs.containsKey(lkey)); + assert(lattrDefs.containsKey(lkey)); } } } - if (attrDefs.size() > 0) - this.attrDefs = attrDefs; - else - this.attrDefs = null; - if (attrCommands.size() > 0) - this.attrCommands = attrCommands; - else - this.attrCommands = null; + this.attrDefs = (lattrDefs.isEmpty()) ? null : lattrDefs; + this.attrCommands = (lattrCommands.isEmpty()) ? null : lattrCommands; } final boolean keepFileOrder @@ -275,8 +271,8 @@ { // Which class files will be passed through? passFiles = props.getProperties(Pack200.Packer.PASS_FILE_PFX); - for (ListIterator i = passFiles.listIterator(); i.hasNext(); ) { - String file = (String) i.next(); + for (ListIterator i = passFiles.listIterator(); i.hasNext(); ) { + String file = i.next(); if (file == null) { i.remove(); continue; } file = Utils.getJarEntryName(file); // normalize '\\' to '/' if (file.endsWith("/")) @@ -333,7 +329,7 @@ pkg.reset(); } - class InFile { + final class InFile { final String name; final JarFile jf; final JarEntry je; @@ -596,8 +592,8 @@ // Package builder must have created a stub for each class. assert(pkg.files.containsAll(pkg.getClassStubs())); // Order of stubs in file list must agree with classes. - List res = pkg.files; - assert((res = new ArrayList(pkg.files)) + List res = pkg.files; + assert((res = new ArrayList<>(pkg.files)) .retainAll(pkg.getClassStubs()) || true); assert(res.equals(pkg.getClassStubs())); } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/PopulationCoding.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PopulationCoding.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PopulationCoding.java Wed Jul 05 17:32:27 2017 +0200 @@ -31,6 +31,8 @@ import java.io.OutputStream; import java.util.Arrays; import java.util.HashSet; +import java.util.Set; +import static com.sun.java.util.jar.pack.Constants.*; /** * Population-based coding. @@ -38,7 +40,7 @@ * @author John Rose */ // This tactic alone reduces the final zipped rt.jar by about a percent. -class PopulationCoding implements Constants, CodingMethod { +class PopulationCoding implements CodingMethod { Histogram vHist; // histogram of all values int[] fValues; // list of favored values int fVlen; // inclusive max index @@ -62,8 +64,8 @@ } } public void setFavoredValues(int[] fValues) { - int fVlen = fValues.length-1; - setFavoredValues(fValues, fVlen); + int lfVlen = fValues.length-1; + setFavoredValues(fValues, lfVlen); } public void setHistogram(Histogram vHist) { this.vHist = vHist; @@ -103,7 +105,7 @@ if (tokenCoding instanceof Coding && fValues != null) { Coding tc = (Coding) tokenCoding; if (tc == fitTokenCoding(fVlen, tc.L())) - this.L = tc.L();; + this.L = tc.L(); // Otherwise, it's a non-default coding. } } @@ -217,13 +219,13 @@ } private long[] makeSymtab() { - long[] symtab = new long[fVlen]; + long[] lsymtab = new long[fVlen]; for (int token = 1; token <= fVlen; token++) { - symtab[token-1] = ((long)fValues[token] << 32) | token; + lsymtab[token-1] = ((long)fValues[token] << 32) | token; } // Index by value: - Arrays.sort(symtab); - return symtab; + Arrays.sort(lsymtab); + return lsymtab; } private Coding getTailCoding(CodingMethod c) { @@ -302,12 +304,12 @@ } int[] readFavoredValuesFrom(InputStream in, int maxForDebug) throws IOException { - int[] fValues = new int[1000]; // realloc as needed + int[] lfValues = new int[1000]; // realloc as needed // The set uniqueValuesForDebug records all favored values. // As each new value is added, we assert that the value // was not already in the set. - HashSet uniqueValuesForDebug = null; - assert((uniqueValuesForDebug = new HashSet()) != null); + Set uniqueValuesForDebug = null; + assert((uniqueValuesForDebug = new HashSet<>()) != null); int fillp = 1; maxForDebug += fillp; int min = Integer.MIN_VALUE; // farthest from the center @@ -317,13 +319,14 @@ while (fcm instanceof AdaptiveCoding) { AdaptiveCoding ac = (AdaptiveCoding) fcm; int len = ac.headLength; - while (fillp + len > fValues.length) - fValues = BandStructure.realloc(fValues); + while (fillp + len > lfValues.length) { + lfValues = BandStructure.realloc(lfValues); + } int newFillp = fillp + len; - ac.headCoding.readArrayFrom(in, fValues, fillp, newFillp); + ac.headCoding.readArrayFrom(in, lfValues, fillp, newFillp); while (fillp < newFillp) { - int val = fValues[fillp++]; - assert(uniqueValuesForDebug.add(new Integer(val))); + int val = lfValues[fillp++]; + assert(uniqueValuesForDebug.add(val)); assert(fillp <= maxForDebug); last = val; min = moreCentral(min, val); @@ -344,10 +347,10 @@ state = val; if (fillp > 1 && (val == last || val == min)) //|| val == min2 break; - if (fillp == fValues.length) - fValues = BandStructure.realloc(fValues); - fValues[fillp++] = val; - assert(uniqueValuesForDebug.add(new Integer(val))); + if (fillp == lfValues.length) + lfValues = BandStructure.realloc(lfValues); + lfValues[fillp++] = val; + assert(uniqueValuesForDebug.add(val)); assert(fillp <= maxForDebug); last = val; min = moreCentral(min, val); @@ -358,17 +361,17 @@ int val = fc.readFrom(in); if (fillp > 1 && (val == last || val == min)) //|| val == min2 break; - if (fillp == fValues.length) - fValues = BandStructure.realloc(fValues); - fValues[fillp++] = val; - assert(uniqueValuesForDebug.add(new Integer(val))); + if (fillp == lfValues.length) + lfValues = BandStructure.realloc(lfValues); + lfValues[fillp++] = val; + assert(uniqueValuesForDebug.add(val)); assert(fillp <= maxForDebug); last = val; min = moreCentral(min, val); //min2 = moreCentral2(min2, val, min); } } - return BandStructure.realloc(fValues, fillp); + return BandStructure.realloc(lfValues, fillp); } private static int moreCentral(int x, int y) { @@ -478,7 +481,7 @@ boolean verbose = (p200 != null && p200.getBoolean(Utils.COM_PREFIX+"verbose.pop")); - StringBuffer res = new StringBuffer(100); + StringBuilder res = new StringBuilder(100); res.append("pop(").append("fVlen=").append(fVlen); if (verbose && fValues != null) { res.append(" fV=["); diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java Wed Jul 05 17:32:27 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003,2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,8 +34,8 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; +import java.util.Comparator; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; @@ -46,36 +46,36 @@ /** * Control block for publishing Pack200 options to the other classes. */ -class PropMap extends TreeMap { - ArrayList _listeners = new ArrayList(1); + +final class PropMap implements SortedMap { + private final TreeMap theMap = new TreeMap<>();; + private final List listenerList = new ArrayList<>(1); void addListener(PropertyChangeListener listener) { - _listeners.add(listener); + listenerList.add(listener); } void removeListener(PropertyChangeListener listener) { - _listeners.remove(listener); + listenerList.remove(listener); } - void addListeners(ArrayList listeners) { - _listeners.addAll(listeners); + void addListeners(ArrayList listeners) { + listenerList.addAll(listeners); } - void removeListeners(ArrayList listeners) { - _listeners.removeAll(listeners); + void removeListeners(ArrayList listeners) { + listenerList.removeAll(listeners); } // Override: public Object put(Object key, Object value) { - Object oldValue = super.put(key, value); - if (value != oldValue && _listeners.size() > 0) { + Object oldValue = theMap.put(key, value); + if (value != oldValue && !listenerList.isEmpty()) { // Post the property change event. PropertyChangeEvent event = new PropertyChangeEvent(this, (String) key, oldValue, value); - for (Iterator i = _listeners.iterator(); i.hasNext(); ) { - PropertyChangeListener listener = - (PropertyChangeListener) i.next(); + for (PropertyChangeListener listener : listenerList) { listener.propertyChange(event); } } @@ -85,7 +85,7 @@ // All this other stuff is private to the current package. // Outide clients of Pack200 do not need to use it; they can // get by with generic SortedMap functionality. - private static Map defaultProps; + private static Map defaultProps; static { Properties props = new Properties(); @@ -122,13 +122,12 @@ // Define certain attribute layouts by default. // Do this after the previous props are put in place, // to allow override if necessary. + InputStream propStr = null; try { String propFile = "intrinsic.properties"; - InputStream propStr = PackerImpl.class.getResourceAsStream(propFile); + propStr = PackerImpl.class.getResourceAsStream(propFile); props.load(new BufferedInputStream(propStr)); - propStr.close(); - for (Iterator i = props.entrySet().iterator(); i.hasNext(); ) { - Map.Entry e = (Map.Entry) i.next(); + for (Map.Entry e : props.entrySet()) { String key = (String) e.getKey(); String val = (String) e.getValue(); if (key.startsWith("attribute.")) { @@ -137,19 +136,25 @@ } } catch (IOException ee) { throw new RuntimeException(ee); + } finally { + try { + if (propStr != null) { + propStr.close(); + } + } catch (IOException ignore) {} } - defaultProps = (new HashMap(props)); // shrink to fit + defaultProps = (new HashMap<>(props)); // shrink to fit } PropMap() { - putAll(defaultProps); + theMap.putAll(defaultProps); } // Return a view of this map which includes only properties // that begin with the given prefix. This is easy because // the map is sorted, and has a subMap accessor. - SortedMap prefixMap(String prefix) { + SortedMap prefixMap(String prefix) { int len = prefix.length(); if (len == 0) return this; @@ -174,8 +179,8 @@ // Get sequence of props for "prefix", and "prefix.*". List getProperties(String prefix) { - Collection values = prefixMap(prefix).values(); - ArrayList res = new ArrayList(values.size()); + Collection values = prefixMap(prefix).values(); + List res = new ArrayList<>(values.size()); res.addAll(values); while (res.remove(null)); return res; @@ -240,11 +245,97 @@ void list(PrintWriter out) { out.println("#"+Utils.PACK_ZIP_ARCHIVE_MARKER_COMMENT+"["); Set defaults = defaultProps.entrySet(); - for (Iterator i = entrySet().iterator(); i.hasNext(); ) { - Map.Entry e = (Map.Entry) i.next(); + for (Map.Entry e : theMap.entrySet()) { if (defaults.contains(e)) continue; out.println(" " + e.getKey() + " = " + e.getValue()); } out.println("#]"); } + + @Override + public int size() { + return theMap.size(); + } + + @Override + public boolean isEmpty() { + return theMap.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + return theMap.containsKey(key); + } + + @Override + public boolean containsValue(Object value) { + return theMap.containsValue(value); + } + + @Override + public Object get(Object key) { + return theMap.get(key); + } + + @Override + public Object remove(Object key) { + return theMap.remove(key); + } + + @Override + @SuppressWarnings("unchecked") + public void putAll(Map m) { + theMap.putAll(m); + } + + @Override + public void clear() { + theMap.clear(); + } + + @Override + public Set keySet() { + return theMap.keySet(); + } + + @Override + public Collection values() { + return theMap.values(); + } + + @Override + public Set> entrySet() { + return theMap.entrySet(); + } + + @Override + @SuppressWarnings("unchecked") + public Comparator comparator() { + return (Comparator) theMap.comparator(); + } + + @Override + public SortedMap subMap(Object fromKey, Object toKey) { + return theMap.subMap(fromKey, toKey); + } + + @Override + public SortedMap headMap(Object toKey) { + return theMap.headMap(toKey); + } + + @Override + public SortedMap tailMap(Object fromKey) { + return theMap.tailMap(fromKey); + } + + @Override + public Object firstKey() { + return theMap.firstKey(); + } + + @Override + public Object lastKey() { + return theMap.lastKey(); + } } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java Wed Jul 05 17:32:27 2017 +0200 @@ -34,7 +34,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.HashSet; -import java.util.Iterator; +import java.util.Set; import java.util.SortedMap; import java.util.TimeZone; import java.util.jar.JarEntry; @@ -81,7 +81,8 @@ * Get the set of options for the pack and unpack engines. * @return A sorted association of option key strings to option values. */ - public SortedMap properties() { + @SuppressWarnings("unchecked") + public SortedMap properties() { return props; } @@ -225,9 +226,8 @@ props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50"); pkg.ensureAllClassFiles(); // Now write out the files. - HashSet classesToWrite = new HashSet<>(pkg.getClasses()); - for (Iterator i = pkg.getFiles().iterator(); i.hasNext(); ) { - Package.File file = (Package.File) i.next(); + Set classesToWrite = new HashSet<>(pkg.getClasses()); + for (Package.File file : pkg.getFiles()) { String name = file.nameString; JarEntry je = new JarEntry(Utils.getJarEntryName(name)); boolean deflate; diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java Wed Jul 05 17:32:27 2017 +0200 @@ -297,7 +297,7 @@ (int)( (1.0 - ((double)ze.getCompressedSize()/(double)ze.getSize()))*100 ) : 0 ; // Follow unzip -lv output - return (long)ze.getSize() + "\t" + ze.getMethod() + return ze.getSize() + "\t" + ze.getMethod() + "\t" + ze.getCompressedSize() + "\t" + store + "%\t" + new Date(ze.getTime()) + "\t" diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java --- a/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java Wed Jul 05 17:32:27 2017 +0200 @@ -1393,8 +1393,11 @@ public void run() { if (Printer.trace) Printer.trace(">>> DirectClip: run() threadID="+Thread.currentThread().getId()); while (thread != null) { - if (!doIO) { - synchronized(lock) { + // doIO is volatile, but we could check it, then get + // pre-empted while another thread changes doIO and notifies, + // before we wait (so we sleep in wait forever). + synchronized(lock) { + if (!doIO) { try { lock.wait(); } catch(InterruptedException ie) {} diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java --- a/jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java Wed Jul 05 17:32:27 2017 +0200 @@ -61,26 +61,43 @@ private ScriptEngineFactory factory; private InterfaceImplementor implementor; + private static final int languageVersion = getLanguageVersion(); + private static final int optimizationLevel = getOptimizationLevel(); static { ContextFactory.initGlobal(new ContextFactory() { protected Context makeContext() { Context cx = super.makeContext(); + cx.setLanguageVersion(languageVersion); + cx.setOptimizationLevel(optimizationLevel); cx.setClassShutter(RhinoClassShutter.getInstance()); cx.setWrapFactory(RhinoWrapFactory.getInstance()); return cx; } - - public boolean hasFeature(Context cx, int feature) { - // we do not support E4X (ECMAScript for XML)! - if (feature == Context.FEATURE_E4X) { - return false; - } else { - return super.hasFeature(cx, feature); - } - } }); } + private static final String RHINO_JS_VERSION = "rhino.js.version"; + private static int getLanguageVersion() { + int version; + String tmp = java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction(RHINO_JS_VERSION)); + if (tmp != null) { + version = Integer.parseInt((String)tmp); + } else { + version = Context.VERSION_1_8; + } + return version; + } + + private static final String RHINO_OPT_LEVEL = "rhino.opt.level"; + private static int getOptimizationLevel() { + int optLevel = -1; + // disable optimizer under security manager, for now. + if (System.getSecurityManager() == null) { + optLevel = Integer.getInteger(RHINO_OPT_LEVEL, -1); + } + return optLevel; + } /** * Creates a new instance of RhinoScriptEngine @@ -333,6 +350,7 @@ return result instanceof Undefined ? null : result; } + /* public static void main(String[] args) throws Exception { if (args.length == 0) { System.out.println("No file specified"); @@ -347,4 +365,5 @@ engine.eval(r); System.out.println(engine.get("x")); } + */ } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngineFactory.java --- a/jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngineFactory.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngineFactory.java Wed Jul 05 17:32:27 2017 +0200 @@ -58,11 +58,11 @@ } else if (key.equals(ScriptEngine.ENGINE)) { return "Mozilla Rhino"; } else if (key.equals(ScriptEngine.ENGINE_VERSION)) { - return "1.6 release 2"; + return "1.7 release 3 PRERELEASE"; } else if (key.equals(ScriptEngine.LANGUAGE)) { return "ECMAScript"; } else if (key.equals(ScriptEngine.LANGUAGE_VERSION)) { - return "1.6"; + return "1.8"; } else if (key.equals("THREADING")) { return "MULTITHREADED"; } else { @@ -128,10 +128,12 @@ return ret; } + /* public static void main(String[] args) { RhinoScriptEngineFactory fact = new RhinoScriptEngineFactory(); System.out.println(fact.getParameter(ScriptEngine.ENGINE_VERSION)); } + */ private static List names; private static List mimeTypes; diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/script/javascript/RhinoTopLevel.java --- a/jdk/src/share/classes/com/sun/script/javascript/RhinoTopLevel.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/script/javascript/RhinoTopLevel.java Wed Jul 05 17:32:27 2017 +0200 @@ -37,15 +37,6 @@ * @since 1.6 */ public final class RhinoTopLevel extends ImporterTopLevel { - - // variables defined always to help Java access from JavaScript - private static final String builtinVariables = - "var com = Packages.com; \n" + - "var edu = Packages.edu; \n" + - "var javax = Packages.javax; \n" + - "var net = Packages.net; \n" + - "var org = Packages.org; \n"; - RhinoTopLevel(Context cx, RhinoScriptEngine engine) { super(cx); this.engine = engine; @@ -67,9 +58,6 @@ String names[] = { "bindings", "scope", "sync" }; defineFunctionProperties(names, RhinoTopLevel.class, ScriptableObject.DONTENUM); - - // define built-in variables - cx.evaluateString(this, builtinVariables, "", 1, null); } /** diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/com/sun/tools/script/shell/init.js --- a/jdk/src/share/classes/com/sun/tools/script/shell/init.js Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/com/sun/tools/script/shell/init.js Wed Jul 05 17:32:27 2017 +0200 @@ -311,9 +311,9 @@ try { engine.eval(reader); } finally { - engine.put(engine.FILENAME, oldFilename); + engine.put(engine.FILENAME, oldFilename); + streamClose(stream); } - streamClose(stream); } // file system utilities diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/awt/SplashScreen.java --- a/jdk/src/share/classes/java/awt/SplashScreen.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/awt/SplashScreen.java Wed Jul 05 17:32:27 2017 +0200 @@ -33,27 +33,17 @@ import sun.awt.image.SunWritableRaster; /** - * The splash screen can be created at application startup, before the + * The splash screen can be displayed at application startup, before the * Java Virtual Machine (JVM) starts. The splash screen is displayed as an - * undecorated window containing an image. You can use GIF, JPEG, and PNG files - * for the image. Animation (for GIF) and transparency (for GIF, PNG) are - * supported. The window is positioned at the center of the screen (the - * position on multi-monitor systems is not specified - it is platform and - * implementation dependent). - * The window is closed automatically as soon as the first window is displayed by - * Swing/AWT (may be also closed manually using the Java API, see below). + * undecorated window containing an image. You can use GIF, JPEG, or PNG files + * for the image. Animation is supported for the GIF format, while transparency + * is supported both for GIF and PNG. The window is positioned at the center + * of the screen. The position on multi-monitor systems is not specified. It is + * platform and implementation dependent. The splash screen window is closed + * automatically as soon as the first window is displayed by Swing/AWT (may be + * also closed manually using the Java API, see below). *

- * There are two ways to show the native splash screen: - *

- *

    - *
  • If your application is run from the command line or from a shortcut, - * use the "-splash:" Java application launcher option to show a splash screen. - *
    - * For example: - *
    - * java -splash:filename.gif Test
    - * 
    - *
  • If your application is packaged in a jar file, you can use the + * If your application is packaged in a jar file, you can use the * "SplashScreen-Image" option in a manifest file to show a splash screen. * Place the image in the jar archive and specify the path in the option. * The path should not have a leading slash. @@ -64,18 +54,39 @@ * Main-Class: Test * SplashScreen-Image: filename.gif * + *

    + * If the Java implementation provides the command-line interface and you run + * your application by using the command line or a shortcut, use the Java + * application launcher option to show a splash screen. The Oracle reference + * implementation allows you to specify the splash screen image location with + * the {@code -splash:} option. + *
    + * For example: + *

    + * java -splash:filename.gif Test
    + * 
    * The command line interface has higher precedence over the manifest * setting. - *
+ *

+ * The splash screen will be displayed as faithfully as possible to present the + * whole splash screen image given the limitations of the target platform and + * display. + *

+ * It is implied that the specified image is presented on the screen "as is", + * i.e. preserving the exact color values as specified in the image file. Under + * certain circumstances, though, the presented image may differ, e.g. when + * applying color dithering to present a 32 bits per pixel (bpp) image on a 16 + * or 8 bpp screen. The native platform display configuration may also affect + * the colors of the displayed image (e.g. color profiles, etc.) *

* The {@code SplashScreen} class provides the API for controlling the splash * screen. This class may be used to close the splash screen, change the splash - * screen image, get the image position/size and paint in the splash screen. It - * cannot be used to create the splash screen; you should use the command line or manifest - * file option for that. + * screen image, get the splash screen native window position/size, and paint + * in the splash screen. It cannot be used to create the splash screen. You + * should use the options provided by the Java implementation for that. *

* This class cannot be instantiated. Only a single instance of this class - * can exist, and it may be obtained using the {@link #getSplashScreen()} + * can exist, and it may be obtained by using the {@link #getSplashScreen()} * static method. In case the splash screen has not been created at * application startup via the command line or manifest file option, * the getSplashScreen method returns null. @@ -91,7 +102,7 @@ /** * Returns the {@code SplashScreen} object used for - * Java startup splash screen control. + * Java startup splash screen control on systems that support display. * * @throws UnsupportedOperationException if the splash screen feature is not * supported by the current toolkit @@ -219,6 +230,9 @@ *

* You cannot control the size or position of the splash screen. * The splash screen size is adjusted automatically when the image changes. + *

+ * The image may contain transparent areas, and thus the reported bounds may + * be larger than the visible splash screen image on the screen. * * @return a {@code Rectangle} containing the splash screen bounds * @throws IllegalStateException if the splash screen has already been closed @@ -237,6 +251,9 @@ *

* You cannot control the size or position of the splash screen. * The splash screen size is adjusted automatically when the image changes. + *

+ * The image may contain transparent areas, and thus the reported size may + * be larger than the visible splash screen image on the screen. * * @return a {@link Dimension} object indicating the splash screen size * @throws IllegalStateException if the splash screen has already been closed @@ -254,6 +271,10 @@ * screen window. You should call {@code update()} on the * SplashScreen when you want the splash screen to be * updated immediately. + *

+ * The pixel (0, 0) in the coordinate space of the graphics context + * corresponds to the origin of the splash screen native window bounds (see + * {@link #getBounds()}). * * @return graphics context for the splash screen overlay surface * @throws IllegalStateException if the splash screen has already been closed @@ -334,6 +355,11 @@ * Determines whether the splash screen is visible. The splash screen may * be hidden using {@link #close()}, it is also hidden automatically when * the first AWT/Swing window is made visible. + *

+ * Note that the native platform may delay presenting the splash screen + * native window on the screen. The return value of {@code true} for this + * method only guarantees that the conditions to hide the splash screen + * window have not occurred yet. * * @return true if the splash screen is visible (has not been closed yet), * false otherwise diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/awt/font/NumericShaper.java --- a/jdk/src/share/classes/java/awt/font/NumericShaper.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/awt/font/NumericShaper.java Wed Jul 05 17:32:27 2017 +0200 @@ -58,20 +58,20 @@ * It is also possible to perform numeric shaping explicitly using instances * of NumericShaper, as this code snippet demonstrates:
*

- *   char[] text = ...;
- *   // shape all EUROPEAN digits (except zero) to ARABIC digits
- *   NumericShaper shaper = NumericShaper.getShaper(NumericShaper.ARABIC);
- *   shaper.shape(text, start, count);
+ * char[] text = ...;
+ * // shape all EUROPEAN digits (except zero) to ARABIC digits
+ * NumericShaper shaper = NumericShaper.getShaper(NumericShaper.ARABIC);
+ * shaper.shape(text, start, count);
  *
- *   // shape European digits to ARABIC digits if preceding text is Arabic, or
- *   // shape European digits to TAMIL digits if preceding text is Tamil, or
- *   // leave European digits alone if there is no preceding text, or
- *   // preceding text is neither Arabic nor Tamil
- *   NumericShaper shaper =
- *      NumericShaper.getContextualShaper(NumericShaper.ARABIC |
- *                                              NumericShaper.TAMIL,
- *                                              NumericShaper.EUROPEAN);
- *   shaper.shape(text, start, count);
+ * // shape European digits to ARABIC digits if preceding text is Arabic, or
+ * // shape European digits to TAMIL digits if preceding text is Tamil, or
+ * // leave European digits alone if there is no preceding text, or
+ * // preceding text is neither Arabic nor Tamil
+ * NumericShaper shaper =
+ *     NumericShaper.getContextualShaper(NumericShaper.ARABIC |
+ *                                         NumericShaper.TAMIL,
+ *                                       NumericShaper.EUROPEAN);
+ * shaper.shape(text, start, count);
  * 
* *

Bit mask- and enum-based Unicode ranges

@@ -99,6 +99,37 @@ * values are specified, such as {@code NumericShaper.Range.BALINESE}, * those ranges are ignored. * + *

Decimal Digits Precedence

+ * + *

A Unicode range may have more than one set of decimal digits. If + * multiple decimal digits sets are specified for the same Unicode + * range, one of the sets will take precedence as follows. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Unicode RangeNumericShaper ConstantsPrecedence
Arabic{@link NumericShaper#ARABIC NumericShaper.ARABIC}
+ * {@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}
{@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}
{@link NumericShaper.Range#ARABIC}
+ * {@link NumericShaper.Range#EASTERN_ARABIC}
{@link NumericShaper.Range#EASTERN_ARABIC}
Tai Tham{@link NumericShaper.Range#TAI_THAM_HORA}
+ * {@link NumericShaper.Range#TAI_THAM_THAM}
{@link NumericShaper.Range#TAI_THAM_THAM}
+ * * @since 1.4 */ diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/awt/image/IndexColorModel.java --- a/jdk/src/share/classes/java/awt/image/IndexColorModel.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/awt/image/IndexColorModel.java Wed Jul 05 17:32:27 2017 +0200 @@ -625,7 +625,7 @@ } nBits[0] = nBits[1] = nBits[2] = 8; } - return nBits; + return nBits.clone(); } /** diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/awt/image/SampleModel.java --- a/jdk/src/share/classes/java/awt/image/SampleModel.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/awt/image/SampleModel.java Wed Jul 05 17:32:27 2017 +0200 @@ -121,7 +121,7 @@ */ public SampleModel(int dataType, int w, int h, int numBands) { - float size = (float)w*h; + long size = (long)w * h; if (w <= 0 || h <= 0) { throw new IllegalArgumentException("Width ("+w+") and height ("+ h+") must be > 0"); diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/awt/image/SinglePixelPackedSampleModel.java --- a/jdk/src/share/classes/java/awt/image/SinglePixelPackedSampleModel.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/awt/image/SinglePixelPackedSampleModel.java Wed Jul 05 17:32:27 2017 +0200 @@ -92,7 +92,8 @@ * Constructs a SinglePixelPackedSampleModel with bitMasks.length bands. * Each sample is stored in a data array element in the position of * its corresponding bit mask. Each bit mask must be contiguous and - * masks must not overlap. + * masks must not overlap. Bit masks exceeding data type capacity are + * truncated. * @param dataType The data type for storing samples. * @param w The width (in pixels) of the region of the * image data described. @@ -120,7 +121,8 @@ * and a scanline stride equal to scanlineStride data array elements. * Each sample is stored in a data array element in the position of * its corresponding bit mask. Each bit mask must be contiguous and - * masks must not overlap. + * masks must not overlap. Bit masks exceeding data type capacity are + * truncated. * @param dataType The data type for storing samples. * @param w The width (in pixels) of the region of * image data described. @@ -153,11 +155,13 @@ this.bitOffsets = new int[numBands]; this.bitSizes = new int[numBands]; + int maxMask = (int)((1L << DataBuffer.getDataTypeSize(dataType)) - 1); + this.maxBitSize = 0; for (int i=0; i>> 1; @@ -243,30 +247,12 @@ /** Returns the number of bits per sample for all bands. */ public int[] getSampleSize() { - int mask; - int sampleSize[] = new int [numBands]; - for (int i=0; i>> bitOffsets[i]; - while ((mask & 1) != 0) { - sampleSize[i] ++; - mask = mask >>> 1; - } - } - - return sampleSize; + return bitSizes.clone(); } /** Returns the number of bits per sample for the specified band. */ public int getSampleSize(int band) { - int sampleSize = 0; - int mask = bitMasks[band] >>> bitOffsets[band]; - while ((mask & 1) != 0) { - sampleSize ++; - mask = mask >>> 1; - } - - return sampleSize; + return bitSizes[band]; } /** Returns the offset (in data array elements) of pixel (x,y). diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/io/DeleteOnExitHook.java --- a/jdk/src/share/classes/java/io/DeleteOnExitHook.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/io/DeleteOnExitHook.java Wed Jul 05 17:32:27 2017 +0200 @@ -34,7 +34,7 @@ */ class DeleteOnExitHook { - private static LinkedHashSet files = new LinkedHashSet(); + private static LinkedHashSet files = new LinkedHashSet<>(); static { // DeleteOnExitHook must be the last shutdown hook to be invoked. // Application shutdown hooks may add the first file to the @@ -71,7 +71,7 @@ files = null; } - ArrayList toBeDeleted = new ArrayList(theFiles); + ArrayList toBeDeleted = new ArrayList<>(theFiles); // reverse the list to maintain previous jdk deletion order. // Last in first deleted. diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/io/File.java --- a/jdk/src/share/classes/java/io/File.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/io/File.java Wed Jul 05 17:32:27 2017 +0200 @@ -1067,7 +1067,7 @@ if ((names == null) || (filter == null)) { return names; } - List v = new ArrayList(); + List v = new ArrayList<>(); for (int i = 0 ; i < names.length ; i++) { if (filter.accept(this, names[i])) { v.add(names[i]); @@ -1158,7 +1158,7 @@ public File[] listFiles(FilenameFilter filter) { String ss[] = list(); if (ss == null) return null; - ArrayList files = new ArrayList(); + ArrayList files = new ArrayList<>(); for (String s : ss) if ((filter == null) || filter.accept(this, s)) files.add(new File(s, this)); @@ -1195,7 +1195,7 @@ public File[] listFiles(FileFilter filter) { String ss[] = list(); if (ss == null) return null; - ArrayList files = new ArrayList(); + ArrayList files = new ArrayList<>(); for (String s : ss) { File f = new File(s, this); if ((filter == null) || filter.accept(f)) diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/io/FileInputStream.java --- a/jdk/src/share/classes/java/io/FileInputStream.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/io/FileInputStream.java Wed Jul 05 17:32:27 2017 +0200 @@ -56,7 +56,7 @@ private volatile boolean closed = false; private static final ThreadLocal runningFinalize = - new ThreadLocal(); + new ThreadLocal<>(); private static boolean isRunningFinalize() { Boolean val; diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/io/FileOutputStream.java --- a/jdk/src/share/classes/java/io/FileOutputStream.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/io/FileOutputStream.java Wed Jul 05 17:32:27 2017 +0200 @@ -69,7 +69,7 @@ private final Object closeLock = new Object(); private volatile boolean closed = false; private static final ThreadLocal runningFinalize = - new ThreadLocal(); + new ThreadLocal<>(); private static boolean isRunningFinalize() { Boolean val; diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/io/FilePermission.java --- a/jdk/src/share/classes/java/io/FilePermission.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/io/FilePermission.java Wed Jul 05 17:32:27 2017 +0200 @@ -725,7 +725,7 @@ */ public FilePermissionCollection() { - perms = new ArrayList(); + perms = new ArrayList<>(); } /** @@ -830,7 +830,7 @@ // Don't call out.defaultWriteObject() // Write out Vector - Vector permissions = new Vector(perms.size()); + Vector permissions = new Vector<>(perms.size()); synchronized (this) { permissions.addAll(perms); } @@ -853,7 +853,7 @@ // Get the one we want Vector permissions = (Vector)gfields.get("permissions", null); - perms = new ArrayList(permissions.size()); + perms = new ArrayList<>(permissions.size()); perms.addAll(permissions); } } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/io/ObjectInputStream.java --- a/jdk/src/share/classes/java/io/ObjectInputStream.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/io/ObjectInputStream.java Wed Jul 05 17:32:27 2017 +0200 @@ -213,7 +213,7 @@ /** table mapping primitive type names to corresponding class objects */ private static final HashMap> primClasses - = new HashMap>(8, 1.0F); + = new HashMap<>(8, 1.0F); static { primClasses.put("boolean", boolean.class); primClasses.put("byte", byte.class); @@ -229,11 +229,11 @@ private static class Caches { /** cache of subclass security audit results */ static final ConcurrentMap subclassAudits = - new ConcurrentHashMap(); + new ConcurrentHashMap<>(); /** queue for WeakReferences to audited subclasses */ static final ReferenceQueue> subclassAuditsQueue = - new ReferenceQueue>(); + new ReferenceQueue<>(); } /** filter stream for handling block data conversion */ diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/io/ObjectOutputStream.java --- a/jdk/src/share/classes/java/io/ObjectOutputStream.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/io/ObjectOutputStream.java Wed Jul 05 17:32:27 2017 +0200 @@ -165,11 +165,11 @@ private static class Caches { /** cache of subclass security audit results */ static final ConcurrentMap subclassAudits = - new ConcurrentHashMap(); + new ConcurrentHashMap<>(); /** queue for WeakReferences to audited subclasses */ static final ReferenceQueue> subclassAuditsQueue = - new ReferenceQueue>(); + new ReferenceQueue<>(); } /** filter stream for handling block data conversion */ @@ -2413,7 +2413,7 @@ private final List stack; DebugTraceInfoStack() { - stack = new ArrayList(); + stack = new ArrayList<>(); } /** diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/io/ObjectStreamClass.java --- a/jdk/src/share/classes/java/io/ObjectStreamClass.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/io/ObjectStreamClass.java Wed Jul 05 17:32:27 2017 +0200 @@ -84,18 +84,18 @@ private static class Caches { /** cache mapping local classes -> descriptors */ static final ConcurrentMap> localDescs = - new ConcurrentHashMap>(); + new ConcurrentHashMap<>(); /** cache mapping field group/local desc pairs -> field reflectors */ static final ConcurrentMap> reflectors = - new ConcurrentHashMap>(); + new ConcurrentHashMap<>(); /** queue for WeakReferences to local classes */ private static final ReferenceQueue> localDescsQueue = - new ReferenceQueue>(); + new ReferenceQueue<>(); /** queue for WeakReferences to field reflectors keys */ private static final ReferenceQueue> reflectorsQueue = - new ReferenceQueue>(); + new ReferenceQueue<>(); } /** class associated with this descriptor (if any) */ @@ -290,7 +290,7 @@ EntryFuture future = null; if (entry == null) { EntryFuture newEntry = new EntryFuture(); - Reference newRef = new SoftReference(newEntry); + Reference newRef = new SoftReference<>(newEntry); do { if (ref != null) { Caches.localDescs.remove(key, ref); @@ -329,7 +329,7 @@ entry = th; } if (future.set(entry)) { - Caches.localDescs.put(key, new SoftReference(entry)); + Caches.localDescs.put(key, new SoftReference<>(entry)); } else { // nested lookup call already set future entry = future.get(); @@ -1130,7 +1130,7 @@ private ClassDataSlot[] getClassDataLayout0() throws InvalidClassException { - ArrayList slots = new ArrayList(); + ArrayList slots = new ArrayList<>(); Class start = cl, end = cl; // locate closest non-serializable superclass @@ -1566,7 +1566,7 @@ ObjectStreamField[] boundFields = new ObjectStreamField[serialPersistentFields.length]; - Set fieldNames = new HashSet(serialPersistentFields.length); + Set fieldNames = new HashSet<>(serialPersistentFields.length); for (int i = 0; i < serialPersistentFields.length; i++) { ObjectStreamField spf = serialPersistentFields[i]; @@ -1604,7 +1604,7 @@ */ private static ObjectStreamField[] getDefaultSerialFields(Class cl) { Field[] clFields = cl.getDeclaredFields(); - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList<>(); int mask = Modifier.STATIC | Modifier.TRANSIENT; for (int i = 0; i < clFields.length; i++) { @@ -1855,8 +1855,8 @@ writeKeys = new long[nfields]; offsets = new int[nfields]; typeCodes = new char[nfields]; - ArrayList> typeList = new ArrayList>(); - Set usedKeys = new HashSet(); + ArrayList> typeList = new ArrayList<>(); + Set usedKeys = new HashSet<>(); for (int i = 0; i < nfields; i++) { @@ -2092,7 +2092,7 @@ EntryFuture future = null; if (entry == null) { EntryFuture newEntry = new EntryFuture(); - Reference newRef = new SoftReference(newEntry); + Reference newRef = new SoftReference<>(newEntry); do { if (ref != null) { Caches.reflectors.remove(key, ref); @@ -2118,7 +2118,7 @@ entry = th; } future.set(entry); - Caches.reflectors.put(key, new SoftReference(entry)); + Caches.reflectors.put(key, new SoftReference<>(entry)); } if (entry instanceof FieldReflector) { diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/ApplicationShutdownHooks.java --- a/jdk/src/share/classes/java/lang/ApplicationShutdownHooks.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/ApplicationShutdownHooks.java Wed Jul 05 17:32:27 2017 +0200 @@ -47,7 +47,7 @@ } } ); - hooks = new IdentityHashMap(); + hooks = new IdentityHashMap<>(); } catch (IllegalStateException e) { // application shutdown hooks cannot be added if // shutdown is in progress. diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/Character.java --- a/jdk/src/share/classes/java/lang/Character.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/Character.java Wed Jul 05 17:32:27 2017 +0200 @@ -648,8 +648,7 @@ */ public static final class UnicodeBlock extends Subset { - private static Map map - = new HashMap(256); + private static Map map = new HashMap<>(256); /** * Creates a UnicodeBlock with the given identifier name. @@ -4178,7 +4177,7 @@ private static HashMap aliases; static { - aliases = new HashMap(128); + aliases = new HashMap<>(128); aliases.put("ARAB", ARABIC); aliases.put("ARMI", IMPERIAL_ARAMAIC); aliases.put("ARMN", ARMENIAN); diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/CharacterName.java --- a/jdk/src/share/classes/java/lang/CharacterName.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/CharacterName.java Wed Jul 05 17:32:27 2017 +0200 @@ -81,7 +81,7 @@ } while (cpOff < cpEnd); strPool = new byte[total - cpEnd]; dis.readFully(strPool); - refStrPool = new SoftReference(strPool); + refStrPool = new SoftReference<>(strPool); } catch (Exception x) { throw new InternalError(x.getMessage()); } finally { diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/Class.java --- a/jdk/src/share/classes/java/lang/Class.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/Class.java Wed Jul 05 17:32:27 2017 +0200 @@ -1306,7 +1306,7 @@ return java.security.AccessController.doPrivileged( new java.security.PrivilegedAction[]>() { public Class[] run() { - List> list = new ArrayList>(); + List> list = new ArrayList<>(); Class currentClass = Class.this; while (currentClass != null) { Class[] members = currentClass.getDeclaredClasses(); @@ -2306,9 +2306,9 @@ res = Reflection.filterFields(this, getDeclaredFields0(publicOnly)); if (useCaches) { if (publicOnly) { - declaredPublicFields = new SoftReference(res); + declaredPublicFields = new SoftReference<>(res); } else { - declaredFields = new SoftReference(res); + declaredFields = new SoftReference<>(res); } } return res; @@ -2330,9 +2330,9 @@ // No cached value available; compute value recursively. // Traverse in correct order for getField(). - List fields = new ArrayList(); + List fields = new ArrayList<>(); if (traversedInterfaces == null) { - traversedInterfaces = new HashSet>(); + traversedInterfaces = new HashSet<>(); } // Local fields @@ -2358,7 +2358,7 @@ res = new Field[fields.size()]; fields.toArray(res); if (useCaches) { - publicFields = new SoftReference(res); + publicFields = new SoftReference<>(res); } return res; } @@ -2403,9 +2403,9 @@ } if (useCaches) { if (publicOnly) { - publicConstructors = new SoftReference[]>(res); + publicConstructors = new SoftReference<>(res); } else { - declaredConstructors = new SoftReference[]>(res); + declaredConstructors = new SoftReference<>(res); } } return res; @@ -2440,9 +2440,9 @@ res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly)); if (useCaches) { if (publicOnly) { - declaredPublicMethods = new SoftReference(res); + declaredPublicMethods = new SoftReference<>(res); } else { - declaredMethods = new SoftReference(res); + declaredMethods = new SoftReference<>(res); } } return res; @@ -2598,7 +2598,7 @@ methods.compactAndTrim(); res = methods.getArray(); if (useCaches) { - publicMethods = new SoftReference(res); + publicMethods = new SoftReference<>(res); } return res; } @@ -2977,7 +2977,7 @@ if (universe == null) throw new IllegalArgumentException( getName() + " is not an enum type"); - Map m = new HashMap(2 * universe.length); + Map m = new HashMap<>(2 * universe.length); for (T constant : universe) m.put(((Enum)constant).name(), constant); enumConstantDirectory = m; @@ -3090,7 +3090,7 @@ if (superClass == null) { annotations = declaredAnnotations; } else { - annotations = new HashMap, Annotation>(); + annotations = new HashMap<>(); superClass.initAnnotationsIfNecessary(); for (Map.Entry, Annotation> e : superClass.annotations.entrySet()) { Class annotationClass = e.getKey(); diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/ClassLoader.java --- a/jdk/src/share/classes/java/lang/ClassLoader.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/ClassLoader.java Wed Jul 05 17:32:27 2017 +0200 @@ -247,7 +247,7 @@ // The classes loaded by this class loader. The only purpose of this table // is to keep the classes from being GC'ed until the loader is GC'ed. - private final Vector> classes = new Vector>(); + private final Vector> classes = new Vector<>(); // The "default" domain. Set as the default ProtectionDomain on newly // created classes. @@ -266,8 +266,7 @@ // The packages defined in this class loader. Each package name is mapped // to its corresponding Package object. // @GuardedBy("itself") - private final HashMap packages = - new HashMap(); + private final HashMap packages = new HashMap<>(); private static Void checkCreateClassLoader() { SecurityManager security = System.getSecurityManager(); @@ -280,16 +279,16 @@ private ClassLoader(Void unused, ClassLoader parent) { this.parent = parent; if (ParallelLoaders.isRegistered(this.getClass())) { - parallelLockMap = new ConcurrentHashMap(); - package2certs = new ConcurrentHashMap(); + parallelLockMap = new ConcurrentHashMap<>(); + package2certs = new ConcurrentHashMap<>(); domains = Collections.synchronizedSet(new HashSet()); assertionLock = new Object(); } else { // no finer-grained lock; lock on the classloader instance parallelLockMap = null; - package2certs = new Hashtable(); - domains = new HashSet(); + package2certs = new Hashtable<>(); + domains = new HashSet<>(); assertionLock = this; } } @@ -1182,7 +1181,7 @@ } tmp[1] = findResources(name); - return new CompoundEnumeration(tmp); + return new CompoundEnumeration<>(tmp); } /** @@ -1657,7 +1656,7 @@ protected Package[] getPackages() { Map map; synchronized (packages) { - map = new HashMap(packages); + map = new HashMap<>(packages); } Package[] pkgs; if (parent != null) { @@ -1764,20 +1763,17 @@ } // All native library names we've loaded. - private static Vector loadedLibraryNames - = new Vector(); + private static Vector loadedLibraryNames = new Vector<>(); // Native libraries belonging to system classes. private static Vector systemNativeLibraries - = new Vector(); + = new Vector<>(); // Native libraries associated with the class loader. - private Vector nativeLibraries - = new Vector(); + private Vector nativeLibraries = new Vector<>(); // native libraries being loaded/unloaded. - private static Stack nativeLibraryContext - = new Stack(); + private static Stack nativeLibraryContext = new Stack<>(); // The paths searched for libraries private static String usr_paths[]; @@ -2101,8 +2097,8 @@ * them to empty maps, effectively ignoring any present settings. */ synchronized (assertionLock) { - classAssertionStatus = new HashMap(); - packageAssertionStatus = new HashMap(); + classAssertionStatus = new HashMap<>(); + packageAssertionStatus = new HashMap<>(); defaultAssertionStatus = false; } } @@ -2164,8 +2160,8 @@ private void initializeJavaAssertionMaps() { // assert Thread.holdsLock(assertionLock); - classAssertionStatus = new HashMap(); - packageAssertionStatus = new HashMap(); + classAssertionStatus = new HashMap<>(); + packageAssertionStatus = new HashMap<>(); AssertionStatusDirectives directives = retrieveDirectives(); for(int i = 0; i < directives.classes.length; i++) diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/Package.java --- a/jdk/src/share/classes/java/lang/Package.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/Package.java Wed Jul 05 17:32:27 2017 +0200 @@ -588,16 +588,13 @@ } // The map of loaded system packages - private static Map pkgs - = new HashMap(31); + private static Map pkgs = new HashMap<>(31); // Maps each directory or zip file name to its corresponding url - private static Map urls - = new HashMap(10); + private static Map urls = new HashMap<>(10); // Maps each code source url for a jar file to its manifest - private static Map mans - = new HashMap(10); + private static Map mans = new HashMap<>(10); private static native String getSystemPackage0(String name); private static native String[] getSystemPackages0(); diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/ProcessBuilder.java --- a/jdk/src/share/classes/java/lang/ProcessBuilder.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/ProcessBuilder.java Wed Jul 05 17:32:27 2017 +0200 @@ -214,7 +214,7 @@ * @param command a string array containing the program and its arguments */ public ProcessBuilder(String... command) { - this.command = new ArrayList(command.length); + this.command = new ArrayList<>(command.length); for (String arg : command) this.command.add(arg); } @@ -251,7 +251,7 @@ * @return this process builder */ public ProcessBuilder command(String... command) { - this.command = new ArrayList(command.length); + this.command = new ArrayList<>(command.length); for (String arg : command) this.command.add(arg); return this; diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/String.java --- a/jdk/src/share/classes/java/lang/String.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/String.java Wed Jul 05 17:32:27 2017 +0200 @@ -2330,7 +2330,7 @@ int off = 0; int next = 0; boolean limited = limit > 0; - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList<>(); while ((next = indexOf(ch, off)) != -1) { if (!limited || list.size() < limit - 1) { list.add(substring(off, next)); diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/StringCoding.java --- a/jdk/src/share/classes/java/lang/StringCoding.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/StringCoding.java Wed Jul 05 17:32:27 2017 +0200 @@ -53,9 +53,9 @@ /** The cached coders for each thread */ private final static ThreadLocal> decoder = - new ThreadLocal>(); + new ThreadLocal<>(); private final static ThreadLocal> encoder = - new ThreadLocal>(); + new ThreadLocal<>(); private static boolean warnUnsupportedCharset = true; @@ -67,7 +67,7 @@ } private static void set(ThreadLocal> tl, T ob) { - tl.set(new SoftReference(ob)); + tl.set(new SoftReference<>(ob)); } // Trim the given byte array to the given length diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/Thread.java --- a/jdk/src/share/classes/java/lang/Thread.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/Thread.java Wed Jul 05 17:32:27 2017 +0200 @@ -1642,8 +1642,7 @@ // Get a snapshot of the list of all threads Thread[] threads = getThreads(); StackTraceElement[][] traces = dumpThreads(threads); - Map m - = new HashMap(threads.length); + Map m = new HashMap<>(threads.length); for (int i = 0; i < threads.length; i++) { StackTraceElement[] stackTrace = traces[i]; if (stackTrace != null) { @@ -1664,11 +1663,11 @@ private static class Caches { /** cache of subclass security audit results */ static final ConcurrentMap subclassAudits = - new ConcurrentHashMap(); + new ConcurrentHashMap<>(); /** queue for WeakReferences to audited subclasses */ static final ReferenceQueue> subclassAuditsQueue = - new ReferenceQueue>(); + new ReferenceQueue<>(); } /** diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/Throwable.java --- a/jdk/src/share/classes/java/lang/Throwable.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/Throwable.java Wed Jul 05 17:32:27 2017 +0200 @@ -828,7 +828,7 @@ // Use the sentinel for a zero-length list suppressed = SUPPRESSED_SENTINEL; } else { // Copy Throwables to new list - suppressed = new ArrayList(1); + suppressed = new ArrayList<>(1); for (Throwable t : suppressedExceptions) { // Enforce constraints on suppressed exceptions in // case of corrupt or malicious stream. @@ -911,7 +911,7 @@ return; if (suppressedExceptions == SUPPRESSED_SENTINEL) - suppressedExceptions = new ArrayList(1); + suppressedExceptions = new ArrayList<>(1); assert suppressedExceptions != SUPPRESSED_SENTINEL; diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/management/ManagementFactory.java --- a/jdk/src/share/classes/java/lang/management/ManagementFactory.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/management/ManagementFactory.java Wed Jul 05 17:32:27 2017 +0200 @@ -794,7 +794,7 @@ */ public static List> getAllPlatformMXBeanInterfaces() { List> result = - new ArrayList>(); + new ArrayList<>(); for (PlatformComponent component: PlatformComponent.values()) { result.add(component.getMXBeanInterface()); } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/management/PlatformComponent.java --- a/jdk/src/share/classes/java/lang/management/PlatformComponent.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/management/PlatformComponent.java Wed Jul 05 17:32:27 2017 +0200 @@ -267,7 +267,7 @@ List getGcMXBeanList(Class gcMXBeanIntf) { List list = ManagementFactoryHelper.getGarbageCollectorMXBeans(); - List result = new ArrayList(list.size()); + List result = new ArrayList<>(list.size()); for (GarbageCollectorMXBean m : list) { if (gcMXBeanIntf.isInstance(m)) { result.add(gcMXBeanIntf.cast(m)); @@ -330,7 +330,7 @@ } private static Set keyProperties(String... keyNames) { - Set set = new HashSet(); + Set set = new HashSet<>(); set.add("type"); for (String s : keyNames) { set.add(s); @@ -364,7 +364,7 @@ List getMXBeans(MBeanServerConnection mbs, Class mxbeanInterface) throws java.io.IOException { - List result = new ArrayList(); + List result = new ArrayList<>(); for (ObjectName on : getObjectNames(mbs)) { result.add(ManagementFactory. newPlatformMXBeanProxy(mbs, diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/reflect/Constructor.java --- a/jdk/src/share/classes/java/lang/reflect/Constructor.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/reflect/Constructor.java Wed Jul 05 17:32:27 2017 +0200 @@ -144,7 +144,7 @@ // which implicitly requires that new java.lang.reflect // objects be fabricated for each reflective call on Class // objects.) - Constructor res = new Constructor(clazz, + Constructor res = new Constructor<>(clazz, parameterTypes, exceptionTypes, modifiers, slot, signature, diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/reflect/Proxy.java --- a/jdk/src/share/classes/java/lang/reflect/Proxy.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/reflect/Proxy.java Wed Jul 05 17:32:27 2017 +0200 @@ -232,7 +232,7 @@ /** maps a class loader to the proxy class cache for that loader */ private static Map, Object>> loaderToCache - = new WeakHashMap, Object>>(); + = new WeakHashMap<>(); /** marks that a particular proxy class is currently being generated */ private static Object pendingGenerationMarker = new Object(); @@ -356,7 +356,7 @@ String[] interfaceNames = new String[interfaces.length]; // for detecting duplicates - Set> interfaceSet = new HashSet>(); + Set> interfaceSet = new HashSet<>(); for (int i = 0; i < interfaces.length; i++) { /* @@ -413,7 +413,7 @@ synchronized (loaderToCache) { cache = loaderToCache.get(loader); if (cache == null) { - cache = new HashMap, Object>(); + cache = new HashMap<>(); loaderToCache.put(loader, cache); } /* diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/lang/reflect/ReflectAccess.java --- a/jdk/src/share/classes/java/lang/reflect/ReflectAccess.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/lang/reflect/ReflectAccess.java Wed Jul 05 17:32:27 2017 +0200 @@ -84,7 +84,7 @@ byte[] annotations, byte[] parameterAnnotations) { - return new Constructor(declaringClass, + return new Constructor<>(declaringClass, parameterTypes, checkedExceptions, modifiers, diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/sql/DriverManager.java --- a/jdk/src/share/classes/java/sql/DriverManager.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/sql/DriverManager.java Wed Jul 05 17:32:27 2017 +0200 @@ -364,7 +364,7 @@ * @return the list of JDBC Drivers loaded by the caller's class loader */ public static java.util.Enumeration getDrivers() { - java.util.Vector result = new java.util.Vector(); + java.util.Vector result = new java.util.Vector<>(); java.util.Vector drivers = null; if (!initialized) { diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/sql/Statement.java --- a/jdk/src/share/classes/java/sql/Statement.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/sql/Statement.java Wed Jul 05 17:32:27 2017 +0200 @@ -577,7 +577,7 @@ * * @see #addBatch * @see DatabaseMetaData#supportsBatchUpdates - * @since 1.3 + * @since 1.2 */ int[] executeBatch() throws SQLException; diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/text/MessageFormat.java --- a/jdk/src/share/classes/java/text/MessageFormat.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/java/text/MessageFormat.java Wed Jul 05 17:32:27 2017 +0200 @@ -93,73 +93,65 @@ * currency * percent * SubformatPattern - * - * String: - * StringPartopt - * String StringPart - * - * StringPart: - * '' - * ' QuotedString ' - * UnquotedString - * - * SubformatPattern: - * SubformatPatternPartopt - * SubformatPattern SubformatPatternPart - * - * SubFormatPatternPart: - * ' QuotedPattern ' - * UnquotedPattern * * - *

- * Within a String, "''" represents a single - * quote. A QuotedString can contain arbitrary characters - * except single quotes; the surrounding single quotes are removed. - * An UnquotedString can contain arbitrary characters - * except single quotes and left curly brackets. Thus, a string that - * should result in the formatted message "'{0}'" can be written as - * "'''{'0}''" or "'''{0}'''". - *

- * Within a SubformatPattern, different rules apply. - * A QuotedPattern can contain arbitrary characters - * except single quotes; but the surrounding single quotes are - * not removed, so they may be interpreted by the - * subformat. For example, "{1,number,$'#',##}" will - * produce a number format with the pound-sign quoted, with a result - * such as: "$#31,45". - * An UnquotedPattern can contain arbitrary characters - * except single quotes, but curly braces within it must be balanced. - * For example, "ab {0} de" and "ab '}' de" - * are valid subformat patterns, but "ab {0'}' de" and - * "ab } de" are not. + *

Within a String, a pair of single quotes can be used to + * quote any arbitrary characters except single quotes. For example, + * pattern string "'{0}'" represents string + * "{0}", not a FormatElement. A single quote itself + * must be represented by doubled single quotes {@code ''} throughout a + * String. For example, pattern string "'{''}'" is + * interpreted as a sequence of '{ (start of quoting and a + * left curly brace), '' (a single quote), and + * }' (a right curly brace and end of quoting), + * not '{' and '}' (quoted left and + * right curly braces): representing string "{'}", + * not "{}". + * + *

A SubformatPattern is interpreted by its corresponding + * subformat, and subformat-dependent pattern rules apply. For example, + * pattern string "{1,number,$'#',##}" + * (SubformatPattern with underline) will produce a number format + * with the pound-sign quoted, with a result such as: {@code + * "$#31,45"}. Refer to each {@code Format} subclass documentation for + * details. + * + *

Any unmatched quote is treated as closed at the end of the given + * pattern. For example, pattern string {@code "'{0}"} is treated as + * pattern {@code "'{0}'"}. + * + *

Any curly braces within an unquoted pattern must be balanced. For + * example, "ab {0} de" and "ab '}' de" are + * valid patterns, but "ab {0'}' de", "ab } de" + * and "''{''" are not. + * *

*

Warning:
The rules for using quotes within message * format patterns unfortunately have shown to be somewhat confusing. * In particular, it isn't always obvious to localizers whether single * quotes need to be doubled or not. Make sure to inform localizers about * the rules, and tell them (for example, by using comments in resource - * bundle source files) which strings will be processed by MessageFormat. + * bundle source files) which strings will be processed by {@code MessageFormat}. * Note that localizers may need to use single quotes in translated * strings where the original version doesn't have them. *
*

* The ArgumentIndex value is a non-negative integer written - * using the digits '0' through '9', and represents an index into the - * arguments array passed to the format methods - * or the result array returned by the parse methods. + * using the digits {@code '0'} through {@code '9'}, and represents an index into the + * {@code arguments} array passed to the {@code format} methods + * or the result array returned by the {@code parse} methods. *

* The FormatType and FormatStyle values are used to create - * a Format instance for the format element. The following - * table shows how the values map to Format instances. Combinations not + * a {@code Format} instance for the format element. The following + * table shows how the values map to {@code Format} instances. Combinations not * shown in the table are illegal. A SubformatPattern must - * be a valid pattern string for the Format subclass used. + * be a valid pattern string for the {@code Format} subclass used. *

* * - * * * * * * * * * * * * * * * * * * * *
Format Type - * Format Style - * Subformat Created + * FormatType + * FormatStyle + * Subformat Created *
(none) * (none) @@ -167,61 +159,61 @@ *
number * (none) - * NumberFormat.getInstance(getLocale()) + * {@link NumberFormat#getInstance(Locale) NumberFormat.getInstance}{@code (getLocale())} *
integer - * NumberFormat.getIntegerInstance(getLocale()) + * {@link NumberFormat#getIntegerInstance(Locale) NumberFormat.getIntegerInstance}{@code (getLocale())} *
currency - * NumberFormat.getCurrencyInstance(getLocale()) + * {@link NumberFormat#getCurrencyInstance(Locale) NumberFormat.getCurrencyInstance}{@code (getLocale())} *
percent - * NumberFormat.getPercentInstance(getLocale()) + * {@link NumberFormat#getPercentInstance(Locale) NumberFormat.getPercentInstance}{@code (getLocale())} *
SubformatPattern - * new DecimalFormat(subformatPattern, DecimalFormatSymbols.getInstance(getLocale())) + * {@code new} {@link DecimalFormat#DecimalFormat(String,DecimalFormatSymbols) DecimalFormat}{@code (subformatPattern,} {@link DecimalFormatSymbols#getInstance(Locale) DecimalFormatSymbols.getInstance}{@code (getLocale()))} *
date * (none) - * DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale()) + * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} *
short - * DateFormat.getDateInstance(DateFormat.SHORT, getLocale()) + * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())} *
medium - * DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale()) + * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} *
long - * DateFormat.getDateInstance(DateFormat.LONG, getLocale()) + * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())} *
full - * DateFormat.getDateInstance(DateFormat.FULL, getLocale()) + * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())} *
SubformatPattern - * new SimpleDateFormat(subformatPattern, getLocale()) + * {@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())} *
time * (none) - * DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale()) + * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} *
short - * DateFormat.getTimeInstance(DateFormat.SHORT, getLocale()) + * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())} *
medium - * DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale()) + * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} *
long - * DateFormat.getTimeInstance(DateFormat.LONG, getLocale()) + * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())} *
full - * DateFormat.getTimeInstance(DateFormat.FULL, getLocale()) + * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())} *
SubformatPattern - * new SimpleDateFormat(subformatPattern, getLocale()) + * {@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())} *
choice * SubformatPattern - * new ChoiceFormat(subformatPattern) + * {@code new} {@link ChoiceFormat#ChoiceFormat(String) ChoiceFormat}{@code (subformatPattern)} *
*

* @@ -321,7 +313,7 @@ * * *

- * Likewise, parsing with a MessageFormat object using patterns containing + * Likewise, parsing with a {@code MessageFormat} object using patterns containing * multiple occurrences of the same argument would return the last match. For * example, *

@@ -343,7 +335,11 @@
  * @see          Format
  * @see          NumberFormat
  * @see          DecimalFormat
+ * @see          DecimalFormatSymbols
  * @see          ChoiceFormat
+ * @see          DateFormat
+ * @see          SimpleDateFormat
+ *
  * @author       Mark Davis
  */
 
@@ -427,18 +423,19 @@
      * @exception IllegalArgumentException if the pattern is invalid
      */
     public void applyPattern(String pattern) {
-            StringBuffer[] segments = new StringBuffer[4];
-            for (int i = 0; i < segments.length; ++i) {
-                segments[i] = new StringBuffer();
-            }
-            int part = 0;
+            StringBuilder[] segments = new StringBuilder[4];
+            // Allocate only segments[SEG_RAW] here. The rest are
+            // allocated on demand.
+            segments[SEG_RAW] = new StringBuilder();
+
+            int part = SEG_RAW;
             int formatNumber = 0;
             boolean inQuote = false;
             int braceStack = 0;
             maxOffset = -1;
             for (int i = 0; i < pattern.length(); ++i) {
                 char ch = pattern.charAt(i);
-                if (part == 0) {
+                if (part == SEG_RAW) {
                     if (ch == '\'') {
                         if (i + 1 < pattern.length()
                             && pattern.charAt(i+1) == '\'') {
@@ -448,43 +445,61 @@
                             inQuote = !inQuote;
                         }
                     } else if (ch == '{' && !inQuote) {
-                        part = 1;
+                        part = SEG_INDEX;
+                        if (segments[SEG_INDEX] == null) {
+                            segments[SEG_INDEX] = new StringBuilder();
+                        }
                     } else {
                         segments[part].append(ch);
                     }
-                } else  if (inQuote) {              // just copy quotes in parts
-                    segments[part].append(ch);
-                    if (ch == '\'') {
-                        inQuote = false;
-                    }
-                } else {
-                    switch (ch) {
-                    case ',':
-                        if (part < 3)
-                            part += 1;
-                        else
-                            segments[part].append(ch);
-                        break;
-                    case '{':
-                        ++braceStack;
+                } else  {
+                    if (inQuote) {              // just copy quotes in parts
                         segments[part].append(ch);
-                        break;
-                    case '}':
-                        if (braceStack == 0) {
-                            part = 0;
-                            makeFormat(i, formatNumber, segments);
-                            formatNumber++;
-                        } else {
-                            --braceStack;
+                        if (ch == '\'') {
+                            inQuote = false;
+                        }
+                    } else {
+                        switch (ch) {
+                        case ',':
+                            if (part < SEG_MODIFIER) {
+                                if (segments[++part] == null) {
+                                    segments[part] = new StringBuilder();
+                                }
+                            } else {
+                                segments[part].append(ch);
+                            }
+                            break;
+                        case '{':
+                            ++braceStack;
                             segments[part].append(ch);
+                            break;
+                        case '}':
+                            if (braceStack == 0) {
+                                part = SEG_RAW;
+                                makeFormat(i, formatNumber, segments);
+                                formatNumber++;
+                                // throw away other segments
+                                segments[SEG_INDEX] = null;
+                                segments[SEG_TYPE] = null;
+                                segments[SEG_MODIFIER] = null;
+                            } else {
+                                --braceStack;
+                                segments[part].append(ch);
+                            }
+                            break;
+                        case ' ':
+                            // Skip any leading space chars for SEG_TYPE.
+                            if (part != SEG_TYPE || segments[SEG_TYPE].length() > 0) {
+                                segments[part].append(ch);
+                            }
+                            break;
+                        case '\'':
+                            inQuote = true;
+                            // fall through, so we keep quotes in other parts
+                        default:
+                            segments[part].append(ch);
+                            break;
                         }
-                        break;
-                    case '\'':
-                        inQuote = true;
-                        // fall through, so we keep quotes in other parts
-                    default:
-                        segments[part].append(ch);
-                        break;
                     }
                 }
             }
@@ -506,65 +521,57 @@
     public String toPattern() {
         // later, make this more extensible
         int lastOffset = 0;
-        StringBuffer result = new StringBuffer();
+        StringBuilder result = new StringBuilder();
         for (int i = 0; i <= maxOffset; ++i) {
-            copyAndFixQuotes(pattern, lastOffset, offsets[i],result);
+            copyAndFixQuotes(pattern, lastOffset, offsets[i], result);
             lastOffset = offsets[i];
-            result.append('{');
-            result.append(argumentNumbers[i]);
-            if (formats[i] == null) {
+            result.append('{').append(argumentNumbers[i]);
+            Format fmt = formats[i];
+            if (fmt == null) {
                 // do nothing, string format
-            } else if (formats[i] instanceof DecimalFormat) {
-                if (formats[i].equals(NumberFormat.getInstance(locale))) {
+            } else if (fmt instanceof NumberFormat) {
+                if (fmt.equals(NumberFormat.getInstance(locale))) {
                     result.append(",number");
-                } else if (formats[i].equals(NumberFormat.getCurrencyInstance(locale))) {
+                } else if (fmt.equals(NumberFormat.getCurrencyInstance(locale))) {
                     result.append(",number,currency");
-                } else if (formats[i].equals(NumberFormat.getPercentInstance(locale))) {
+                } else if (fmt.equals(NumberFormat.getPercentInstance(locale))) {
                     result.append(",number,percent");
-                } else if (formats[i].equals(NumberFormat.getIntegerInstance(locale))) {
+                } else if (fmt.equals(NumberFormat.getIntegerInstance(locale))) {
                     result.append(",number,integer");
                 } else {
-                    result.append(",number," +
-                                  ((DecimalFormat)formats[i]).toPattern());
+                    if (fmt instanceof DecimalFormat) {
+                        result.append(",number,").append(((DecimalFormat)fmt).toPattern());
+                    } else if (fmt instanceof ChoiceFormat) {
+                        result.append(",choice,").append(((ChoiceFormat)fmt).toPattern());
+                    } else {
+                        // UNKNOWN
+                    }
                 }
-            } else if (formats[i] instanceof SimpleDateFormat) {
-                if (formats[i].equals(DateFormat.getDateInstance(
-                                                               DateFormat.DEFAULT,locale))) {
-                    result.append(",date");
-                } else if (formats[i].equals(DateFormat.getDateInstance(
-                                                                      DateFormat.SHORT,locale))) {
-                    result.append(",date,short");
-                } else if (formats[i].equals(DateFormat.getDateInstance(
-                                                                      DateFormat.DEFAULT,locale))) {
-                    result.append(",date,medium");
-                } else if (formats[i].equals(DateFormat.getDateInstance(
-                                                                      DateFormat.LONG,locale))) {
-                    result.append(",date,long");
-                } else if (formats[i].equals(DateFormat.getDateInstance(
-                                                                      DateFormat.FULL,locale))) {
-                    result.append(",date,full");
-                } else if (formats[i].equals(DateFormat.getTimeInstance(
-                                                                      DateFormat.DEFAULT,locale))) {
-                    result.append(",time");
-                } else if (formats[i].equals(DateFormat.getTimeInstance(
-                                                                      DateFormat.SHORT,locale))) {
-                    result.append(",time,short");
-                } else if (formats[i].equals(DateFormat.getTimeInstance(
-                                                                      DateFormat.DEFAULT,locale))) {
-                    result.append(",time,medium");
-                } else if (formats[i].equals(DateFormat.getTimeInstance(
-                                                                      DateFormat.LONG,locale))) {
-                    result.append(",time,long");
-                } else if (formats[i].equals(DateFormat.getTimeInstance(
-                                                                      DateFormat.FULL,locale))) {
-                    result.append(",time,full");
-                } else {
-                    result.append(",date,"
-                                  + ((SimpleDateFormat)formats[i]).toPattern());
+            } else if (fmt instanceof DateFormat) {
+                int index;
+                for (index = MODIFIER_DEFAULT; index < DATE_TIME_MODIFIERS.length; index++) {
+                    DateFormat df = DateFormat.getDateInstance(DATE_TIME_MODIFIERS[index],
+                                                               locale);
+                    if (fmt.equals(df)) {
+                        result.append(",date");
+                        break;
+                    }
+                    df = DateFormat.getTimeInstance(DATE_TIME_MODIFIERS[index],
+                                                    locale);
+                    if (fmt.equals(df)) {
+                        result.append(",time");
+                        break;
+                    }
                 }
-            } else if (formats[i] instanceof ChoiceFormat) {
-                result.append(",choice,"
-                              + ((ChoiceFormat)formats[i]).toPattern());
+                if (index >= DATE_TIME_MODIFIERS.length) {
+                    if (fmt instanceof SimpleDateFormat) {
+                        result.append(",date,").append(((SimpleDateFormat)fmt).toPattern());
+                    } else {
+                        // UNKNOWN
+                    }
+                } else if (index != MODIFIER_DEFAULT) {
+                    result.append(',').append(DATE_TIME_MODIFIER_KEYWORDS[index]);
+                }
             } else {
                 //result.append(", unknown");
             }
@@ -678,7 +685,7 @@
      *
      * @param formatElementIndex the index of a format element within the pattern
      * @param newFormat the format to use for the specified format element
-     * @exception ArrayIndexOutOfBoundsException if formatElementIndex is equal to or
+     * @exception ArrayIndexOutOfBoundsException if {@code formatElementIndex} is equal to or
      *            larger than the number of format elements in the pattern string
      */
     public void setFormat(int formatElementIndex, Format newFormat) {
@@ -972,7 +979,8 @@
                 if (patternOffset >= tempLength) {
                     next = source.length();
                 }else{
-                    next = source.indexOf( pattern.substring(patternOffset,tempLength), sourceOffset);
+                    next = source.indexOf(pattern.substring(patternOffset, tempLength),
+                                          sourceOffset);
                 }
 
                 if (next < 0) {
@@ -1226,7 +1234,7 @@
             lastOffset = offsets[i];
             int argumentNumber = argumentNumbers[i];
             if (arguments == null || argumentNumber >= arguments.length) {
-                result.append("{" + argumentNumber + "}");
+                result.append('{').append(argumentNumber).append('}');
                 continue;
             }
             // int argRecursion = ((recursionProtection >> (argumentNumber*2)) & 0x3);
@@ -1338,25 +1346,83 @@
         }
     }
 
-    private static final String[] typeList =
-    {"", "", "number", "", "date", "", "time", "", "choice"};
-    private static final String[] modifierList =
-    {"", "", "currency", "", "percent", "", "integer"};
-    private static final String[] dateModifierList =
-    {"", "", "short", "", "medium", "", "long", "", "full"};
+    // Indices for segments
+    private static final int SEG_RAW      = 0;
+    private static final int SEG_INDEX    = 1;
+    private static final int SEG_TYPE     = 2;
+    private static final int SEG_MODIFIER = 3; // modifier or subformat
+
+    // Indices for type keywords
+    private static final int TYPE_NULL    = 0;
+    private static final int TYPE_NUMBER  = 1;
+    private static final int TYPE_DATE    = 2;
+    private static final int TYPE_TIME    = 3;
+    private static final int TYPE_CHOICE  = 4;
+
+    private static final String[] TYPE_KEYWORDS = {
+        "",
+        "number",
+        "date",
+        "time",
+        "choice"
+    };
+
+    // Indices for number modifiers
+    private static final int MODIFIER_DEFAULT  = 0; // common in number and date-time
+    private static final int MODIFIER_CURRENCY = 1;
+    private static final int MODIFIER_PERCENT  = 2;
+    private static final int MODIFIER_INTEGER  = 3;
+
+    private static final String[] NUMBER_MODIFIER_KEYWORDS = {
+        "",
+        "currency",
+        "percent",
+        "integer"
+    };
+
+    // Indices for date-time modifiers
+    private static final int MODIFIER_SHORT   = 1;
+    private static final int MODIFIER_MEDIUM  = 2;
+    private static final int MODIFIER_LONG    = 3;
+    private static final int MODIFIER_FULL    = 4;
+
+    private static final String[] DATE_TIME_MODIFIER_KEYWORDS = {
+        "",
+        "short",
+        "medium",
+        "long",
+        "full"
+    };
+
+    // Date-time style values corresponding to the date-time modifiers.
+    private static final int[] DATE_TIME_MODIFIERS = {
+        DateFormat.DEFAULT,
+        DateFormat.SHORT,
+        DateFormat.MEDIUM,
+        DateFormat.LONG,
+        DateFormat.FULL,
+    };
 
     private void makeFormat(int position, int offsetNumber,
-                            StringBuffer[] segments)
+                            StringBuilder[] textSegments)
     {
+        String[] segments = new String[textSegments.length];
+        for (int i = 0; i < textSegments.length; i++) {
+            StringBuilder oneseg = textSegments[i];
+            segments[i] = (oneseg != null) ? oneseg.toString() : "";
+        }
+
         // get the argument number
         int argumentNumber;
         try {
-            argumentNumber = Integer.parseInt(segments[1].toString()); // always unlocalized!
+            argumentNumber = Integer.parseInt(segments[SEG_INDEX]); // always unlocalized!
         } catch (NumberFormatException e) {
-            throw new IllegalArgumentException("can't parse argument number: " + segments[1]);
+            throw new IllegalArgumentException("can't parse argument number: "
+                                               + segments[SEG_INDEX], e);
         }
         if (argumentNumber < 0) {
-            throw new IllegalArgumentException("negative argument number: " + argumentNumber);
+            throw new IllegalArgumentException("negative argument number: "
+                                               + argumentNumber);
         }
 
         // resize format information arrays if necessary
@@ -1374,120 +1440,129 @@
         }
         int oldMaxOffset = maxOffset;
         maxOffset = offsetNumber;
-        offsets[offsetNumber] = segments[0].length();
+        offsets[offsetNumber] = segments[SEG_RAW].length();
         argumentNumbers[offsetNumber] = argumentNumber;
 
         // now get the format
         Format newFormat = null;
-        switch (findKeyword(segments[2].toString(), typeList)) {
-        case 0:
-            break;
-        case 1: case 2:// number
-            switch (findKeyword(segments[3].toString(), modifierList)) {
-            case 0: // default;
-                newFormat = NumberFormat.getInstance(locale);
+        if (segments[SEG_TYPE].length() != 0) {
+            int type = findKeyword(segments[SEG_TYPE], TYPE_KEYWORDS);
+            switch (type) {
+            case TYPE_NULL:
+                // Type "" is allowed. e.g., "{0,}", "{0,,}", and "{0,,#}"
+                // are treated as "{0}".
                 break;
-            case 1: case 2:// currency
-                newFormat = NumberFormat.getCurrencyInstance(locale);
-                break;
-            case 3: case 4:// percent
-                newFormat = NumberFormat.getPercentInstance(locale);
-                break;
-            case 5: case 6:// integer
-                newFormat = NumberFormat.getIntegerInstance(locale);
-                break;
-            default: // pattern
-                newFormat = new DecimalFormat(segments[3].toString(), DecimalFormatSymbols.getInstance(locale));
+
+            case TYPE_NUMBER:
+                switch (findKeyword(segments[SEG_MODIFIER], NUMBER_MODIFIER_KEYWORDS)) {
+                case MODIFIER_DEFAULT:
+                    newFormat = NumberFormat.getInstance(locale);
+                    break;
+                case MODIFIER_CURRENCY:
+                    newFormat = NumberFormat.getCurrencyInstance(locale);
+                    break;
+                case MODIFIER_PERCENT:
+                    newFormat = NumberFormat.getPercentInstance(locale);
+                    break;
+                case MODIFIER_INTEGER:
+                    newFormat = NumberFormat.getIntegerInstance(locale);
+                    break;
+                default: // DecimalFormat pattern
+                    try {
+                        newFormat = new DecimalFormat(segments[SEG_MODIFIER],
+                                                      DecimalFormatSymbols.getInstance(locale));
+                    } catch (IllegalArgumentException e) {
+                        maxOffset = oldMaxOffset;
+                        throw e;
+                    }
+                    break;
+                }
                 break;
-            }
-            break;
-        case 3: case 4: // date
-            switch (findKeyword(segments[3].toString(), dateModifierList)) {
-            case 0: // default
-                newFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, locale);
-                break;
-            case 1: case 2: // short
-                newFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+
+            case TYPE_DATE:
+            case TYPE_TIME:
+                int mod = findKeyword(segments[SEG_MODIFIER], DATE_TIME_MODIFIER_KEYWORDS);
+                if (mod >= 0 && mod < DATE_TIME_MODIFIER_KEYWORDS.length) {
+                    if (type == TYPE_DATE) {
+                        newFormat = DateFormat.getDateInstance(DATE_TIME_MODIFIERS[mod],
+                                                               locale);
+                    } else {
+                        newFormat = DateFormat.getTimeInstance(DATE_TIME_MODIFIERS[mod],
+                                                               locale);
+                    }
+                } else {
+                    // SimpleDateFormat pattern
+                    try {
+                        newFormat = new SimpleDateFormat(segments[SEG_MODIFIER], locale);
+                    } catch (IllegalArgumentException e) {
+                        maxOffset = oldMaxOffset;
+                        throw e;
+                    }
+                }
                 break;
-            case 3: case 4: // medium
-                newFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, locale);
+
+            case TYPE_CHOICE:
+                try {
+                    // ChoiceFormat pattern
+                    newFormat = new ChoiceFormat(segments[SEG_MODIFIER]);
+                } catch (Exception e) {
+                    maxOffset = oldMaxOffset;
+                    throw new IllegalArgumentException("Choice Pattern incorrect: "
+                                                       + segments[SEG_MODIFIER], e);
+                }
                 break;
-            case 5: case 6: // long
-                newFormat = DateFormat.getDateInstance(DateFormat.LONG, locale);
-                break;
-            case 7: case 8: // full
-                newFormat = DateFormat.getDateInstance(DateFormat.FULL, locale);
-                break;
+
             default:
-                newFormat = new SimpleDateFormat(segments[3].toString(), locale);
-                break;
+                maxOffset = oldMaxOffset;
+                throw new IllegalArgumentException("unknown format type: " +
+                                                   segments[SEG_TYPE]);
             }
-            break;
-        case 5: case 6:// time
-            switch (findKeyword(segments[3].toString(), dateModifierList)) {
-            case 0: // default
-                newFormat = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale);
-                break;
-            case 1: case 2: // short
-                newFormat = DateFormat.getTimeInstance(DateFormat.SHORT, locale);
-                break;
-            case 3: case 4: // medium
-                newFormat = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale);
-                break;
-            case 5: case 6: // long
-                newFormat = DateFormat.getTimeInstance(DateFormat.LONG, locale);
-                break;
-            case 7: case 8: // full
-                newFormat = DateFormat.getTimeInstance(DateFormat.FULL, locale);
-                break;
-            default:
-                newFormat = new SimpleDateFormat(segments[3].toString(), locale);
-                break;
-            }
-            break;
-        case 7: case 8:// choice
-            try {
-                newFormat = new ChoiceFormat(segments[3].toString());
-            } catch (Exception e) {
-                maxOffset = oldMaxOffset;
-                throw new IllegalArgumentException(
-                                         "Choice Pattern incorrect");
-            }
-            break;
-        default:
-            maxOffset = oldMaxOffset;
-            throw new IllegalArgumentException("unknown format type: " +
-                                               segments[2].toString());
         }
         formats[offsetNumber] = newFormat;
-        segments[1].setLength(0);   // throw away other segments
-        segments[2].setLength(0);
-        segments[3].setLength(0);
     }
 
     private static final int findKeyword(String s, String[] list) {
-        s = s.trim().toLowerCase();
         for (int i = 0; i < list.length; ++i) {
             if (s.equals(list[i]))
                 return i;
         }
+
+        // Try trimmed lowercase.
+        String ls = s.trim().toLowerCase(Locale.ROOT);
+        if (ls != s) {
+            for (int i = 0; i < list.length; ++i) {
+                if (ls.equals(list[i]))
+                    return i;
+            }
+        }
         return -1;
     }
 
-    private static final void copyAndFixQuotes(
-                                               String source, int start, int end, StringBuffer target) {
+    private static final void copyAndFixQuotes(String source, int start, int end,
+                                               StringBuilder target) {
+        boolean quoted = false;
+
         for (int i = start; i < end; ++i) {
             char ch = source.charAt(i);
             if (ch == '{') {
-                target.append("'{'");
-            } else if (ch == '}') {
-                target.append("'}'");
+                if (!quoted) {
+                    target.append('\'');
+                    quoted = true;
+                }
+                target.append(ch);
             } else if (ch == '\'') {
                 target.append("''");
             } else {
+                if (quoted) {
+                    target.append('\'');
+                    quoted = false;
+                }
                 target.append(ch);
             }
         }
+        if (quoted) {
+            target.append('\'');
+        }
     }
 
     /**
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/text/SimpleDateFormat.java
--- a/jdk/src/share/classes/java/text/SimpleDateFormat.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/text/SimpleDateFormat.java	Wed Jul 05 17:32:27 2017 +0200
@@ -1663,6 +1663,81 @@
     }
 
     /**
+     * Parses numeric forms of time zone offset, such as "hh:mm", and
+     * sets calb to the parsed value.
+     *
+     * @param text  the text to be parsed
+     * @param start the character position to start parsing
+     * @param sign  1: positive; -1: negative
+     * @param count 0: 'Z' or "GMT+hh:mm" parsing; 1 - 3: the number of 'X's
+     * @param colon true - colon required between hh and mm; false - no colon required
+     * @param calb  a CalendarBuilder in which the parsed value is stored
+     * @return updated parsed position, or its negative value to indicate a parsing error
+     */
+    private int subParseNumericZone(String text, int start, int sign, int count,
+                                    boolean colon, CalendarBuilder calb) {
+        int index = start;
+
+      parse:
+        try {
+            char c = text.charAt(index++);
+            // Parse hh
+            int hours;
+            if (!isDigit(c)) {
+                break parse;
+            }
+            hours = c - '0';
+            c = text.charAt(index++);
+            if (isDigit(c)) {
+                hours = hours * 10 + (c - '0');
+            } else {
+                // If no colon in RFC 822 or 'X' (ISO), two digits are
+                // required.
+                if (count > 0 || !colon) {
+                    break parse;
+                }
+                --index;
+            }
+            if (hours > 23) {
+                break parse;
+            }
+            int minutes = 0;
+            if (count != 1) {
+                // Proceed with parsing mm
+                c = text.charAt(index++);
+                if (colon) {
+                    if (c != ':') {
+                        break parse;
+                    }
+                    c = text.charAt(index++);
+                }
+                if (!isDigit(c)) {
+                    break parse;
+                }
+                minutes = c - '0';
+                c = text.charAt(index++);
+                if (!isDigit(c)) {
+                    break parse;
+                }
+                minutes = minutes * 10 + (c - '0');
+                if (minutes > 59) {
+                    break parse;
+                }
+            }
+            minutes += hours * 60;
+            calb.set(Calendar.ZONE_OFFSET, minutes * MILLIS_PER_MINUTE * sign)
+                .set(Calendar.DST_OFFSET, 0);
+            return index;
+        } catch (IndexOutOfBoundsException e) {
+        }
+        return  1 - index; // -(index - 1)
+    }
+
+    private boolean isDigit(char c) {
+        return c >= '0' && c <= '9';
+    }
+
+    /**
      * Private member function that converts the parsed date strings into
      * timeFields. Returns -start (for ParsePosition) if failed.
      * @param text the time text to be parsed.
@@ -1907,248 +1982,95 @@
 
             case PATTERN_ZONE_NAME:  // 'z'
             case PATTERN_ZONE_VALUE: // 'Z'
-                // First try to parse generic forms such as GMT-07:00. Do this first
-                // in case localized TimeZoneNames contains the string "GMT"
-                // for a zone; in that case, we don't want to match the first three
-                // characters of GMT+/-hh:mm etc.
                 {
                     int sign = 0;
-                    int offset;
-
-                    // For time zones that have no known names, look for strings
-                    // of the form:
-                    //    GMT[+-]hours:minutes or
-                    //    GMT.
-                    if ((text.length() - start) >= GMT.length() &&
-                        text.regionMatches(true, start, GMT, 0, GMT.length())) {
-                        int num;
-                        calb.set(Calendar.DST_OFFSET, 0);
-                        pos.index = start + GMT.length();
-
-                        try { // try-catch for "GMT" only time zone string
-                            char c = text.charAt(pos.index);
-                            if (c == '+') {
-                                sign = 1;
-                            } else if (c == '-') {
-                                sign = -1;
-                            }
+                    try {
+                        char c = text.charAt(pos.index);
+                        if (c == '+') {
+                            sign = 1;
+                        } else if (c == '-') {
+                            sign = -1;
                         }
-                        catch(StringIndexOutOfBoundsException e) {}
-
-                        if (sign == 0) {    /* "GMT" without offset */
-                            calb.set(Calendar.ZONE_OFFSET, 0);
-                            return pos.index;
-                        }
+                        if (sign == 0) {
+                            // Try parsing a custom time zone "GMT+hh:mm" or "GMT".
+                            if ((c == 'G' || c == 'g')
+                                && (text.length() - start) >= GMT.length()
+                                && text.regionMatches(true, start, GMT, 0, GMT.length())) {
+                                pos.index = start + GMT.length();
 
-                        // Look for hours.
-                        try {
-                            char c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            num = c - '0';
-
-                            if (text.charAt(++pos.index) != ':') {
-                                c = text.charAt(pos.index);
-                                if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                    break parsing;
+                                if ((text.length() - pos.index) > 0) {
+                                    c = text.charAt(pos.index);
+                                    if (c == '+') {
+                                        sign = 1;
+                                    } else if (c == '-') {
+                                        sign = -1;
+                                    }
                                 }
-                                num *= 10;
-                                num += c - '0';
-                                pos.index++;
-                            }
-                            if (num > 23) {
-                                --pos.index;
-                                break parsing;
-                            }
-                            if  (text.charAt(pos.index) != ':') {
-                                break parsing;
-                            }
 
-                            // Look for minutes.
-                            offset = num * 60;
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            num = c - '0';
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            num *= 10;
-                            num += c - '0';
+                                if (sign == 0) {    /* "GMT" without offset */
+                                    calb.set(Calendar.ZONE_OFFSET, 0)
+                                        .set(Calendar.DST_OFFSET, 0);
+                                    return pos.index;
+                                }
 
-                            if (num > 59) {
-                                break parsing;
-                            }
-                        } catch (StringIndexOutOfBoundsException e) {
-                            break parsing;
-                        }
-                        offset += num;
-                        // Fall through for final processing below of 'offset' and 'sign'.
-                    } else {
-                        // If the first character is a sign, look for numeric timezones of
-                        // the form [+-]hhmm as specified by RFC 822. Otherwise, check
-                        // for named time zones by looking through the locale data from
-                        // the TimeZoneNames strings.
-                        try {
-                            char c = text.charAt(pos.index);
-                            if (c == '+') {
-                                sign = 1;
-                            } else if (c == '-') {
-                                sign = -1;
-                            } else {
-                                // Try parsing the text as a time zone name (abbr).
-                                int i = subParseZoneString(text, pos.index, calb);
-                                if (i != 0) {
+                                // Parse the rest as "hh:mm"
+                                int i = subParseNumericZone(text, ++pos.index,
+                                                            sign, 0, true, calb);
+                                if (i > 0) {
                                     return i;
                                 }
-                                break parsing;
-                            }
-
-                            // Parse the text as an RFC 822 time zone string. This code is
-                            // actually a little more permissive than RFC 822.  It will
-                            // try to do its best with numbers that aren't strictly 4
-                            // digits long.
-
-                            // Look for hh.
-                            int hours = 0;
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            hours = c - '0';
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            hours *= 10;
-                            hours += c - '0';
-
-                            if (hours > 23) {
-                                break parsing;
+                                pos.index = -i;
+                            } else {
+                                // Try parsing the text as a time zone
+                                // name or abbreviation.
+                                int i = subParseZoneString(text, pos.index, calb);
+                                if (i > 0) {
+                                    return i;
+                                }
+                                pos.index = -i;
                             }
-
-                            // Look for mm.
-                            int minutes = 0;
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            minutes = c - '0';
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
+                        } else {
+                            // Parse the rest as "hhmm" (RFC 822)
+                            int i = subParseNumericZone(text, ++pos.index,
+                                                        sign, 0, false, calb);
+                            if (i > 0) {
+                                return i;
                             }
-                            minutes *= 10;
-                            minutes += c - '0';
-
-                            if (minutes > 59) {
-                                break parsing;
-                            }
-
-                            offset = hours * 60 + minutes;
-                        } catch (StringIndexOutOfBoundsException e) {
-                            break parsing;
+                            pos.index = -i;
                         }
-                    }
-
-                    // Do the final processing for both of the above cases.  We only
-                    // arrive here if the form GMT+/-... or an RFC 822 form was seen.
-                    if (sign != 0) {
-                        offset *= MILLIS_PER_MINUTE * sign;
-                        calb.set(Calendar.ZONE_OFFSET, offset).set(Calendar.DST_OFFSET, 0);
-                        return ++pos.index;
+                    } catch (IndexOutOfBoundsException e) {
                     }
                 }
                 break parsing;
 
             case PATTERN_ISO_ZONE:   // 'X'
                 {
-                    int sign = 0;
-                    int offset = 0;
-
-                    iso8601: {
-                        try {
-                            char c = text.charAt(pos.index);
-                            if (c == 'Z') {
-                                calb.set(Calendar.ZONE_OFFSET, 0).set(Calendar.DST_OFFSET, 0);
-                                return ++pos.index;
-                            }
-
-                            // parse text as "+/-hh[[:]mm]" based on count
-                            if (c == '+') {
-                                sign = 1;
-                            } else if (c == '-') {
-                                sign = -1;
-                            }
-                            // Look for hh.
-                            int hours = 0;
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            hours = c - '0';
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            hours *= 10;
-                            hours += c - '0';
-                            if (hours > 23) {
-                                break parsing;
-                            }
+                    if ((text.length() - pos.index) <= 0) {
+                        break parsing;
+                    }
 
-                            if (count == 1) { // "X"
-                                offset = hours * 60;
-                                break iso8601;
-                            }
-
-                            c = text.charAt(++pos.index);
-                            // Skip ':' if "XXX"
-                            if (c == ':') {
-                                if (count == 2) {
-                                    break parsing;
-                                }
-                                c = text.charAt(++pos.index);
-                            } else {
-                                if (count == 3) {
-                                    // missing ':'
-                                    break parsing;
-                                }
-                            }
-
-                            // Look for mm.
-                            int minutes = 0;
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            minutes = c - '0';
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            minutes *= 10;
-                            minutes += c - '0';
-
-                            if (minutes > 59) {
-                                break parsing;
-                            }
-
-                            offset = hours * 60 + minutes;
-                        } catch (StringIndexOutOfBoundsException e) {
-                            break parsing;
-                        }
+                    int sign = 0;
+                    char c = text.charAt(pos.index);
+                    if (c == 'Z') {
+                        calb.set(Calendar.ZONE_OFFSET, 0).set(Calendar.DST_OFFSET, 0);
+                        return ++pos.index;
                     }
 
-                    // Do the final processing for both of the above cases.  We only
-                    // arrive here if the form GMT+/-... or an RFC 822 form was seen.
-                    if (sign != 0) {
-                        offset *= MILLIS_PER_MINUTE * sign;
-                        calb.set(Calendar.ZONE_OFFSET, offset).set(Calendar.DST_OFFSET, 0);
-                        return ++pos.index;
+                    // parse text as "+/-hh[[:]mm]" based on count
+                    if (c == '+') {
+                        sign = 1;
+                    } else if (c == '-') {
+                        sign = -1;
+                    } else {
+                        ++pos.index;
+                        break parsing;
                     }
+                    int i = subParseNumericZone(text, ++pos.index, sign, count,
+                                                count == 3, calb);
+                    if (i > 0) {
+                        return i;
+                    }
+                    pos.index = -i;
                 }
                 break parsing;
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/AbstractList.java
--- a/jdk/src/share/classes/java/util/AbstractList.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/AbstractList.java	Wed Jul 05 17:32:27 2017 +0200
@@ -482,8 +482,8 @@
      */
     public List subList(int fromIndex, int toIndex) {
         return (this instanceof RandomAccess ?
-                new RandomAccessSubList(this, fromIndex, toIndex) :
-                new SubList(this, fromIndex, toIndex));
+                new RandomAccessSubList<>(this, fromIndex, toIndex) :
+                new SubList<>(this, fromIndex, toIndex));
     }
 
     // Comparison and hashing
@@ -747,7 +747,7 @@
     }
 
     public List subList(int fromIndex, int toIndex) {
-        return new SubList(this, fromIndex, toIndex);
+        return new SubList<>(this, fromIndex, toIndex);
     }
 
     private void rangeCheck(int index) {
@@ -776,6 +776,6 @@
     }
 
     public List subList(int fromIndex, int toIndex) {
-        return new RandomAccessSubList(this, fromIndex, toIndex);
+        return new RandomAccessSubList<>(this, fromIndex, toIndex);
     }
 }
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/Arrays.java
--- a/jdk/src/share/classes/java/util/Arrays.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/Arrays.java	Wed Jul 05 17:32:27 2017 +0200
@@ -2824,7 +2824,7 @@
      * @return a list view of the specified array
      */
     public static  List asList(T... a) {
-        return new ArrayList(a);
+        return new ArrayList<>(a);
     }
 
     /**
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/Collections.java
--- a/jdk/src/share/classes/java/util/Collections.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/Collections.java	Wed Jul 05 17:32:27 2017 +0200
@@ -1035,7 +1035,7 @@
      * @return an unmodifiable view of the specified collection.
      */
     public static  Collection unmodifiableCollection(Collection c) {
-        return new UnmodifiableCollection(c);
+        return new UnmodifiableCollection<>(c);
     }
 
     /**
@@ -1109,7 +1109,7 @@
      * @return an unmodifiable view of the specified set.
      */
     public static  Set unmodifiableSet(Set s) {
-        return new UnmodifiableSet(s);
+        return new UnmodifiableSet<>(s);
     }
 
     /**
@@ -1141,7 +1141,7 @@
      * @return an unmodifiable view of the specified sorted set.
      */
     public static  SortedSet unmodifiableSortedSet(SortedSet s) {
-        return new UnmodifiableSortedSet(s);
+        return new UnmodifiableSortedSet<>(s);
     }
 
     /**
@@ -1158,13 +1158,13 @@
         public Comparator comparator() {return ss.comparator();}
 
         public SortedSet subSet(E fromElement, E toElement) {
-            return new UnmodifiableSortedSet(ss.subSet(fromElement,toElement));
+            return new UnmodifiableSortedSet<>(ss.subSet(fromElement,toElement));
         }
         public SortedSet headSet(E toElement) {
-            return new UnmodifiableSortedSet(ss.headSet(toElement));
+            return new UnmodifiableSortedSet<>(ss.headSet(toElement));
         }
         public SortedSet tailSet(E fromElement) {
-            return new UnmodifiableSortedSet(ss.tailSet(fromElement));
+            return new UnmodifiableSortedSet<>(ss.tailSet(fromElement));
         }
 
         public E first()                   {return ss.first();}
@@ -1188,8 +1188,8 @@
      */
     public static  List unmodifiableList(List list) {
         return (list instanceof RandomAccess ?
-                new UnmodifiableRandomAccessList(list) :
-                new UnmodifiableList(list));
+                new UnmodifiableRandomAccessList<>(list) :
+                new UnmodifiableList<>(list));
     }
 
     /**
@@ -1250,7 +1250,7 @@
         }
 
         public List subList(int fromIndex, int toIndex) {
-            return new UnmodifiableList(list.subList(fromIndex, toIndex));
+            return new UnmodifiableList<>(list.subList(fromIndex, toIndex));
         }
 
         /**
@@ -1267,7 +1267,7 @@
          */
         private Object readResolve() {
             return (list instanceof RandomAccess
-                    ? new UnmodifiableRandomAccessList(list)
+                    ? new UnmodifiableRandomAccessList<>(list)
                     : this);
         }
     }
@@ -1283,7 +1283,7 @@
         }
 
         public List subList(int fromIndex, int toIndex) {
-            return new UnmodifiableRandomAccessList(
+            return new UnmodifiableRandomAccessList<>(
                 list.subList(fromIndex, toIndex));
         }
 
@@ -1296,7 +1296,7 @@
          * deserialization.
          */
         private Object writeReplace() {
-            return new UnmodifiableList(list);
+            return new UnmodifiableList<>(list);
         }
     }
 
@@ -1315,7 +1315,7 @@
      * @return an unmodifiable view of the specified map.
      */
     public static  Map unmodifiableMap(Map m) {
-        return new UnmodifiableMap(m);
+        return new UnmodifiableMap<>(m);
     }
 
     /**
@@ -1363,7 +1363,7 @@
 
         public Set> entrySet() {
             if (entrySet==null)
-                entrySet = new UnmodifiableEntrySet(m.entrySet());
+                entrySet = new UnmodifiableEntrySet<>(m.entrySet());
             return entrySet;
         }
 
@@ -1400,7 +1400,7 @@
                         return i.hasNext();
                     }
                     public Map.Entry next() {
-                        return new UnmodifiableEntry(i.next());
+                        return new UnmodifiableEntry<>(i.next());
                     }
                     public void remove() {
                         throw new UnsupportedOperationException();
@@ -1411,7 +1411,7 @@
             public Object[] toArray() {
                 Object[] a = c.toArray();
                 for (int i=0; i((Map.Entry)a[i]);
+                    a[i] = new UnmodifiableEntry<>((Map.Entry)a[i]);
                 return a;
             }
 
@@ -1422,7 +1422,7 @@
                 Object[] arr = c.toArray(a.length==0 ? a : Arrays.copyOf(a, 0));
 
                 for (int i=0; i((Map.Entry)arr[i]);
+                    arr[i] = new UnmodifiableEntry<>((Map.Entry)arr[i]);
 
                 if (arr.length > a.length)
                     return (T[])arr;
@@ -1443,7 +1443,7 @@
                 if (!(o instanceof Map.Entry))
                     return false;
                 return c.contains(
-                    new UnmodifiableEntry((Map.Entry) o));
+                    new UnmodifiableEntry<>((Map.Entry) o));
             }
 
             /**
@@ -1517,7 +1517,7 @@
      * @return an unmodifiable view of the specified sorted map.
      */
     public static  SortedMap unmodifiableSortedMap(SortedMap m) {
-        return new UnmodifiableSortedMap(m);
+        return new UnmodifiableSortedMap<>(m);
     }
 
     /**
@@ -1535,13 +1535,13 @@
         public Comparator comparator() {return sm.comparator();}
 
         public SortedMap subMap(K fromKey, K toKey) {
-            return new UnmodifiableSortedMap(sm.subMap(fromKey, toKey));
+            return new UnmodifiableSortedMap<>(sm.subMap(fromKey, toKey));
         }
         public SortedMap headMap(K toKey) {
-            return new UnmodifiableSortedMap(sm.headMap(toKey));
+            return new UnmodifiableSortedMap<>(sm.headMap(toKey));
         }
         public SortedMap tailMap(K fromKey) {
-            return new UnmodifiableSortedMap(sm.tailMap(fromKey));
+            return new UnmodifiableSortedMap<>(sm.tailMap(fromKey));
         }
 
         public K firstKey()           {return sm.firstKey();}
@@ -1583,11 +1583,11 @@
      * @return a synchronized view of the specified collection.
      */
     public static  Collection synchronizedCollection(Collection c) {
-        return new SynchronizedCollection(c);
+        return new SynchronizedCollection<>(c);
     }
 
     static  Collection synchronizedCollection(Collection c, Object mutex) {
-        return new SynchronizedCollection(c, mutex);
+        return new SynchronizedCollection<>(c, mutex);
     }
 
     /**
@@ -1686,11 +1686,11 @@
      * @return a synchronized view of the specified set.
      */
     public static  Set synchronizedSet(Set s) {
-        return new SynchronizedSet(s);
+        return new SynchronizedSet<>(s);
     }
 
     static  Set synchronizedSet(Set s, Object mutex) {
-        return new SynchronizedSet(s, mutex);
+        return new SynchronizedSet<>(s, mutex);
     }
 
     /**
@@ -1754,7 +1754,7 @@
      * @return a synchronized view of the specified sorted set.
      */
     public static  SortedSet synchronizedSortedSet(SortedSet s) {
-        return new SynchronizedSortedSet(s);
+        return new SynchronizedSortedSet<>(s);
     }
 
     /**
@@ -1783,18 +1783,18 @@
 
         public SortedSet subSet(E fromElement, E toElement) {
             synchronized (mutex) {
-                return new SynchronizedSortedSet(
+                return new SynchronizedSortedSet<>(
                     ss.subSet(fromElement, toElement), mutex);
             }
         }
         public SortedSet headSet(E toElement) {
             synchronized (mutex) {
-                return new SynchronizedSortedSet(ss.headSet(toElement), mutex);
+                return new SynchronizedSortedSet<>(ss.headSet(toElement), mutex);
             }
         }
         public SortedSet tailSet(E fromElement) {
             synchronized (mutex) {
-               return new SynchronizedSortedSet(ss.tailSet(fromElement),mutex);
+               return new SynchronizedSortedSet<>(ss.tailSet(fromElement),mutex);
             }
         }
 
@@ -1833,14 +1833,14 @@
      */
     public static  List synchronizedList(List list) {
         return (list instanceof RandomAccess ?
-                new SynchronizedRandomAccessList(list) :
-                new SynchronizedList(list));
+                new SynchronizedRandomAccessList<>(list) :
+                new SynchronizedList<>(list));
     }
 
     static  List synchronizedList(List list, Object mutex) {
         return (list instanceof RandomAccess ?
-                new SynchronizedRandomAccessList(list, mutex) :
-                new SynchronizedList(list, mutex));
+                new SynchronizedRandomAccessList<>(list, mutex) :
+                new SynchronizedList<>(list, mutex));
     }
 
     /**
@@ -1903,7 +1903,7 @@
 
         public List subList(int fromIndex, int toIndex) {
             synchronized (mutex) {
-                return new SynchronizedList(list.subList(fromIndex, toIndex),
+                return new SynchronizedList<>(list.subList(fromIndex, toIndex),
                                             mutex);
             }
         }
@@ -1922,7 +1922,7 @@
          */
         private Object readResolve() {
             return (list instanceof RandomAccess
-                    ? new SynchronizedRandomAccessList(list)
+                    ? new SynchronizedRandomAccessList<>(list)
                     : this);
         }
     }
@@ -1944,7 +1944,7 @@
 
         public List subList(int fromIndex, int toIndex) {
             synchronized (mutex) {
-                return new SynchronizedRandomAccessList(
+                return new SynchronizedRandomAccessList<>(
                     list.subList(fromIndex, toIndex), mutex);
             }
         }
@@ -1958,7 +1958,7 @@
          * deserialization.
          */
         private Object writeReplace() {
-            return new SynchronizedList(list);
+            return new SynchronizedList<>(list);
         }
     }
 
@@ -1990,7 +1990,7 @@
      * @return a synchronized view of the specified map.
      */
     public static  Map synchronizedMap(Map m) {
-        return new SynchronizedMap(m);
+        return new SynchronizedMap<>(m);
     }
 
     /**
@@ -2051,7 +2051,7 @@
         public Set keySet() {
             synchronized (mutex) {
                 if (keySet==null)
-                    keySet = new SynchronizedSet(m.keySet(), mutex);
+                    keySet = new SynchronizedSet<>(m.keySet(), mutex);
                 return keySet;
             }
         }
@@ -2059,7 +2059,7 @@
         public Set> entrySet() {
             synchronized (mutex) {
                 if (entrySet==null)
-                    entrySet = new SynchronizedSet>(m.entrySet(), mutex);
+                    entrySet = new SynchronizedSet<>(m.entrySet(), mutex);
                 return entrySet;
             }
         }
@@ -2067,7 +2067,7 @@
         public Collection values() {
             synchronized (mutex) {
                 if (values==null)
-                    values = new SynchronizedCollection(m.values(), mutex);
+                    values = new SynchronizedCollection<>(m.values(), mutex);
                 return values;
             }
         }
@@ -2129,7 +2129,7 @@
      * @return a synchronized view of the specified sorted map.
      */
     public static  SortedMap synchronizedSortedMap(SortedMap m) {
-        return new SynchronizedSortedMap(m);
+        return new SynchronizedSortedMap<>(m);
     }
 
 
@@ -2159,18 +2159,18 @@
 
         public SortedMap subMap(K fromKey, K toKey) {
             synchronized (mutex) {
-                return new SynchronizedSortedMap(
+                return new SynchronizedSortedMap<>(
                     sm.subMap(fromKey, toKey), mutex);
             }
         }
         public SortedMap headMap(K toKey) {
             synchronized (mutex) {
-                return new SynchronizedSortedMap(sm.headMap(toKey), mutex);
+                return new SynchronizedSortedMap<>(sm.headMap(toKey), mutex);
             }
         }
         public SortedMap tailMap(K fromKey) {
             synchronized (mutex) {
-               return new SynchronizedSortedMap(sm.tailMap(fromKey),mutex);
+               return new SynchronizedSortedMap<>(sm.tailMap(fromKey),mutex);
             }
         }
 
@@ -2246,7 +2246,7 @@
      */
     public static  Collection checkedCollection(Collection c,
                                                       Class type) {
-        return new CheckedCollection(c, type);
+        return new CheckedCollection<>(c, type);
     }
 
     @SuppressWarnings("unchecked")
@@ -2378,7 +2378,7 @@
      * @since 1.5
      */
     public static  Set checkedSet(Set s, Class type) {
-        return new CheckedSet(s, type);
+        return new CheckedSet<>(s, type);
     }
 
     /**
@@ -2424,7 +2424,7 @@
      */
     public static  SortedSet checkedSortedSet(SortedSet s,
                                                     Class type) {
-        return new CheckedSortedSet(s, type);
+        return new CheckedSortedSet<>(s, type);
     }
 
     /**
@@ -2484,8 +2484,8 @@
      */
     public static  List checkedList(List list, Class type) {
         return (list instanceof RandomAccess ?
-                new CheckedRandomAccessList(list, type) :
-                new CheckedList(list, type));
+                new CheckedRandomAccessList<>(list, type) :
+                new CheckedList<>(list, type));
     }
 
     /**
@@ -2550,7 +2550,7 @@
         }
 
         public List subList(int fromIndex, int toIndex) {
-            return new CheckedList(list.subList(fromIndex, toIndex), type);
+            return new CheckedList<>(list.subList(fromIndex, toIndex), type);
         }
     }
 
@@ -2567,7 +2567,7 @@
         }
 
         public List subList(int fromIndex, int toIndex) {
-            return new CheckedRandomAccessList(
+            return new CheckedRandomAccessList<>(
                 list.subList(fromIndex, toIndex), type);
         }
     }
@@ -2609,7 +2609,7 @@
     public static  Map checkedMap(Map m,
                                               Class keyType,
                                               Class valueType) {
-        return new CheckedMap(m, keyType, valueType);
+        return new CheckedMap<>(m, keyType, valueType);
     }
 
 
@@ -2677,15 +2677,14 @@
             // - protection from malicious t
             // - correct behavior if t is a concurrent map
             Object[] entries = t.entrySet().toArray();
-            List> checked =
-                new ArrayList>(entries.length);
+            List> checked = new ArrayList<>(entries.length);
             for (Object o : entries) {
                 Map.Entry e = (Map.Entry) o;
                 Object k = e.getKey();
                 Object v = e.getValue();
                 typeCheck(k, v);
                 checked.add(
-                    new AbstractMap.SimpleImmutableEntry((K) k, (V) v));
+                    new AbstractMap.SimpleImmutableEntry<>((K) k, (V) v));
             }
             for (Map.Entry e : checked)
                 m.put(e.getKey(), e.getValue());
@@ -2695,7 +2694,7 @@
 
         public Set> entrySet() {
             if (entrySet==null)
-                entrySet = new CheckedEntrySet(m.entrySet(), valueType);
+                entrySet = new CheckedEntrySet<>(m.entrySet(), valueType);
             return entrySet;
         }
 
@@ -2810,7 +2809,7 @@
                 if (!(o instanceof Map.Entry))
                     return false;
                 return s.remove(new AbstractMap.SimpleImmutableEntry
-                                ((Map.Entry)o));
+                                <>((Map.Entry)o));
             }
 
             public boolean removeAll(Collection c) {
@@ -2843,7 +2842,7 @@
 
             static  CheckedEntry checkedEntry(Map.Entry e,
                                                             Class valueType) {
-                return new CheckedEntry(e, valueType);
+                return new CheckedEntry<>(e, valueType);
             }
 
             /**
@@ -2884,7 +2883,7 @@
                     if (!(o instanceof Map.Entry))
                         return false;
                     return e.equals(new AbstractMap.SimpleImmutableEntry
-                                    ((Map.Entry)o));
+                                    <>((Map.Entry)o));
                 }
             }
         }
@@ -2927,7 +2926,7 @@
     public static  SortedMap checkedSortedMap(SortedMap m,
                                                         Class keyType,
                                                         Class valueType) {
-        return new CheckedSortedMap(m, keyType, valueType);
+        return new CheckedSortedMap<>(m, keyType, valueType);
     }
 
     /**
@@ -2993,7 +2992,7 @@
 
     private static class EmptyIterator implements Iterator {
         static final EmptyIterator EMPTY_ITERATOR
-            = new EmptyIterator();
+            = new EmptyIterator<>();
 
         public boolean hasNext() { return false; }
         public E next() { throw new NoSuchElementException(); }
@@ -3042,7 +3041,7 @@
         implements ListIterator
     {
         static final EmptyListIterator EMPTY_ITERATOR
-            = new EmptyListIterator();
+            = new EmptyListIterator<>();
 
         public boolean hasPrevious() { return false; }
         public E previous() { throw new NoSuchElementException(); }
@@ -3078,7 +3077,7 @@
 
     private static class EmptyEnumeration implements Enumeration {
         static final EmptyEnumeration EMPTY_ENUMERATION
-            = new EmptyEnumeration();
+            = new EmptyEnumeration<>();
 
         public boolean hasMoreElements() { return false; }
         public E nextElement() { throw new NoSuchElementException(); }
@@ -3090,7 +3089,7 @@
      * @see #emptySet()
      */
     @SuppressWarnings("unchecked")
-    public static final Set EMPTY_SET = new EmptySet();
+    public static final Set EMPTY_SET = new EmptySet<>();
 
     /**
      * Returns the empty set (immutable).  This set is serializable.
@@ -3150,7 +3149,7 @@
      * @see #emptyList()
      */
     @SuppressWarnings("unchecked")
-    public static final List EMPTY_LIST = new EmptyList();
+    public static final List EMPTY_LIST = new EmptyList<>();
 
     /**
      * Returns the empty list (immutable).  This list is serializable.
@@ -3224,7 +3223,7 @@
      * @since 1.3
      */
     @SuppressWarnings("unchecked")
-    public static final Map EMPTY_MAP = new EmptyMap();
+    public static final Map EMPTY_MAP = new EmptyMap<>();
 
     /**
      * Returns the empty map (immutable).  This map is serializable.
@@ -3286,7 +3285,7 @@
      * @return an immutable set containing only the specified object.
      */
     public static  Set singleton(T o) {
-        return new SingletonSet(o);
+        return new SingletonSet<>(o);
     }
 
     static  Iterator singletonIterator(final E e) {
@@ -3339,7 +3338,7 @@
      * @since 1.3
      */
     public static  List singletonList(T o) {
-        return new SingletonList(o);
+        return new SingletonList<>(o);
     }
 
     /**
@@ -3381,7 +3380,7 @@
      * @since 1.3
      */
     public static  Map singletonMap(K key, V value) {
-        return new SingletonMap(key, value);
+        return new SingletonMap<>(key, value);
     }
 
     /**
@@ -3423,7 +3422,7 @@
         public Set> entrySet() {
             if (entrySet==null)
                 entrySet = Collections.>singleton(
-                    new SimpleImmutableEntry(k, v));
+                    new SimpleImmutableEntry<>(k, v));
             return entrySet;
         }
 
@@ -3455,7 +3454,7 @@
     public static  List nCopies(int n, T o) {
         if (n < 0)
             throw new IllegalArgumentException("List length = " + n);
-        return new CopiesList(n, o);
+        return new CopiesList<>(n, o);
     }
 
     /**
@@ -3529,7 +3528,7 @@
             if (fromIndex > toIndex)
                 throw new IllegalArgumentException("fromIndex(" + fromIndex +
                                                    ") > toIndex(" + toIndex + ")");
-            return new CopiesList(toIndex - fromIndex, element);
+            return new CopiesList<>(toIndex - fromIndex, element);
         }
     }
 
@@ -3595,7 +3594,7 @@
         if (cmp instanceof ReverseComparator2)
             return ((ReverseComparator2)cmp).cmp;
 
-        return new ReverseComparator2(cmp);
+        return new ReverseComparator2<>(cmp);
     }
 
     /**
@@ -3674,7 +3673,7 @@
      * @see ArrayList
      */
     public static  ArrayList list(Enumeration e) {
-        ArrayList l = new ArrayList();
+        ArrayList l = new ArrayList<>();
         while (e.hasMoreElements())
             l.add(e.nextElement());
         return l;
@@ -3819,7 +3818,7 @@
      * @since 1.6
      */
     public static  Set newSetFromMap(Map map) {
-        return new SetFromMap(map);
+        return new SetFromMap<>(map);
     }
 
     /**
@@ -3883,7 +3882,7 @@
      * @since  1.6
      */
     public static  Queue asLifoQueue(Deque deque) {
-        return new AsLIFOQueue(deque);
+        return new AsLIFOQueue<>(deque);
     }
 
     /**
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/EnumMap.java
--- a/jdk/src/share/classes/java/util/EnumMap.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/EnumMap.java	Wed Jul 05 17:32:27 2017 +0200
@@ -499,7 +499,7 @@
             int j = 0;
             for (int i = 0; i < vals.length; i++)
                 if (vals[i] != null)
-                    a[j++] = new AbstractMap.SimpleEntry(
+                    a[j++] = new AbstractMap.SimpleEntry<>(
                         keyUniverse[i], unmaskNull(vals[i]));
             return a;
         }
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/EnumSet.java
--- a/jdk/src/share/classes/java/util/EnumSet.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/EnumSet.java	Wed Jul 05 17:32:27 2017 +0200
@@ -110,9 +110,9 @@
             throw new ClassCastException(elementType + " not an enum");
 
         if (universe.length <= 64)
-            return new RegularEnumSet(elementType, universe);
+            return new RegularEnumSet<>(elementType, universe);
         else
-            return new JumboEnumSet(elementType, universe);
+            return new JumboEnumSet<>(elementType, universe);
     }
 
     /**
@@ -430,7 +430,7 @@
     }
 
     Object writeReplace() {
-        return new SerializationProxy(this);
+        return new SerializationProxy<>(this);
     }
 
     // readObject method for the serialization proxy pattern
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/Formatter.java
--- a/jdk/src/share/classes/java/util/Formatter.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/Formatter.java	Wed Jul 05 17:32:27 2017 +0200
@@ -2490,7 +2490,7 @@
      * Finds format specifiers in the format string.
      */
     private FormatString[] parse(String s) {
-        ArrayList al = new ArrayList();
+        ArrayList al = new ArrayList<>();
         Matcher m = fsPattern.matcher(s);
         for (int i = 0, len = s.length(); i < len; ) {
             if (m.find(i)) {
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/HashMap.java
--- a/jdk/src/share/classes/java/util/HashMap.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/HashMap.java	Wed Jul 05 17:32:27 2017 +0200
@@ -763,7 +763,7 @@
      */
     void addEntry(int hash, K key, V value, int bucketIndex) {
         Entry e = table[bucketIndex];
-        table[bucketIndex] = new Entry(hash, key, value, e);
+        table[bucketIndex] = new Entry<>(hash, key, value, e);
         if (size++ >= threshold)
             resize(2 * table.length);
     }
@@ -778,7 +778,7 @@
      */
     void createEntry(int hash, K key, V value, int bucketIndex) {
         Entry e = table[bucketIndex];
-        table[bucketIndex] = new Entry(hash, key, value, e);
+        table[bucketIndex] = new Entry<>(hash, key, value, e);
         size++;
     }
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/HashSet.java
--- a/jdk/src/share/classes/java/util/HashSet.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/HashSet.java	Wed Jul 05 17:32:27 2017 +0200
@@ -100,7 +100,7 @@
      * default initial capacity (16) and load factor (0.75).
      */
     public HashSet() {
-        map = new HashMap();
+        map = new HashMap<>();
     }
 
     /**
@@ -113,7 +113,7 @@
      * @throws NullPointerException if the specified collection is null
      */
     public HashSet(Collection c) {
-        map = new HashMap(Math.max((int) (c.size()/.75f) + 1, 16));
+        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
         addAll(c);
     }
 
@@ -127,7 +127,7 @@
      *             than zero, or if the load factor is nonpositive
      */
     public HashSet(int initialCapacity, float loadFactor) {
-        map = new HashMap(initialCapacity, loadFactor);
+        map = new HashMap<>(initialCapacity, loadFactor);
     }
 
     /**
@@ -139,7 +139,7 @@
      *             than zero
      */
     public HashSet(int initialCapacity) {
-        map = new HashMap(initialCapacity);
+        map = new HashMap<>(initialCapacity);
     }
 
     /**
@@ -156,7 +156,7 @@
      *             than zero, or if the load factor is nonpositive
      */
     HashSet(int initialCapacity, float loadFactor, boolean dummy) {
-        map = new LinkedHashMap(initialCapacity, loadFactor);
+        map = new LinkedHashMap<>(initialCapacity, loadFactor);
     }
 
     /**
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/Hashtable.java
--- a/jdk/src/share/classes/java/util/Hashtable.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/Hashtable.java	Wed Jul 05 17:32:27 2017 +0200
@@ -455,7 +455,7 @@
 
         // Creates the new entry.
         Entry e = tab[index];
-        tab[index] = new Entry(hash, key, value, e);
+        tab[index] = new Entry<>(hash, key, value, e);
         count++;
         return null;
     }
@@ -579,7 +579,7 @@
         if (count == 0) {
             return Collections.emptyEnumeration();
         } else {
-            return new Enumerator(type, false);
+            return new Enumerator<>(type, false);
         }
     }
 
@@ -587,7 +587,7 @@
         if (count == 0) {
             return Collections.emptyIterator();
         } else {
-            return new Enumerator(type, true);
+            return new Enumerator<>(type, true);
         }
     }
 
@@ -929,7 +929,7 @@
         }
         // Creates the new entry.
         Entry e = tab[index];
-        tab[index] = new Entry(hash, key, value, e);
+        tab[index] = new Entry<>(hash, key, value, e);
         count++;
     }
 
@@ -950,7 +950,7 @@
         }
 
         protected Object clone() {
-            return new Entry(hash, key, value,
+            return new Entry<>(hash, key, value,
                                   (next==null ? null : (Entry) next.clone()));
         }
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/IdentityHashMap.java
--- a/jdk/src/share/classes/java/util/IdentityHashMap.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/IdentityHashMap.java	Wed Jul 05 17:32:27 2017 +0200
@@ -1134,7 +1134,7 @@
             Object[] result = new Object[size];
             Iterator> it = iterator();
             for (int i = 0; i < size; i++)
-                result[i] = new AbstractMap.SimpleEntry(it.next());
+                result[i] = new AbstractMap.SimpleEntry<>(it.next());
             return result;
         }
 
@@ -1146,7 +1146,7 @@
                     .newInstance(a.getClass().getComponentType(), size);
             Iterator> it = iterator();
             for (int i = 0; i < size; i++)
-                a[i] = (T) new AbstractMap.SimpleEntry(it.next());
+                a[i] = (T) new AbstractMap.SimpleEntry<>(it.next());
             if (a.length > size)
                 a[size] = null;
             return a;
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/JumboEnumSet.java
--- a/jdk/src/share/classes/java/util/JumboEnumSet.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/JumboEnumSet.java	Wed Jul 05 17:32:27 2017 +0200
@@ -89,7 +89,7 @@
      * @return an iterator over the elements contained in this set
      */
     public Iterator iterator() {
-        return new EnumSetIterator();
+        return new EnumSetIterator<>();
     }
 
     private class EnumSetIterator> implements Iterator {
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/LinkedHashMap.java
--- a/jdk/src/share/classes/java/util/LinkedHashMap.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/LinkedHashMap.java	Wed Jul 05 17:32:27 2017 +0200
@@ -237,7 +237,7 @@
      * the chain.
      */
     void init() {
-        header = new Entry(-1, null, null, null);
+        header = new Entry<>(-1, null, null, null);
         header.before = header.after = header;
     }
 
@@ -438,7 +438,7 @@
      */
     void createEntry(int hash, K key, V value, int bucketIndex) {
         HashMap.Entry old = table[bucketIndex];
-        Entry e = new Entry(hash, key, value, old);
+        Entry e = new Entry<>(hash, key, value, old);
         table[bucketIndex] = e;
         e.addBefore(header);
         size++;
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/LinkedList.java
--- a/jdk/src/share/classes/java/util/LinkedList.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/LinkedList.java	Wed Jul 05 17:32:27 2017 +0200
@@ -122,7 +122,7 @@
      */
     private void linkFirst(E e) {
         final Node f = first;
-        final Node newNode = new Node(null, e, f);
+        final Node newNode = new Node<>(null, e, f);
         first = newNode;
         if (f == null)
             last = newNode;
@@ -137,7 +137,7 @@
      */
     void linkLast(E e) {
         final Node l = last;
-        final Node newNode = new Node(l, e, null);
+        final Node newNode = new Node<>(l, e, null);
         last = newNode;
         if (l == null)
             first = newNode;
@@ -153,7 +153,7 @@
     void linkBefore(E e, Node succ) {
         // assert succ != null;
         final Node pred = succ.prev;
-        final Node newNode = new Node(pred, e, succ);
+        final Node newNode = new Node<>(pred, e, succ);
         succ.prev = newNode;
         if (pred == null)
             first = newNode;
@@ -419,7 +419,7 @@
 
         for (Object o : a) {
             @SuppressWarnings("unchecked") E e = (E) o;
-            Node newNode = new Node(pred, e, null);
+            Node newNode = new Node<>(pred, e, null);
             if (pred == null)
                 first = newNode;
             else
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/ListResourceBundle.java
--- a/jdk/src/share/classes/java/util/ListResourceBundle.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/ListResourceBundle.java	Wed Jul 05 17:32:27 2017 +0200
@@ -187,7 +187,7 @@
             return;
 
         Object[][] contents = getContents();
-        HashMap temp = new HashMap(contents.length);
+        HashMap temp = new HashMap<>(contents.length);
         for (int i = 0; i < contents.length; ++i) {
             // key must be non-null String, value must be non-null
             String key = (String) contents[i][0];
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/Locale.java
--- a/jdk/src/share/classes/java/util/Locale.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/Locale.java	Wed Jul 05 17:32:27 2017 +0200
@@ -1449,10 +1449,15 @@
      * three-letter language abbreviation is not available for this locale.
      */
     public String getISO3Language() throws MissingResourceException {
-        String language3 = getISO3Code(_baseLocale.getLanguage(), LocaleISOData.isoLanguageTable);
+        String lang = _baseLocale.getLanguage();
+        if (lang.length() == 3) {
+            return lang;
+        }
+
+        String language3 = getISO3Code(lang, LocaleISOData.isoLanguageTable);
         if (language3 == null) {
             throw new MissingResourceException("Couldn't find 3-letter language code for "
-                    + _baseLocale.getLanguage(), "FormatData_" + toString(), "ShortLanguage");
+                    + lang, "FormatData_" + toString(), "ShortLanguage");
         }
         return language3;
     }
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/PriorityQueue.java
--- a/jdk/src/share/classes/java/util/PriorityQueue.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/PriorityQueue.java	Wed Jul 05 17:32:27 2017 +0200
@@ -538,7 +538,7 @@
                     cursor--;
                 else {
                     if (forgetMeNot == null)
-                        forgetMeNot = new ArrayDeque();
+                        forgetMeNot = new ArrayDeque<>();
                     forgetMeNot.add(moved);
                 }
             } else if (lastRetElt != null) {
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/Properties.java
--- a/jdk/src/share/classes/java/util/Properties.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/Properties.java	Wed Jul 05 17:32:27 2017 +0200
@@ -1011,7 +1011,7 @@
      * @since   1.6
      */
     public Set stringPropertyNames() {
-        Hashtable h = new Hashtable();
+        Hashtable h = new Hashtable<>();
         enumerateStringProperties(h);
         return h.keySet();
     }
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/RegularEnumSet.java
--- a/jdk/src/share/classes/java/util/RegularEnumSet.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/RegularEnumSet.java	Wed Jul 05 17:32:27 2017 +0200
@@ -71,7 +71,7 @@
      * @return an iterator over the elements contained in this set
      */
     public Iterator iterator() {
-        return new EnumSetIterator();
+        return new EnumSetIterator<>();
     }
 
     private class EnumSetIterator> implements Iterator {
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/ServiceLoader.java
--- a/jdk/src/share/classes/java/util/ServiceLoader.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/ServiceLoader.java	Wed Jul 05 17:32:27 2017 +0200
@@ -191,7 +191,7 @@
     private ClassLoader loader;
 
     // Cached providers, in instantiation order
-    private LinkedHashMap providers = new LinkedHashMap();
+    private LinkedHashMap providers = new LinkedHashMap<>();
 
     // The current lazy-lookup iterator
     private LazyIterator lookupIterator;
@@ -291,7 +291,7 @@
     {
         InputStream in = null;
         BufferedReader r = null;
-        ArrayList names = new ArrayList();
+        ArrayList names = new ArrayList<>();
         try {
             in = u.openStream();
             r = new BufferedReader(new InputStreamReader(in, "utf-8"));
@@ -463,7 +463,7 @@
     public static  ServiceLoader load(Class service,
                                             ClassLoader loader)
     {
-        return new ServiceLoader(service, loader);
+        return new ServiceLoader<>(service, loader);
     }
 
     /**
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/TimSort.java
--- a/jdk/src/share/classes/java/util/TimSort.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/TimSort.java	Wed Jul 05 17:32:27 2017 +0200
@@ -196,7 +196,7 @@
          * extending short natural runs to minRun elements, and merging runs
          * to maintain stack invariant.
          */
-        TimSort ts = new TimSort(a, c);
+        TimSort ts = new TimSort<>(a, c);
         int minRun = minRunLength(nRemaining);
         do {
             // Identify next run
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/TreeMap.java
--- a/jdk/src/share/classes/java/util/TreeMap.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/TreeMap.java	Wed Jul 05 17:32:27 2017 +0200
@@ -533,7 +533,7 @@
             // throw NullPointerException
             //
             // compare(key, key); // type check
-            root = new Entry(key, value, null);
+            root = new Entry<>(key, value, null);
             size = 1;
             modCount++;
             return null;
@@ -569,7 +569,7 @@
                     return t.setValue(value);
             } while (t != null);
         }
-        Entry e = new Entry(key, value, parent);
+        Entry e = new Entry<>(key, value, parent);
         if (cmp < 0)
             parent.left = e;
         else
@@ -1069,14 +1069,14 @@
         }
         public NavigableSet subSet(E fromElement, boolean fromInclusive,
                                       E toElement,   boolean toInclusive) {
-            return new KeySet(m.subMap(fromElement, fromInclusive,
+            return new KeySet<>(m.subMap(fromElement, fromInclusive,
                                           toElement,   toInclusive));
         }
         public NavigableSet headSet(E toElement, boolean inclusive) {
-            return new KeySet(m.headMap(toElement, inclusive));
+            return new KeySet<>(m.headMap(toElement, inclusive));
         }
         public NavigableSet tailSet(E fromElement, boolean inclusive) {
-            return new KeySet(m.tailMap(fromElement, inclusive));
+            return new KeySet<>(m.tailMap(fromElement, inclusive));
         }
         public SortedSet subSet(E fromElement, E toElement) {
             return subSet(fromElement, true, toElement, false);
@@ -1205,7 +1205,7 @@
      */
     static  Map.Entry exportEntry(TreeMap.Entry e) {
         return (e == null) ? null :
-            new AbstractMap.SimpleImmutableEntry(e);
+            new AbstractMap.SimpleImmutableEntry<>(e);
     }
 
     /**
@@ -2406,7 +2406,7 @@
             value = (defaultVal != null ? defaultVal : (V) str.readObject());
         }
 
-        Entry middle =  new Entry(key, value, null);
+        Entry middle =  new Entry<>(key, value, null);
 
         // color nodes in non-full bottommost level red
         if (level == redLevel)
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/TreeSet.java
--- a/jdk/src/share/classes/java/util/TreeSet.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/TreeSet.java	Wed Jul 05 17:32:27 2017 +0200
@@ -138,7 +138,7 @@
      *        ordering} of the elements will be used.
      */
     public TreeSet(Comparator comparator) {
-        this(new TreeMap(comparator));
+        this(new TreeMap<>(comparator));
     }
 
     /**
@@ -195,7 +195,7 @@
      * @since 1.6
      */
     public NavigableSet descendingSet() {
-        return new TreeSet(m.descendingMap());
+        return new TreeSet<>(m.descendingMap());
     }
 
     /**
@@ -322,7 +322,7 @@
      */
     public NavigableSet subSet(E fromElement, boolean fromInclusive,
                                   E toElement,   boolean toInclusive) {
-        return new TreeSet(m.subMap(fromElement, fromInclusive,
+        return new TreeSet<>(m.subMap(fromElement, fromInclusive,
                                        toElement,   toInclusive));
     }
 
@@ -335,7 +335,7 @@
      * @since 1.6
      */
     public NavigableSet headSet(E toElement, boolean inclusive) {
-        return new TreeSet(m.headMap(toElement, inclusive));
+        return new TreeSet<>(m.headMap(toElement, inclusive));
     }
 
     /**
@@ -347,7 +347,7 @@
      * @since 1.6
      */
     public NavigableSet tailSet(E fromElement, boolean inclusive) {
-        return new TreeSet(m.tailMap(fromElement, inclusive));
+        return new TreeSet<>(m.tailMap(fromElement, inclusive));
     }
 
     /**
@@ -477,7 +477,7 @@
             throw new InternalError();
         }
 
-        clone.m = new TreeMap(m);
+        clone.m = new TreeMap<>(m);
         return clone;
     }
 
@@ -524,9 +524,9 @@
         // Create backing TreeMap
         TreeMap tm;
         if (c==null)
-            tm = new TreeMap();
+            tm = new TreeMap<>();
         else
-            tm = new TreeMap(c);
+            tm = new TreeMap<>(c);
         m = tm;
 
         // Read in size
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/WeakHashMap.java
--- a/jdk/src/share/classes/java/util/WeakHashMap.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/WeakHashMap.java	Wed Jul 05 17:32:27 2017 +0200
@@ -171,7 +171,7 @@
     /**
      * Reference queue for cleared WeakEntries
      */
-    private final ReferenceQueue queue = new ReferenceQueue();
+    private final ReferenceQueue queue = new ReferenceQueue<>();
 
     /**
      * The number of times this WeakHashMap has been structurally modified.
@@ -439,7 +439,7 @@
 
         modCount++;
         Entry e = tab[i];
-        tab[i] = new Entry(k, value, queue, h, e);
+        tab[i] = new Entry<>(k, value, queue, h, e);
         if (++size >= threshold)
             resize(tab.length * 2);
         return null;
@@ -955,10 +955,9 @@
         }
 
         private List> deepCopy() {
-            List> list =
-                new ArrayList>(size());
+            List> list = new ArrayList<>(size());
             for (Map.Entry e : this)
-                list.add(new AbstractMap.SimpleEntry(e));
+                list.add(new AbstractMap.SimpleEntry<>(e));
             return list;
         }
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/jar/Pack200.java
--- a/jdk/src/share/classes/java/util/jar/Pack200.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/jar/Pack200.java	Wed Jul 05 17:32:27 2017 +0200
@@ -732,14 +732,14 @@
     private synchronized static Object newInstance(String prop) {
         String implName = "(unknown)";
         try {
-            Class impl = (prop == PACK_PROVIDER)? packerImpl: unpackerImpl;
+            Class impl = (PACK_PROVIDER.equals(prop))? packerImpl: unpackerImpl;
             if (impl == null) {
                 // The first time, we must decide which class to use.
                 implName = java.security.AccessController.doPrivileged(
                     new sun.security.action.GetPropertyAction(prop,""));
                 if (implName != null && !implName.equals(""))
                     impl = Class.forName(implName);
-                else if (prop == PACK_PROVIDER)
+                else if (PACK_PROVIDER.equals(prop))
                     impl = com.sun.java.util.jar.pack.PackerImpl.class;
                 else
                     impl = com.sun.java.util.jar.pack.UnpackerImpl.class;
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/logging/FileHandler.java
--- a/jdk/src/share/classes/java/util/logging/FileHandler.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/FileHandler.java	Wed Jul 05 17:32:27 2017 +0200
@@ -127,7 +127,7 @@
     private FileOutputStream lockStream;
     private File files[];
     private static final int MAX_LOCKS = 100;
-    private static java.util.HashMap locks = new java.util.HashMap();
+    private static java.util.HashMap locks = new java.util.HashMap<>();
 
     // A metered stream is a subclass of OutputStream that
     //   (a) forwards all its output to a target stream
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/logging/Level.java
--- a/jdk/src/share/classes/java/util/logging/Level.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/Level.java	Wed Jul 05 17:32:27 2017 +0200
@@ -59,7 +59,7 @@
  */
 
 public class Level implements java.io.Serializable {
-    private static java.util.ArrayList known = new java.util.ArrayList();
+    private static java.util.ArrayList known = new java.util.ArrayList<>();
     private static String defaultBundle = "sun.util.logging.resources.logging";
 
     /**
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/logging/LogManager.java
--- a/jdk/src/share/classes/java/util/logging/LogManager.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/LogManager.java	Wed Jul 05 17:32:27 2017 +0200
@@ -156,8 +156,7 @@
     private final static Level defaultLevel = Level.INFO;
 
     // Table of named Loggers that maps names to Loggers.
-    private Hashtable namedLoggers =
-        new Hashtable();
+    private Hashtable namedLoggers = new Hashtable<>();
     // Tree of named Loggers
     private LogNode root = new LogNode(null);
     private Logger rootLogger;
@@ -422,7 +421,7 @@
     // loggerRefQueue holds LoggerWeakRef objects for Logger objects
     // that have been GC'ed.
     private final ReferenceQueue loggerRefQueue
-        = new ReferenceQueue();
+        = new ReferenceQueue<>();
 
     // Package-level inner class.
     // Helper class for managing WeakReferences to Logger objects.
@@ -672,7 +671,7 @@
                 name = "";
             }
             if (node.children == null) {
-                node.children = new HashMap();
+                node.children = new HashMap<>();
             }
             LogNode child = node.children.get(head);
             if (child == null) {
@@ -856,7 +855,7 @@
         }
         hands = hands.trim();
         int ix = 0;
-        Vector result = new Vector();
+        Vector result = new Vector<>();
         while (ix < hands.length()) {
             int end = ix;
             while (end < hands.length()) {
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/logging/LogRecord.java
--- a/jdk/src/share/classes/java/util/logging/LogRecord.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/LogRecord.java	Wed Jul 05 17:32:27 2017 +0200
@@ -85,8 +85,7 @@
     private static final AtomicInteger nextThreadId
         = new AtomicInteger(MIN_SEQUENTIAL_THREAD_ID);
 
-    private static final ThreadLocal threadIds
-        = new ThreadLocal();
+    private static final ThreadLocal threadIds = new ThreadLocal<>();
 
     /**
      * @serial Logging message level
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/logging/Logger.java
--- a/jdk/src/share/classes/java/util/logging/Logger.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/Logger.java	Wed Jul 05 17:32:27 2017 +0200
@@ -170,7 +170,7 @@
     private LogManager manager;
     private String name;
     private final CopyOnWriteArrayList handlers =
-        new CopyOnWriteArrayList();
+        new CopyOnWriteArrayList<>();
     private String resourceBundleName;
     private volatile boolean useParentHandlers = true;
     private volatile Filter filter;
@@ -1420,13 +1420,13 @@
             // Set our new parent.
             parent = newParent;
             if (parent.kids == null) {
-                parent.kids = new ArrayList(2);
+                parent.kids = new ArrayList<>(2);
             }
             if (ref == null) {
                 // we didn't have a previous parent
                 ref = manager.new LoggerWeakRef(this);
             }
-            ref.setParentRef(new WeakReference(parent));
+            ref.setParentRef(new WeakReference<>(parent));
             parent.kids.add(ref);
 
             // As a result of the reparenting, the effective level
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/logging/Logging.java
--- a/jdk/src/share/classes/java/util/logging/Logging.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/Logging.java	Wed Jul 05 17:32:27 2017 +0200
@@ -56,7 +56,7 @@
 
     public List getLoggerNames() {
         Enumeration loggers = logManager.getLoggerNames();
-        ArrayList array = new ArrayList();
+        ArrayList array = new ArrayList<>();
 
         for (; loggers.hasMoreElements();) {
             array.add((String) loggers.nextElement());
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/prefs/AbstractPreferences.java
--- a/jdk/src/share/classes/java/util/prefs/AbstractPreferences.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/prefs/AbstractPreferences.java	Wed Jul 05 17:32:27 2017 +0200
@@ -155,8 +155,7 @@
      * All known unremoved children of this node.  (This "cache" is consulted
      * prior to calling childSpi() or getChild().
      */
-    private Map kidCache
-        = new HashMap();
+    private Map kidCache = new HashMap<>();
 
     /**
      * This field is used to keep track of whether or not this node has
@@ -713,7 +712,7 @@
             if (removed)
                 throw new IllegalStateException("Node has been removed.");
 
-            Set s = new TreeSet(kidCache.keySet());
+            Set s = new TreeSet<>(kidCache.keySet());
             for (String kid : childrenNamesSpi())
                 s.add(kid);
             return s.toArray(EMPTY_STRING_ARRAY);
@@ -1442,8 +1441,7 @@
      * event delivery from preference activity, greatly simplifying
      * locking and reducing opportunity for deadlock.
      */
-    private static final List eventQueue
-        = new LinkedList();
+    private static final List eventQueue = new LinkedList<>();
 
     /**
      * These two classes are used to distinguish NodeChangeEvents on
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/regex/Pattern.java
--- a/jdk/src/share/classes/java/util/regex/Pattern.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/regex/Pattern.java	Wed Jul 05 17:32:27 2017 +0200
@@ -1068,7 +1068,7 @@
     public String[] split(CharSequence input, int limit) {
         int index = 0;
         boolean matchLimited = limit > 0;
-        ArrayList matchList = new ArrayList();
+        ArrayList matchList = new ArrayList<>();
         Matcher m = matcher(input);
 
         // Add segments before each match found
@@ -1566,7 +1566,7 @@
 
     Map namedGroups() {
         if (namedGroups == null)
-            namedGroups = new HashMap(2);
+            namedGroups = new HashMap<>(2);
         return namedGroups;
     }
 
@@ -5309,7 +5309,7 @@
         }
 
         private static final HashMap map
-            = new HashMap();
+            = new HashMap<>();
 
         static {
             // Unicode character property aliases, defined in
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/zip/Inflater.java
--- a/jdk/src/share/classes/java/util/zip/Inflater.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/zip/Inflater.java	Wed Jul 05 17:32:27 2017 +0200
@@ -382,6 +382,12 @@
             throw new NullPointerException("Inflater has been closed");
     }
 
+    boolean ended() {
+        synchronized (zsRef) {
+            return zsRef.address() == 0;
+        }
+    }
+
     private native static void initIDs();
     private native static long init(boolean nowrap);
     private native static void setDictionary(long addr, byte[] b, int off,
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/zip/ZipFile.java
--- a/jdk/src/share/classes/java/util/zip/ZipFile.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/zip/ZipFile.java	Wed Jul 05 17:32:27 2017 +0200
@@ -424,6 +424,8 @@
      */
     private void releaseInflater(Inflater inf) {
         synchronized (inflaters) {
+            if (inf.ended())
+                return;
             inf.reset();
             inflaters.add(inf);
         }
@@ -543,7 +545,7 @@
 
             if (streams.size() !=0) {
                 Set copy = streams;
-                streams = new HashSet();
+                streams = new HashSet<>();
                 for (InputStream is: copy)
                     is.close();
             }
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/java/util/zip/ZipOutputStream.java
--- a/jdk/src/share/classes/java/util/zip/ZipOutputStream.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/java/util/zip/ZipOutputStream.java	Wed Jul 05 17:32:27 2017 +0200
@@ -52,8 +52,8 @@
     }
 
     private XEntry current;
-    private Vector xentries = new Vector();
-    private HashSet names = new HashSet();
+    private Vector xentries = new Vector<>();
+    private HashSet names = new HashSet<>();
     private CRC32 crc = new CRC32();
     private long written = 0;
     private long locoff = 0;
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/javax/net/ssl/X509ExtendedTrustManager.java
--- a/jdk/src/share/classes/javax/net/ssl/X509ExtendedTrustManager.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/javax/net/ssl/X509ExtendedTrustManager.java	Wed Jul 05 17:32:27 2017 +0200
@@ -63,7 +63,7 @@
      * should be "RSA". Checking is case-sensitive.
      * 

* If the socket parameter is an instance of - * {@link javax.net.SSLSocket}, and the endpoint identification + * {@link javax.net.ssl.SSLSocket}, and the endpoint identification * algorithm of the SSLParameters is non-empty, to prevent * man-in-the-middle attacks, the address that the socket * connected to should be checked against the peer's identity presented @@ -71,7 +71,7 @@ * identification algorithm. *

* If the socket parameter is an instance of - * {@link javax.net.SSLSocket}, and the algorithm constraints of the + * {@link javax.net.ssl.SSLSocket}, and the algorithm constraints of the * SSLParameters is non-null, for every certificate in the * certification path, fields such as subject public key, the signature * algorithm, key usage, extended key usage, etc. need to conform to the @@ -88,8 +88,8 @@ * @throws CertificateException if the certificate chain is not trusted * by this TrustManager * - * @see SSLParameters#getEndpointIdentificationProtocol - * @see SSLParameters#setEndpointIdentificationProtocol(String) + * @see SSLParameters#getEndpointIdentificationAlgorithm + * @see SSLParameters#setEndpointIdentificationAlgorithm(String) * @see SSLParameters#getAlgorithmConstraints * @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints) */ @@ -111,7 +111,7 @@ * certificate is used. Checking is case-sensitive. *

* If the socket parameter is an instance of - * {@link javax.net.SSLSocket}, and the endpoint identification + * {@link javax.net.ssl.SSLSocket}, and the endpoint identification * algorithm of the SSLParameters is non-empty, to prevent * man-in-the-middle attacks, the address that the socket * connected to should be checked against the peer's identity presented @@ -119,7 +119,7 @@ * identification algorithm. *

* If the socket parameter is an instance of - * {@link javax.net.SSLSocket}, and the algorithm constraints of the + * {@link javax.net.ssl.SSLSocket}, and the algorithm constraints of the * SSLParameters is non-null, for every certificate in the * certification path, fields such as subject public key, the signature * algorithm, key usage, extended key usage, etc. need to conform to the @@ -136,8 +136,8 @@ * @throws CertificateException if the certificate chain is not trusted * by this TrustManager * - * @see SSLParameters#getEndpointIdentificationProtocol - * @see SSLParameters#setEndpointIdentificationProtocol(String) + * @see SSLParameters#getEndpointIdentificationAlgorithm + * @see SSLParameters#setEndpointIdentificationAlgorithm(String) * @see SSLParameters#getAlgorithmConstraints * @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints) */ @@ -177,8 +177,8 @@ * @throws CertificateException if the certificate chain is not trusted * by this TrustManager * - * @see SSLParameters#getEndpointIdentificationProtocol - * @see SSLParameters#setEndpointIdentificationProtocol(String) + * @see SSLParameters#getEndpointIdentificationAlgorithm + * @see SSLParameters#setEndpointIdentificationAlgorithm(String) * @see SSLParameters#getAlgorithmConstraints * @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints) */ @@ -223,8 +223,8 @@ * @throws CertificateException if the certificate chain is not trusted * by this TrustManager * - * @see SSLParameters#getEndpointIdentificationProtocol - * @see SSLParameters#setEndpointIdentificationProtocol(String) + * @see SSLParameters#getEndpointIdentificationAlgorithm + * @see SSLParameters#setEndpointIdentificationAlgorithm(String) * @see SSLParameters#getAlgorithmConstraints * @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints) */ diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/javax/print/attribute/standard/DialogTypeSelection.java --- a/jdk/src/share/classes/javax/print/attribute/standard/DialogTypeSelection.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/javax/print/attribute/standard/DialogTypeSelection.java Wed Jul 05 17:32:27 2017 +0200 @@ -52,6 +52,8 @@ public final class DialogTypeSelection extends EnumSyntax implements PrintRequestAttribute { + private static final long serialVersionUID = 7518682952133256029L; + /** * */ diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/javax/sound/midi/MidiSystem.java --- a/jdk/src/share/classes/javax/sound/midi/MidiSystem.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/javax/sound/midi/MidiSystem.java Wed Jul 05 17:32:27 2017 +0200 @@ -310,7 +310,7 @@ } else { transmitter = device.getTransmitter(); } - if (!(transmitter instanceof MidiDeviceReceiver)) { + if (!(transmitter instanceof MidiDeviceTransmitter)) { transmitter = new MidiDeviceTransmitterEnvelope(device, transmitter); } return transmitter; diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/javax/swing/DefaultDesktopManager.java --- a/jdk/src/share/classes/javax/swing/DefaultDesktopManager.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/javax/swing/DefaultDesktopManager.java Wed Jul 05 17:32:27 2017 +0200 @@ -359,7 +359,22 @@ f.getWidth()-1, f.getHeight()-1); } g.drawRect( newX, newY, f.getWidth()-1, f.getHeight()-1); - currentLoc = new Point (newX, newY); + /* Work around for 6635462: XOR mode may cause a SurfaceLost on first use. + * Swing doesn't expect that its XOR drawRect did + * not complete, so believes that on re-entering at + * the next update location, that there is an XOR rect + * to draw out at "currentLoc". But in fact + * its now got a new clean surface without that rect, + * so drawing it "out" in fact draws it on, leaving garbage. + * So only update/set currentLoc if the draw completed. + */ + sun.java2d.SurfaceData sData = + ((sun.java2d.SunGraphics2D)g).getSurfaceData(); + + if (!sData.isSurfaceLost()) { + currentLoc = new Point (newX, newY); + } +; g.dispose(); } } else if (dragMode == FASTER_DRAG_MODE) { @@ -412,7 +427,14 @@ g.drawRect( currentBounds.x, currentBounds.y, currentBounds.width-1, currentBounds.height-1); } g.drawRect( newX, newY, newWidth-1, newHeight-1); - currentBounds = new Rectangle (newX, newY, newWidth, newHeight); + + // Work around for 6635462, see comment in dragFrame() + sun.java2d.SurfaceData sData = + ((sun.java2d.SunGraphics2D)g).getSurfaceData(); + if (!sData.isSurfaceLost()) { + currentBounds = new Rectangle (newX, newY, newWidth, newHeight); + } + g.setPaintMode(); g.dispose(); } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/javax/swing/JSlider.java --- a/jdk/src/share/classes/javax/swing/JSlider.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/javax/swing/JSlider.java Wed Jul 05 17:32:27 2017 +0200 @@ -40,7 +40,8 @@ /** * A component that lets the user graphically select a value by sliding - * a knob within a bounded interval. + * a knob within a bounded interval. The knob is always positioned + * at the points that match integer values within the specified interval. *

* The slider can show both * major tick marks, and minor tick marks between the major ones. The number of diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java Wed Jul 05 17:32:27 2017 +0200 @@ -908,6 +908,14 @@ int height = parent.getHeight(); Insets insets = parent.getInsets(); + + if (nextButton == null && previousButton == null) { + setBounds(editor, insets.left, insets.top, width - insets.left - insets.right, + height - insets.top - insets.bottom); + + return; + } + Dimension nextD = preferredSize(nextButton); Dimension previousD = preferredSize(previousButton); int buttonsWidth = Math.max(nextD.width, previousD.width); diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/awt/FontConfiguration.java --- a/jdk/src/share/classes/sun/awt/FontConfiguration.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/awt/FontConfiguration.java Wed Jul 05 17:32:27 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,10 +37,10 @@ import java.nio.charset.CharsetEncoder; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; -import java.util.Iterator; import java.util.Locale; import java.util.Map.Entry; import java.util.Properties; @@ -329,6 +329,8 @@ * tables. */ public static void saveBinary(OutputStream out) throws IOException { + sanityCheck(); + DataOutputStream dataOut = new DataOutputStream(out); writeShortTable(dataOut, head); writeShortTable(dataOut, table_scriptIDs); @@ -350,7 +352,6 @@ if (verbose) { dump(); } - sanityCheck(); } //private static boolean loadingProperties; @@ -1343,6 +1344,11 @@ private static short[] table_stringIDs; private static char[] table_stringTable; + /** + * Checks consistencies of complied fontconfig data. This method + * is called only at the build-time from + * build.tools.compilefontconfig.CompileFontConfig. + */ private static void sanityCheck() { int errors = 0; @@ -1358,12 +1364,20 @@ //componentFontNameID starts from "1" for (int ii = 1; ii < table_filenames.length; ii++) { if (table_filenames[ii] == -1) { - System.out.println("\n Warning: " - + " entry is missing!!!"); - if (!osName.contains("Linux")) { + // The corresponding finename entry for a component + // font name is mandatory on Windows, but it's + // optional on Solaris and Linux. + if (osName.contains("Windows")) { + System.err.println("\n Error: entry is missing!!!"); errors++; + } else { + if (verbose && !isEmpty(table_filenames)) { + System.err.println("\n Note: 'filename' entry is undefined for \"" + + getString(table_componentFontNameIDs[ii]) + + "\""); + } } } } @@ -1382,7 +1396,7 @@ int jj = iii * NUM_STYLES + iij; short ffid = table_scriptFonts[fid + jj]; if (ffid == 0) { - System.out.println("\n Error: <" + System.err.println("\n Error: <" + getFontName(iii) + "." + getStyleName(iij) + "." + getString(table_scriptIDs[ii]) @@ -1402,7 +1416,7 @@ script.contains("symbol")) { continue; } - System.out.println("\nError: " + System.err.println("\nError: " + " entry is missing!!!"); @@ -1411,11 +1425,19 @@ } } if (errors != 0) { - System.out.println("!!THERE ARE " + errors + " ERROR(S) IN " + System.err.println("!!THERE ARE " + errors + " ERROR(S) IN " + "THE FONTCONFIG FILE, PLEASE CHECK ITS CONTENT!!\n"); System.exit(1); + } + } + private static boolean isEmpty(short[] a) { + for (short s : a) { + if (s != -1) { + return false; + } } + return true; } //dump the fontconfig data tables @@ -1652,20 +1674,16 @@ private static void writeShortTable(DataOutputStream out, short[] data) throws IOException { - for (int i = 0; i < data.length; i++) { - out.writeShort(data[i]); + for (short val : data) { + out.writeShort(val); } } - private static short[] toList(HashMap map) { + private static short[] toList(HashMap map) { short[] list = new short[map.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = -1; - } - Iterator iterator = map.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); - list[entry.getValue().shortValue()] = getStringID(entry.getKey()); + Arrays.fill(list, (short) -1); + for (Entry entry : map.entrySet()) { + list[entry.getValue()] = getStringID(entry.getKey()); } return list; } @@ -1763,25 +1781,19 @@ int len = table_scriptIDs.length + scriptFonts.size() * 20; table_scriptFonts = new short[len]; - Iterator iterator = scriptAllfonts.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); - table_scriptFonts[entry.getKey().intValue()] = (short)entry.getValue().shortValue(); + for (Entry entry : scriptAllfonts.entrySet()) { + table_scriptFonts[entry.getKey().intValue()] = entry.getValue(); } int off = table_scriptIDs.length; - iterator = scriptFonts.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); + for (Entry entry : scriptFonts.entrySet()) { table_scriptFonts[entry.getKey().intValue()] = (short)-off; Short[] v = entry.getValue(); - int i = 0; - while (i < 20) { + for (int i = 0; i < 20; i++) { if (v[i] != null) { - table_scriptFonts[off++] = v[i].shortValue(); + table_scriptFonts[off++] = v[i]; } else { table_scriptFonts[off++] = 0; } - i++; } } @@ -1792,9 +1804,7 @@ //(3) sequences elcID -> XXXX[1|5] -> scriptID[] head[INDEX_sequences] = (short)(head[INDEX_elcIDs] + table_elcIDs.length); table_sequences = new short[elcIDs.size() * NUM_FONTS]; - iterator = sequences.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); + for (Entry entry : sequences.entrySet()) { //table_sequences[entry.getKey().intValue()] = (short)-off; int k = entry.getKey().intValue(); short[] v = entry.getValue(); @@ -1827,31 +1837,24 @@ //(6)componentFontNameID -> filenameID head[INDEX_filenames] = (short)(head[INDEX_componentFontNameIDs] + table_componentFontNameIDs.length); table_filenames = new short[table_componentFontNameIDs.length]; - for (int i = 0; i < table_filenames.length; i++) { - table_filenames[i] = -1; - } - iterator = filenames.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); - table_filenames[entry.getKey().shortValue()] = entry.getValue().shortValue(); + Arrays.fill(table_filenames, (short) -1); + + for (Entry entry : filenames.entrySet()) { + table_filenames[entry.getKey()] = entry.getValue(); } //(7)scriptID-> awtfontpath //the paths are stored as scriptID -> stringID in awtfontpahts head[INDEX_awtfontpaths] = (short)(head[INDEX_filenames] + table_filenames.length); table_awtfontpaths = new short[table_scriptIDs.length]; - iterator = awtfontpaths.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); - table_awtfontpaths[entry.getKey().shortValue()] = entry.getValue().shortValue(); + for (Entry entry : awtfontpaths.entrySet()) { + table_awtfontpaths[entry.getKey()] = entry.getValue(); } //(8)exclusions head[INDEX_exclusions] = (short)(head[INDEX_awtfontpaths] + table_awtfontpaths.length); table_exclusions = new short[scriptIDs.size()]; - iterator = exclusions.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); + for (Entry entry : exclusions.entrySet()) { int[] exI = entry.getValue(); char[] exC = new char[exI.length * 2]; int j = 0; @@ -1859,17 +1862,15 @@ exC[j++] = (char) (exI[i] >> 16); exC[j++] = (char) (exI[i] & 0xffff); } - table_exclusions[entry.getKey().shortValue()] = getStringID(new String (exC)); + table_exclusions[entry.getKey()] = getStringID(new String (exC)); } //(9)proportionals head[INDEX_proportionals] = (short)(head[INDEX_exclusions] + table_exclusions.length); table_proportionals = new short[proportionals.size() * 2]; - iterator = proportionals.entrySet().iterator(); int j = 0; - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); - table_proportionals[j++] = entry.getKey().shortValue(); - table_proportionals[j++] = entry.getValue().shortValue(); + for (Entry entry : proportionals.entrySet()) { + table_proportionals[j++] = entry.getKey(); + table_proportionals[j++] = entry.getValue(); } //(10) see (1) for info, the only difference is "xxx.motif" @@ -1878,22 +1879,18 @@ len = table_scriptIDs.length + scriptFontsMotif.size() * 20; table_scriptFontsMotif = new short[len]; - iterator = scriptAllfontsMotif.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); + for (Entry entry : scriptAllfontsMotif.entrySet()) { table_scriptFontsMotif[entry.getKey().intValue()] = - (short)entry.getValue().shortValue(); + (short)entry.getValue(); } off = table_scriptIDs.length; - iterator = scriptFontsMotif.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); + for (Entry entry : scriptFontsMotif.entrySet()) { table_scriptFontsMotif[entry.getKey().intValue()] = (short)-off; Short[] v = entry.getValue(); int i = 0; while (i < 20) { if (v[i] != null) { - table_scriptFontsMotif[off++] = v[i].shortValue(); + table_scriptFontsMotif[off++] = v[i]; } else { table_scriptFontsMotif[off++] = 0; } @@ -1907,12 +1904,10 @@ //(11)short[] alphabeticSuffix head[INDEX_alphabeticSuffix] = (short)(head[INDEX_scriptFontsMotif] + table_scriptFontsMotif.length); table_alphabeticSuffix = new short[alphabeticSuffix.size() * 2]; - iterator = alphabeticSuffix.entrySet().iterator(); j = 0; - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); - table_alphabeticSuffix[j++] = entry.getKey().shortValue(); - table_alphabeticSuffix[j++] = entry.getValue().shortValue(); + for (Entry entry : alphabeticSuffix.entrySet()) { + table_alphabeticSuffix[j++] = entry.getKey(); + table_alphabeticSuffix[j++] = entry.getValue(); } //(15)short[] fallbackScriptIDs; just put the ID in head diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/awt/SunToolkit.java --- a/jdk/src/share/classes/sun/awt/SunToolkit.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/awt/SunToolkit.java Wed Jul 05 17:32:27 2017 +0200 @@ -102,26 +102,6 @@ public final static int MAX_BUTTONS_SUPPORTED = 20; public SunToolkit() { - /* If awt.threadgroup is set to class name the instance of - * this class is created (should be subclass of ThreadGroup) - * and EventDispatchThread is created inside of it - * - * If loaded class overrides uncaughtException instance - * handles all uncaught exception on EventDispatchThread - */ - ThreadGroup threadGroup = null; - String tgName = System.getProperty("awt.threadgroup", ""); - - if (tgName.length() != 0) { - try { - Constructor ctor = Class.forName(tgName). - getConstructor(new Class[] {String.class}); - threadGroup = (ThreadGroup)ctor.newInstance(new Object[] {"AWT-ThreadGroup"}); - } catch (Exception e) { - System.err.println("Failed loading " + tgName + ": " + e); - } - } - Runnable initEQ = new Runnable() { public void run () { EventQueue eventQueue; @@ -144,17 +124,7 @@ } }; - if (threadGroup != null) { - Thread eqInitThread = new Thread(threadGroup, initEQ, "EventQueue-Init"); - eqInitThread.start(); - try { - eqInitThread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } else { - initEQ.run(); - } + initEQ.run(); } public boolean useBufferPerWindow() { diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/dc/DuctusRenderingEngine.java --- a/jdk/src/share/classes/sun/dc/DuctusRenderingEngine.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/dc/DuctusRenderingEngine.java Wed Jul 05 17:32:27 2017 +0200 @@ -635,6 +635,88 @@ return r; } + /** + * {@inheritDoc} + */ + @Override + public AATileGenerator getAATileGenerator(double x, double y, + double dx1, double dy1, + double dx2, double dy2, + double lw1, double lw2, + Region clip, + int bbox[]) + { + // REMIND: Deal with large coordinates! + double ldx1, ldy1, ldx2, ldy2; + boolean innerpgram = (lw1 > 0 && lw2 > 0); + + if (innerpgram) { + ldx1 = dx1 * lw1; + ldy1 = dy1 * lw1; + ldx2 = dx2 * lw2; + ldy2 = dy2 * lw2; + x -= (ldx1 + ldx2) / 2.0; + y -= (ldy1 + ldy2) / 2.0; + dx1 += ldx1; + dy1 += ldy1; + dx2 += ldx2; + dy2 += ldy2; + if (lw1 > 1 && lw2 > 1) { + // Inner parallelogram was entirely consumed by stroke... + innerpgram = false; + } + } else { + ldx1 = ldy1 = ldx2 = ldy2 = 0; + } + + Rasterizer r = getRasterizer(); + + r.setUsage(Rasterizer.EOFILL); + + r.beginPath(); + r.beginSubpath((float) x, (float) y); + r.appendLine((float) (x+dx1), (float) (y+dy1)); + r.appendLine((float) (x+dx1+dx2), (float) (y+dy1+dy2)); + r.appendLine((float) (x+dx2), (float) (y+dy2)); + r.closedSubpath(); + if (innerpgram) { + x += ldx1 + ldx2; + y += ldy1 + ldy2; + dx1 -= 2.0 * ldx1; + dy1 -= 2.0 * ldy1; + dx2 -= 2.0 * ldx2; + dy2 -= 2.0 * ldy2; + r.beginSubpath((float) x, (float) y); + r.appendLine((float) (x+dx1), (float) (y+dy1)); + r.appendLine((float) (x+dx1+dx2), (float) (y+dy1+dy2)); + r.appendLine((float) (x+dx2), (float) (y+dy2)); + r.closedSubpath(); + } + + try { + r.endPath(); + r.getAlphaBox(bbox); + clip.clipBoxToBounds(bbox); + if (bbox[0] >= bbox[2] || bbox[1] >= bbox[3]) { + dropRasterizer(r); + return null; + } + r.setOutputArea(bbox[0], bbox[1], + bbox[2] - bbox[0], + bbox[3] - bbox[1]); + } catch (PRException e) { + /* + * This exeption is thrown from the native part of the Ductus + * (only in case of a debug build) to indicate that some + * segments of the path have very large coordinates. + * See 4485298 for more info. + */ + System.err.println("DuctusRenderingEngine.getAATileGenerator: "+e); + } + + return r; + } + private void feedConsumer(PathConsumer consumer, PathIterator pi) { try { consumer.beginPath(); diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/font/FileFontStrike.java --- a/jdk/src/share/classes/sun/font/FileFontStrike.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/font/FileFontStrike.java Wed Jul 05 17:32:27 2017 +0200 @@ -58,10 +58,10 @@ private static final int SEGINTARRAY = 3; private static final int SEGLONGARRAY = 4; - private int glyphCacheFormat = UNINITIALISED; + private volatile int glyphCacheFormat = UNINITIALISED; - /* segmented arrays are blocks of 256 */ - private static final int SEGSHIFT = 8; + /* segmented arrays are blocks of 32 */ + private static final int SEGSHIFT = 5; private static final int SEGSIZE = 1 << SEGSHIFT; private boolean segmentedCache; @@ -171,7 +171,7 @@ mapper = fileFont.getMapper(); int numGlyphs = mapper.getNumGlyphs(); - /* Always segment for fonts with > 2K glyphs, but also for smaller + /* Always segment for fonts with > 256 glyphs, but also for smaller * fonts with non-typical sizes and transforms. * Segmenting for all non-typical pt sizes helps to minimise memory * usage when very many distinct strikes are created. @@ -522,32 +522,33 @@ } /* Called only from synchronized code or constructor */ - private void initGlyphCache() { + private synchronized void initGlyphCache() { int numGlyphs = mapper.getNumGlyphs(); - + int tmpFormat = UNINITIALISED; if (segmentedCache) { int numSegments = (numGlyphs + SEGSIZE-1)/SEGSIZE; if (longAddresses) { - glyphCacheFormat = SEGLONGARRAY; + tmpFormat = SEGLONGARRAY; segLongGlyphImages = new long[numSegments][]; this.disposer.segLongGlyphImages = segLongGlyphImages; } else { - glyphCacheFormat = SEGINTARRAY; + tmpFormat = SEGINTARRAY; segIntGlyphImages = new int[numSegments][]; this.disposer.segIntGlyphImages = segIntGlyphImages; } } else { if (longAddresses) { - glyphCacheFormat = LONGARRAY; + tmpFormat = LONGARRAY; longGlyphImages = new long[numGlyphs]; this.disposer.longGlyphImages = longGlyphImages; } else { - glyphCacheFormat = INTARRAY; + tmpFormat = INTARRAY; intGlyphImages = new int[numGlyphs]; this.disposer.intGlyphImages = intGlyphImages; } } + glyphCacheFormat = tmpFormat; } float getGlyphAdvance(int glyphCode) { diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/font/Font2D.java --- a/jdk/src/share/classes/sun/font/Font2D.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/font/Font2D.java Wed Jul 05 17:32:27 2017 +0200 @@ -343,7 +343,21 @@ } strike = createStrike(desc); //StrikeCache.addStrike(); - strikeRef = StrikeCache.getStrikeRef(strike); + /* If we are creating many strikes on this font which + * involve non-quadrant rotations, or more general + * transforms which include shears, then force the use + * of weak references rather than soft references. + * This means that it won't live much beyond the next GC, + * which is what we want for what is likely a transient strike. + */ + int txType = desc.glyphTx.getType(); + if (txType == AffineTransform.TYPE_GENERAL_TRANSFORM || + (txType & AffineTransform.TYPE_GENERAL_ROTATION) != 0 && + strikeCache.size() > 10) { + strikeRef = StrikeCache.getStrikeRef(strike, true); + } else { + strikeRef = StrikeCache.getStrikeRef(strike); + } strikeCache.put(desc, strikeRef); //strike.lastlookupTime = System.currentTimeMillis(); lastFontStrike = new SoftReference(strike); diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/io/Converters.java --- a/jdk/src/share/classes/sun/io/Converters.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/io/Converters.java Wed Jul 05 17:32:27 2017 +0200 @@ -120,7 +120,7 @@ private static Class cache(int type, Object encoding, Class c) { SoftReference[] srs = classCache[type]; - srs[CACHE_SIZE - 1] = new SoftReference(new Object[] { c, encoding }); + srs[CACHE_SIZE - 1] = new SoftReference<>(new Object[] { c, encoding }); moveToFront(srs, CACHE_SIZE - 1); return c; } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/java2d/SurfaceData.java --- a/jdk/src/share/classes/sun/java2d/SurfaceData.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/SurfaceData.java Wed Jul 05 17:32:27 2017 +0200 @@ -367,16 +367,17 @@ public static final TextPipe aaTextRenderer; public static final TextPipe lcdTextRenderer; - protected static final CompositePipe colorPipe; + protected static final AlphaColorPipe colorPipe; protected static final PixelToShapeConverter colorViaShape; protected static final PixelToParallelogramConverter colorViaPgram; protected static final TextPipe colorText; protected static final CompositePipe clipColorPipe; protected static final TextPipe clipColorText; protected static final AAShapePipe AAColorShape; - protected static final PixelToShapeConverter AAColorViaShape; + protected static final PixelToParallelogramConverter AAColorViaShape; + protected static final PixelToParallelogramConverter AAColorViaPgram; protected static final AAShapePipe AAClipColorShape; - protected static final PixelToShapeConverter AAClipColorViaShape; + protected static final PixelToParallelogramConverter AAClipColorViaShape; protected static final CompositePipe paintPipe; protected static final SpanShapeRenderer paintShape; @@ -385,9 +386,9 @@ protected static final CompositePipe clipPaintPipe; protected static final TextPipe clipPaintText; protected static final AAShapePipe AAPaintShape; - protected static final PixelToShapeConverter AAPaintViaShape; + protected static final PixelToParallelogramConverter AAPaintViaShape; protected static final AAShapePipe AAClipPaintShape; - protected static final PixelToShapeConverter AAClipPaintViaShape; + protected static final PixelToParallelogramConverter AAClipPaintViaShape; protected static final CompositePipe compPipe; protected static final SpanShapeRenderer compShape; @@ -396,9 +397,9 @@ protected static final CompositePipe clipCompPipe; protected static final TextPipe clipCompText; protected static final AAShapePipe AACompShape; - protected static final PixelToShapeConverter AACompViaShape; + protected static final PixelToParallelogramConverter AACompViaShape; protected static final AAShapePipe AAClipCompShape; - protected static final PixelToShapeConverter AAClipCompViaShape; + protected static final PixelToParallelogramConverter AAClipCompViaShape; protected static final DrawImagePipe imagepipe; @@ -427,6 +428,22 @@ } } + private static PixelToParallelogramConverter + makeConverter(AAShapePipe renderer, + ParallelogramPipe pgrampipe) + { + return new PixelToParallelogramConverter(renderer, + pgrampipe, + 1.0/8.0, 0.499, + false); + } + + private static PixelToParallelogramConverter + makeConverter(AAShapePipe renderer) + { + return makeConverter(renderer, renderer); + } + static { colorPrimitives = new LoopPipe(); @@ -445,9 +462,10 @@ clipColorPipe = new SpanClipRenderer(colorPipe); clipColorText = new TextRenderer(clipColorPipe); AAColorShape = new AAShapePipe(colorPipe); - AAColorViaShape = new PixelToShapeConverter(AAColorShape); + AAColorViaShape = makeConverter(AAColorShape); + AAColorViaPgram = makeConverter(AAColorShape, colorPipe); AAClipColorShape = new AAShapePipe(clipColorPipe); - AAClipColorViaShape = new PixelToShapeConverter(AAClipColorShape); + AAClipColorViaShape = makeConverter(AAClipColorShape); paintPipe = new AlphaPaintPipe(); paintShape = new SpanShapeRenderer.Composite(paintPipe); @@ -456,9 +474,9 @@ clipPaintPipe = new SpanClipRenderer(paintPipe); clipPaintText = new TextRenderer(clipPaintPipe); AAPaintShape = new AAShapePipe(paintPipe); - AAPaintViaShape = new PixelToShapeConverter(AAPaintShape); + AAPaintViaShape = makeConverter(AAPaintShape); AAClipPaintShape = new AAShapePipe(clipPaintPipe); - AAClipPaintViaShape = new PixelToShapeConverter(AAClipPaintShape); + AAClipPaintViaShape = makeConverter(AAClipPaintShape); compPipe = new GeneralCompositePipe(); compShape = new SpanShapeRenderer.Composite(compPipe); @@ -467,9 +485,9 @@ clipCompPipe = new SpanClipRenderer(compPipe); clipCompText = new TextRenderer(clipCompPipe); AACompShape = new AAShapePipe(compPipe); - AACompViaShape = new PixelToShapeConverter(AACompShape); + AACompViaShape = makeConverter(AACompShape); AAClipCompShape = new AAShapePipe(clipCompPipe); - AAClipCompViaShape = new PixelToShapeConverter(AAClipCompShape); + AAClipCompViaShape = makeConverter(AAClipCompShape); imagepipe = new DrawImage(); } @@ -591,12 +609,12 @@ if (sg2d.clipState == sg2d.CLIP_SHAPE) { sg2d.drawpipe = AAClipCompViaShape; sg2d.fillpipe = AAClipCompViaShape; - sg2d.shapepipe = AAClipCompShape; + sg2d.shapepipe = AAClipCompViaShape; sg2d.textpipe = clipCompText; } else { sg2d.drawpipe = AACompViaShape; sg2d.fillpipe = AACompViaShape; - sg2d.shapepipe = AACompShape; + sg2d.shapepipe = AACompViaShape; sg2d.textpipe = compText; } } else { @@ -616,13 +634,17 @@ if (sg2d.clipState == sg2d.CLIP_SHAPE) { sg2d.drawpipe = AAClipColorViaShape; sg2d.fillpipe = AAClipColorViaShape; - sg2d.shapepipe = AAClipColorShape; + sg2d.shapepipe = AAClipColorViaShape; sg2d.textpipe = clipColorText; } else { - sg2d.drawpipe = AAColorViaShape; - sg2d.fillpipe = AAColorViaShape; - sg2d.shapepipe = AAColorShape; - if (sg2d.paintState > sg2d.PAINT_OPAQUECOLOR || + PixelToParallelogramConverter converter = + (sg2d.alphafill.canDoParallelograms() + ? AAColorViaPgram + : AAColorViaShape); + sg2d.drawpipe = converter; + sg2d.fillpipe = converter; + sg2d.shapepipe = converter; + if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR || sg2d.compositeState > sg2d.COMP_ISCOPY) { sg2d.textpipe = colorText; @@ -634,12 +656,12 @@ if (sg2d.clipState == sg2d.CLIP_SHAPE) { sg2d.drawpipe = AAClipPaintViaShape; sg2d.fillpipe = AAClipPaintViaShape; - sg2d.shapepipe = AAClipPaintShape; + sg2d.shapepipe = AAClipPaintViaShape; sg2d.textpipe = clipPaintText; } else { sg2d.drawpipe = AAPaintViaShape; sg2d.fillpipe = AAPaintViaShape; - sg2d.shapepipe = AAPaintShape; + sg2d.shapepipe = AAPaintViaShape; sg2d.textpipe = paintText; } } @@ -793,6 +815,18 @@ } } + private static CompositeType getFillCompositeType(SunGraphics2D sg2d) { + CompositeType compType = sg2d.imageComp; + if (sg2d.compositeState == sg2d.COMP_ISCOPY) { + if (compType == CompositeType.SrcOverNoEa) { + compType = CompositeType.OpaqueSrcOverNoEa; + } else { + compType = CompositeType.SrcNoEa; + } + } + return compType; + } + /** * Returns a MaskFill object that can be used on this destination * with the source (paint) and composite types determined by the given @@ -802,9 +836,10 @@ * surface) before returning a specific MaskFill object. */ protected MaskFill getMaskFill(SunGraphics2D sg2d) { - return MaskFill.getFromCache(getPaintSurfaceType(sg2d), - sg2d.imageComp, - getSurfaceType()); + SurfaceType src = getPaintSurfaceType(sg2d); + CompositeType comp = getFillCompositeType(sg2d); + SurfaceType dst = getSurfaceType(); + return MaskFill.getFromCache(src, comp, dst); } private static RenderCache loopcache = new RenderCache(30); @@ -816,9 +851,7 @@ */ public RenderLoops getRenderLoops(SunGraphics2D sg2d) { SurfaceType src = getPaintSurfaceType(sg2d); - CompositeType comp = (sg2d.compositeState == sg2d.COMP_ISCOPY - ? CompositeType.SrcNoEa - : sg2d.imageComp); + CompositeType comp = getFillCompositeType(sg2d); SurfaceType dst = sg2d.getSurfaceData().getSurfaceType(); Object o = loopcache.get(src, comp, dst); diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/java2d/loops/CompositeType.java --- a/jdk/src/share/classes/sun/java2d/loops/CompositeType.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/loops/CompositeType.java Wed Jul 05 17:32:27 2017 +0200 @@ -27,6 +27,7 @@ import java.awt.image.BufferedImage; import java.awt.AlphaComposite; +import java.util.HashMap; /** * A CompositeType object provides a chained description of a type of @@ -51,6 +52,11 @@ * the indicated algorithm if all of the more specific searches fail. */ public final class CompositeType { + + private static int unusedUID = 1; + private static final HashMap compositeUIDMap = + new HashMap(100); + /* * CONSTANTS USED BY ALL PRIMITIVES TO DESCRIBE THE COMPOSITING * ALGORITHMS THEY CAN PERFORM @@ -153,6 +159,22 @@ SrcOverNoEa = SrcOver.deriveSubType(DESC_SRC_OVER_NO_EA); /* + * A special CompositeType for the case where we are filling in + * SrcOverNoEa mode with an opaque color. In that case then the + * best loop for us to use would be a SrcNoEa loop, but what if + * there is no such loop? In that case then we would end up + * backing off to a Src loop (which should still be fine) or an + * AnyAlpha loop which would be slower than a SrcOver loop in + * most cases. + * The fix is to use the following chain which looks for loops + * in the following order: + * SrcNoEa, Src, SrcOverNoEa, SrcOver, AnyAlpha + */ + public static final CompositeType + OpaqueSrcOverNoEa = SrcOverNoEa.deriveSubType(DESC_SRC) + .deriveSubType(DESC_SRC_NO_EA); + + /* * END OF CompositeType OBJECTS FOR THE VARIOUS CONSTANTS */ @@ -210,7 +232,6 @@ } } - private static int unusedUID = 1; private int uniqueID; private String desc; private CompositeType next; @@ -218,14 +239,20 @@ private CompositeType(CompositeType parent, String desc) { next = parent; this.desc = desc; - this.uniqueID = makeUniqueID(); + this.uniqueID = makeUniqueID(desc); } - private synchronized static final int makeUniqueID() { - if (unusedUID > 255) { - throw new InternalError("composite type id overflow"); + public synchronized static final int makeUniqueID(String desc) { + Integer i = compositeUIDMap.get(desc); + + if (i == null) { + if (unusedUID > 255) { + throw new InternalError("composite type id overflow"); + } + i = unusedUID++; + compositeUIDMap.put(desc, i); } - return unusedUID++; + return i; } public int getUniqueID() { diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/java2d/loops/MaskFill.java --- a/jdk/src/share/classes/sun/java2d/loops/MaskFill.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/loops/MaskFill.java Wed Jul 05 17:32:27 2017 +0200 @@ -50,6 +50,10 @@ public class MaskFill extends GraphicsPrimitive { public static final String methodSignature = "MaskFill(...)".toString(); + public static final String fillPgramSignature = + "FillAAPgram(...)".toString(); + public static final String drawPgramSignature = + "DrawAAPgram(...)".toString(); public static final int primTypeID = makePrimTypeID(); @@ -92,6 +96,14 @@ return fill; } + protected MaskFill(String alternateSignature, + SurfaceType srctype, + CompositeType comptype, + SurfaceType dsttype) + { + super(alternateSignature, primTypeID, srctype, comptype, dsttype); + } + protected MaskFill(SurfaceType srctype, CompositeType comptype, SurfaceType dsttype) @@ -115,6 +127,23 @@ int x, int y, int w, int h, byte[] mask, int maskoff, int maskscan); + public native void FillAAPgram(SunGraphics2D sg2d, SurfaceData sData, + Composite comp, + double x, double y, + double dx1, double dy1, + double dx2, double dy2); + + public native void DrawAAPgram(SunGraphics2D sg2d, SurfaceData sData, + Composite comp, + double x, double y, + double dx1, double dy1, + double dx2, double dy2, + double lw1, double lw2); + + public boolean canDoParallelograms() { + return (getNativePrim() != 0); + } + static { GraphicsPrimitiveMgr.registerGeneral(new MaskFill(null, null, null)); } @@ -182,12 +211,22 @@ private static class TraceMaskFill extends MaskFill { MaskFill target; + MaskFill fillPgramTarget; + MaskFill drawPgramTarget; public TraceMaskFill(MaskFill target) { super(target.getSourceType(), target.getCompositeType(), target.getDestType()); this.target = target; + this.fillPgramTarget = new MaskFill(fillPgramSignature, + target.getSourceType(), + target.getCompositeType(), + target.getDestType()); + this.drawPgramTarget = new MaskFill(drawPgramSignature, + target.getSourceType(), + target.getCompositeType(), + target.getDestType()); } public GraphicsPrimitive traceWrap() { @@ -203,5 +242,32 @@ target.MaskFill(sg2d, sData, comp, x, y, w, h, mask, maskoff, maskscan); } + + public void FillAAPgram(SunGraphics2D sg2d, SurfaceData sData, + Composite comp, + double x, double y, + double dx1, double dy1, + double dx2, double dy2) + { + tracePrimitive(fillPgramTarget); + target.FillAAPgram(sg2d, sData, comp, + x, y, dx1, dy1, dx2, dy2); + } + + public void DrawAAPgram(SunGraphics2D sg2d, SurfaceData sData, + Composite comp, + double x, double y, + double dx1, double dy1, + double dx2, double dy2, + double lw1, double lw2) + { + tracePrimitive(drawPgramTarget); + target.DrawAAPgram(sg2d, sData, comp, + x, y, dx1, dy1, dx2, dy2, lw1, lw2); + } + + public boolean canDoParallelograms() { + return target.canDoParallelograms(); + } } } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/java2d/pipe/AAShapePipe.java --- a/jdk/src/share/classes/sun/java2d/pipe/AAShapePipe.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/pipe/AAShapePipe.java Wed Jul 05 17:32:27 2017 +0200 @@ -28,6 +28,7 @@ import java.awt.BasicStroke; import java.awt.Rectangle; import java.awt.Shape; +import java.awt.geom.Rectangle2D; import java.awt.geom.PathIterator; import sun.awt.SunHints; import sun.java2d.SunGraphics2D; @@ -39,7 +40,9 @@ * This class sets up the Generator and computes the alpha tiles * and then passes them on to a CompositePipe object for painting. */ -public class AAShapePipe implements ShapeDrawPipe { +public class AAShapePipe + implements ShapeDrawPipe, ParallelogramPipe +{ static RenderingEngine renderengine = RenderingEngine.getInstance(); CompositePipe outpipe; @@ -65,6 +68,59 @@ renderPath(sg, s, null); } + private static Rectangle2D computeBBox(double x, double y, + double dx1, double dy1, + double dx2, double dy2) + { + double lox, loy, hix, hiy; + lox = hix = x; + loy = hiy = y; + if (dx1 < 0) { lox += dx1; } else { hix += dx1; } + if (dy1 < 0) { loy += dy1; } else { hiy += dy1; } + if (dx2 < 0) { lox += dx2; } else { hix += dx2; } + if (dy2 < 0) { loy += dy2; } else { hiy += dy2; } + return new Rectangle2D.Double(lox, loy, hix-lox, hiy-loy); + } + + public void fillParallelogram(SunGraphics2D sg, + double x, double y, + double dx1, double dy1, + double dx2, double dy2) + { + Region clip = sg.getCompClip(); + int abox[] = new int[4]; + AATileGenerator aatg = + renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, 0, 0, + clip, abox); + if (aatg == null) { + // Nothing to render + return; + } + + renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox); + } + + public void drawParallelogram(SunGraphics2D sg, + double x, double y, + double dx1, double dy1, + double dx2, double dy2, + double lw1, double lw2) + { + Region clip = sg.getCompClip(); + int abox[] = new int[4]; + AATileGenerator aatg = + renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, 0, 0, + clip, abox); + if (aatg == null) { + // Nothing to render + return; + } + + // Note that bbox is of the original shape, not the wide path. + // This is appropriate for handing to Paint methods... + renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox); + } + private static byte[] theTile; public synchronized static byte[] getAlphaTile(int len) { @@ -85,8 +141,6 @@ boolean adjust = (bs != null && sg.strokeHint != SunHints.INTVAL_STROKE_PURE); boolean thin = (sg.strokeState <= sg.STROKE_THINDASHED); - Object context = null; - byte alpha[] = null; Region clip = sg.getCompClip(); int abox[] = new int[4]; @@ -98,6 +152,14 @@ return; } + renderTiles(sg, s, aatg, abox); + } + + public void renderTiles(SunGraphics2D sg, Shape s, + AATileGenerator aatg, int abox[]) + { + Object context = null; + byte alpha[] = null; try { context = outpipe.startSequence(sg, s, new Rectangle(abox[0], abox[1], diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/java2d/pipe/AlphaColorPipe.java --- a/jdk/src/share/classes/sun/java2d/pipe/AlphaColorPipe.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/pipe/AlphaColorPipe.java Wed Jul 05 17:32:27 2017 +0200 @@ -34,7 +34,7 @@ * into a destination that supports direct alpha compositing of a solid * color, according to one of the rules in the AlphaComposite class. */ -public class AlphaColorPipe implements CompositePipe { +public class AlphaColorPipe implements CompositePipe, ParallelogramPipe { public AlphaColorPipe() { } @@ -64,4 +64,23 @@ public void endSequence(Object context) { return; } + + public void fillParallelogram(SunGraphics2D sg, + double x, double y, + double dx1, double dy1, + double dx2, double dy2) + { + sg.alphafill.FillAAPgram(sg, sg.getSurfaceData(), sg.composite, + x, y, dx1, dy1, dx2, dy2); + } + + public void drawParallelogram(SunGraphics2D sg, + double x, double y, + double dx1, double dy1, + double dx2, double dy2, + double lw1, double lw2) + { + sg.alphafill.DrawAAPgram(sg, sg.getSurfaceData(), sg.composite, + x, y, dx1, dy1, dx2, dy2, lw1, lw2); + } } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/java2d/pipe/RenderingEngine.java --- a/jdk/src/share/classes/sun/java2d/pipe/RenderingEngine.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/pipe/RenderingEngine.java Wed Jul 05 17:32:27 2017 +0200 @@ -281,6 +281,72 @@ int bbox[]); /** + * Construct an antialiased tile generator for the given parallelogram + * store the bounds of the tile iteration in the bbox parameter. + * The parallelogram is specified as a starting point and 2 delta + * vectors that indicate the slopes of the 2 pairs of sides of the + * parallelogram. + * The 4 corners of the parallelogram are defined by the 4 points: + *

    + *
  • {@code x}, {@code y} + *
  • {@code x+dx1}, {@code y+dy1} + *
  • {@code x+dx1+dx2}, {@code y+dy1+dy2} + *
  • {@code x+dx2}, {@code y+dy2} + *
+ * The {@code lw1} and {@code lw2} parameters provide a specification + * for an optionally stroked parallelogram if they are positive numbers. + * The {@code lw1} parameter is the ratio of the length of the {@code dx1}, + * {@code dx2} delta vector to half of the line width in that same + * direction. + * The {@code lw2} parameter provides the same ratio for the other delta + * vector. + * If {@code lw1} and {@code lw2} are both greater than zero, then + * the parallelogram figure is doubled by both expanding and contracting + * each delta vector by its corresponding {@code lw} value. + * If either (@code lw1) or {@code lw2} are also greater than 1, then + * the inner (contracted) parallelogram disappears and the figure is + * simply a single expanded parallelogram. + * The {@code clip} parameter specifies the current clip in effect + * in device coordinates and can be used to prune the data for the + * operation, but the renderer is not required to perform any + * clipping. + *

+ * Upon returning, this method will fill the {@code bbox} parameter + * with 4 values indicating the bounds of the iteration of the + * tile generator. + * The iteration order of the tiles will be as specified by the + * pseudo-code: + *

+     *     for (y = bbox[1]; y < bbox[3]; y += tileheight) {
+     *         for (x = bbox[0]; x < bbox[2]; x += tilewidth) {
+     *         }
+     *     }
+     * 
+ * If there is no output to be rendered, this method may return + * null. + * + * @param x the X coordinate of the first corner of the parallelogram + * @param y the Y coordinate of the first corner of the parallelogram + * @param dx1 the X coordinate delta of the first leg of the parallelogram + * @param dy1 the Y coordinate delta of the first leg of the parallelogram + * @param dx2 the X coordinate delta of the second leg of the parallelogram + * @param dy2 the Y coordinate delta of the second leg of the parallelogram + * @param lw1 the line width ratio for the first leg of the parallelogram + * @param lw2 the line width ratio for the second leg of the parallelogram + * @param clip the current clip in effect in device coordinates + * @param bbox returns the bounds of the iteration + * @return the {@code AATileGenerator} instance to be consulted + * for tile coverages, or null if there is no output to render + * @since 1.7 + */ + public abstract AATileGenerator getAATileGenerator(double x, double y, + double dx1, double dy1, + double dx2, double dy2, + double lw1, double lw2, + Region clip, + int bbox[]); + + /** * Returns the minimum pen width that the antialiasing rasterizer * can represent without dropouts occuring. * @since 1.7 @@ -393,5 +459,24 @@ bs, thin, normalize, bbox); } + public AATileGenerator getAATileGenerator(double x, double y, + double dx1, double dy1, + double dx2, double dy2, + double lw1, double lw2, + Region clip, + int bbox[]) + { + System.out.println(name+".getAATileGenerator("+ + x+", "+y+", "+ + dx1+", "+dy1+", "+ + dx2+", "+dy2+", "+ + lw1+", "+lw2+", "+ + clip+")"); + return target.getAATileGenerator(x, y, + dx1, dy1, + dx2, dy2, + lw1, lw2, + clip, bbox); + } } } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java --- a/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java Wed Jul 05 17:32:27 2017 +0200 @@ -557,6 +557,69 @@ return ptg; } + public AATileGenerator getAATileGenerator(double x, double y, + double dx1, double dy1, + double dx2, double dy2, + double lw1, double lw2, + Region clip, + int bbox[]) + { + // REMIND: Deal with large coordinates! + double ldx1, ldy1, ldx2, ldy2; + boolean innerpgram = (lw1 > 0 && lw2 > 0); + + if (innerpgram) { + ldx1 = dx1 * lw1; + ldy1 = dy1 * lw1; + ldx2 = dx2 * lw2; + ldy2 = dy2 * lw2; + x -= (ldx1 + ldx2) / 2.0; + y -= (ldy1 + ldy2) / 2.0; + dx1 += ldx1; + dy1 += ldy1; + dx2 += ldx2; + dy2 += ldy2; + if (lw1 > 1 && lw2 > 1) { + // Inner parallelogram was entirely consumed by stroke... + innerpgram = false; + } + } else { + ldx1 = ldy1 = ldx2 = ldy2 = 0; + } + + Renderer r = new Renderer(3, 3, + clip.getLoX(), clip.getLoY(), + clip.getWidth(), clip.getHeight(), + PathIterator.WIND_EVEN_ODD); + + r.moveTo((float) x, (float) y); + r.lineTo((float) (x+dx1), (float) (y+dy1)); + r.lineTo((float) (x+dx1+dx2), (float) (y+dy1+dy2)); + r.lineTo((float) (x+dx2), (float) (y+dy2)); + r.closePath(); + + if (innerpgram) { + x += ldx1 + ldx2; + y += ldy1 + ldy2; + dx1 -= 2.0 * ldx1; + dy1 -= 2.0 * ldy1; + dx2 -= 2.0 * ldx2; + dy2 -= 2.0 * ldy2; + r.moveTo((float) x, (float) y); + r.lineTo((float) (x+dx1), (float) (y+dy1)); + r.lineTo((float) (x+dx1+dx2), (float) (y+dy1+dy2)); + r.lineTo((float) (x+dx2), (float) (y+dy2)); + r.closePath(); + } + + r.pathDone(); + + r.endRendering(); + PiscesTileGenerator ptg = new PiscesTileGenerator(r, r.MAX_AA_ALPHA); + ptg.getBbox(bbox); + return ptg; + } + /** * Returns the minimum pen width that the antialiasing rasterizer * can represent without dropouts occuring. diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/launcher/LauncherHelper.java --- a/jdk/src/share/classes/sun/launcher/LauncherHelper.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/launcher/LauncherHelper.java Wed Jul 05 17:32:27 2017 +0200 @@ -45,15 +45,18 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.math.BigDecimal; -import java.math.MathContext; import java.math.RoundingMode; import java.util.ResourceBundle; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Locale.Category; import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; @@ -73,11 +76,6 @@ private static final String PROP_SETTINGS = "Property settings:"; private static final String LOCALE_SETTINGS = "Locale settings:"; - private static final long K = 1024; - private static final long M = K * K; - private static final long G = M * K; - private static final long T = G * K; - private static synchronized ResourceBundle getLauncherResourceBundle() { if (javarb == null) { javarb = ResourceBundle.getBundle(defaultBundleName); @@ -96,14 +94,20 @@ * optionFlag: specifies which options to print default is all other * possible values are vm, properties, locale. * + * initialHeapSize: in bytes, as set by the launcher, a zero-value indicates + * this code should determine this value, using a suitable method or + * the line could be omitted. + * * maxHeapSize: in bytes, as set by the launcher, a zero-value indicates * this code should determine this value, using a suitable method. * * stackSize: in bytes, as set by the launcher, a zero-value indicates - * this code determine this value, using a suitable method. + * this code determine this value, using a suitable method or omit the + * line entirely. */ static void showSettings(boolean printToStderr, String optionFlag, - long maxHeapSize, long stackSize, boolean isServer) { + long initialHeapSize, long maxHeapSize, long stackSize, + boolean isServer) { PrintStream ostream = (printToStderr) ? System.err : System.out; String opts[] = optionFlag.split(":"); @@ -112,7 +116,8 @@ : "all"; switch (optStr) { case "vm": - printVmSettings(ostream, maxHeapSize, stackSize, isServer); + printVmSettings(ostream, initialHeapSize, maxHeapSize, + stackSize, isServer); break; case "properties": printProperties(ostream); @@ -121,7 +126,8 @@ printLocale(ostream); break; default: - printVmSettings(ostream, maxHeapSize, stackSize, isServer); + printVmSettings(ostream, initialHeapSize, maxHeapSize, + stackSize, isServer); printProperties(ostream); printLocale(ostream); break; @@ -131,18 +137,25 @@ /* * prints the main vm settings subopt/section */ - private static void printVmSettings(PrintStream ostream, long maxHeapSize, + private static void printVmSettings(PrintStream ostream, + long initialHeapSize, long maxHeapSize, long stackSize, boolean isServer) { ostream.println(VM_SETTINGS); if (stackSize != 0L) { - ostream.println(INDENT + "Stack Size: " + scaleValue(stackSize)); + ostream.println(INDENT + "Stack Size: " + + SizePrefix.scaleValue(stackSize)); + } + if (initialHeapSize != 0L) { + ostream.println(INDENT + "Min. Heap Size: " + + SizePrefix.scaleValue(initialHeapSize)); } if (maxHeapSize != 0L) { - ostream.println(INDENT + "Max. Heap Size: " + scaleValue(maxHeapSize)); + ostream.println(INDENT + "Max. Heap Size: " + + SizePrefix.scaleValue(maxHeapSize)); } else { ostream.println(INDENT + "Max. Heap Size (Estimated): " - + scaleValue(Runtime.getRuntime().maxMemory())); + + SizePrefix.scaleValue(Runtime.getRuntime().maxMemory())); } ostream.println(INDENT + "Ergonomics Machine Class: " + ((isServer) ? "server" : "client")); @@ -152,28 +165,6 @@ } /* - * scale the incoming values to a human readable form, represented as - * K, M, G and T, see java.c parse_size for the scaled values and - * suffixes. - */ - - private static String scaleValue(double v) { - MathContext mc2 = new MathContext(3, RoundingMode.HALF_EVEN); - - if (v >= K && v < M) { - return (new BigDecimal(v / K, mc2)).toPlainString() + "K"; - } else if (v >= M && v < G) { - return (new BigDecimal(v / M, mc2)).toPlainString() + "M"; - } else if (v >= G && v < T) { - return (new BigDecimal(v / G, mc2)).toPlainString() + "G"; - } else if (v >= T) { - return (new BigDecimal(v / T, mc2)).toPlainString() + "T"; - } else { - return String.format("%.0f", v); - } - } - - /* * prints the properties subopt/section */ private static void printProperties(PrintStream ostream) { @@ -196,16 +187,17 @@ String key, String value) { ostream.print(INDENT + key + " = "); if (key.equals("line.separator")) { - byte[] bytes = value.getBytes(); - for (byte b : bytes) { + for (byte b : value.getBytes()) { switch (b) { case 0xd: - ostream.print("CR "); + ostream.print("\\r "); break; case 0xa: - ostream.print("LF "); + ostream.print("\\n "); break; default: + // print any bizzare line separators in hex, but really + // shouldn't happen. ostream.printf("0x%02X", b & 0xff); break; } @@ -217,15 +209,14 @@ ostream.println(value); return; } - // pretty print the path values as a list String[] values = value.split(System.getProperty("path.separator")); - int len = values.length; - for (int i = 0 ; i < len ; i++) { - if (i == 0) { // first line treated specially - ostream.println(values[i]); + boolean first = true; + for (String s : values) { + if (first) { // first line treated specially + ostream.println(s); + first = false; } else { // following lines prefix with indents - ostream.print(INDENT + INDENT); - ostream.println(values[i]); + ostream.println(INDENT + INDENT + s); } } } @@ -236,21 +227,35 @@ private static void printLocale(PrintStream ostream) { Locale locale = Locale.getDefault(); ostream.println(LOCALE_SETTINGS); - ostream.println(INDENT + "default locale = " + locale.getDisplayLanguage()); + ostream.println(INDENT + "default locale = " + + locale.getDisplayLanguage()); + ostream.println(INDENT + "default display locale = " + + Locale.getDefault(Category.DISPLAY).getDisplayName()); + ostream.println(INDENT + "default format locale = " + + Locale.getDefault(Category.FORMAT).getDisplayName()); printLocales(ostream); ostream.println(); } private static void printLocales(PrintStream ostream) { - Locale[] locales = Locale.getAvailableLocales(); - final int len = locales == null ? 0 : locales.length; + Locale[] tlocales = Locale.getAvailableLocales(); + final int len = tlocales == null ? 0 : tlocales.length; if (len < 1 ) { return; } + // Locale does not implement Comparable so we convert it to String + // and sort it for pretty printing. + Set sortedSet = new TreeSet<>(); + for (Locale l : tlocales) { + sortedSet.add(l.toString()); + } + ostream.print(INDENT + "available locales = "); - final int last = len - 1 ; - for (int i = 0; i < last ; i++) { - ostream.print(locales[i]); + Iterator iter = sortedSet.iterator(); + final int last = len - 1; + for (int i = 0 ; iter.hasNext() ; i++) { + String s = iter.next(); + ostream.print(s); if (i != last) { ostream.print(", "); } @@ -260,7 +265,42 @@ ostream.print(INDENT + INDENT); } } - ostream.println(locales[last]); + } + + private enum SizePrefix { + + KILO(1024, "K"), + MEGA(1024 * 1024, "M"), + GIGA(1024 * 1024 * 1024, "G"), + TERA(1024L * 1024L * 1024L * 1024L, "T"); + long size; + String abbrev; + + SizePrefix(long size, String abbrev) { + this.size = size; + this.abbrev = abbrev; + } + + private static String scale(long v, SizePrefix prefix) { + return BigDecimal.valueOf(v).divide(BigDecimal.valueOf(prefix.size), + 2, RoundingMode.HALF_EVEN).toPlainString() + prefix.abbrev; + } + /* + * scale the incoming values to a human readable form, represented as + * K, M, G and T, see java.c parse_size for the scaled values and + * suffixes. The lowest possible scaled value is Kilo. + */ + static String scaleValue(long v) { + if (v < MEGA.size) { + return scale(v, KILO); + } else if (v < GIGA.size) { + return scale(v, MEGA); + } else if (v < TERA.size) { + return scale(v, GIGA); + } else { + return scale(v, TERA); + } + } } /** diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/security/jgss/krb5/CipherHelper.java --- a/jdk/src/share/classes/sun/security/jgss/krb5/CipherHelper.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/security/jgss/krb5/CipherHelper.java Wed Jul 05 17:32:27 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -710,29 +710,21 @@ * where HMAC is on {16-byte confounder | plaintext | 16-byte token_header} * HMAC is not encrypted; it is appended at the end. */ - void encryptData(WrapToken_v2 token, byte[] confounder, byte[] tokenHeader, - byte[] plaintext, int start, int len, int key_usage, OutputStream os) - throws GSSException, IOException { + byte[] encryptData(WrapToken_v2 token, byte[] confounder, byte[] tokenHeader, + byte[] plaintext, int start, int len, int key_usage) + throws GSSException { - byte[] ctext = null; switch (etype) { - case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96: - ctext = aes128Encrypt(confounder, tokenHeader, - plaintext, start, len, key_usage); - break; - case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96: - ctext = aes256Encrypt(confounder, tokenHeader, - plaintext, start, len, key_usage); - break; - default: - throw new GSSException(GSSException.FAILURE, -1, - "Unsupported etype: " + etype); + case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96: + return aes128Encrypt(confounder, tokenHeader, + plaintext, start, len, key_usage); + case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96: + return aes256Encrypt(confounder, tokenHeader, + plaintext, start, len, key_usage); + default: + throw new GSSException(GSSException.FAILURE, -1, + "Unsupported etype: " + etype); } - - // Krb5Token.debug("EncryptedData = " + - // Krb5Token.getHexBytes(ctext) + "\n"); - // Write to stream - os.write(ctext); } void encryptData(WrapToken token, byte[] confounder, byte[] plaintext, diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java --- a/jdk/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java Wed Jul 05 17:32:27 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,42 +26,40 @@ package sun.security.jgss.krb5; import org.ietf.jgss.*; -import sun.security.jgss.*; -import sun.security.krb5.*; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.io.ByteArrayInputStream; -import java.security.GeneralSecurityException; +import java.io.ByteArrayOutputStream; import java.security.MessageDigest; +import java.util.Arrays; /** * This class is a base class for new GSS token definitions, as defined - * in draft-ietf-krb-wg-gssapi-cfx-07.txt, that pertain to per-message - * GSS-API calls. Conceptually GSS-API has two types of per-message tokens: - * WrapToken and MicToken. They differ in the respect that a WrapToken - * carries additional plaintext or ciphertext application data besides - * just the sequence number and checksum. This class encapsulates the - * commonality in the structure of the WrapToken and the MicToken. - * This structure can be represented as: + * in RFC 4121, that pertain to per-message GSS-API calls. Conceptually + * GSS-API has two types of per-message tokens: WrapToken and MicToken. + * They differ in the respect that a WrapToken carries additional plaintext + * or ciphertext application data besides just the sequence number and + * checksum. This class encapsulates the commonality in the structure of + * the WrapToken and the MicToken. This structure can be represented as: *

*

- *  Wrap Tokens
+ * Wrap Tokens
  *
  *     Octet no   Name        Description
  *    ---------------------------------------------------------------
  *      0..1     TOK_ID     Identification field.  Tokens emitted by
- *                          GSS_Wrap() contain the the hex value 05 04
- *                          expressed in big endian order in this field.
+ *                          GSS_Wrap() contain the hex value 05 04
+ *                          expressed in big-endian order in this field.
  *      2        Flags      Attributes field, as described in section
  *                          4.2.2.
  *      3        Filler     Contains the hex value FF.
- *      4..5     EC         Contains the "extra count" field, in big
+ *      4..5     EC         Contains the "extra count" field, in big-
  *                          endian order as described in section 4.2.3.
  *      6..7     RRC        Contains the "right rotation count" in big
  *                          endian order, as described in section 4.2.5.
  *      8..15    SND_SEQ    Sequence number field in clear text,
- *                          expressed in big endian order.
+ *                          expressed in big-endian order.
  *      16..last Data       Encrypted data for Wrap tokens with
  *                          confidentiality, or plaintext data followed
  *                          by the checksum for Wrap tokens without
@@ -73,67 +71,82 @@
  *     -----------------------------------------------------------------
  *      0..1     TOK_ID     Identification field.  Tokens emitted by
  *                          GSS_GetMIC() contain the hex value 04 04
- *                          expressed in big endian order in this field.
+ *                          expressed in big-endian order in this field.
  *      2        Flags      Attributes field, as described in section
  *                          4.2.2.
  *      3..7     Filler     Contains five octets of hex value FF.
  *      8..15    SND_SEQ    Sequence number field in clear text,
- *                          expressed in big endian order.
+ *                          expressed in big-endian order.
  *      16..last SGN_CKSUM  Checksum of the "to-be-signed" data and
  *                          octet 0..15, as described in section 4.2.4.
  *
  * 
*

+ * This class is the super class of WrapToken_v2 and MicToken_v2. The token's + * header (bytes[0..15]) and data (byte[16..]) are saved in tokenHeader and + * tokenData fields. Since there is no easy way to find out the exact length + * of a WrapToken_v2 token from any header info, in the case of reading from + * stream, we read all available() bytes into the token. + *

+ * All read actions are performed in this super class. On the write part, the + * super class only write the tokenHeader, and the content writing is inside + * child classes. * * @author Seema Malkani */ abstract class MessageToken_v2 extends Krb5Token { + protected static final int TOKEN_HEADER_SIZE = 16; private static final int TOKEN_ID_POS = 0; private static final int TOKEN_FLAG_POS = 2; private static final int TOKEN_EC_POS = 4; private static final int TOKEN_RRC_POS = 6; - // token header size - static final int TOKEN_HEADER_SIZE = 16; - - private int tokenId = 0; - private int seqNumber; - - // EC and RRC fields - private int ec = 0; - private int rrc = 0; - - private boolean confState = true; - private boolean initiator = true; + /** + * The size of the random confounder used in a WrapToken. + */ + protected static final int CONFOUNDER_SIZE = 16; - byte[] confounder = null; - byte[] checksum = null; - - private int key_usage = 0; - private byte[] seqNumberData = null; - - private MessageTokenHeader tokenHeader = null; - - /* cipher instance used by the corresponding GSSContext */ - CipherHelper cipherHelper = null; - - // draft-ietf-krb-wg-gssapi-cfx-07 + // RFC 4121, key usage values static final int KG_USAGE_ACCEPTOR_SEAL = 22; static final int KG_USAGE_ACCEPTOR_SIGN = 23; static final int KG_USAGE_INITIATOR_SEAL = 24; static final int KG_USAGE_INITIATOR_SIGN = 25; - // draft-ietf-krb-wg-gssapi-cfx-07 + // RFC 4121, Flags Field private static final int FLAG_SENDER_IS_ACCEPTOR = 1; private static final int FLAG_WRAP_CONFIDENTIAL = 2; private static final int FLAG_ACCEPTOR_SUBKEY = 4; private static final int FILLER = 0xff; + private MessageTokenHeader tokenHeader = null; + + // Common field + private int tokenId = 0; + private int seqNumber; + protected byte[] tokenData; // content of token, without the header + protected int tokenDataLen; + + // Key usage number for crypto action + private int key_usage = 0; + + // EC and RRC fields, WrapToken only + private int ec = 0; + private int rrc = 0; + + // Checksum. Always in MicToken, might be in WrapToken + byte[] checksum = null; + + // Context properties + private boolean confState = true; + private boolean initiator = true; + + /* cipher instance used by the corresponding GSSContext */ + CipherHelper cipherHelper = null; + /** - * Constructs a MessageToken from a byte array. If there are more bytes - * in the array than needed, the extra bytes are simply ignroed. + * Constructs a MessageToken from a byte array. * * @param tokenId the token id that should be contained in this token as * it is read. @@ -156,7 +169,9 @@ /** * Constructs a MessageToken from an InputStream. Bytes will be read on * demand and the thread might block if there are not enough bytes to - * complete the token. + * complete the token. Please note there is no accurate way to find out + * the size of a token, but we try our best to make sure there is + * enough bytes to construct one. * * @param tokenId the token id that should be contained in this token as * it is read. @@ -186,25 +201,58 @@ : KG_USAGE_ACCEPTOR_SIGN); } - // Read checksum - int tokenLen = is.available(); - byte[] data = new byte[tokenLen]; - readFully(is, data); - checksum = new byte[cipherHelper.getChecksumLength()]; - System.arraycopy(data, tokenLen-cipherHelper.getChecksumLength(), - checksum, 0, cipherHelper.getChecksumLength()); - // debug("\nLeaving MessageToken.Cons\n"); + int minSize = 0; // minimal size for token data + if (tokenId == Krb5Token.WRAP_ID_v2 && prop.getPrivacy()) { + minSize = CONFOUNDER_SIZE + + TOKEN_HEADER_SIZE + cipherHelper.getChecksumLength(); + } else { + minSize = cipherHelper.getChecksumLength(); + } - // validate EC for Wrap tokens without confidentiality - if (!prop.getPrivacy() && - (tokenId == Krb5Token.WRAP_ID_v2)) { - if (checksum.length != ec) { - throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1, - getTokenName(tokenId) + ":" + "EC incorrect!"); + // Read token data + if (tokenId == Krb5Token.MIC_ID_v2) { + // The only case we can precisely predict the token data length + tokenDataLen = minSize; + tokenData = new byte[minSize]; + readFully(is, tokenData); + } else { + tokenDataLen = is.available(); + if (tokenDataLen >= minSize) { // read in one shot + tokenData = new byte[tokenDataLen]; + readFully(is, tokenData); + } else { + byte[] tmp = new byte[minSize]; + readFully(is, tmp); + // Hope while blocked in the read above, more data would + // come and is.available() below contains the whole token. + int more = is.available(); + tokenDataLen = minSize + more; + tokenData = Arrays.copyOf(tmp, tokenDataLen); + readFully(is, tokenData, minSize, more); } } + if (tokenId == Krb5Token.WRAP_ID_v2) { + // Does non-confidential data needs a rotate? + rotate(); + } + if (tokenId == Krb5Token.MIC_ID_v2 || + (tokenId == Krb5Token.WRAP_ID_v2 && !prop.getPrivacy())) { + // Read checksum + int chkLen = cipherHelper.getChecksumLength(); + checksum = new byte[chkLen]; + System.arraycopy(tokenData, tokenDataLen-chkLen, + checksum, 0, chkLen); + + // validate EC for Wrap tokens without confidentiality + if (tokenId == Krb5Token.WRAP_ID_v2 && !prop.getPrivacy()) { + if (chkLen != ec) { + throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1, + getTokenName(tokenId) + ":" + "EC incorrect!"); + } + } + } } catch (IOException e) { throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1, getTokenName(tokenId) + ":" + e.getMessage()); @@ -263,8 +311,7 @@ prop.setPrivacy(false); } - // Create a new gss token header as defined in - // draft-ietf-krb-wg-gssapi-cfx-07 + // Create a new gss token header as defined in RFC 4121 tokenHeader = new MessageTokenHeader(tokenId, prop.getPrivacy(), true); // debug("\n\t Message Header = " + @@ -326,50 +373,21 @@ * Rotate bytes as per the "RRC" (Right Rotation Count) received. * Our implementation does not do any rotates when sending, only * when receiving, we rotate left as per the RRC count, to revert it. - * - * @return true if bytes are rotated */ - public boolean rotate_left(byte[] in_bytes, int tokenOffset, - byte[] out_bytes, int bufsize) { - - int offset = 0; - // debug("\nRotate left: (before rotation) in_bytes = [ " + - // getHexBytes(in_bytes, tokenOffset, bufsize) + "]"); - if (rrc > 0) { - if (bufsize == 0) { - return false; - } - rrc = rrc % (bufsize - TOKEN_HEADER_SIZE); - if (rrc == 0) { - return false; - } + private void rotate() { + if (rrc % tokenDataLen != 0) { + rrc = rrc % tokenDataLen; + byte[] newBytes = new byte[tokenDataLen]; - // if offset is not zero - if (tokenOffset > 0) { - offset += tokenOffset; - } - - // copy the header - System.arraycopy(in_bytes, offset, out_bytes, 0, TOKEN_HEADER_SIZE); - offset += TOKEN_HEADER_SIZE; + System.arraycopy(tokenData, rrc, newBytes, 0, tokenDataLen-rrc); + System.arraycopy(tokenData, 0, newBytes, tokenDataLen-rrc, rrc); - // copy rest of the bytes - System.arraycopy(in_bytes, offset+rrc, out_bytes, - TOKEN_HEADER_SIZE, bufsize-TOKEN_HEADER_SIZE-rrc); - - // copy the bytes specified by rrc count - System.arraycopy(in_bytes, offset, out_bytes, - bufsize-TOKEN_HEADER_SIZE-rrc, rrc); - - // debug("\nRotate left: (after rotation) out_bytes = [ " + - // getHexBytes(out_bytes, 0, bufsize) + "]"); - return true; + tokenData = newBytes; } - return false; } public final int getSequenceNumber() { - return (readBigEndian(seqNumberData, 0, 4)); + return seqNumber; } /** @@ -444,44 +462,25 @@ this.cipherHelper = context.getCipherHelper(null); // debug("In MessageToken.Cons"); - - // draft-ietf-krb-wg-gssapi-cfx-07 - this.tokenId = tokenId; } /** - * Encodes a GSSHeader and this token onto an OutputStream. + * Encodes a MessageTokenHeader onto an OutputStream. * * @param os the OutputStream to which this should be written - * @throws GSSException if an error occurs while writing to the OutputStream + * @throws IOException is an error occurs while writing to the OutputStream */ - public void encode(OutputStream os) throws IOException, GSSException { - // debug("Writing tokenHeader " + getHexBytes(tokenHeader.getBytes()); - // (16 bytes of token header that includes sequence Number) + protected void encodeHeader(OutputStream os) throws IOException { tokenHeader.encode(os); - // debug("Writing checksum: " + getHexBytes(checksum)); - if (tokenId == MIC_ID_v2) { - os.write(checksum); - } } /** - * Obtains the size of this token. Note that this excludes the size of - * the GSSHeader. - * @return token size + * Encodes a MessageToken_v2 onto an OutputStream. + * + * @param os the OutputStream to which this should be written + * @throws IOException is an error occurs while encoding the token */ - protected int getKrb5TokenSize() throws GSSException { - return getTokenSize(); - } - - protected final int getTokenSize() throws GSSException { - return (TOKEN_HEADER_SIZE + cipherHelper.getChecksumLength()); - } - - protected static final int getTokenSize(CipherHelper ch) - throws GSSException { - return (TOKEN_HEADER_SIZE + ch.getChecksumLength()); - } + public abstract void encode(OutputStream os) throws IOException; protected final byte[] getTokenHeader() { return (tokenHeader.getBytes()); @@ -493,45 +492,14 @@ /** * This inner class represents the initial portion of the message token. - * It constitutes the first 16 bytes of the message token: - *

-     *  Wrap Tokens
-     *
-     *     Octet no   Name        Description
-     *    ---------------------------------------------------------------
-     *      0..1     TOK_ID     Identification field.  Tokens emitted by
-     *                          GSS_Wrap() contain the the hex value 05 04
-     *                          expressed in big endian order in this field.
-     *      2        Flags      Attributes field, as described in section
-     *                          4.2.2.
-     *      3        Filler     Contains the hex value FF.
-     *      4..5     EC         Contains the "extra count" field, in big
-     *                          endian order as described in section 4.2.3.
-     *      6..7     RRC        Contains the "right rotation count" in big
-     *                          endian order, as described in section 4.2.5.
-     *      8..15    SND_SEQ    Sequence number field in clear text,
-     *                          expressed in big endian order.
-     *
-     * MIC Tokens
-     *
-     *     Octet no   Name        Description
-     *     -----------------------------------------------------------------
-     *      0..1     TOK_ID     Identification field.  Tokens emitted by
-     *                          GSS_GetMIC() contain the hex value 04 04
-     *                          expressed in big endian order in this field.
-     *      2        Flags      Attributes field, as described in section
-     *                          4.2.2.
-     *      3..7     Filler     Contains five octets of hex value FF.
-     *      8..15    SND_SEQ    Sequence number field in clear text,
-     *                          expressed in big endian order.
-     * 
+ * It constitutes the first 16 bytes of the message token. */ class MessageTokenHeader { private int tokenId; private byte[] bytes = new byte[TOKEN_HEADER_SIZE]; - // new token header draft-ietf-krb-wg-gssapi-cfx-07 + // Writes a new token header public MessageTokenHeader(int tokenId, boolean conf, boolean have_acceptor_subkey) throws GSSException { @@ -542,16 +510,15 @@ // Flags (Note: MIT impl requires subkey) int flags = 0; - flags = ((initiator ? 0 : FLAG_SENDER_IS_ACCEPTOR) | + flags = (initiator ? 0 : FLAG_SENDER_IS_ACCEPTOR) | ((conf && tokenId != MIC_ID_v2) ? FLAG_WRAP_CONFIDENTIAL : 0) | - (have_acceptor_subkey ? FLAG_ACCEPTOR_SUBKEY : 0)); + (have_acceptor_subkey ? FLAG_ACCEPTOR_SUBKEY : 0); bytes[2] = (byte) flags; // filler bytes[3] = (byte) FILLER; - // EC and RRC fields if (tokenId == WRAP_ID_v2) { // EC field bytes[4] = (byte) 0; @@ -560,21 +527,19 @@ bytes[6] = (byte) 0; bytes[7] = (byte) 0; } else if (tokenId == MIC_ID_v2) { - // octets of filler FF + // more filler for MicToken for (int i = 4; i < 8; i++) { bytes[i] = (byte) FILLER; } } - // Calculate SND_SEQ - seqNumberData = new byte[8]; - writeBigEndian(seqNumber, seqNumberData, 4); - System.arraycopy(seqNumberData, 0, bytes, 8, 8); + // Calculate SND_SEQ, only write 4 bytes from the 12th position + writeBigEndian(seqNumber, bytes, 12); } /** - * Constructs a MessageTokenHeader by reading it from an InputStream - * and sets the appropriate confidentiality and quality of protection + * Reads a MessageTokenHeader from an InputStream and sets the + * appropriate confidentiality and quality of protection * values in a MessageProp structure. * * @param is the InputStream to read from @@ -588,15 +553,23 @@ readFully(is, bytes, 0, TOKEN_HEADER_SIZE); tokenId = readInt(bytes, TOKEN_ID_POS); + // validate Token ID + if (tokenId != tokId) { + throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1, + getTokenName(tokenId) + ":" + "Defective Token ID!"); + } + /* * Validate new GSS TokenHeader */ - // valid acceptor_flag is set + + // valid acceptor_flag + // If I am initiator, the received token should have ACCEPTOR on int acceptor_flag = (initiator ? FLAG_SENDER_IS_ACCEPTOR : 0); int flag = bytes[TOKEN_FLAG_POS] & FLAG_SENDER_IS_ACCEPTOR; - if (!(flag == acceptor_flag)) { + if (flag != acceptor_flag) { throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1, - getTokenName(tokenId) + ":" + "Acceptor Flag Missing!"); + getTokenName(tokenId) + ":" + "Acceptor Flag Error!"); } // check for confidentiality @@ -608,21 +581,20 @@ prop.setPrivacy(false); } - // validate Token ID - if (tokenId != tokId) { - throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1, - getTokenName(tokenId) + ":" + "Defective Token ID!"); - } + if (tokenId == WRAP_ID_v2) { + // validate filler + if ((bytes[3] & 0xff) != FILLER) { + throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1, + getTokenName(tokenId) + ":" + "Defective Token Filler!"); + } - // validate filler - if ((bytes[3] & 0xff) != FILLER) { - throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1, - getTokenName(tokenId) + ":" + "Defective Token Filler!"); - } + // read EC field + ec = readBigEndian(bytes, TOKEN_EC_POS, 2); - // validate next 4 bytes of filler for MIC tokens - if (tokenId == MIC_ID_v2) { - for (int i = 4; i < 8; i++) { + // read RRC field + rrc = readBigEndian(bytes, TOKEN_RRC_POS, 2); + } else if (tokenId == MIC_ID_v2) { + for (int i = 3; i < 8; i++) { if ((bytes[i] & 0xff) != FILLER) { throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1, getTokenName(tokenId) + ":" + @@ -631,18 +603,11 @@ } } - // read EC field - ec = readBigEndian(bytes, TOKEN_EC_POS, 2); - - // read RRC field - rrc = readBigEndian(bytes, TOKEN_RRC_POS, 2); - // set default QOP prop.setQOP(0); // sequence number - seqNumberData = new byte[8]; - System.arraycopy(bytes, 8, seqNumberData, 0, 8); + seqNumber = readBigEndian(bytes, 0, 8); } /** diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/security/jgss/krb5/MicToken_v2.java --- a/jdk/src/share/classes/sun/security/jgss/krb5/MicToken_v2.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/security/jgss/krb5/MicToken_v2.java Wed Jul 05 17:32:27 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,12 +29,11 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; /** * This class represents the new format of GSS MIC tokens, as specified - * in draft-ietf-krb-wg-gssapi-cfx-07.txt + * in RFC 4121 * * MIC tokens = { 16-byte token-header | HMAC } * where HMAC is on { plaintext | 16-byte token-header } @@ -48,12 +47,11 @@ byte[] tokenBytes, int tokenOffset, int tokenLen, MessageProp prop) throws GSSException { super(Krb5Token.MIC_ID_v2, context, - tokenBytes, tokenOffset, tokenLen, prop); + tokenBytes, tokenOffset, tokenLen, prop); } - public MicToken_v2(Krb5Context context, - InputStream is, MessageProp prop) - throws GSSException { + public MicToken_v2(Krb5Context context, InputStream is, MessageProp prop) + throws GSSException { super(Krb5Token.MIC_ID_v2, context, is, prop); } @@ -64,7 +62,6 @@ } public void verify(InputStream data) throws GSSException { - byte[] dataBytes = null; try { dataBytes = new byte[data.available()]; @@ -79,7 +76,7 @@ public MicToken_v2(Krb5Context context, MessageProp prop, byte[] data, int pos, int len) - throws GSSException { + throws GSSException { super(Krb5Token.MIC_ID_v2, context); // debug("Application data to MicToken verify is [" + @@ -89,7 +86,7 @@ } public MicToken_v2(Krb5Context context, MessageProp prop, InputStream data) - throws GSSException, IOException { + throws GSSException, IOException { super(Krb5Token.MIC_ID_v2, context); byte[] dataBytes = new byte[data.available()]; @@ -101,22 +98,21 @@ genSignAndSeqNumber(prop, dataBytes, 0, dataBytes.length); } - public int encode(byte[] outToken, int offset) - throws IOException, GSSException { - - // Token is small - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - super.encode(bos); - byte[] token = bos.toByteArray(); - System.arraycopy(token, 0, outToken, offset, token.length); - return token.length; - } - - public byte[] encode() throws IOException, GSSException { - + public byte[] encode() throws IOException { // XXX Fine tune this initial size ByteArrayOutputStream bos = new ByteArrayOutputStream(50); encode(bos); return bos.toByteArray(); } + + public int encode(byte[] outToken, int offset) throws IOException { + byte[] token = encode(); + System.arraycopy(token, 0, outToken, offset, token.length); + return token.length; + } + + public void encode(OutputStream os) throws IOException { + encodeHeader(os); + os.write(checksum); + } } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/security/jgss/krb5/WrapToken.java --- a/jdk/src/share/classes/sun/security/jgss/krb5/WrapToken.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/security/jgss/krb5/WrapToken.java Wed Jul 05 17:32:27 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,14 +27,11 @@ import org.ietf.jgss.*; import sun.security.jgss.*; -import java.security.GeneralSecurityException; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import sun.security.krb5.Confounder; -import sun.security.krb5.KrbException; /** * This class represents a token emitted by the GSSContext.wrap() @@ -336,24 +333,29 @@ // debug("\t\tNo encryption was performed by peer.\n"); readFully(is, confounder); - // Data is always a multiple of 8 with this GSS Mech - // Copy all but last block as they are - int numBlocks = (dataSize - CONFOUNDER_SIZE)/8 - 1; - int offset = dataBufOffset; - for (int i = 0; i < numBlocks; i++) { - readFully(is, dataBuf, offset, 8); - offset += 8; - } + if (cipherHelper.isArcFour()) { + padding = pads[1]; + readFully(is, dataBuf, dataBufOffset, dataSize-CONFOUNDER_SIZE-1); + } else { + // Data is always a multiple of 8 with this GSS Mech + // Copy all but last block as they are + int numBlocks = (dataSize - CONFOUNDER_SIZE)/8 - 1; + int offset = dataBufOffset; + for (int i = 0; i < numBlocks; i++) { + readFully(is, dataBuf, offset, 8); + offset += 8; + } - byte[] finalBlock = new byte[8]; - readFully(is, finalBlock); + byte[] finalBlock = new byte[8]; + readFully(is, finalBlock); - int padSize = finalBlock[7]; - padding = pads[padSize]; + int padSize = finalBlock[7]; + padding = pads[padSize]; - // debug("\t\tPadding applied was: " + padSize + "\n"); - System.arraycopy(finalBlock, 0, dataBuf, offset, - finalBlock.length - padSize); + // debug("\t\tPadding applied was: " + padSize + "\n"); + System.arraycopy(finalBlock, 0, dataBuf, offset, + finalBlock.length - padSize); + } } } catch (IOException e) { throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1, diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/security/jgss/krb5/WrapToken_v2.java --- a/jdk/src/share/classes/sun/security/jgss/krb5/WrapToken_v2.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/security/jgss/krb5/WrapToken_v2.java Wed Jul 05 17:32:27 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,66 +27,30 @@ import org.ietf.jgss.*; import sun.security.jgss.*; -import java.security.GeneralSecurityException; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.util.Arrays; import sun.security.krb5.Confounder; -import sun.security.krb5.KrbException; /** - * This class represents the new format of GSS tokens, as specified in - * draft-ietf-krb-wg-gssapi-cfx-07.txt, emitted by the GSSContext.wrap() - * call. It is a MessageToken except that it also contains plaintext or - * encrypted data at the end. A WrapToken has certain other rules that are - * peculiar to it and different from a MICToken, which is another type of - * MessageToken. All data in a WrapToken is prepended by a random counfounder - * of 16 bytes. Thus, all application data is replaced by - * (confounder || data || tokenHeader || checksum). + * This class represents the new format of GSS tokens, as specified in RFC + * 4121, emitted by the GSSContext.wrap() call. It is a MessageToken except + * that it also contains plaintext or encrypted data at the end. A WrapToken + * has certain other rules that are peculiar to it and different from a + * MICToken, which is another type of MessageToken. All data in a WrapToken is + * prepended by a random confounder of 16 bytes. Thus, all application data + * is replaced by (confounder || data || tokenHeader || checksum). * * @author Seema Malkani */ class WrapToken_v2 extends MessageToken_v2 { - /** - * The size of the random confounder used in a WrapToken. - */ - static final int CONFOUNDER_SIZE = 16; - - /* - * A token may come in either in an InputStream or as a - * byte[]. Store a reference to it in either case and process - * it's data only later when getData() is called and - * decryption/copying is needed to be done. Note that JCE can - * decrypt both from a byte[] and from an InputStream. - */ - private boolean readTokenFromInputStream = true; - private InputStream is = null; - private byte[] tokenBytes = null; - private int tokenOffset = 0; - private int tokenLen = 0; - - /* - * Application data may come from an InputStream or from a - * byte[]. However, it will always be stored and processed as a - * byte[] since - * (a) the MessageDigest class only accepts a byte[] as input and - * (b) It allows writing to an OuputStream via a CipherOutputStream. - */ - private byte[] dataBytes = null; - private int dataOffset = 0; - private int dataLen = 0; - - // the len of the token data: - // (confounder || data || tokenHeader || checksum) - private int dataSize = 0; // Accessed by CipherHelper byte[] confounder = null; - private boolean privacy = false; - private boolean initiator = true; + private final boolean privacy; /** * Constructs a WrapToken from token bytes obtained from the @@ -104,30 +68,9 @@ byte[] tokenBytes, int tokenOffset, int tokenLen, MessageProp prop) throws GSSException { - // Just parse the MessageToken part first super(Krb5Token.WRAP_ID_v2, context, tokenBytes, tokenOffset, tokenLen, prop); - this.readTokenFromInputStream = false; - - // rotate token bytes as per RRC - byte[] new_tokenBytes = new byte[tokenLen]; - if (rotate_left(tokenBytes, tokenOffset, new_tokenBytes, tokenLen)) { - this.tokenBytes = new_tokenBytes; - this.tokenOffset = 0; - } else { - this.tokenBytes = tokenBytes; - this.tokenOffset = tokenOffset; - } - - // Will need the token bytes again when extracting data - this.tokenLen = tokenLen; this.privacy = prop.getPrivacy(); - - dataSize = tokenLen - TOKEN_HEADER_SIZE; - - // save initiator - this.initiator = context.isInitiator(); - } /** @@ -145,27 +88,8 @@ InputStream is, MessageProp prop) throws GSSException { - // Just parse the MessageToken part first super(Krb5Token.WRAP_ID_v2, context, is, prop); - - // Will need the token bytes again when extracting data - this.is = is; this.privacy = prop.getPrivacy(); - - // get the token length - try { - this.tokenLen = is.available(); - } catch (IOException e) { - throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1, - getTokenName(getTokenId()) - + ": " + e.getMessage()); - } - - // data size - dataSize = tokenLen - TOKEN_HEADER_SIZE; - - // save initiator - this.initiator = context.isInitiator(); } /** @@ -177,13 +101,9 @@ */ public byte[] getData() throws GSSException { - byte[] temp = new byte[dataSize]; + byte[] temp = new byte[tokenDataLen]; int len = getData(temp, 0); - // len obtained is after removing confounder, tokenHeader and HMAC - - byte[] retVal = new byte[len]; - System.arraycopy(temp, 0, retVal, 0, retVal.length); - return retVal; + return Arrays.copyOf(temp, len); } /** @@ -200,69 +120,26 @@ public int getData(byte[] dataBuf, int dataBufOffset) throws GSSException { - if (readTokenFromInputStream) - getDataFromStream(dataBuf, dataBufOffset); - else - getDataFromBuffer(dataBuf, dataBufOffset); - - int retVal = 0; - if (privacy) { - retVal = dataSize - confounder.length - - TOKEN_HEADER_SIZE - cipherHelper.getChecksumLength(); - } else { - retVal = dataSize - cipherHelper.getChecksumLength(); - } - return retVal; - } - - /** - * Helper routine to obtain the application data transmitted in - * this WrapToken. It is called if the WrapToken was constructed - * with a byte array as input. - * @param dataBuf the output buffer into which the data must be - * written - * @param dataBufOffset the offset at which to write the data - * @throws GSSException if an error occurs while decrypting any - * cipher text and checking for validity - */ - private void getDataFromBuffer(byte[] dataBuf, int dataBufOffset) - throws GSSException { - - int dataPos = tokenOffset + TOKEN_HEADER_SIZE; - int data_length = 0; - - if (dataPos + dataSize > tokenOffset + tokenLen) - throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1, - "Insufficient data in " - + getTokenName(getTokenId())); // debug("WrapToken cons: data is token is [" + // getHexBytes(tokenBytes, tokenOffset, tokenLen) + "]\n"); - confounder = new byte[CONFOUNDER_SIZE]; // Do decryption if this token was privacy protected. if (privacy) { // decrypt data - cipherHelper.decryptData(this, tokenBytes, dataPos, dataSize, + cipherHelper.decryptData(this, tokenData, 0, tokenDataLen, dataBuf, dataBufOffset, getKeyUsage()); - /* - debug("\t\tDecrypted data is [" + - getHexBytes(confounder) + " " + - getHexBytes(dataBuf, dataBufOffset, - dataSize - CONFOUNDER_SIZE) + - "]\n"); - */ - data_length = dataSize - CONFOUNDER_SIZE - - TOKEN_HEADER_SIZE - cipherHelper.getChecksumLength(); + return tokenDataLen - CONFOUNDER_SIZE - + TOKEN_HEADER_SIZE - cipherHelper.getChecksumLength(); } else { // Token data is in cleartext - debug("\t\tNo encryption was performed by peer.\n"); + // debug("\t\tNo encryption was performed by peer.\n"); // data - data_length = dataSize - cipherHelper.getChecksumLength(); - System.arraycopy(tokenBytes, dataPos, + int data_length = tokenDataLen - cipherHelper.getChecksumLength(); + System.arraycopy(tokenData, 0, dataBuf, dataBufOffset, data_length); // debug("\t\tData is: " + getHexBytes(dataBuf, data_length)); @@ -274,95 +151,26 @@ throw new GSSException(GSSException.BAD_MIC, -1, "Corrupt checksum in Wrap token"); } + return data_length; } } /** - * Helper routine to obtain the application data transmitted in - * this WrapToken. It is called if the WrapToken was constructed - * with an Inputstream. - * @param dataBuf the output buffer into which the data must be - * written - * @param dataBufOffset the offset at which to write the data - * @throws GSSException if an error occurs while decrypting any - * cipher text and checking for validity + * Writes a WrapToken_v2 object */ - private void getDataFromStream(byte[] dataBuf, int dataBufOffset) - throws GSSException { - - int data_length = 0; - // Don't check the token length. Data will be read on demand from - // the InputStream. - // debug("WrapToken cons: data will be read from InputStream.\n"); - - confounder = new byte[CONFOUNDER_SIZE]; - - try { - // Do decryption if this token was privacy protected. - if (privacy) { - - cipherHelper.decryptData(this, is, dataSize, - dataBuf, dataBufOffset, getKeyUsage()); - - /* - debug("\t\tDecrypted data is [" + - getHexBytes(confounder) + " " + - getHexBytes(dataBuf, dataBufOffset, - dataSize - CONFOUNDER_SIZE) + - "]\n"); - */ - data_length = dataSize - CONFOUNDER_SIZE - - TOKEN_HEADER_SIZE - cipherHelper.getChecksumLength(); - } else { - - // Token data is in cleartext - debug("\t\tNo encryption was performed by peer.\n"); - readFully(is, confounder); - - // read the data - data_length = dataSize - cipherHelper.getChecksumLength(); - readFully(is, dataBuf, dataBufOffset, data_length); - - /* - * Make sure checksum is not corrupt - */ - if (!verifySign(dataBuf, dataBufOffset, data_length)) { - throw new GSSException(GSSException.BAD_MIC, -1, - "Corrupt checksum in Wrap token"); - } - } - } catch (IOException e) { - throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1, - getTokenName(getTokenId()) - + ": " + e.getMessage()); - } - - } - - public WrapToken_v2(Krb5Context context, MessageProp prop, byte[] dataBytes, int dataOffset, int dataLen) - throws GSSException { + throws GSSException { super(Krb5Token.WRAP_ID_v2, context); confounder = Confounder.bytes(CONFOUNDER_SIZE); - dataSize = confounder.length + dataLen + TOKEN_HEADER_SIZE + - cipherHelper.getChecksumLength(); - this.dataBytes = dataBytes; - this.dataOffset = dataOffset; - this.dataLen = dataLen; - - // save initiator - this.initiator = context.isInitiator(); - // debug("\nWrapToken cons: data to wrap is [" + // getHexBytes(confounder) + " " + // getHexBytes(dataBytes, dataOffset, dataLen) + "]\n"); - genSignAndSeqNumber(prop, - dataBytes, dataOffset, dataLen); + genSignAndSeqNumber(prop, dataBytes, dataOffset, dataLen); /* * If the application decides to ask for privacy when the context @@ -374,110 +182,42 @@ prop.setPrivacy(false); privacy = prop.getPrivacy(); - } - public void encode(OutputStream os) throws IOException, GSSException { - - super.encode(os); - - // debug("\n\nWriting data: ["); if (!privacy) { - // Wrap Tokens (without confidentiality) = // { 16 byte token_header | plaintext | 12-byte HMAC } // where HMAC is on { plaintext | token_header } - // calculate checksum - byte[] checksum = getChecksum(dataBytes, dataOffset, dataLen); - - // data - // debug(" " + getHexBytes(dataBytes, dataOffset, dataLen)); - os.write(dataBytes, dataOffset, dataLen); - - // write HMAC - // debug(" " + getHexBytes(checksum, - // cipherHelper.getChecksumLength())); - os.write(checksum); - + tokenData = new byte[dataLen + checksum.length]; + System.arraycopy(dataBytes, dataOffset, tokenData, 0, dataLen); + System.arraycopy(checksum, 0, tokenData, dataLen, checksum.length); } else { - // Wrap Tokens (with confidentiality) = // { 16 byte token_header | // Encrypt(16-byte confounder | plaintext | token_header) | // 12-byte HMAC } - cipherHelper.encryptData(this, confounder, getTokenHeader(), - dataBytes, dataOffset, dataLen, getKeyUsage(), os); - + tokenData = cipherHelper.encryptData(this, confounder, getTokenHeader(), + dataBytes, dataOffset, dataLen, getKeyUsage()); } - // debug("]\n"); } - public byte[] encode() throws IOException, GSSException { - // XXX Fine tune this initial size - ByteArrayOutputStream bos = new ByteArrayOutputStream(dataSize + 50); + public void encode(OutputStream os) throws IOException { + encodeHeader(os); + os.write(tokenData); + } + + public byte[] encode() throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream( + MessageToken_v2.TOKEN_HEADER_SIZE + tokenData.length); encode(bos); return bos.toByteArray(); } - public int encode(byte[] outToken, int offset) - throws IOException, GSSException { - - int retVal = 0; - - // Token header is small - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - super.encode(bos); - byte[] header = bos.toByteArray(); - System.arraycopy(header, 0, outToken, offset, header.length); - offset += header.length; - - // debug("WrapToken.encode: Writing data: ["); - if (!privacy) { - - // Wrap Tokens (without confidentiality) = - // { 16 byte token_header | plaintext | 12-byte HMAC } - // where HMAC is on { plaintext | token_header } - - // calculate checksum - byte[] checksum = getChecksum(dataBytes, dataOffset, dataLen); - - // data - // debug(" " + getHexBytes(dataBytes, dataOffset, dataLen)); - System.arraycopy(dataBytes, dataOffset, outToken, offset, - dataLen); - offset += dataLen; - - // write HMAC - // debug(" " + getHexBytes(checksum, - // cipherHelper.getChecksumLength())); - System.arraycopy(checksum, 0, outToken, offset, - cipherHelper.getChecksumLength()); - - retVal = header.length + dataLen + cipherHelper.getChecksumLength(); - } else { - - // Wrap Tokens (with confidentiality) = - // { 16 byte token_header | - // Encrypt(16-byte confounder | plaintext | token_header) | - // 12-byte HMAC } - int cLen = cipherHelper.encryptData(this, confounder, - getTokenHeader(), dataBytes, dataOffset, dataLen, - outToken, offset, getKeyUsage()); - - retVal = header.length + cLen; - // debug(getHexBytes(outToken, offset, dataSize)); - } - - // debug("]\n"); - - // %%% assume that plaintext length == ciphertext len - return retVal; - - } - - protected int getKrb5TokenSize() throws GSSException { - return (getTokenSize() + dataSize); + public int encode(byte[] outToken, int offset) throws IOException { + byte[] token = encode(); + System.arraycopy(token, 0, outToken, offset, token.length); + return token.length; } // This implementation is way to conservative. And it certainly @@ -485,6 +225,7 @@ static int getSizeLimit(int qop, boolean confReq, int maxTokenSize, CipherHelper ch) throws GSSException { return (GSSHeader.getMaxMechTokenSize(OID, maxTokenSize) - - (getTokenSize(ch) + CONFOUNDER_SIZE) - 8 /* safety */); + (TOKEN_HEADER_SIZE + ch.getChecksumLength() + CONFOUNDER_SIZE) + - 8 /* safety */); } } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/security/pkcs11/Config.java --- a/jdk/src/share/classes/sun/security/pkcs11/Config.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/security/pkcs11/Config.java Wed Jul 05 17:32:27 2017 +0200 @@ -343,6 +343,7 @@ st.wordChars('{', '{'); // need {} for property subst st.wordChars('}', '}'); st.wordChars('*', '*'); + st.wordChars('~', '~'); // XXX check ASCII table and add all other characters except special // special: #="(), diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java --- a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Wed Jul 05 17:32:27 2017 +0200 @@ -395,6 +395,8 @@ } } catch (PKCS11Exception e) { throw new ProviderException("Cancel failed", e); + } finally { + reset(); } } @@ -408,12 +410,18 @@ if (session == null) { session = token.getOpSession(); } - if (encrypt) { - token.p11.C_EncryptInit(session.id(), - new CK_MECHANISM(mechanism, iv), p11Key.keyID); - } else { - token.p11.C_DecryptInit(session.id(), - new CK_MECHANISM(mechanism, iv), p11Key.keyID); + try { + if (encrypt) { + token.p11.C_EncryptInit(session.id(), + new CK_MECHANISM(mechanism, iv), p11Key.keyID); + } else { + token.p11.C_DecryptInit(session.id(), + new CK_MECHANISM(mechanism, iv), p11Key.keyID); + } + } catch (PKCS11Exception ex) { + // release session when initialization failed + session = token.releaseSession(session); + throw ex; } bytesBuffered = 0; padBufferLen = 0; @@ -448,6 +456,16 @@ return result; } + // reset the states to the pre-initialized values + private void reset() { + initialized = false; + bytesBuffered = 0; + padBufferLen = 0; + if (session != null) { + session = token.releaseSession(session); + } + } + // see JCE spec protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) { try { @@ -566,6 +584,7 @@ throw (ShortBufferException) (new ShortBufferException().initCause(e)); } + reset(); throw new ProviderException("update() failed", e); } } @@ -683,6 +702,7 @@ throw (ShortBufferException) (new ShortBufferException().initCause(e)); } + reset(); throw new ProviderException("update() failed", e); } } @@ -729,10 +749,7 @@ handleException(e); throw new ProviderException("doFinal() failed", e); } finally { - initialized = false; - bytesBuffered = 0; - padBufferLen = 0; - session = token.releaseSession(session); + reset(); } } @@ -806,9 +823,7 @@ handleException(e); throw new ProviderException("doFinal() failed", e); } finally { - initialized = false; - bytesBuffered = 0; - session = token.releaseSession(session); + reset(); } } diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/security/ssl/CipherSuite.java --- a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java Wed Jul 05 17:32:27 2017 +0200 @@ -577,14 +577,16 @@ final static MacAlg M_SHA256 = new MacAlg("SHA256", 32); final static MacAlg M_SHA384 = new MacAlg("SHA384", 48); - // PRFs (PseudoRandom Function) from TLS specifications. - // - // TLS 1.1- uses a single MD5/SHA1-based PRF algorithm for generating - // the necessary material. - // - // In TLS 1.2+, all existing/known CipherSuites use SHA256, however - // new Ciphersuites (e.g. RFC 5288) can define specific PRF hash - // algorithms. + /** + * PRFs (PseudoRandom Function) from TLS specifications. + * + * TLS 1.1- uses a single MD5/SHA1-based PRF algorithm for generating + * the necessary material. + * + * In TLS 1.2+, all existing/known CipherSuites use SHA256, however + * new Ciphersuites (e.g. RFC 5288) can define specific PRF hash + * algorithms. + */ static enum PRF { // PRF algorithms @@ -862,8 +864,18 @@ add("SSL_NULL_WITH_NULL_NULL", 0x0000, 1, K_NULL, B_NULL, F); - // Definition of the CipherSuites that are enabled by default. - // They are listed in preference order, most preferred first. + /* + * Definition of the CipherSuites that are enabled by default. + * They are listed in preference order, most preferred first, using + * the following criteria: + * 1. Prefer the stronger buld cipher, in the order of AES_256, + * AES_128, RC-4, 3DES-EDE. + * 2. Prefer the stronger MAC algorithm, in the order of SHA384, + * SHA256, SHA, MD5. + * 3. Prefer the better performance of key exchange and digital + * signature algorithm, in the order of ECDHE-ECDSA, ECDHE-RSA, + * RSA, ECDH-ECDSA, ECDH-RSA, DHE-RSA, DHE-DSS. + */ int p = DEFAULT_SUITES_PRIORITY * 2; // shorten names to fit the following table cleanly. @@ -873,170 +885,185 @@ // ID Key Exchange Cipher A obs suprt PRF // ====== ============ ========= = === ===== ======== - add("TLS_RSA_WITH_AES_128_CBC_SHA256", - 0x003c, --p, K_RSA, B_AES_128, T, max, tls12, P_SHA256); + add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", + 0xc024, --p, K_ECDHE_ECDSA, B_AES_256, T, max, tls12, P_SHA384); + add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", + 0xc028, --p, K_ECDHE_RSA, B_AES_256, T, max, tls12, P_SHA384); add("TLS_RSA_WITH_AES_256_CBC_SHA256", 0x003d, --p, K_RSA, B_AES_256, T, max, tls12, P_SHA256); - add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", - 0x0040, --p, K_DHE_DSS, B_AES_128, T, max, tls12, P_SHA256); - add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", - 0x0067, --p, K_DHE_RSA, B_AES_128, T, max, tls12, P_SHA256); + add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", + 0xc026, --p, K_ECDH_ECDSA, B_AES_256, T, max, tls12, P_SHA384); + add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", + 0xc02a, --p, K_ECDH_RSA, B_AES_256, T, max, tls12, P_SHA384); + add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", + 0x006b, --p, K_DHE_RSA, B_AES_256, T, max, tls12, P_SHA256); add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", 0x006a, --p, K_DHE_DSS, B_AES_256, T, max, tls12, P_SHA256); - add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", - 0x006b, --p, K_DHE_RSA, B_AES_256, T, max, tls12, P_SHA256); + + add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + 0xC00A, --p, K_ECDHE_ECDSA, B_AES_256, T); + add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + 0xC014, --p, K_ECDHE_RSA, B_AES_256, T); + add("TLS_RSA_WITH_AES_256_CBC_SHA", + 0x0035, --p, K_RSA, B_AES_256, T); + add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", + 0xC005, --p, K_ECDH_ECDSA, B_AES_256, T); + add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", + 0xC00F, --p, K_ECDH_RSA, B_AES_256, T); + add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA", + 0x0039, --p, K_DHE_RSA, B_AES_256, T); + add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA", + 0x0038, --p, K_DHE_DSS, B_AES_256, T); add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 0xc023, --p, K_ECDHE_ECDSA, B_AES_128, T, max, tls12, P_SHA256); - add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", - 0xc024, --p, K_ECDHE_ECDSA, B_AES_256, T, max, tls12, P_SHA384); + add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + 0xc027, --p, K_ECDHE_RSA, B_AES_128, T, max, tls12, P_SHA256); + add("TLS_RSA_WITH_AES_128_CBC_SHA256", + 0x003c, --p, K_RSA, B_AES_128, T, max, tls12, P_SHA256); add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", 0xc025, --p, K_ECDH_ECDSA, B_AES_128, T, max, tls12, P_SHA256); - add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", - 0xc026, --p, K_ECDH_ECDSA, B_AES_256, T, max, tls12, P_SHA384); - add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", - 0xc027, --p, K_ECDHE_RSA, B_AES_128, T, max, tls12, P_SHA256); - add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", - 0xc028, --p, K_ECDHE_RSA, B_AES_256, T, max, tls12, P_SHA384); add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", 0xc029, --p, K_ECDH_RSA, B_AES_128, T, max, tls12, P_SHA256); - add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", - 0xc02a, --p, K_ECDH_RSA, B_AES_256, T, max, tls12, P_SHA384); + add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", + 0x0067, --p, K_DHE_RSA, B_AES_128, T, max, tls12, P_SHA256); + add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", + 0x0040, --p, K_DHE_DSS, B_AES_128, T, max, tls12, P_SHA256); - add("SSL_RSA_WITH_RC4_128_MD5", - 0x0004, --p, K_RSA, B_RC4_128, N); - add("SSL_RSA_WITH_RC4_128_SHA", - 0x0005, --p, K_RSA, B_RC4_128, N); + add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + 0xC009, --p, K_ECDHE_ECDSA, B_AES_128, T); + add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + 0xC013, --p, K_ECDHE_RSA, B_AES_128, T); add("TLS_RSA_WITH_AES_128_CBC_SHA", 0x002f, --p, K_RSA, B_AES_128, T); - add("TLS_RSA_WITH_AES_256_CBC_SHA", - 0x0035, --p, K_RSA, B_AES_256, T); - - add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA", - 0xC002, --p, K_ECDH_ECDSA, B_RC4_128, N); add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", 0xC004, --p, K_ECDH_ECDSA, B_AES_128, T); - add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", - 0xC005, --p, K_ECDH_ECDSA, B_AES_256, T); - add("TLS_ECDH_RSA_WITH_RC4_128_SHA", - 0xC00C, --p, K_ECDH_RSA, B_RC4_128, N); add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", 0xC00E, --p, K_ECDH_RSA, B_AES_128, T); - add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", - 0xC00F, --p, K_ECDH_RSA, B_AES_256, T); + add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA", + 0x0033, --p, K_DHE_RSA, B_AES_128, T); + add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA", + 0x0032, --p, K_DHE_DSS, B_AES_128, T); add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", 0xC007, --p, K_ECDHE_ECDSA, B_RC4_128, N); - add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", - 0xC009, --p, K_ECDHE_ECDSA, B_AES_128, T); - add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", - 0xC00A, --p, K_ECDHE_ECDSA, B_AES_256, T); add("TLS_ECDHE_RSA_WITH_RC4_128_SHA", 0xC011, --p, K_ECDHE_RSA, B_RC4_128, N); - add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", - 0xC013, --p, K_ECDHE_RSA, B_AES_128, T); - add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", - 0xC014, --p, K_ECDHE_RSA, B_AES_256, T); + add("SSL_RSA_WITH_RC4_128_SHA", + 0x0005, --p, K_RSA, B_RC4_128, N); + add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA", + 0xC002, --p, K_ECDH_ECDSA, B_RC4_128, N); + add("TLS_ECDH_RSA_WITH_RC4_128_SHA", + 0xC00C, --p, K_ECDH_RSA, B_RC4_128, N); - add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA", - 0x0033, --p, K_DHE_RSA, B_AES_128, T); - add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA", - 0x0039, --p, K_DHE_RSA, B_AES_256, T); - add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA", - 0x0032, --p, K_DHE_DSS, B_AES_128, T); - add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA", - 0x0038, --p, K_DHE_DSS, B_AES_256, T); - + add("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", + 0xC008, --p, K_ECDHE_ECDSA, B_3DES, T); + add("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", + 0xC012, --p, K_ECDHE_RSA, B_3DES, T); add("SSL_RSA_WITH_3DES_EDE_CBC_SHA", 0x000a, --p, K_RSA, B_3DES, T); add("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", 0xC003, --p, K_ECDH_ECDSA, B_3DES, T); add("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", 0xC00D, --p, K_ECDH_RSA, B_3DES, T); - add("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", - 0xC008, --p, K_ECDHE_ECDSA, B_3DES, T); - add("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", - 0xC012, --p, K_ECDHE_RSA, B_3DES, T); add("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", 0x0016, --p, K_DHE_RSA, B_3DES, T); add("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", 0x0013, --p, K_DHE_DSS, B_3DES, N); + add("SSL_RSA_WITH_RC4_128_MD5", + 0x0004, --p, K_RSA, B_RC4_128, N); + // Renegotiation protection request Signalling Cipher Suite Value (SCSV) add("TLS_EMPTY_RENEGOTIATION_INFO_SCSV", 0x00ff, --p, K_SCSV, B_NULL, T); - // Definition of the CipherSuites that are supported but not enabled - // by default. - // They are listed in preference order, preferred first. + /* + * Definition of the CipherSuites that are supported but not enabled + * by default. + * They are listed in preference order, preferred first, using the + * following criteria: + * 1. CipherSuites for KRB5 need additional KRB5 service + * configuration, and these suites are not common in practice, + * so we put KRB5 based cipher suites at the end of the supported + * list. + * 2. If a cipher suite has been obsoleted, we put it at the end of + * the list. + * 3. Prefer the stronger bulk cipher, in the order of AES_256, + * AES_128, RC-4, 3DES-EDE, DES, RC4_40, DES40, NULL. + * 4. Prefer the stronger MAC algorithm, in the order of SHA384, + * SHA256, SHA, MD5. + * 5. Prefer the better performance of key exchange and digital + * signature algorithm, in the order of ECDHE-ECDSA, ECDHE-RSA, + * RSA, ECDH-ECDSA, ECDH-RSA, DHE-RSA, DHE-DSS, anonymous. + */ p = DEFAULT_SUITES_PRIORITY; - // weak single-DES cipher suites + add("TLS_DH_anon_WITH_AES_256_CBC_SHA256", + 0x006d, --p, K_DH_ANON, B_AES_256, N, max, tls12, P_SHA256); + add("TLS_ECDH_anon_WITH_AES_256_CBC_SHA", + 0xC019, --p, K_ECDH_ANON, B_AES_256, T); + add("TLS_DH_anon_WITH_AES_256_CBC_SHA", + 0x003a, --p, K_DH_ANON, B_AES_256, N); + + add("TLS_DH_anon_WITH_AES_128_CBC_SHA256", + 0x006c, --p, K_DH_ANON, B_AES_128, N, max, tls12, P_SHA256); + add("TLS_ECDH_anon_WITH_AES_128_CBC_SHA", + 0xC018, --p, K_ECDH_ANON, B_AES_128, T); + add("TLS_DH_anon_WITH_AES_128_CBC_SHA", + 0x0034, --p, K_DH_ANON, B_AES_128, N); + + add("TLS_ECDH_anon_WITH_RC4_128_SHA", + 0xC016, --p, K_ECDH_ANON, B_RC4_128, N); + add("SSL_DH_anon_WITH_RC4_128_MD5", + 0x0018, --p, K_DH_ANON, B_RC4_128, N); + + add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", + 0xC017, --p, K_ECDH_ANON, B_3DES, T); + add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", + 0x001b, --p, K_DH_ANON, B_3DES, N); + + add("TLS_RSA_WITH_NULL_SHA256", + 0x003b, --p, K_RSA, B_NULL, N, max, tls12, P_SHA256); + add("TLS_ECDHE_ECDSA_WITH_NULL_SHA", + 0xC006, --p, K_ECDHE_ECDSA, B_NULL, N); + add("TLS_ECDHE_RSA_WITH_NULL_SHA", + 0xC010, --p, K_ECDHE_RSA, B_NULL, N); + add("SSL_RSA_WITH_NULL_SHA", + 0x0002, --p, K_RSA, B_NULL, N); + add("TLS_ECDH_ECDSA_WITH_NULL_SHA", + 0xC001, --p, K_ECDH_ECDSA, B_NULL, N); + add("TLS_ECDH_RSA_WITH_NULL_SHA", + 0xC00B, --p, K_ECDH_RSA, B_NULL, N); + add("TLS_ECDH_anon_WITH_NULL_SHA", + 0xC015, --p, K_ECDH_ANON, B_NULL, N); + add("SSL_RSA_WITH_NULL_MD5", + 0x0001, --p, K_RSA, B_NULL, N); + + // weak cipher suites obsoleted in TLS 1.2 add("SSL_RSA_WITH_DES_CBC_SHA", 0x0009, --p, K_RSA, B_DES, N, tls12); add("SSL_DHE_RSA_WITH_DES_CBC_SHA", 0x0015, --p, K_DHE_RSA, B_DES, N, tls12); add("SSL_DHE_DSS_WITH_DES_CBC_SHA", 0x0012, --p, K_DHE_DSS, B_DES, N, tls12); - - // Anonymous key exchange and the NULL ciphers - add("SSL_RSA_WITH_NULL_MD5", - 0x0001, --p, K_RSA, B_NULL, N); - add("SSL_RSA_WITH_NULL_SHA", - 0x0002, --p, K_RSA, B_NULL, N); - add("TLS_RSA_WITH_NULL_SHA256", - 0x003b, --p, K_RSA, B_NULL, N, max, tls12, P_SHA256); - - add("TLS_ECDH_ECDSA_WITH_NULL_SHA", - 0xC001, --p, K_ECDH_ECDSA, B_NULL, N); - add("TLS_ECDH_RSA_WITH_NULL_SHA", - 0xC00B, --p, K_ECDH_RSA, B_NULL, N); - add("TLS_ECDHE_ECDSA_WITH_NULL_SHA", - 0xC006, --p, K_ECDHE_ECDSA, B_NULL, N); - add("TLS_ECDHE_RSA_WITH_NULL_SHA", - 0xC010, --p, K_ECDHE_RSA, B_NULL, N); - - add("SSL_DH_anon_WITH_RC4_128_MD5", - 0x0018, --p, K_DH_ANON, B_RC4_128, N); - add("TLS_DH_anon_WITH_AES_128_CBC_SHA", - 0x0034, --p, K_DH_ANON, B_AES_128, N); - add("TLS_DH_anon_WITH_AES_256_CBC_SHA", - 0x003a, --p, K_DH_ANON, B_AES_256, N); - add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", - 0x001b, --p, K_DH_ANON, B_3DES, N); add("SSL_DH_anon_WITH_DES_CBC_SHA", 0x001a, --p, K_DH_ANON, B_DES, N, tls12); - add("TLS_DH_anon_WITH_AES_128_CBC_SHA256", - 0x006c, --p, K_DH_ANON, B_AES_128, N, max, tls12, P_SHA256); - add("TLS_DH_anon_WITH_AES_256_CBC_SHA256", - 0x006d, --p, K_DH_ANON, B_AES_256, N, max, tls12, P_SHA256); - - add("TLS_ECDH_anon_WITH_RC4_128_SHA", - 0xC016, --p, K_ECDH_ANON, B_RC4_128, N); - add("TLS_ECDH_anon_WITH_AES_128_CBC_SHA", - 0xC018, --p, K_ECDH_ANON, B_AES_128, T); - add("TLS_ECDH_anon_WITH_AES_256_CBC_SHA", - 0xC019, --p, K_ECDH_ANON, B_AES_256, T); - add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", - 0xC017, --p, K_ECDH_ANON, B_3DES, T); - + // weak cipher suites obsoleted in TLS 1.1 + add("SSL_RSA_EXPORT_WITH_RC4_40_MD5", + 0x0003, --p, K_RSA_EXPORT, B_RC4_40, N, tls11); add("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", 0x0017, --p, K_DH_ANON, B_RC4_40, N, tls11); - add("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", - 0x0019, --p, K_DH_ANON, B_DES_40, N, tls11); - add("TLS_ECDH_anon_WITH_NULL_SHA", - 0xC015, --p, K_ECDH_ANON, B_NULL, N); - - add("SSL_RSA_EXPORT_WITH_RC4_40_MD5", - 0x0003, --p, K_RSA_EXPORT, B_RC4_40, N, tls11); add("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x0008, --p, K_RSA_EXPORT, B_DES_40, N, tls11); add("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x0014, --p, K_DHE_RSA, B_DES_40, N, tls11); add("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", 0x0011, --p, K_DHE_DSS, B_DES_40, N, tls11); + add("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", + 0x0019, --p, K_DH_ANON, B_DES_40, N, tls11); // Supported Kerberos ciphersuites from RFC2712 add("TLS_KRB5_WITH_RC4_128_SHA", diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java --- a/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java Wed Jul 05 17:32:27 2017 +0200 @@ -381,8 +381,7 @@ mesgVersion); } - handshakeHash.protocolDetermined( - mesgVersion.v >= ProtocolVersion.TLS12.v); + handshakeHash.protocolDetermined(mesgVersion); // Set protocolVersion and propagate to SSLSocket and the // Handshake streams @@ -1223,7 +1222,7 @@ // not follow the spec that HandshakeHash.reset() can be only be // called before protocolDetermined. // if (maxProtocolVersion.v < ProtocolVersion.TLS12.v) { - // handshakeHash.protocolDetermined(false); + // handshakeHash.protocolDetermined(maxProtocolVersion); // } // create the ClientHello message diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/security/ssl/HandshakeHash.java --- a/jdk/src/share/classes/sun/security/ssl/HandshakeHash.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/src/share/classes/sun/security/ssl/HandshakeHash.java Wed Jul 05 17:32:27 2017 +0200 @@ -49,27 +49,27 @@ * * You need to obey these conventions when using this class: * - * 1. protocolDetermined(boolean isTLS12) should be called when the negotiated + * 1. protocolDetermined(version) should be called when the negotiated * protocol version is determined. * * 2. Before protocolDetermined() is called, only update(), reset(), * restrictCertificateVerifyAlgs(), setFinishedAlg(), and * setCertificateVerifyAlg() can be called. * - * 3. After protocolDetermined(*) is called. reset() cannot be called. + * 3. After protocolDetermined() is called, reset() cannot be called. * - * 4. After protocolDetermined(false) is called, getFinishedHash() and - * getCertificateVerifyHash() cannot be called. After protocolDetermined(true) - * is called, getMD5Clone() and getSHAClone() cannot be called. + * 4. After protocolDetermined() is called, if the version is pre-TLS 1.2, + * getFinishedHash() and getCertificateVerifyHash() cannot be called. Otherwise, + * getMD5Clone() and getSHAClone() cannot be called. * * 5. getMD5Clone() and getSHAClone() can only be called after - * protocolDetermined(false) is called. + * protocolDetermined() is called and version is pre-TLS 1.2. * * 6. getFinishedHash() and getCertificateVerifyHash() can only be called after - * all protocolDetermined(true), setCertificateVerifyAlg() and setFinishedAlg() - * have been called. If a CertificateVerify message is to be used, call - * setCertificateVerifyAlg() with the hash algorithm as the argument. - * Otherwise, you still must call setCertificateVerifyAlg(null) before + * all protocolDetermined(), setCertificateVerifyAlg() and setFinishedAlg() + * have been called and the version is TLS 1.2. If a CertificateVerify message + * is to be used, call setCertificateVerifyAlg() with the hash algorithm as the + * argument. Otherwise, you still must call setCertificateVerifyAlg(null) before * calculating any hash value. * * Suggestions: Call protocolDetermined(), restrictCertificateVerifyAlgs(), @@ -78,6 +78,7 @@ * Example: *
  * HandshakeHash hh = new HandshakeHash(...)
+ * hh.protocolDetermined(ProtocolVersion.TLS12);
  * hh.update(clientHelloBytes);
  * hh.setFinishedAlg("SHA-256");
  * hh.update(serverHelloBytes);
@@ -161,12 +162,12 @@
     }
 
 
-    void protocolDetermined(boolean isTLS12) {
+    void protocolDetermined(ProtocolVersion pv) {
 
         // Do not set again, will ignore
         if (version != -1) return;
 
-        version = isTLS12 ? 2 : 1;
+        version = pv.compareTo(ProtocolVersion.TLS12) >= 0 ? 2 : 1;
         switch (version) {
             case 1:
                 // initiate md5, sha and call update on saved array
@@ -310,91 +311,6 @@
             throw new Error("BAD");
         }
     }
-
-    ////////////////////////////////////////////////////////////////
-    // TEST
-    ////////////////////////////////////////////////////////////////
-
-    public static void main(String[] args) throws Exception {
-        Test t = new Test();
-        t.test(null, "SHA-256");
-        t.test("", "SHA-256");
-        t.test("SHA-1", "SHA-256");
-        t.test("SHA-256", "SHA-256");
-        t.test("SHA-384", "SHA-256");
-        t.test("SHA-512", "SHA-256");
-        t.testSame("sha", "SHA-1");
-        t.testSame("SHA", "SHA-1");
-        t.testSame("SHA1", "SHA-1");
-        t.testSame("SHA-1", "SHA-1");
-        t.testSame("SHA256", "SHA-256");
-        t.testSame("SHA-256", "SHA-256");
-    }
-
-    static class Test {
-        void update(HandshakeHash hh, String s) {
-            hh.update(s.getBytes(), 0, s.length());
-        }
-        static byte[] digest(String alg, String data) throws Exception {
-            return MessageDigest.getInstance(alg).digest(data.getBytes());
-        }
-        static void equals(byte[] b1, byte[] b2) {
-            if (!Arrays.equals(b1, b2)) {
-                throw new RuntimeException("Bad");
-            }
-        }
-        void testSame(String a, String a2) {
-            System.out.println("testSame: " + a + " " + a2);
-            if (!HandshakeHash.normalizeAlgName(a).equals(a2)) {
-                throw new RuntimeException("Bad");
-            }
-        }
-        /**
-         * Special convention: when it's certain that CV will not be used at the
-         * very beginning, use null as cvAlg. If known at a late stage, use "".
-         */
-        void test(String cvAlg, String finAlg) throws Exception {
-            System.out.println("test: " + cvAlg + " " + finAlg);
-            byte[] cv = null, f1, f2;
-            HandshakeHash hh = new HandshakeHash(true, true, null);
-            if (cvAlg == null) {
-                hh.setCertificateVerifyAlg(cvAlg);
-            }
-
-            update(hh, "ClientHello,");
-            hh.reset();
-            update(hh, "ClientHellov2,");
-            hh.setFinishedAlg(finAlg);
-
-            // Useless calls
-            hh.setFinishedAlg("SHA-1");
-            hh.setFinishedAlg("SHA-512");
-
-            update(hh, "More,");
-            if (cvAlg != null) {
-                if (cvAlg.isEmpty()) cvAlg = null;
-                hh.setCertificateVerifyAlg(cvAlg);
-            }
-
-            // Useless calls
-            hh.setCertificateVerifyAlg("SHA-1");
-            hh.setCertificateVerifyAlg(null);
-
-            hh.protocolDetermined(true);
-
-            if (cvAlg != null) {
-                cv = hh.getAllHandshakeMessages();
-                equals(cv, "ClientHellov2,More,".getBytes());
-            }
-
-            update(hh, "FIN1,");
-            f1 = hh.getFinishedHash();
-            equals(f1, digest(finAlg, "ClientHellov2,More,FIN1,"));
-            update(hh, "FIN2,");
-            f2 = hh.getFinishedHash();
-            equals(f2, digest(finAlg, "ClientHellov2,More,FIN1,FIN2,"));
-        }
-    }
 }
 
 /**
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java
--- a/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java	Wed Jul 05 17:32:27 2017 +0200
@@ -424,8 +424,7 @@
                 " not enabled or not supported");
         }
 
-        handshakeHash.protocolDetermined(
-            selectedVersion.v >= ProtocolVersion.TLS12.v);
+        handshakeHash.protocolDetermined(selectedVersion);
         setVersion(selectedVersion);
 
         m1.protocolVersion = protocolVersion;
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/tools/jstat/resources/jstat_options
--- a/jdk/src/share/classes/sun/tools/jstat/resources/jstat_options	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/sun/tools/jstat/resources/jstat_options	Wed Jul 05 17:32:27 2017 +0200
@@ -589,7 +589,7 @@
   }
   column {
     header "^S0CMX^"	/* Survivor 0 Space Capacity - Maximum */
-    data sun.gc.generation.0.space.1.capacity
+    data sun.gc.generation.0.space.1.maxCapacity
     scale K
     align right
     width 8
@@ -597,7 +597,7 @@
   }
   column {
     header "^S0C^"	/* Survivor 0 Space Capacity - Current */
-    data sun.gc.generation.0.space.1.maxCapacity
+    data sun.gc.generation.0.space.1.capacity
     scale K
     align right
     width 8
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/classes/sun/util/logging/PlatformLogger.java
--- a/jdk/src/share/classes/sun/util/logging/PlatformLogger.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/classes/sun/util/logging/PlatformLogger.java	Wed Jul 05 17:32:27 2017 +0200
@@ -113,7 +113,7 @@
 
     // Table of known loggers.  Maps names to PlatformLoggers.
     private static Map> loggers =
-        new HashMap>();
+        new HashMap<>();
 
     /**
      * Returns a PlatformLogger of a given name.
@@ -126,7 +126,7 @@
         }
         if (log == null) {
             log = new PlatformLogger(name);
-            loggers.put(name, new WeakReference(log));
+            loggers.put(name, new WeakReference<>(log));
         }
         return log;
     }
@@ -488,7 +488,7 @@
      */
     static class JavaLogger extends LoggerProxy {
         private static final Map levelObjects =
-            new HashMap();
+            new HashMap<>();
 
         static {
             if (LoggingSupport.isAvailable()) {
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/demo/jvmti/heapTracker/heapTracker.c
--- a/jdk/src/share/demo/jvmti/heapTracker/heapTracker.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/demo/jvmti/heapTracker/heapTracker.c	Wed Jul 05 17:32:27 2017 +0200
@@ -340,7 +340,7 @@
 }
 
 /* Java Native Method for Object. */
-static void
+static void JNICALL
 HEAP_TRACKER_native_newobj(JNIEnv *env, jclass klass, jthread thread, jobject o)
 {
     TraceInfo *tinfo;
@@ -353,7 +353,7 @@
 }
 
 /* Java Native Method for newarray */
-static void
+static void JNICALL
 HEAP_TRACKER_native_newarr(JNIEnv *env, jclass klass, jthread thread, jobject a)
 {
     TraceInfo *tinfo;
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/native/sun/awt/image/awt_parseImage.c
--- a/jdk/src/share/native/sun/awt/image/awt_parseImage.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/native/sun/awt/image/awt_parseImage.c	Wed Jul 05 17:32:27 2017 +0200
@@ -178,7 +178,7 @@
         jnbits = (*env)->GetObjectField(env, rasterP->jsampleModel,
                                         g_SPPSMnBitsID);
         if (jmask == NULL || joffs == NULL || jnbits == NULL ||
-            rasterP->sppsm.maxBitSize < 0 || rasterP->sppsm.maxBitSize > 8)
+            rasterP->sppsm.maxBitSize < 0)
         {
             JNU_ThrowInternalError(env, "Can't grab SPPSM fields");
             return -1;
@@ -280,6 +280,17 @@
                                   rasterP->chanOffsets);
     }
 
+    /* additioanl check for sppsm fields validity: make sure that
+     * size of raster samples doesn't exceed the data type cpacity.
+     */
+    if (rasterP->dataType > UNKNOWN_DATA_TYPE && /* data type has been recognized */
+        rasterP->sppsm.maxBitSize > 0 && /* raster has SPP sample model */
+        rasterP->sppsm.maxBitSize > (rasterP->dataSize * 8))
+    {
+        JNU_ThrowInternalError(env, "Raster samples are too big");
+        return -1;
+    }
+
 #if 0
     fprintf(stderr,"---------------------\n");
     fprintf(stderr,"Width  : %d\n",rasterP->width);
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/native/sun/awt/splashscreen/splashscreen_gfx_impl.h
--- a/jdk/src/share/native/sun/awt/splashscreen/splashscreen_gfx_impl.h	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/native/sun/awt/splashscreen/splashscreen_gfx_impl.h	Wed Jul 05 17:32:27 2017 +0200
@@ -88,27 +88,18 @@
 /*      blend (lerp between) two rgb quads
         src and dst alpha is ignored
         the algorithm: src*alpha+dst*(1-alpha)=(src-dst)*alpha+dst, rb and g are done separately
-        it's possible to verify that it's almost accurate indeed */
-
+*/
 INLINE rgbquad_t
 blendRGB(rgbquad_t dst, rgbquad_t src, rgbquad_t alpha)
 {
-    const rgbquad_t dstrb = dst & 0xFF00FF;
-    const rgbquad_t dstg = dst & 0xFF00;
-    const rgbquad_t srcrb = src & 0xFF00FF;
-    const rgbquad_t srcg = src & 0xFF00;
-
-    rgbquad_t drb = srcrb - dstrb;
-    rgbquad_t dg = srcg - dstg;
+    const rgbquad_t a = alpha;
+    const rgbquad_t a1 = 0xFF - alpha;
 
-    alpha += 1;
-
-    drb *= alpha;
-    dg *= alpha;
-    drb >>= 8;
-    dg >>= 8;
-
-    return ((drb + dstrb) & 0xFF00FF) | ((dg + dstg) & 0xFF00);
+    return MAKE_QUAD(
+        (rgbquad_t)((QUAD_RED(src) * a + QUAD_RED(dst) * a1) / 0xFF),
+        (rgbquad_t)((QUAD_GREEN(src) * a + QUAD_GREEN(dst) * a1) / 0xFF),
+        (rgbquad_t)((QUAD_BLUE(src) * a + QUAD_BLUE(dst) * a1) / 0xFF),
+        0);
 }
 
 /*      scales rgb quad by alpha. basically similar to what's above. src alpha is retained.
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/native/sun/java2d/loops/DrawParallelogram.c
--- a/jdk/src/share/native/sun/java2d/loops/DrawParallelogram.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/native/sun/java2d/loops/DrawParallelogram.c	Wed Jul 05 17:32:27 2017 +0200
@@ -26,14 +26,11 @@
 #include "math.h"
 #include "GraphicsPrimitiveMgr.h"
 #include "LineUtils.h"
-#include "LoopMacros.h"
 #include "Trace.h"
+#include "ParallelogramUtils.h"
 
-#include "sun_java2d_loops_FillParallelogram.h"
 #include "sun_java2d_loops_DrawParallelogram.h"
 
-DECLARE_SOLID_DRAWLINE(AnyInt);
-
 #define HANDLE_PGRAM_EDGE(X1, Y1, X2, Y2, \
                           pRasInfo, pixel, pPrim, pFunc, pCompInfo) \
     do { \
@@ -46,28 +43,6 @@
                                ix1, iy1, ix2, iy2, JNI_TRUE); \
     } while (0)
 
-#define PGRAM_MIN_MAX(bmin, bmax, v0, dv1, dv2) \
-    do { \
-        double vmin, vmax; \
-        if (dv1 < 0) { \
-            vmin = v0+dv1; \
-            vmax = v0; \
-        } else { \
-            vmin = v0; \
-            vmax = v0+dv1; \
-        } \
-        if (dv2 < 0) { \
-            vmin -= dv2; \
-        } else { \
-            vmax += dv2; \
-        } \
-        bmin = (jint) floor(vmin + 0.5); \
-        bmax = (jint) floor(vmax + 0.5); \
-    } while(0)
-
-#define PGRAM_INIT_X(starty, x, y, slope) \
-    (DblToLong((x) + (slope) * ((starty)+0.5 - (y))) + LongOneHalf - 1)
-
 typedef struct {
     jdouble x0;
     jdouble y0;
@@ -136,20 +111,8 @@
      * Sort parallelogram by y values, ensure that each delta vector
      * has a non-negative y delta.
      */
-    if (dy1 < 0) {
-        x0 += dx1;  y0 += dy1;
-        dx1 = -dx1; dy1 = -dy1;
-    }
-    if (dy2 < 0) {
-        x0 += dx2;  y0 += dy2;
-        dx2 = -dx2; dy2 = -dy2;
-    }
-    /* Sort delta vectors so dxy1 is left of dxy2. */
-    if (dx1 * dy2 > dx2 * dy1) {
-        double v = dx1; dx1 = dx2; dx2 = v;
-               v = dy1; dy1 = dy2; dy2 = v;
-               v = lw1; lw1 = lw2; lw2 = v;
-    }
+    SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2,
+               v = lw1; lw1 = lw2; lw2 = v;);
 
     // dx,dy for line width in the "1" and "2" directions.
     ldx1 = dx1 * lw1;
@@ -161,7 +124,7 @@
     ox0 = x0 - (ldx1 + ldx2) / 2.0;
     oy0 = y0 - (ldy1 + ldy2) / 2.0;
 
-    PGRAM_MIN_MAX(ix1, ix2, ox0, dx1+ldx1, dx2+ldx2);
+    PGRAM_MIN_MAX(ix1, ix2, ox0, dx1+ldx1, dx2+ldx2, JNI_FALSE);
     iy1 = (jint) floor(oy0 + 0.5);
     iy2 = (jint) floor(oy0 + dy1 + ldy1 + dy2 + ldy2 + 0.5);
 
@@ -212,7 +175,7 @@
             // Only need to generate 4 quads if the interior still
             // has a hole in it (i.e. if the line width ratios were
             // both less than 1.0)
-            if (lw1 < 1.0f && lw2 < 1.0f) {
+            if (lw1 < 1.0 && lw2 < 1.0) {
                 // If the line widths are both less than a pixel wide
                 // then we can use a drawline function instead for even
                 // more performance.
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/native/sun/java2d/loops/FillParallelogram.c
--- a/jdk/src/share/native/sun/java2d/loops/FillParallelogram.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/native/sun/java2d/loops/FillParallelogram.c	Wed Jul 05 17:32:27 2017 +0200
@@ -25,31 +25,10 @@
 
 #include "math.h"
 #include "GraphicsPrimitiveMgr.h"
+#include "ParallelogramUtils.h"
 
 #include "sun_java2d_loops_FillParallelogram.h"
 
-#define PGRAM_MIN_MAX(bmin, bmax, v0, dv1, dv2) \
-    do { \
-        double vmin, vmax; \
-        if (dv1 < 0) { \
-            vmin = v0+dv1; \
-            vmax = v0; \
-        } else { \
-            vmin = v0; \
-            vmax = v0+dv1; \
-        } \
-        if (dv2 < 0) { \
-            vmin -= dv2; \
-        } else { \
-            vmax += dv2; \
-        } \
-        bmin = (jint) floor(vmin + 0.5); \
-        bmax = (jint) floor(vmax + 0.5); \
-    } while(0)
-
-#define PGRAM_INIT_X(starty, x, y, slope) \
-    (DblToLong((x) + (slope) * ((starty)+0.5 - (y))) + LongOneHalf - 1)
-
 /*
  * Class:     sun_java2d_loops_FillParallelogram
  * Method:    FillParallelogram
@@ -76,22 +55,11 @@
 
     /*
      * Sort parallelogram by y values, ensure that each delta vector
-     * has a non-negative y delta, and eliminate degenerate parallelograms.
+     * has a non-negative y delta.
      */
-    if (dy1 < 0) {
-        x0 += dx1;  y0 += dy1;
-        dx1 = -dx1; dy1 = -dy1;
-    }
-    if (dy2 < 0) {
-        x0 += dx2;  y0 += dy2;
-        dx2 = -dx2; dy2 = -dy2;
-    }
-    /* Sort delta vectors so dxy1 is left of dxy2. */
-    if (dx1 * dy2 > dx2 * dy1) {
-        double v = dx1; dx1 = dx2; dx2 = v;
-               v = dy1; dy1 = dy2; dy2 = v;
-    }
-    PGRAM_MIN_MAX(ix1, ix2, x0, dx1, dx2);
+    SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2, );
+
+    PGRAM_MIN_MAX(ix1, ix2, x0, dx1, dx2, JNI_FALSE);
     iy1 = (jint) floor(y0 + 0.5);
     iy2 = (jint) floor(y0 + dy1 + dy2 + 0.5);
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/native/sun/java2d/loops/MaskFill.c
--- a/jdk/src/share/native/sun/java2d/loops/MaskFill.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/native/sun/java2d/loops/MaskFill.c	Wed Jul 05 17:32:27 2017 +0200
@@ -23,7 +23,11 @@
  * questions.
  */
 
+#include 
+#include 
+#include 
 #include "GraphicsPrimitiveMgr.h"
+#include "ParallelogramUtils.h"
 
 #include "sun_java2d_loops_MaskFill.h"
 
@@ -93,6 +97,967 @@
             }
         }
         SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
+   }
+   SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
+}
+
+#define MASK_BUF_LEN 1024
+
+#define DblToMask(v) ((unsigned char) ((v)*255.9999))
+
+/* Fills an aligned rectangle with potentially translucent edges. */
+static void
+fillAARect(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo,
+           CompositeInfo *pCompInfo, jint color, unsigned char *pMask,
+           void *pDst,
+           jdouble x1, jdouble y1, jdouble x2, jdouble y2)
+{
+    jint cx1 = pRasInfo->bounds.x1;
+    jint cy1 = pRasInfo->bounds.y1;
+    jint cx2 = pRasInfo->bounds.x2;
+    jint cy2 = pRasInfo->bounds.y2;
+    jint rx1 = (jint) ceil(x1);
+    jint ry1 = (jint) ceil(y1);
+    jint rx2 = (jint) floor(x2);
+    jint ry2 = (jint) floor(y2);
+    jint width = cx2 - cx1;
+    jint scan = pRasInfo->scanStride;
+    /* Convert xy12 into the edge coverage fractions for those edges. */
+    x1 = rx1-x1;
+    y1 = ry1-y1;
+    x2 = x2-rx2;
+    y2 = y2-ry2;
+    if (ry2 < ry1) {
+        /* Accumulate bottom coverage into top coverage. */
+        y1 = y1 + y2 - 1.0;
+        /* prevent processing of "bottom fractional row" */
+        ry2 = cy2;
+    }
+    if (rx2 < rx1) {
+        /* Accumulate right coverage into left coverage. */
+        x1 = x1 + x2 - 1.0;
+        /* prevent processing of "right fractional column" */
+        rx2 = cx2;
+    }
+    /* Check for a visible "top fractional row" and process it */
+    if (cy1 < ry1) {
+        unsigned char midcov = DblToMask(y1);
+        jint x;
+        for (x = 0; x < width; x++) {
+            pMask[x] = midcov;
+        }
+        if (cx1 < rx1) {
+            pMask[0] = DblToMask(y1 * x1);
+        }
+        if (cx2 > rx2) {
+            pMask[width-1] = DblToMask(y1 * x2);
+        }
+        (*pPrim->funcs.maskfill)(pDst,
+                                 pMask, 0, 0,
+                                 width, 1,
+                                 color, pRasInfo,
+                                 pPrim, pCompInfo);
+        pDst = PtrAddBytes(pDst, scan);
+        cy1++;
+    }
+    /* Check for a visible "left fract, solid middle, right fract" section. */
+    if (cy1 < ry2 && cy1 < cy2) {
+        jint midh = ((ry2 < cy2) ? ry2 : cy2) - cy1;
+        jint midx = cx1;
+        void *pMid = pDst;
+        /* First process the left "fractional column" if it is visible. */
+        if (midx < rx1) {
+            pMask[0] = DblToMask(x1);
+            /* Note: maskscan == 0 means we reuse this value for every row. */
+            (*pPrim->funcs.maskfill)(pMid,
+                                     pMask, 0, 0,
+                                     1, midh,
+                                     color, pRasInfo,
+                                     pPrim, pCompInfo);
+            pMid = PtrAddBytes(pMid, pRasInfo->pixelStride);
+            midx++;
+        }
+        /* Process the central solid section if it is visible. */
+        if (midx < rx2 && midx < cx2) {
+            jint midw = ((rx2 < cx2) ? rx2 : cx2) - midx;
+            /* A NULL mask buffer means "all coverages are 0xff" */
+            (*pPrim->funcs.maskfill)(pMid,
+                                     NULL, 0, 0,
+                                     midw, midh,
+                                     color, pRasInfo,
+                                     pPrim, pCompInfo);
+            pMid = PtrCoord(pMid, midw, pRasInfo->pixelStride, 0, 0);
+            midx += midw;
+        }
+        /* Finally process the right "fractional column" if it is visible. */
+        if (midx < cx2) {
+            pMask[0] = DblToMask(x2);
+            /* Note: maskscan == 0 means we reuse this value for every row. */
+            (*pPrim->funcs.maskfill)(pMid,
+                                     pMask, 0, 0,
+                                     1, midh,
+                                     color, pRasInfo,
+                                     pPrim, pCompInfo);
+        }
+        cy1 += midh;
+        pDst = PtrCoord(pDst, 0, 0, midh, scan);
+    }
+    /* Check for a visible "bottom fractional row" and process it */
+    if (cy1 < cy2) {
+        unsigned char midcov = DblToMask(y2);
+        jint x;
+        for (x = 0; x < width; x++) {
+            pMask[x] = midcov;
+        }
+        if (cx1 < rx1) {
+            pMask[0] = DblToMask(y2 * x1);
+        }
+        if (cx2 > rx2) {
+            pMask[width-1] = DblToMask(y2 * x2);
+        }
+        (*pPrim->funcs.maskfill)(pDst,
+                                 pMask, 0, 0,
+                                 width, 1,
+                                 color, pRasInfo,
+                                 pPrim, pCompInfo);
+    }
+}
+
+/*
+ * Support code for arbitrary tracing and MaskFill filling of
+ * non-rectilinear (diagonal) parallelograms.
+ *
+ * This code is based upon the following model of AA coverage.
+ *
+ * Each edge of a parallelogram (for fillPgram) or a double
+ * parallelogram (inner and outer parallelograms for drawPgram)
+ * can be rasterized independently because the geometry is well
+ * defined in such a way that none of the sides will ever cross
+ * each other and they have a fixed ordering that is fairly
+ * well predetermined.
+ *
+ * So, for each edge we will look at the diagonal line that
+ * the edge makes as it passes through a row of pixels.  Some
+ * such diagonal lines may pass entirely through the row of
+ * pixels in a single pixel column.  Some may cut across the
+ * row and pass through several pixel columns before they pass
+ * on to the next row.
+ *
+ * As the edge passes through the row of pixels it will affect
+ * the coverage of the pixels it passes through as well as all
+ * of the pixels to the right of the edge.  The coverage will
+ * either be increased (by a left edge of a parallelogram) or
+ * decreased (by a right edge) for all pixels to the right, until
+ * another edge passing the opposite direction is encountered.
+ *
+ * The coverage added or subtracted by an edge as it crosses a
+ * given pixel is calculated using a trapezoid formula in the
+ * following manner:
+ *
+ *                /
+ *     +-----+---/-+-----+
+ *     |     |  /  |     |
+ *     |     | /   |     |
+ *     +-----+/----+-----+
+ *           /
+ *
+ * The area to the right of that edge for the pixel where it
+ * crosses is given as:
+ *
+ *     trapheight * (topedge + bottomedge)/2
+ *
+ * Another thing to note is that the above formula gives the
+ * contribution of that edge to the given pixel where it crossed,
+ * but in so crossing the pixel row, it also created 100% coverage
+ * for all of the pixels to the right.
+ *
+ * This example was simplified in that the edge depicted crossed
+ * the complete pixel row and it did so entirely within the bounds
+ * of a single pixel column.  In practice, many edges may start or
+ * end in a given row and thus provide only partial row coverage
+ * (i.e. the total "trapheight" in the formula never reaches 1.0).
+ * And in other cases, edges may travel sideways through several
+ * pixel columns on a given pixel row from where they enter it to
+ * where the leave it (which also mans that the trapheight for a
+ * given pixel will be less than 1.0, but by the time the edge
+ * completes its journey through the pixel row the "coverage shadow"
+ * that it casts on all pixels to the right eventually reaches 100%).
+ *
+ * In order to simplify the calculations so that we don't have to
+ * keep propagating coverages we calculate for one edge "until we
+ * reach another edge" we will process one edge at a time and
+ * simply record in a buffer the amount that an edge added to
+ * or subtracted from the coverage for a given pixel and its
+ * following right-side neighbors.  Thus, the true total coverage
+ * of a given pixel is only determined by summing the deltas for
+ * that pixel and all of the pixels to its left.  Since we already
+ * have to scan the buffer to change floating point coverages into
+ * mask values for a MaskFill loop, it is simple enough to sum the
+ * values as we perform that scan from left to right.
+ *
+ * In the above example, note that 2 deltas need to be recorded even
+ * though the edge only intersected a single pixel.  The delta recorded
+ * for the pixel where the edge crossed will be approximately 55%
+ * (guesstimating by examining the poor ascii art) which is fine for
+ * determining how to render that pixel, but the rest of the pixels
+ * to its right should have their coverage modified by a full 100%
+ * and the 55% delta value we recorded for the pixel that the edge
+ * crossed will not get them there.  We adjust for this by adding
+ * the "remainder" of the coverage implied by the shadow to the
+ * pixel immediately to the right of where we record a trapezoidal
+ * contribution.  In this case a delta of 45% will be recorded in
+ * the pixel immediately to the right to raise the total to 100%.
+ *
+ * As we sum these delta values as we process the line from left
+ * to right, these delta values will typically drive the sum from
+ * 0% up to 100% and back down to 0% over the course of a single
+ * pixel row.  In the case of a drawn (double) parallelogram the
+ * sum will go to 100% and back to 0% twice on most scanlines.
+ *
+ * The fillAAPgram and drawAAPgram functions drive the main flow
+ * of the algorithm with help from the following structures,
+ * macros, and functions.  It is probably best to start with
+ * those 2 functions to gain an understanding of the algorithm.
+ */
+typedef struct {
+    jdouble x;
+    jdouble y;
+    jdouble xbot;
+    jdouble ybot;
+    jdouble xnexty;
+    jdouble ynextx;
+    jdouble xnextx;
+    jdouble linedx;
+    jdouble celldx;
+    jdouble celldy;
+    jboolean isTrailing;
+} EdgeInfo;
+
+#define MIN_DELTA  (1.0/256.0)
+
+/*
+ * Calculates slopes and deltas for an edge and stores results in an EdgeInfo.
+ * Returns true if the edge was valid (i.e. not ignored for some reason).
+ */
+static jboolean
+storeEdge(EdgeInfo *pEdge,
+          jdouble x, jdouble y, jdouble dx, jdouble dy,
+          jint cx1, jint cy1, jint cx2, jint cy2,
+          jboolean isTrailing)
+{
+    jdouble xbot = x + dx;
+    jdouble ybot = y + dy;
+    jboolean ret;
+
+    pEdge->x = x;
+    pEdge->y = y;
+    pEdge->xbot = xbot;
+    pEdge->ybot = ybot;
+
+    /* Note that parallelograms are sorted so dy is always non-negative */
+    if (dy > MIN_DELTA &&        /* NaN and horizontal protection */
+        ybot > cy1 &&            /* NaN and "OUT_ABOVE" protection */
+        y < cy2 &&               /* NaN and "OUT_BELOW" protection */
+        xbot == xbot &&          /* NaN protection */
+        (x < cx2 || xbot < cx2)) /* "OUT_RIGHT" protection */
+        /* Note: "OUT_LEFT" segments may still contribute coverage... */
+    {
+        /* no NaNs, dy is not horizontal, and segment contributes to clip */
+        if (dx < -MIN_DELTA || dx > MIN_DELTA) {
+            /* dx is not vertical */
+            jdouble linedx;
+            jdouble celldy;
+            jdouble nextx;
+
+            linedx = dx / dy;
+            celldy = dy / dx;
+            if (y < cy1) {
+                pEdge->x = x = x + (cy1 - y) * linedx;
+                pEdge->y = y = cy1;
+            }
+            pEdge->linedx = linedx;
+            if (dx < 0) {
+                pEdge->celldx = -1.0;
+                pEdge->celldy = -celldy;
+                pEdge->xnextx = nextx = ceil(x) - 1.0;
+            } else {
+                pEdge->celldx = +1.0;
+                pEdge->celldy = celldy;
+                pEdge->xnextx = nextx = floor(x) + 1.0;
+            }
+            pEdge->ynextx = y + (nextx - x) * celldy;
+            pEdge->xnexty = x + ((floor(y) + 1) - y) * linedx;
+        } else {
+            /* dx is essentially vertical */
+            if (y < cy1) {
+                pEdge->y = y = cy1;
+            }
+            pEdge->xbot = x;
+            pEdge->linedx = 0.0;
+            pEdge->celldx = 0.0;
+            pEdge->celldy = 1.0;
+            pEdge->xnextx = x;
+            pEdge->xnexty = x;
+            pEdge->ynextx = ybot;
+        }
+        ret = JNI_TRUE;
+    } else {
+        /* There is some reason to ignore this segment, "celldy=0" omits it */
+        pEdge->ybot = y;
+        pEdge->linedx = dx;
+        pEdge->celldx = dx;
+        pEdge->celldy = 0.0;
+        pEdge->xnextx = xbot;
+        pEdge->xnexty = xbot;
+        pEdge->ynextx = y;
+        ret = JNI_FALSE;
+    }
+    pEdge->isTrailing = isTrailing;
+    return ret;
+}
+
+/*
+ * Calculates and stores slopes and deltas for all edges of a parallelogram.
+ * Returns true if at least 1 edge was valid (i.e. not ignored for some reason).
+ *
+ * The inverted flag is true for an outer parallelogram (left and right
+ * edges are leading and trailing) and false for an inner parallelogram
+ * (where the left edge is trailing and the right edge is leading).
+ */
+static jboolean
+storePgram(EdgeInfo *pLeftEdge, EdgeInfo *pRightEdge,
+           jdouble x, jdouble y,
+           jdouble dx1, jdouble dy1,
+           jdouble dx2, jdouble dy2,
+           jint cx1, jint cy1, jint cx2, jint cy2,
+           jboolean inverted)
+{
+    jboolean ret = JNI_FALSE;
+    ret = (storeEdge(pLeftEdge  + 0,
+                     x    , y    , dx1, dy1,
+                     cx1, cy1, cx2, cy2, inverted) || ret);
+    ret = (storeEdge(pLeftEdge  + 1,
+                     x+dx1, y+dy1, dx2, dy2,
+                     cx1, cy1, cx2, cy2, inverted) || ret);
+    ret = (storeEdge(pRightEdge + 0,
+                     x    , y    , dx2, dy2,
+                     cx1, cy1, cx2, cy2, !inverted) || ret);
+    ret = (storeEdge(pRightEdge + 1,
+                     x+dx2, y+dy2, dx1, dy1,
+                     cx1, cy1, cx2, cy2, !inverted) || ret);
+    return ret;
+}
+
+/*
+ * The X0,Y0,X1,Y1 values represent a trapezoidal fragment whose
+ * coverage must be accounted for in the accum buffer.
+ *
+ * All four values are assumed to fall within (or on the edge of)
+ * a single pixel.
+ *
+ * The trapezoid area is accumulated into the proper element of
+ * the accum buffer and the remainder of the "slice height" is
+ * accumulated into the element to its right.
+ */
+#define INSERT_ACCUM(pACCUM, IMIN, IMAX, X0, Y0, X1, Y1, CX1, CX2, MULT) \
+    do { \
+        jdouble xmid = ((X0) + (X1)) * 0.5; \
+        if (xmid <= (CX2)) { \
+            jdouble sliceh = ((Y1) - (Y0)); \
+            jdouble slicearea; \
+            jint i; \
+            if (xmid < (CX1)) { \
+                /* Accumulate the entire slice height into accum[0]. */ \
+                i = 0; \
+                slicearea = sliceh; \
+            } else { \
+                jdouble xpos = floor(xmid); \
+                i = ((jint) xpos) - (CX1); \
+                slicearea = (xpos+1-xmid) * sliceh; \
+            } \
+            if (IMIN > i) { \
+                IMIN = i; \
+            } \
+            (pACCUM)[i++] += (jfloat) ((MULT) * slicearea); \
+            (pACCUM)[i++] += (jfloat) ((MULT) * (sliceh - slicearea)); \
+            if (IMAX < i) { \
+                IMAX = i; \
+            } \
+        } \
+    } while (0)
+
+/*
+ * Accumulate the contributions for a given edge crossing a given
+ * scan line into the corresponding entries of the accum buffer.
+ * CY1 is the Y coordinate of the top edge of the scanline and CY2
+ * is equal to (CY1 + 1) and is the Y coordinate of the bottom edge
+ * of the scanline.  CX1 and CX2 are the left and right edges of the
+ * clip (or area of interest) being rendered.
+ *
+ * The edge is processed from the top edge to the bottom edge and
+ * a single pixel column at a time.
+ */
+#define ACCUM_EDGE(pEDGE, pACCUM, IMIN, IMAX, CX1, CY1, CX2, CY2) \
+    do { \
+        jdouble x, y, xnext, ynext, xlast, ylast, dx, dy, mult; \
+        y = (pEDGE)->y; \
+        dy = (pEDGE)->celldy; \
+        ylast = (pEDGE)->ybot; \
+        if (ylast <= (CY1) || y >= (CY2) || dy == 0.0) { \
+            break; \
+        } \
+        x = (pEDGE)->x; \
+        dx = (pEDGE)->celldx; \
+        if (ylast > (CY2)) { \
+            ylast = (CY2); \
+            xlast = (pEDGE)->xnexty; \
+        } else { \
+            xlast = (pEDGE)->xbot; \
+        } \
+        xnext = (pEDGE)->xnextx; \
+        ynext = (pEDGE)->ynextx; \
+        mult = ((pEDGE)->isTrailing) ? -1.0 : 1.0; \
+        while (ynext <= ylast) { \
+            INSERT_ACCUM(pACCUM, IMIN, IMAX, \
+                         x, y, xnext, ynext, \
+                         CX1, CX2, mult); \
+            x = xnext; \
+            y = ynext; \
+            xnext += dx; \
+            ynext += dy; \
+        } \
+        (pEDGE)->ynextx = ynext; \
+        (pEDGE)->xnextx = xnext; \
+        INSERT_ACCUM(pACCUM, IMIN, IMAX, \
+                     x, y, xlast, ylast, \
+                     CX1, CX2, mult); \
+        (pEDGE)->x = xlast; \
+        (pEDGE)->y = ylast; \
+        (pEDGE)->xnexty = xlast + (pEDGE)->linedx; \
+    } while(0)
+
+/* Main function to fill a single Parallelogram */
+static void
+fillAAPgram(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo,
+            CompositeInfo *pCompInfo, jint color, unsigned char *pMask,
+            void *pDst,
+            jdouble x1, jdouble y1,
+            jdouble dx1, jdouble dy1,
+            jdouble dx2, jdouble dy2)
+{
+    jint cx1 = pRasInfo->bounds.x1;
+    jint cy1 = pRasInfo->bounds.y1;
+    jint cx2 = pRasInfo->bounds.x2;
+    jint cy2 = pRasInfo->bounds.y2;
+    jint width = cx2 - cx1;
+    EdgeInfo edges[4];
+    jfloat localaccum[MASK_BUF_LEN + 1];
+    jfloat *pAccum;
+
+    if (!storePgram(edges + 0, edges + 2,
+                    x1, y1, dx1, dy1, dx2, dy2,
+                    cx1, cy1, cx2, cy2,
+                    JNI_FALSE))
+    {
+        return;
+    }
+
+    pAccum = ((width > MASK_BUF_LEN)
+              ? malloc((width + 1) * sizeof(jfloat))
+              : localaccum);
+    if (pAccum == NULL) {
+        return;
+    }
+    memset(pAccum, 0, (width+1) * sizeof(jfloat));
+
+    while (cy1 < cy2) {
+        jint lmin, lmax, rmin, rmax;
+        jint moff, x;
+        jdouble accum;
+        unsigned char lastcov;
+
+        lmin = rmin = width + 2;
+        lmax = rmax = 0;
+        ACCUM_EDGE(&edges[0], pAccum, lmin, lmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[1], pAccum, lmin, lmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[2], pAccum, rmin, rmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[3], pAccum, rmin, rmax,
+                   cx1, cy1, cx2, cy1+1);
+        if (lmax > width) {
+            lmax = width; /* Extra col has data we do not need. */
+        }
+        if (rmax > width) {
+            rmax = width; /* Extra col has data we do not need. */
+        }
+        /* If ranges overlap, handle both in the first pass. */
+        if (rmin <= lmax) {
+            lmax = rmax;
+        }
+
+        x = lmin;
+        accum = 0.0;
+        moff = 0;
+        lastcov = 0;
+        while (x < lmax) {
+            accum += pAccum[x];
+            pAccum[x] = 0.0f;
+            pMask[moff++] = lastcov = DblToMask(accum);
+            x++;
+        }
+        /* Check for a solid center section. */
+        if (lastcov == 0xFF) {
+            jint endx;
+            void *pRow;
+
+            /* First process the existing partial coverage data. */
+            if (moff > 0) {
+                pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
+                (*pPrim->funcs.maskfill)(pRow,
+                                         pMask, 0, 0,
+                                         moff, 1,
+                                         color, pRasInfo,
+                                         pPrim, pCompInfo);
+                moff = 0;
+            }
+
+            /* Where does the center section end? */
+            /* If there is no right AA edge in the accum buffer, then */
+            /* the right edge was beyond the clip, so fill out to width */
+            endx = (rmin < rmax) ? rmin : width;
+            if (x < endx) {
+                pRow = PtrCoord(pDst, x, pRasInfo->pixelStride, 0, 0);
+                (*pPrim->funcs.maskfill)(pRow,
+                                         NULL, 0, 0,
+                                         endx - x, 1,
+                                         color, pRasInfo,
+                                         pPrim, pCompInfo);
+                x = endx;
+            }
+        } else if (lastcov > 0 && rmin >= rmax) {
+            /* We are not at 0 coverage, but there is no right edge, */
+            /* force a right edge so we process pixels out to width. */
+            rmax = width;
+        }
+        /* The following loop will process the right AA edge and/or any */
+        /* partial coverage center section not processed above. */
+        while (x < rmax) {
+            accum += pAccum[x];
+            pAccum[x] = 0.0f;
+            pMask[moff++] = DblToMask(accum);
+            x++;
+        }
+        if (moff > 0) {
+            void *pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
+            (*pPrim->funcs.maskfill)(pRow,
+                                     pMask, 0, 0,
+                                     moff, 1,
+                                     color, pRasInfo,
+                                     pPrim, pCompInfo);
+        }
+        pDst = PtrAddBytes(pDst, pRasInfo->scanStride);
+        cy1++;
+    }
+    if (pAccum != localaccum) {
+        free(pAccum);
+    }
+}
+
+/*
+ * Class:     sun_java2d_loops_MaskFill
+ * Method:    FillAAPgram
+ * Signature: (Lsun/java2d/SunGraphics2D;Lsun/java2d/SurfaceData;Ljava/awt/Composite;DDDDDD)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_java2d_loops_MaskFill_FillAAPgram
+    (JNIEnv *env, jobject self,
+     jobject sg2d, jobject sData, jobject comp,
+     jdouble x0, jdouble y0,
+     jdouble dx1, jdouble dy1,
+     jdouble dx2, jdouble dy2)
+{
+    SurfaceDataOps *sdOps;
+    SurfaceDataRasInfo rasInfo;
+    NativePrimitive *pPrim;
+    CompositeInfo compInfo;
+    jint ix1, iy1, ix2, iy2;
+
+    if ((dy1 == 0 && dx1 == 0) || (dy2 == 0 && dx2 == 0)) {
+        return;
+    }
+
+    /*
+     * Sort parallelogram by y values, ensure that each delta vector
+     * has a non-negative y delta.
+     */
+    SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2, );
+
+    PGRAM_MIN_MAX(ix1, ix2, x0, dx1, dx2, JNI_TRUE);
+    iy1 = (jint) floor(y0);
+    iy2 = (jint) ceil(y0 + dy1 + dy2);
+
+    pPrim = GetNativePrim(env, self);
+    if (pPrim == NULL) {
+        return;
+    }
+    if (pPrim->pCompType->getCompInfo != NULL) {
+        (*pPrim->pCompType->getCompInfo)(env, &compInfo, comp);
+    }
+
+    sdOps = SurfaceData_GetOps(env, sData);
+    if (sdOps == 0) {
+        return;
+    }
+
+    GrPrim_Sg2dGetClip(env, sg2d, &rasInfo.bounds);
+    SurfaceData_IntersectBoundsXYXY(&rasInfo.bounds, ix1, iy1, ix2, iy2);
+    if (rasInfo.bounds.y2 <= rasInfo.bounds.y1 ||
+        rasInfo.bounds.x2 <= rasInfo.bounds.x1)
+    {
+        return;
+    }
+
+    if (sdOps->Lock(env, sdOps, &rasInfo, pPrim->dstflags) != SD_SUCCESS) {
+        return;
+    }
+
+    ix1 = rasInfo.bounds.x1;
+    iy1 = rasInfo.bounds.y1;
+    ix2 = rasInfo.bounds.x2;
+    iy2 = rasInfo.bounds.y2;
+    if (ix2 > ix1 && iy2 > iy1) {
+        jint width = ix2 - ix1;
+        jint color = GrPrim_Sg2dGetEaRGB(env, sg2d);
+        unsigned char localmask[MASK_BUF_LEN];
+        unsigned char *pMask = ((width > MASK_BUF_LEN)
+                                ? malloc(width)
+                                : localmask);
+
+        sdOps->GetRasInfo(env, sdOps, &rasInfo);
+        if (rasInfo.rasBase != NULL && pMask != NULL) {
+            void *pDst = PtrCoord(rasInfo.rasBase,
+                                  ix1, rasInfo.pixelStride,
+                                  iy1, rasInfo.scanStride);
+            if (dy1 == 0 && dx2 == 0) {
+                if (dx1 < 0) {
+                    // We sorted by Y above, but not by X
+                    x0 += dx1;
+                    dx1 = -dx1;
+                }
+                fillAARect(pPrim, &rasInfo, &compInfo,
+                           color, pMask, pDst,
+                           x0, y0, x0+dx1, y0+dy2);
+            } else if (dx1 == 0 && dy2 == 0) {
+                if (dx2 < 0) {
+                    // We sorted by Y above, but not by X
+                    x0 += dx2;
+                    dx2 = -dx2;
+                }
+                fillAARect(pPrim, &rasInfo, &compInfo,
+                           color, pMask, pDst,
+                           x0, y0, x0+dx2, y0+dy1);
+            } else {
+                fillAAPgram(pPrim, &rasInfo, &compInfo,
+                            color, pMask, pDst,
+                            x0, y0, dx1, dy1, dx2, dy2);
+            }
+        }
+        SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
+        if (pMask != NULL && pMask != localmask) {
+            free(pMask);
+        }
     }
     SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
 }
+
+/* Main function to fill a double pair of (inner and outer) parallelograms */
+static void
+drawAAPgram(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo,
+            CompositeInfo *pCompInfo, jint color, unsigned char *pMask,
+            void *pDst,
+            jdouble ox0, jdouble oy0,
+            jdouble dx1, jdouble dy1,
+            jdouble dx2, jdouble dy2,
+            jdouble ldx1, jdouble ldy1,
+            jdouble ldx2, jdouble ldy2)
+{
+    jint cx1 = pRasInfo->bounds.x1;
+    jint cy1 = pRasInfo->bounds.y1;
+    jint cx2 = pRasInfo->bounds.x2;
+    jint cy2 = pRasInfo->bounds.y2;
+    jint width = cx2 - cx1;
+    EdgeInfo edges[8];
+    jfloat localaccum[MASK_BUF_LEN + 1];
+    jfloat *pAccum;
+
+    if (!storePgram(edges + 0, edges + 6,
+                    ox0, oy0,
+                    dx1 + ldx1, dy1 + ldy1,
+                    dx2 + ldx2, dy2 + ldy2,
+                    cx1, cy1, cx2, cy2,
+                    JNI_FALSE))
+    {
+        /* If outer pgram does not contribute, then inner cannot either. */
+        return;
+    }
+    storePgram(edges + 2, edges + 4,
+               ox0 + ldx1 + ldx2, oy0 + ldy1 + ldy2,
+               dx1 - ldx1, dy1 - ldy1,
+               dx2 - ldx2, dy2 - ldy2,
+               cx1, cy1, cx2, cy2,
+               JNI_TRUE);
+
+    pAccum = ((width > MASK_BUF_LEN)
+              ? malloc((width + 1) * sizeof(jfloat))
+              : localaccum);
+    if (pAccum == NULL) {
+        return;
+    }
+    memset(pAccum, 0, (width+1) * sizeof(jfloat));
+
+    while (cy1 < cy2) {
+        jint lmin, lmax, rmin, rmax;
+        jint moff, x;
+        jdouble accum;
+        unsigned char lastcov;
+
+        lmin = rmin = width + 2;
+        lmax = rmax = 0;
+        ACCUM_EDGE(&edges[0], pAccum, lmin, lmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[1], pAccum, lmin, lmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[2], pAccum, lmin, lmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[3], pAccum, lmin, lmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[4], pAccum, rmin, rmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[5], pAccum, rmin, rmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[6], pAccum, rmin, rmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[7], pAccum, rmin, rmax,
+                   cx1, cy1, cx2, cy1+1);
+        if (lmax > width) {
+            lmax = width; /* Extra col has data we do not need. */
+        }
+        if (rmax > width) {
+            rmax = width; /* Extra col has data we do not need. */
+        }
+        /* If ranges overlap, handle both in the first pass. */
+        if (rmin <= lmax) {
+            lmax = rmax;
+        }
+
+        x = lmin;
+        accum = 0.0;
+        moff = 0;
+        lastcov = 0;
+        while (x < lmax) {
+            accum += pAccum[x];
+            pAccum[x] = 0.0f;
+            pMask[moff++] = lastcov = DblToMask(accum);
+            x++;
+        }
+        /* Check for an empty or solidcenter section. */
+        if (lastcov == 0 || lastcov == 0xFF) {
+            jint endx;
+            void *pRow;
+
+            /* First process the existing partial coverage data. */
+            if (moff > 0) {
+                pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
+                (*pPrim->funcs.maskfill)(pRow,
+                                         pMask, 0, 0,
+                                         moff, 1,
+                                         color, pRasInfo,
+                                         pPrim, pCompInfo);
+                moff = 0;
+            }
+
+            /* Where does the center section end? */
+            /* If there is no right AA edge in the accum buffer, then */
+            /* the right edge was beyond the clip, so fill out to width */
+            endx = (rmin < rmax) ? rmin : width;
+            if (x < endx) {
+                if (lastcov == 0xFF) {
+                    pRow = PtrCoord(pDst, x, pRasInfo->pixelStride, 0, 0);
+                    (*pPrim->funcs.maskfill)(pRow,
+                                             NULL, 0, 0,
+                                             endx - x, 1,
+                                             color, pRasInfo,
+                                             pPrim, pCompInfo);
+                }
+                x = endx;
+            }
+        } else if (rmin >= rmax) {
+            /* We are not at 0 coverage, but there is no right edge, */
+            /* force a right edge so we process pixels out to width. */
+            rmax = width;
+        }
+        /* The following loop will process the right AA edge and/or any */
+        /* partial coverage center section not processed above. */
+        while (x < rmax) {
+            accum += pAccum[x];
+            pAccum[x] = 0.0f;
+            pMask[moff++] = lastcov = DblToMask(accum);
+            x++;
+        }
+        if (moff > 0) {
+            void *pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
+            (*pPrim->funcs.maskfill)(pRow,
+                                     pMask, 0, 0,
+                                     moff, 1,
+                                     color, pRasInfo,
+                                     pPrim, pCompInfo);
+        }
+        if (lastcov == 0xFF && x < width) {
+            void *pRow = PtrCoord(pDst, x, pRasInfo->pixelStride, 0, 0);
+            (*pPrim->funcs.maskfill)(pRow,
+                                     NULL, 0, 0,
+                                     width - x, 1,
+                                     color, pRasInfo,
+                                     pPrim, pCompInfo);
+        }
+        pDst = PtrAddBytes(pDst, pRasInfo->scanStride);
+        cy1++;
+    }
+    if (pAccum != localaccum) {
+        free(pAccum);
+    }
+}
+
+/*
+ * Class:     sun_java2d_loops_MaskFill
+ * Method:    DrawAAPgram
+ * Signature: (Lsun/java2d/SunGraphics2D;Lsun/java2d/SurfaceData;Ljava/awt/Composite;DDDDDDDD)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_java2d_loops_MaskFill_DrawAAPgram
+    (JNIEnv *env, jobject self,
+     jobject sg2d, jobject sData, jobject comp,
+     jdouble x0, jdouble y0,
+     jdouble dx1, jdouble dy1,
+     jdouble dx2, jdouble dy2,
+     jdouble lw1, jdouble lw2)
+{
+    SurfaceDataOps *sdOps;
+    SurfaceDataRasInfo rasInfo;
+    NativePrimitive *pPrim;
+    CompositeInfo compInfo;
+    jint ix1, iy1, ix2, iy2;
+    jdouble ldx1, ldy1, ldx2, ldy2;
+    jdouble ox0, oy0;
+
+    if ((dy1 == 0 && dx1 == 0) || (dy2 == 0 && dx2 == 0)) {
+        return;
+    }
+
+    /*
+     * Sort parallelogram by y values, ensure that each delta vector
+     * has a non-negative y delta.
+     */
+    SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2,
+               v = lw1; lw1 = lw2; lw2 = v;);
+
+    // dx,dy for line width in the "1" and "2" directions.
+    ldx1 = dx1 * lw1;
+    ldy1 = dy1 * lw1;
+    ldx2 = dx2 * lw2;
+    ldy2 = dy2 * lw2;
+
+    // calculate origin of the outer parallelogram
+    ox0 = x0 - (ldx1 + ldx2) / 2.0;
+    oy0 = y0 - (ldy1 + ldy2) / 2.0;
+
+    if (lw1 >= 1.0 || lw2 >= 1.0) {
+        /* Only need to fill an outer pgram if the interior no longer
+         * has a hole in it (i.e. if either of the line width ratios
+         * were greater than or equal to 1.0).
+         */
+        Java_sun_java2d_loops_MaskFill_FillAAPgram(env, self,
+                                                   sg2d, sData, comp,
+                                                   ox0, oy0,
+                                                   dx1 + ldx1, dy1 + ldy1,
+                                                   dx2 + ldx2, dy2 + ldy2);
+        return;
+    }
+
+    PGRAM_MIN_MAX(ix1, ix2, ox0, dx1+ldx1, dx2+ldx2, JNI_TRUE);
+    iy1 = (jint) floor(oy0);
+    iy2 = (jint) ceil(oy0 + dy1 + ldy1 + dy2 + ldy2);
+
+    pPrim = GetNativePrim(env, self);
+    if (pPrim == NULL) {
+        return;
+    }
+    if (pPrim->pCompType->getCompInfo != NULL) {
+        (*pPrim->pCompType->getCompInfo)(env, &compInfo, comp);
+    }
+
+    sdOps = SurfaceData_GetOps(env, sData);
+    if (sdOps == 0) {
+        return;
+    }
+
+    GrPrim_Sg2dGetClip(env, sg2d, &rasInfo.bounds);
+    SurfaceData_IntersectBoundsXYXY(&rasInfo.bounds, ix1, iy1, ix2, iy2);
+    if (rasInfo.bounds.y2 <= rasInfo.bounds.y1 ||
+        rasInfo.bounds.x2 <= rasInfo.bounds.x1)
+    {
+        return;
+    }
+
+    if (sdOps->Lock(env, sdOps, &rasInfo, pPrim->dstflags) != SD_SUCCESS) {
+        return;
+    }
+
+    ix1 = rasInfo.bounds.x1;
+    iy1 = rasInfo.bounds.y1;
+    ix2 = rasInfo.bounds.x2;
+    iy2 = rasInfo.bounds.y2;
+    if (ix2 > ix1 && iy2 > iy1) {
+        jint width = ix2 - ix1;
+        jint color = GrPrim_Sg2dGetEaRGB(env, sg2d);
+        unsigned char localmask[MASK_BUF_LEN];
+        unsigned char *pMask = ((width > MASK_BUF_LEN)
+                                ? malloc(width)
+                                : localmask);
+
+        sdOps->GetRasInfo(env, sdOps, &rasInfo);
+        if (rasInfo.rasBase != NULL && pMask != NULL) {
+            void *pDst = PtrCoord(rasInfo.rasBase,
+                                  ix1, rasInfo.pixelStride,
+                                  iy1, rasInfo.scanStride);
+            /*
+             * NOTE: aligned rects could probably be drawn
+             * even faster with a little work here.
+             * if (dy1 == 0 && dx2 == 0) {
+             *     drawAARect(pPrim, &rasInfo, &compInfo,
+             *                color, pMask, pDst,
+             *                ox0, oy0, ox0+dx1+ldx1, oy0+dy2+ldy2, ldx1, ldy2);
+             * } else if (dx1 == 0 && dy2 == 0) {
+             *     drawAARect(pPrim, &rasInfo, &compInfo,
+             *                color, pMask, pDst,
+             *                ox0, oy0, ox0+dx2+ldx2, oy0+dy1+ldy1, ldx2, ldy1);
+             * } else {
+             */
+            drawAAPgram(pPrim, &rasInfo, &compInfo,
+                        color, pMask, pDst,
+                        ox0, oy0,
+                        dx1, dy1, dx2, dy2,
+                        ldx1, ldy1, ldx2, ldy2);
+            /*
+             * }
+             */
+        }
+        SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
+        if (pMask != NULL && pMask != localmask) {
+            free(pMask);
+        }
+    }
+    SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
+}
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/native/sun/java2d/loops/ParallelogramUtils.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/java2d/loops/ParallelogramUtils.h	Wed Jul 05 17:32:27 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+#ifndef ParallelogramUtils_h_Included
+#define ParallelogramUtils_h_Included
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PGRAM_MIN_MAX(bmin, bmax, v0, dv1, dv2, AA) \
+    do { \
+        double vmin, vmax; \
+        if (dv1 < 0) { \
+            vmin = v0+dv1; \
+            vmax = v0; \
+        } else { \
+            vmin = v0; \
+            vmax = v0+dv1; \
+        } \
+        if (dv2 < 0) { \
+            vmin += dv2; \
+        } else { \
+            vmax += dv2; \
+        } \
+        if (AA) { \
+            bmin = (jint) floor(vmin); \
+            bmax = (jint) ceil(vmax); \
+        } else { \
+            bmin = (jint) floor(vmin + 0.5); \
+            bmax = (jint) floor(vmax + 0.5); \
+        } \
+    } while(0)
+
+#define PGRAM_INIT_X(starty, x, y, slope) \
+    (DblToLong((x) + (slope) * ((starty)+0.5 - (y))) + LongOneHalf - 1)
+
+/*
+ * Sort parallelogram by y values, ensure that each delta vector
+ * has a non-negative y delta.
+ */
+#define SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2, OTHER_SWAP_CODE) \
+    do { \
+        if (dy1 < 0) { \
+            x0 += dx1;  y0 += dy1; \
+            dx1 = -dx1; dy1 = -dy1; \
+        } \
+        if (dy2 < 0) { \
+            x0 += dx2;  y0 += dy2; \
+            dx2 = -dx2; dy2 = -dy2; \
+        } \
+        /* Sort delta vectors so dxy1 is left of dxy2. */ \
+        if (dx1 * dy2 > dx2 * dy1) { \
+            double v; \
+            v = dx1; dx1 = dx2; dx2 = v; \
+            v = dy1; dy1 = dy2; dy2 = v; \
+            OTHER_SWAP_CODE \
+        } \
+    } while(0)
+
+#endif /* ParallelogramUtils_h_Included */
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/share/native/sun/java2d/pipe/BufferedMaskBlit.c
--- a/jdk/src/share/native/sun/java2d/pipe/BufferedMaskBlit.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/share/native/sun/java2d/pipe/BufferedMaskBlit.c	Wed Jul 05 17:32:27 2017 +0200
@@ -119,7 +119,8 @@
                 PtrCoord(srcInfo.rasBase,
                          srcInfo.bounds.x1, srcInfo.pixelStride,
                          srcInfo.bounds.y1, srcInfo.scanStride);
-            unsigned char *pMask =
+            unsigned char *pMask, *pMaskAlloc;
+            pMask = pMaskAlloc =
                 (*env)->GetPrimitiveArrayCritical(env, maskArray, 0);
             if (pMask == NULL) {
                 J2dRlsTraceLn(J2D_TRACE_ERROR,
@@ -274,7 +275,7 @@
             bpos += width * height * sizeof(jint);
 
             (*env)->ReleasePrimitiveArrayCritical(env, maskArray,
-                                                  pMask, JNI_ABORT);
+                                                  pMaskAlloc, JNI_ABORT);
         }
         SurfaceData_InvokeRelease(env, srcOps, &srcInfo);
     }
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/solaris/classes/java/lang/ProcessEnvironment.java
--- a/jdk/src/solaris/classes/java/lang/ProcessEnvironment.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/solaris/classes/java/lang/ProcessEnvironment.java	Wed Jul 05 17:32:27 2017 +0200
@@ -68,7 +68,7 @@
         // We cache the C environment.  This means that subsequent calls
         // to putenv/setenv from C will not be visible from Java code.
         byte[][] environ = environ();
-        theEnvironment = new HashMap(environ.length/2 + 3);
+        theEnvironment = new HashMap<>(environ.length/2 + 3);
         // Read environment variables back to front,
         // so that earlier variables override later ones.
         for (int i = environ.length-1; i > 0; i-=2)
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/solaris/classes/java/util/prefs/FileSystemPreferences.java
--- a/jdk/src/solaris/classes/java/util/prefs/FileSystemPreferences.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/solaris/classes/java/util/prefs/FileSystemPreferences.java	Wed Jul 05 17:32:27 2017 +0200
@@ -354,7 +354,7 @@
      * log against that map.  The resulting map is then written back
      * to the disk.
      */
-    final List changeLog = new ArrayList();
+    final List changeLog = new ArrayList<>();
 
     /**
      * Represents a change to a preference.
@@ -507,7 +507,7 @@
         });
         if (newNode) {
             // These 2 things guarantee node will get wrtten at next flush/sync
-            prefsCache = new TreeMap();
+            prefsCache = new TreeMap<>();
             nodeCreate = new NodeCreate();
             changeLog.add(nodeCreate);
         }
@@ -550,7 +550,7 @@
             loadCache();
         } catch(Exception e) {
             // assert lastSyncTime == 0;
-            prefsCache = new TreeMap();
+            prefsCache = new TreeMap<>();
         }
     }
 
@@ -567,7 +567,7 @@
             AccessController.doPrivileged(
                 new PrivilegedExceptionAction() {
                 public Void run() throws BackingStoreException {
-                    Map m = new TreeMap();
+                    Map m = new TreeMap<>();
                     long newLastSyncTime = 0;
                     try {
                         newLastSyncTime = prefsFile.lastModified();
@@ -581,7 +581,7 @@
                             prefsFile.renameTo( new File(
                                                     prefsFile.getParentFile(),
                                                   "IncorrectFormatPrefs.xml"));
-                            m = new TreeMap();
+                            m = new TreeMap<>();
                         } else if (e instanceof FileNotFoundException) {
                         getLogger().warning("Prefs file removed in background "
                                            + prefsFile.getPath());
@@ -646,7 +646,7 @@
         return AccessController.doPrivileged(
             new PrivilegedAction() {
                 public String[] run() {
-                    List result = new ArrayList();
+                    List result = new ArrayList<>();
                     File[] dirContents = dir.listFiles();
                     if (dirContents != null) {
                         for (int i = 0; i < dirContents.length; i++)
@@ -794,7 +794,7 @@
         } else if (lastSyncTime != 0 && !dir.exists()) {
             // This node was removed in the background.  Playback any changes
             // against a virgin (empty) Map.
-            prefsCache = new TreeMap();
+            prefsCache = new TreeMap<>();
             replayChanges();
         }
         if (!changeLog.isEmpty()) {
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c	Wed Jul 05 17:32:27 2017 +0200
@@ -137,41 +137,43 @@
         file = fopen(ALSA_VERSION_PROC_FILE, "r");
         ALSAVersionString[0] = 0;
         if (file) {
-            fgets(ALSAVersionString, ALSAVersionString_LENGTH, file);
-            // parse for version number
-            totalLen = strlen(ALSAVersionString);
-            inVersionString = FALSE;
-            len = 0;
-            curr = 0;
-            while (curr < totalLen) {
-                if (!inVersionString) {
-                    // is this char the beginning of a version string ?
-                    if (ALSAVersionString[curr] >= '0'
-                        && ALSAVersionString[curr] <= '9') {
-                        inVersionString = TRUE;
+            if (NULL != fgets(ALSAVersionString, ALSAVersionString_LENGTH, file)) {
+                // parse for version number
+                totalLen = strlen(ALSAVersionString);
+                inVersionString = FALSE;
+                len = 0;
+                curr = 0;
+                while (curr < totalLen) {
+                    if (!inVersionString) {
+                        // is this char the beginning of a version string ?
+                        if (ALSAVersionString[curr] >= '0'
+                            && ALSAVersionString[curr] <= '9') {
+                            inVersionString = TRUE;
+                        }
                     }
+                    if (inVersionString) {
+                        // the version string ends with white space
+                        if (ALSAVersionString[curr] <= 32) {
+                            break;
+                        }
+                        if (curr != len) {
+                            // copy this char to the beginning of the string
+                            ALSAVersionString[len] = ALSAVersionString[curr];
+                        }
+                        len++;
+                    }
+                    curr++;
                 }
-                if (inVersionString) {
-                    // the version string ends with white space
-                    if (ALSAVersionString[curr] <= 32) {
-                        break;
-                    }
-                    if (curr != len) {
-                        // copy this char to the beginning of the string
-                        ALSAVersionString[len] = ALSAVersionString[curr];
-                    }
-                    len++;
+                // remove trailing dots
+                while ((len > 0) && (ALSAVersionString[len - 1] == '.')) {
+                    len--;
                 }
-                curr++;
+                // null terminate
+                ALSAVersionString[len] = 0;
             }
-            // remove trailing dots
-            while ((len > 0) && (ALSAVersionString[len - 1] == '.')) {
-                len--;
-            }
-            // null terminate
-            ALSAVersionString[len] = 0;
+            fclose(file);
+            hasGottenALSAVersion = TRUE;
         }
-        hasGottenALSAVersion = TRUE;
     }
     strncpy(buffer, ALSAVersionString, len);
 }
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c	Wed Jul 05 17:32:27 2017 +0200
@@ -32,6 +32,9 @@
 #include 
 #include "PlatformMidi.h"
 #include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
+#if defined(i586)
+#include 
+#endif
 
 /*
  * Helper methods
@@ -73,9 +76,38 @@
     return (char*) getErrorStr(err);
 }
 
+INT32 MIDI_IN_GetNumDevices() {
+/* Workaround for 6842956: 32bit app on 64bit linux
+ * gets assertion failure trying to open midiIn ports.
+ * Untill the issue is fixed in ALSA
+ * (https://bugtrack.alsa-project.org/alsa-bug/view.php?id=4807)
+ * report no midi in devices in the configuration.
+ */
+#if defined(i586)
+    static int jre32onlinux64 = -1;
+    if (jre32onlinux64 < 0) {
+        jre32onlinux64 = 0;
+        /* The workaround may be disabled setting "JAVASOUND_ENABLE_MIDIIN"
+         * environment variable.
+         */
+        if (getenv("JAVASOUND_ENABLE_MIDIIN") == NULL) {
+            struct utsname u;
+            jre32onlinux64 = 0;
+            if (uname(&u) == 0) {
+                if (strstr(u.machine, "64") != NULL) {
+                    TRACE0("jre32 on linux64 detected - report no midiIn devices\n");
+                    jre32onlinux64 = 1;
+                }
+            }
+        }
+    }
+    if (jre32onlinux64) {
+        return 0;
+    }
+#endif
 
-INT32 MIDI_IN_GetNumDevices() {
     TRACE0("MIDI_IN_GetNumDevices()\n");
+
     return getMidiDeviceCount(SND_RAWMIDI_STREAM_INPUT);
 }
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c	Wed Jul 05 17:32:27 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -372,7 +372,7 @@
     snd_rawmidi_t* native_handle;
     snd_midi_event_t* event_parser = NULL;
     int err;
-    UINT32 deviceID;
+    UINT32 deviceID = 0;
     char devicename[100];
 #ifdef ALSA_MIDI_USE_PLUGHW
     int usePlugHw = 1;
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c	Wed Jul 05 17:32:27 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -127,7 +127,7 @@
     int ret;
     int sampleSizeInBytes, significantBits, isSigned, isBigEndian, enc;
     int origSampleSizeInBytes, origSignificantBits;
-    int channels, minChannels, maxChannels;
+    unsigned int channels, minChannels, maxChannels;
     int rate, bitIndex;
 
     for (bitIndex = 0; bitIndex <= MAX_BIT_INDEX; bitIndex++) handledBits[bitIndex] = FALSE;
@@ -152,7 +152,6 @@
             }
         }
         snd_pcm_hw_params_get_format_mask(hwParams, formatMask);
-#ifdef ALSA_PCM_NEW_HW_PARAMS_API
         if (ret == 0) {
             ret = snd_pcm_hw_params_get_channels_min(hwParams, &minChannels);
             if (ret != 0) {
@@ -165,13 +164,6 @@
                 ERROR1("snd_pcm_hw_params_get_channels_max returned error %d\n", ret);
             }
         }
-#else
-        minChannels = snd_pcm_hw_params_get_channels_min(hwParams);
-        maxChannels = snd_pcm_hw_params_get_channels_max(hwParams);
-        if (minChannels > maxChannels) {
-            ERROR2("MinChannels=%d, maxChannels=%d\n", minChannels, maxChannels);
-        }
-#endif
 
         // since we queried the hw: device, for many soundcards, it will only
         // report the maximum number of channels (which is the only way to talk
@@ -222,7 +214,7 @@
                                 } else {
                                     for (channels = minChannels; channels <= maxChannels; channels++) {
                                         DAUDIO_AddAudioFormat(creator, significantBits,
-                                                              (channels < 0)?-1:(sampleSizeInBytes * channels),
+                                                              sampleSizeInBytes * channels,
                                                               channels, rate,
                                                               enc, isSigned, isBigEndian);
                                     }
@@ -254,7 +246,7 @@
     snd_pcm_sw_params_t* swParams;
     int bufferSizeInBytes;
     int frameSize; // storage size in Bytes
-    int periods;
+    unsigned int periods;
     snd_pcm_uframes_t periodSize;
 #ifdef GET_POSITION_METHOD2
     // to be used exclusively by getBytePosition!
@@ -305,8 +297,8 @@
                 int channels,
                 int bufferSizeInFrames,
                 snd_pcm_format_t format) {
-    unsigned int rrate;
-    int ret, dir, periods, periodTime;
+    unsigned int rrate, periodTime, periods;
+    int ret, dir;
     snd_pcm_uframes_t alsaBufferSizeInFrames = (snd_pcm_uframes_t) bufferSizeInFrames;
 
     /* choose all parameters */
@@ -335,12 +327,8 @@
     }
     /* set the stream rate */
     rrate = (int) (sampleRate + 0.5f);
-#ifdef ALSA_PCM_NEW_HW_PARAMS_API
     dir = 0;
     ret = snd_pcm_hw_params_set_rate_near(info->handle, info->hwParams, &rrate, &dir);
-#else
-    ret = snd_pcm_hw_params_set_rate_near(info->handle, info->hwParams, rrate, 0);
-#endif
     if (ret < 0) {
         ERROR2("Rate %dHz not available for playback: %s\n", (int) (sampleRate+0.5f), snd_strerror(ret));
         return FALSE;
@@ -350,12 +338,7 @@
         return FALSE;
     }
     /* set the buffer time */
-#ifdef ALSA_PCM_NEW_HW_PARAMS_API
-
     ret = snd_pcm_hw_params_set_buffer_size_near(info->handle, info->hwParams, &alsaBufferSizeInFrames);
-#else
-    ret = snd_pcm_hw_params_set_buffer_size_near(info->handle, info->hwParams, alsaBufferSizeInFrames);
-#endif
     if (ret < 0) {
         ERROR2("Unable to set buffer size to %d frames: %s\n",
                (int) alsaBufferSizeInFrames, snd_strerror(ret));
@@ -366,12 +349,7 @@
     if (bufferSizeInFrames > 1024) {
         dir = 0;
         periodTime = DEFAULT_PERIOD_TIME;
-#ifdef ALSA_PCM_NEW_HW_PARAMS_API
         ret = snd_pcm_hw_params_set_period_time_near(info->handle, info->hwParams, &periodTime, &dir);
-#else
-        periodTime = snd_pcm_hw_params_set_period_time_near(info->handle, info->hwParams, periodTime, &dir);
-        ret = periodTime;
-#endif
         if (ret < 0) {
             ERROR2("Unable to set period time to %d: %s\n", DEFAULT_PERIOD_TIME, snd_strerror(ret));
             return FALSE;
@@ -380,12 +358,7 @@
         /* set the period count for very small buffer sizes to 2 */
         dir = 0;
         periods = 2;
-#ifdef ALSA_PCM_NEW_HW_PARAMS_API
         ret = snd_pcm_hw_params_set_periods_near(info->handle, info->hwParams, &periods, &dir);
-#else
-        periods = snd_pcm_hw_params_set_periods_near(info->handle, info->hwParams, periods, &dir);
-        ret = periods;
-#endif
         if (ret < 0) {
             ERROR2("Unable to set period count to %d: %s\n", /*periods*/ 2, snd_strerror(ret));
             return FALSE;
@@ -421,12 +394,6 @@
         ERROR1("Unable to set avail min for playback: %s\n", snd_strerror(ret));
         return FALSE;
     }
-    /* align all transfers to 1 sample */
-    ret = snd_pcm_sw_params_set_xfer_align(info->handle, info->swParams, 1);
-    if (ret < 0) {
-        ERROR1("Unable to set transfer align: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
     /* write the parameters to the playback device */
     ret = snd_pcm_sw_params(info->handle, info->swParams);
     if (ret < 0) {
@@ -448,7 +415,6 @@
     int ret = 0;
     AlsaPcmInfo* info = NULL;
     /* snd_pcm_uframes_t is 64 bit on 64-bit systems */
-    snd_pcm_uframes_t alsaPeriodSize = 0;
     snd_pcm_uframes_t alsaBufferSizeInFrames = 0;
 
 
@@ -484,21 +450,13 @@
                                 bufferSizeInBytes / frameSize,
                                 format)) {
                     info->frameSize = frameSize;
-#ifdef ALSA_PCM_NEW_HW_PARAMS_API
-                    ret = snd_pcm_hw_params_get_period_size(info->hwParams, &alsaPeriodSize, &dir);
-                    info->periodSize = (int) alsaPeriodSize;
+                    ret = snd_pcm_hw_params_get_period_size(info->hwParams, &info->periodSize, &dir);
                     if (ret < 0) {
                         ERROR1("ERROR: snd_pcm_hw_params_get_period: %s\n", snd_strerror(ret));
                     }
                     snd_pcm_hw_params_get_periods(info->hwParams, &(info->periods), &dir);
                     snd_pcm_hw_params_get_buffer_size(info->hwParams, &alsaBufferSizeInFrames);
                     info->bufferSizeInBytes = (int) alsaBufferSizeInFrames * frameSize;
-#else
-                    info->periodSize = snd_pcm_hw_params_get_period_size(info->hwParams, &dir);
-                    info->periods = snd_pcm_hw_params_get_periods(info->hwParams, &dir);
-                    info->bufferSizeInBytes = snd_pcm_hw_params_get_buffer_size(info->hwParams) * frameSize;
-                    ret = 0;
-#endif
                     TRACE3("  DAUDIO_Open: period size = %d frames, periods = %d. Buffer size: %d bytes.\n",
                            (int) info->periodSize, info->periods, info->bufferSizeInBytes);
                 }
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h	Wed Jul 05 17:32:27 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
  */
 
 // define this with a later version of ALSA than 0.9.0rc3
+// (starting from 1.0.0 it became default behaviour)
 #define ALSA_PCM_NEW_HW_PARAMS_API
 #include 
 #include "Utilities.h"
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_Ports.c
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_Ports.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_Ports.c	Wed Jul 05 17:32:27 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -380,7 +380,7 @@
     void* controls[10];
     int numControls;
     char* portName;
-    int isPlayback;
+    int isPlayback = 0;
     int isMono;
     int isStereo;
     char* type;
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c
--- a/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c	Wed Jul 05 17:32:27 2017 +0200
@@ -191,7 +191,7 @@
 
     fp_gdk_threads_enter();
 
-    const char *title = (*env)->GetStringUTFChars(env, jtitle, 0);
+    const char *title = jtitle == NULL? "": (*env)->GetStringUTFChars(env, jtitle, 0);
 
     if (mode == 1) {
         /* Save action */
@@ -212,7 +212,9 @@
         }
     }
 
-    (*env)->ReleaseStringUTFChars(env, jtitle, title);
+    if (jtitle != NULL) {
+      (*env)->ReleaseStringUTFChars(env, jtitle, title);
+    }
 
     /* Set the directory */
     if (jdir != NULL) {
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/solaris/native/sun/java2d/loops/vis_IntArgbPre_Mask.c
--- a/jdk/src/solaris/native/sun/java2d/loops/vis_IntArgbPre_Mask.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/solaris/native/sun/java2d/loops/vis_IntArgbPre_Mask.c	Wed Jul 05 17:32:27 2017 +0200
@@ -517,13 +517,15 @@
         ADD_SUFF(AnyIntSetRect)(pRasInfo, 0, 0, width, height,
                                 fgColor, pPrim, pCompInfo);
 #else
+        void *pBase = pRasInfo->rasBase;
+        pRasInfo->rasBase = rasBase;
         if (cnstA != 0xff) {
             fgColor = (cnstA << 24) | (cnstR << 16) | (cnstG << 8) | cnstB;
         }
         ADD_SUFF(AnyIntSetRect)(pRasInfo,
-                                pRasInfo->bounds.x1, pRasInfo->bounds.y1,
-                                pRasInfo->bounds.x2, pRasInfo->bounds.y2,
+                                0, 0, width, height,
                                 fgColor, pPrim, pCompInfo);
+        pRasInfo->rasBase = pBase;
 #endif
         return;
     }
@@ -582,11 +584,13 @@
     }
 
     if (pMask == NULL) {
+        void *pBase = pRasInfo->rasBase;
+        pRasInfo->rasBase = rasBase;
         fgColor = (cnstR << 24) | (cnstG << 16) | (cnstB << 8) | cnstA;
         ADD_SUFF(Any4ByteSetRect)(pRasInfo,
-                                  pRasInfo->bounds.x1, pRasInfo->bounds.y1,
-                                  pRasInfo->bounds.x2, pRasInfo->bounds.y2,
+                                  0, 0, width, height,
                                   fgColor, pPrim, pCompInfo);
+        pRasInfo->rasBase = pBase;
         return;
     }
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/solaris/native/sun/java2d/loops/vis_SrcMaskFill.c
--- a/jdk/src/solaris/native/sun/java2d/loops/vis_SrcMaskFill.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/solaris/native/sun/java2d/loops/vis_SrcMaskFill.c	Wed Jul 05 17:32:27 2017 +0200
@@ -150,10 +150,12 @@
     }
 
     if (pMask == NULL) {
+        void *pBase = pRasInfo->rasBase;
+        pRasInfo->rasBase = rasBase;
         ADD_SUFF(AnyIntSetRect)(pRasInfo,
-                                pRasInfo->bounds.x1, pRasInfo->bounds.y1,
-                                pRasInfo->bounds.x2, pRasInfo->bounds.y2,
+                                0, 0, width, height,
                                 fgColor, pPrim, pCompInfo);
+        pRasInfo->rasBase = pBase;
         return;
     }
 
@@ -214,15 +216,17 @@
     cnstB = (fgColor      ) & 0xff;
 
     if (pMask == NULL) {
+        void *pBase = pRasInfo->rasBase;
+        pRasInfo->rasBase = rasBase;
         if (cnstA == 0) {
             fgColor = 0;
         } else {
             fgColor = (fgColor << 8) | cnstA;
         }
         ADD_SUFF(Any4ByteSetRect)(pRasInfo,
-                                  pRasInfo->bounds.x1, pRasInfo->bounds.y1,
-                                  pRasInfo->bounds.x2, pRasInfo->bounds.y2,
+                                  0, 0, width, height,
                                   fgColor, pPrim, pCompInfo);
+        pRasInfo->rasBase = pBase;
         return;
     }
 
@@ -390,10 +394,12 @@
     if (cnstA == 0) fgColor = 0;
 
     if (pMask == NULL) {
+        void *pBase = pRasInfo->rasBase;
+        pRasInfo->rasBase = rasBase;
         ADD_SUFF(AnyIntSetRect)(pRasInfo,
-                                pRasInfo->bounds.x1, pRasInfo->bounds.y1,
-                                pRasInfo->bounds.x2, pRasInfo->bounds.y2,
+                                0, 0, width, height,
                                 fgColor, pPrim, pCompInfo);
+        pRasInfo->rasBase = pBase;
         return;
     }
 
@@ -458,10 +464,12 @@
     }
 
     if (pMask == NULL) {
+        void *pBase = pRasInfo->rasBase;
+        pRasInfo->rasBase = rasBase;
         ADD_SUFF(AnyIntSetRect)(pRasInfo,
-                                pRasInfo->bounds.x1, pRasInfo->bounds.y1,
-                                pRasInfo->bounds.x2, pRasInfo->bounds.y2,
+                                0, 0, width, height,
                                 fgColor, pPrim, pCompInfo);
+        pRasInfo->rasBase = pBase;
         return;
     }
 
@@ -526,10 +534,12 @@
     }
 
     if (pMask == NULL) {
+        void *pBase = pRasInfo->rasBase;
+        pRasInfo->rasBase = rasBase;
         ADD_SUFF(Any3ByteSetRect)(pRasInfo,
-                                  pRasInfo->bounds.x1, pRasInfo->bounds.y1,
-                                  pRasInfo->bounds.x2, pRasInfo->bounds.y2,
+                                  0, 0, width, height,
                                   fgColor, pPrim, pCompInfo);
+        pRasInfo->rasBase = pBase;
         return;
     }
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/solaris/native/sun/xawt/XToolkit.c
--- a/jdk/src/solaris/native/sun/xawt/XToolkit.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/solaris/native/sun/xawt/XToolkit.c	Wed Jul 05 17:32:27 2017 +0200
@@ -187,7 +187,9 @@
                          "()Ljava/awt/Point;");
 
     keyclass = (*env)->FindClass(env, "java/awt/event/KeyEvent");
-    DASSERT (keyclass != NULL);
+    if (JNU_IsNull(env, keyclass)) {
+        return;
+    }
 
     componentIDs.isProxyActive =
         (*env)->GetFieldID(env, keyclass, "isProxyActive",
@@ -715,8 +717,10 @@
   if (xawt_root_shell == None){
       if (classXRootWindow == NULL){
           jclass cls_tmp = (*env)->FindClass(env, "sun/awt/X11/XRootWindow");
-          classXRootWindow = (jclass)(*env)->NewGlobalRef(env, cls_tmp);
-          (*env)->DeleteLocalRef(env, cls_tmp);
+          if (!JNU_IsNull(env, cls_tmp)) {
+              classXRootWindow = (jclass)(*env)->NewGlobalRef(env, cls_tmp);
+              (*env)->DeleteLocalRef(env, cls_tmp);
+          }
       }
       if( classXRootWindow != NULL) {
           methodGetXRootWindow = (*env)->GetStaticMethodID(env, classXRootWindow, "getXRootWindow", "()J");
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/classes/java/lang/ProcessEnvironment.java
--- a/jdk/src/windows/classes/java/lang/ProcessEnvironment.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/classes/java/lang/ProcessEnvironment.java	Wed Jul 05 17:32:27 2017 +0200
@@ -250,8 +250,7 @@
                                    envblock.substring(eql+1,end));
         }
 
-        theCaseInsensitiveEnvironment
-            = new TreeMap(nameComparator);
+        theCaseInsensitiveEnvironment = new TreeMap<>(nameComparator);
         theCaseInsensitiveEnvironment.putAll(theEnvironment);
     }
 
@@ -296,8 +295,7 @@
     // Only for use by ProcessImpl.start()
     String toEnvironmentBlock() {
         // Sort Unicode-case-insensitively by name
-        List> list
-            = new ArrayList>(entrySet());
+        List> list = new ArrayList<>(entrySet());
         Collections.sort(list, entryComparator);
 
         StringBuilder sb = new StringBuilder(size()*30);
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java
--- a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java	Wed Jul 05 17:32:27 2017 +0200
@@ -999,6 +999,8 @@
     public void setBoundsOperation(int operation) {
     }
 
+    private volatile boolean isAccelCapable = true;
+
     /**
      * Returns whether this component is capable of being hw accelerated.
      * More specifically, whether rendering to this component or a
@@ -1009,11 +1011,22 @@
      * {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
      * PERPIXEL_TRANSLUCENT}.
      *
+     * Another condition is if Xor paint mode was detected when rendering
+     * to an on-screen accelerated surface associated with this peer.
+     * in this case both on- and off-screen acceleration for this peer is
+     * disabled.
+     *
      * @return {@code true} if this component is capable of being hw
      * accelerated, {@code false} otherwise
      * @see GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
      */
     public boolean isAccelCapable() {
+        if (!isAccelCapable ||
+            !isContainingTopLevelAccelCapable((Component)target))
+        {
+            return false;
+        }
+
         boolean isTranslucent =
             SunToolkit.isContainingTopLevelTranslucent((Component)target);
         // D3D/OGL and translucent windows interacted poorly in Windows XP;
@@ -1021,6 +1034,14 @@
         return !isTranslucent || Win32GraphicsEnvironment.isVistaOS();
     }
 
+    /**
+     * Disables acceleration for this peer.
+     */
+    public void disableAcceleration() {
+        isAccelCapable = false;
+    }
+
+
     native void setRectangularShape(int lox, int loy, int hix, int hiy,
                      Region region);
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/classes/sun/java2d/d3d/D3DSurfaceData.java
--- a/jdk/src/windows/classes/sun/java2d/d3d/D3DSurfaceData.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/classes/sun/java2d/d3d/D3DSurfaceData.java	Wed Jul 05 17:32:27 2017 +0200
@@ -437,6 +437,10 @@
         protected int getElem(final int x, final int y,
                               final SurfaceData sData)
         {
+            if (sData.isSurfaceLost()) {
+                return 0;
+            }
+
             int retPixel;
             D3DRenderQueue rq = D3DRenderQueue.getInstance();
             rq.lock();
@@ -456,6 +460,10 @@
         protected void setElem(final int x, final int y, final int pixel,
                                final SurfaceData sData)
         {
+            if (sData.isSurfaceLost()) {
+                  return;
+            }
+
             D3DRenderQueue rq = D3DRenderQueue.getInstance();
             rq.lock();
             try {
@@ -512,15 +520,32 @@
             sg2d.surfaceData.getTransparency() == Transparency.OPAQUE;
     }
 
+    /**
+     * If acceleration should no longer be used for this surface.
+     * This implementation flags to the manager that it should no
+     * longer attempt to re-create a D3DSurface.
+     */
+    void disableAccelerationForSurface() {
+        if (offscreenImage != null) {
+            SurfaceManager sm = SurfaceManager.getManager(offscreenImage);
+            if (sm instanceof D3DVolatileSurfaceManager) {
+                setSurfaceLost(true);
+                ((D3DVolatileSurfaceManager)sm).setAccelerationEnabled(false);
+            }
+        }
+    }
+
     public void validatePipe(SunGraphics2D sg2d) {
         TextPipe textpipe;
         boolean validated = false;
 
         // REMIND: the D3D pipeline doesn't support XOR!, more
-        // fixes will be needed below
+        // fixes will be needed below. For now we disable D3D rendering
+        // for the surface which had any XOR rendering done to.
         if (sg2d.compositeState >= sg2d.COMP_XOR) {
             super.validatePipe(sg2d);
             sg2d.imagepipe = d3dImagePipe;
+            disableAccelerationForSurface();
             return;
         }
 
@@ -895,7 +920,25 @@
         }
 
         @Override
+        void disableAccelerationForSurface() {
+            // for on-screen surfaces we need to make sure a backup GDI surface is
+            // is used until a new one is set (which may happen during a resize). We
+            // don't want the screen update maanger to replace the surface right way
+            // because it causes repainting issues in Swing, so we invalidate it,
+            // this will prevent SUM from issuing a replaceSurfaceData call.
+            setSurfaceLost(true);
+            invalidate();
+            flush();
+            peer.disableAcceleration();
+            ScreenUpdateManager.getInstance().dropScreenSurface(this);
+        }
+
+        @Override
         void restoreSurface() {
+            if (!peer.isAccelCapable()) {
+                throw new InvalidPipeException("Onscreen acceleration " +
+                                               "disabled for this surface");
+            }
             Window fsw = graphicsDevice.getFullScreenWindow();
             if (fsw != null && fsw != peer.getTarget()) {
                 throw new InvalidPipeException("Can't restore onscreen surface"+
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/classes/sun/java2d/opengl/WGLVolatileSurfaceManager.java
--- a/jdk/src/windows/classes/sun/java2d/opengl/WGLVolatileSurfaceManager.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/classes/sun/java2d/opengl/WGLVolatileSurfaceManager.java	Wed Jul 05 17:32:27 2017 +0200
@@ -133,7 +133,9 @@
 
     @Override
     protected boolean isConfigValid(GraphicsConfiguration gc) {
-        return ((gc == null) || (gc == vImg.getGraphicsConfig()));
+        return ((gc == null) ||
+                ((gc instanceof WGLGraphicsConfig) &&
+                 (gc == vImg.getGraphicsConfig())));
     }
 
     @Override
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/lib/tzmappings
--- a/jdk/src/windows/lib/tzmappings	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/lib/tzmappings	Wed Jul 05 17:32:27 2017 +0200
@@ -188,5 +188,6 @@
 UTC-11:921,921::GMT-1100:
 Ulaanbaatar Standard Time:922,922::Asia/Ulaanbaatar:
 Venezuela Standard Time:923,923::America/Caracas:
-Western Brazilian Standard Time:924,924:BR:America/Rio_Branco:
-Armenian Standard Time:925,925:AM:Asia/Yerevan:
+Magadan Standard Time:924,924::Asia/Magadan:
+Western Brazilian Standard Time:925,925:BR:America/Rio_Branco:
+Armenian Standard Time:926,926:AM:Asia/Yerevan:
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/native/java/net/Inet4AddressImpl.c
--- a/jdk/src/windows/native/java/net/Inet4AddressImpl.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/native/java/net/Inet4AddressImpl.c	Wed Jul 05 17:32:27 2017 +0200
@@ -559,8 +559,8 @@
 
         if (timeout >= 0) {
           optlen = sizeof(connect_rv);
-          if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
-                             &optlen) <0) {
+          if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
+                         &optlen) <0) {
             connect_rv = WSAGetLastError();
           }
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/native/java/net/Inet6AddressImpl.c
--- a/jdk/src/windows/native/java/net/Inet6AddressImpl.c	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/native/java/net/Inet6AddressImpl.c	Wed Jul 05 17:32:27 2017 +0200
@@ -671,8 +671,8 @@
         if (timeout >= 0) {
           /* has connection been established? */
           optlen = sizeof(connect_rv);
-          if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
-                             &optlen) <0) {
+          if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
+                         &optlen) <0) {
             connect_rv = WSAGetLastError();
           }
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/native/sun/windows/Devices.h
--- a/jdk/src/windows/native/sun/windows/Devices.h	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/Devices.h	Wed Jul 05 17:32:27 2017 +0200
@@ -54,7 +54,7 @@
            InstanceAccess& operator=(const InstanceAccess&);
            InstanceAccess* operator&();
        };
-friend                          InstanceAccess;
+friend class InstanceAccess;
 
 private:
                                 Devices(int numElements);
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/native/sun/windows/awt.h
--- a/jdk/src/windows/native/sun/windows/awt.h	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/awt.h	Wed Jul 05 17:32:27 2017 +0200
@@ -173,7 +173,7 @@
 
 // Platform encoding is Unicode (UTF-16), re-define JNU_ functions
 // to proper JNI functions.
-#define JNU_NewStringPlatform(env, x) env->NewString(reinterpret_cast(x), static_cast(_tcslen(x)))
+#define JNU_NewStringPlatform(env, x) env->NewString(reinterpret_cast(x), static_cast(_tcslen(x)))
 #define JNU_GetStringPlatformChars(env, x, y) reinterpret_cast(env->GetStringChars(x, y))
 #define JNU_ReleaseStringPlatformChars(env, x, y) env->ReleaseStringChars(x, reinterpret_cast(y))
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/native/sun/windows/awt_Debug.cpp
--- a/jdk/src/windows/native/sun/windows/awt_Debug.cpp	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/awt_Debug.cpp	Wed Jul 05 17:32:27 2017 +0200
@@ -47,12 +47,21 @@
     return ptr;
 }
 
+void * operator new[](size_t size, const char * filename, int linenumber) {
+    void * ptr = DMem_AllocateBlock(size, filename, linenumber);
+    if (ptr == NULL) {
+        throw std::bad_alloc();
+    }
+
+    return ptr;
+}
+
 #if _MSC_VER >= 1200
 void operator delete(void *ptr, const char*, int) {
     DASSERTMSG(FALSE, "This version of 'delete' should never get called!!!");
 }
 #endif
-void operator delete(void *ptr) {
+void operator delete(void *ptr) throw() {
     DMem_FreeBlock(ptr);
 }
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/native/sun/windows/awt_Debug.h
--- a/jdk/src/windows/native/sun/windows/awt_Debug.h	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/awt_Debug.h	Wed Jul 05 17:32:27 2017 +0200
@@ -48,11 +48,14 @@
     };
 
     extern void * operator new(size_t size, const char * filename, int linenumber);
+    extern void * operator new[](size_t size, const char * filename, int linenumber);
+
 #if _MSC_VER >= 1200
     /* VC 6.0 is more strict about enforcing matching placement new & delete */
     extern void operator delete(void *ptr, const char*, int);
 #endif
-    extern void operator delete(void *ptr);
+
+    extern void operator delete(void *ptr) throw();
     extern void DumpClipRectangle(const char * file, int line, int argc, const char * fmt, va_list arglist);
     extern void DumpUpdateRectangle(const char * file, int line, int argc, const char * fmt, va_list arglist);
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp
--- a/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp	Wed Jul 05 17:32:27 2017 +0200
@@ -650,7 +650,7 @@
 }
 
 void AwtDesktopProperties::SetStringProperty(LPCTSTR propName, LPTSTR value) {
-    jstring key = JNU_NewStringPlatform(GetEnv(), const_cast(propName));
+    jstring key = JNU_NewStringPlatform(GetEnv(), propName);
     GetEnv()->CallVoidMethod(self,
                              AwtDesktopProperties::setStringPropertyID,
                              key, JNU_NewStringPlatform(GetEnv(), value));
@@ -658,7 +658,7 @@
 }
 
 void AwtDesktopProperties::SetIntegerProperty(LPCTSTR propName, int value) {
-    jstring key = JNU_NewStringPlatform(GetEnv(), const_cast(propName));
+    jstring key = JNU_NewStringPlatform(GetEnv(), propName);
     GetEnv()->CallVoidMethod(self,
                              AwtDesktopProperties::setIntegerPropertyID,
                              key, (jint)value);
@@ -666,7 +666,7 @@
 }
 
 void AwtDesktopProperties::SetBooleanProperty(LPCTSTR propName, BOOL value) {
-    jstring key = JNU_NewStringPlatform(GetEnv(), const_cast(propName));
+    jstring key = JNU_NewStringPlatform(GetEnv(), propName);
     GetEnv()->CallVoidMethod(self,
                              AwtDesktopProperties::setBooleanPropertyID,
                              key, value ? JNI_TRUE : JNI_FALSE);
@@ -674,7 +674,7 @@
 }
 
 void AwtDesktopProperties::SetColorProperty(LPCTSTR propName, DWORD value) {
-    jstring key = JNU_NewStringPlatform(GetEnv(), const_cast(propName));
+    jstring key = JNU_NewStringPlatform(GetEnv(), propName);
     GetEnv()->CallVoidMethod(self,
                              AwtDesktopProperties::setColorPropertyID,
                              key, GetRValue(value), GetGValue(value),
@@ -726,7 +726,7 @@
                         style |= java_awt_Font_ITALIC;
                     }
 
-                    jstring key = JNU_NewStringPlatform(GetEnv(), const_cast(propName));
+                    jstring key = JNU_NewStringPlatform(GetEnv(), propName);
                     GetEnv()->CallVoidMethod(self,
                               AwtDesktopProperties::setFontPropertyID,
                               key, fontName, style, pointSize);
@@ -744,7 +744,7 @@
     jint pointSize;
     jint style;
 
-    fontName = JNU_NewStringPlatform(GetEnv(), const_cast(font.lfFaceName));
+    fontName = JNU_NewStringPlatform(GetEnv(), font.lfFaceName);
 
 #if 0
     HDC         hdc;
@@ -767,7 +767,7 @@
         style |= java_awt_Font_ITALIC;
     }
 
-    jstring key = JNU_NewStringPlatform(GetEnv(), const_cast(propName));
+    jstring key = JNU_NewStringPlatform(GetEnv(), propName);
     GetEnv()->CallVoidMethod(self, AwtDesktopProperties::setFontPropertyID,
                              key, fontName, style, pointSize);
 
@@ -776,8 +776,8 @@
 }
 
 void AwtDesktopProperties::SetSoundProperty(LPCTSTR propName, LPCTSTR winEventName) {
-    jstring key = JNU_NewStringPlatform(GetEnv(), const_cast(propName));
-    jstring event = JNU_NewStringPlatform(GetEnv(), const_cast(winEventName));
+    jstring key = JNU_NewStringPlatform(GetEnv(), propName);
+    jstring event = JNU_NewStringPlatform(GetEnv(), winEventName);
     GetEnv()->CallVoidMethod(self,
                              AwtDesktopProperties::setSoundPropertyID,
                              key, event);
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/native/sun/windows/awt_Dialog.cpp
--- a/jdk/src/windows/native/sun/windows/awt_Dialog.cpp	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/awt_Dialog.cpp	Wed Jul 05 17:32:27 2017 +0200
@@ -230,7 +230,7 @@
         if (::IsIconic(hWnd)) {
             ::ShowWindow(hWnd, SW_RESTORE);
         }
-        PopupAllDialogs(blocker, TRUE, ::GetForegroundWindow(), FALSE);
+        PopupBlockers(blocker, TRUE, ::GetForegroundWindow(), FALSE);
         // return 1 to prevent the system from allowing the operation
         return 1;
     }
@@ -256,7 +256,7 @@
             HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd));
             if (::IsWindow(blocker)) {
                 BOOL onTaskbar = !(::WindowFromPoint(mhs->pt) == hWnd);
-                PopupAllDialogs(hWnd, FALSE, ::GetForegroundWindow(), onTaskbar);
+                PopupBlockers(blocker, FALSE, ::GetForegroundWindow(), onTaskbar);
                 // return a nonzero value to prevent the system from passing
                 // the message to the target window procedure
                 return 1;
@@ -268,60 +268,60 @@
 }
 
 /*
- * The function goes through the heirarchy of the blocker dialogs and
- * popups all the dialogs. Note that the function starts from the top
- * blocker dialog and goes down to the dialog which is the bottom dialog.
- * Using another traversal may cause to the flickering issue as a bottom
- * dialog will cover a top dialog for some period of time.
+ * The function goes through the hierarchy of the blockers and
+ * popups all the blockers. Note that the function starts from the top
+ * blocker and goes down to the blocker which is the bottom one.
+ * Using another traversal algorithm (bottom->top) may cause to flickering
+ * as the bottom blocker will cover the top blocker for a while.
  */
-void AwtDialog::PopupAllDialogs(HWND dialog, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar)
+void AwtDialog::PopupBlockers(HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar)
 {
-    HWND blocker = AwtWindow::GetModalBlocker(dialog);
-    BOOL isBlocked = ::IsWindow(blocker);
-    if (isBlocked) {
-        PopupAllDialogs(blocker, isModalHook, prevFGWindow, onTaskbar);
+    HWND nextBlocker = AwtWindow::GetModalBlocker(blocker);
+    BOOL nextBlockerExists = ::IsWindow(nextBlocker);
+    if (nextBlockerExists) {
+        PopupBlockers(nextBlocker, isModalHook, prevFGWindow, onTaskbar);
     }
-    PopupOneDialog(dialog, blocker, isModalHook, prevFGWindow, onTaskbar);
+    PopupBlocker(blocker, nextBlocker, isModalHook, prevFGWindow, onTaskbar);
 }
 
 /*
- * The function popups the dialog, it distinguishes non-blocked dialogs
- * and activates the dialogs (sets as foreground window). If the dialog is
- * blocked, then it changes the Z-order of the dialog.
+ * The function popups the blocker, for a non-blocked blocker we need
+ * to activate the blocker but if a blocker is blocked, then we need
+ * to change z-order of the blocker placing the blocker under the next blocker.
  */
-void AwtDialog::PopupOneDialog(HWND dialog, HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar)
+void AwtDialog::PopupBlocker(HWND blocker, HWND nextBlocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar)
 {
-    if (dialog == AwtToolkit::GetInstance().GetHWnd()) {
+    if (blocker == AwtToolkit::GetInstance().GetHWnd()) {
         return;
     }
 
     // fix for 6494032
-    if (isModalHook && !::IsWindowVisible(dialog)) {
-        ::ShowWindow(dialog, SW_SHOWNA);
+    if (isModalHook && !::IsWindowVisible(blocker)) {
+        ::ShowWindow(blocker, SW_SHOWNA);
     }
 
-    BOOL isBlocked = ::IsWindow(blocker);
+    BOOL nextBlockerExists = ::IsWindow(nextBlocker);
     UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
 
-    if (isBlocked) {
+    if (nextBlockerExists) {
         // Fix for 6829546: if blocker is a top-most window, but window isn't, then
         // calling ::SetWindowPos(dialog, blocker, ...) makes window top-most as well
-        BOOL isBlockerTopmost = (::GetWindowLong(blocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
-        BOOL isDialogTopmost = (::GetWindowLong(dialog, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
-        if (!isBlockerTopmost || isDialogTopmost) {
-            ::SetWindowPos(dialog, blocker, 0, 0, 0, 0, flags);
+        BOOL topmostNextBlocker = (::GetWindowLong(nextBlocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
+        BOOL topmostBlocker = (::GetWindowLong(blocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
+        if (!topmostNextBlocker || topmostBlocker) {
+            ::SetWindowPos(blocker, nextBlocker, 0, 0, 0, 0, flags);
         } else {
-            ::SetWindowPos(dialog, HWND_TOP, 0, 0, 0, 0, flags);
+            ::SetWindowPos(blocker, HWND_TOP, 0, 0, 0, 0, flags);
         }
     } else {
-        ::SetWindowPos(dialog, HWND_TOP, 0, 0, 0, 0, flags);
+        ::SetWindowPos(blocker, HWND_TOP, 0, 0, 0, 0, flags);
         // no beep/flash if the mouse was clicked in the taskbar menu
         // or the dialog is currently inactive
-        if (!isModalHook && !onTaskbar && (dialog == prevFGWindow)) {
-            AnimateModalBlocker(dialog);
+        if (!isModalHook && !onTaskbar && (blocker == prevFGWindow)) {
+            AnimateModalBlocker(blocker);
         }
-        ::BringWindowToTop(dialog);
-        ::SetForegroundWindow(dialog);
+        ::BringWindowToTop(blocker);
+        ::SetForegroundWindow(blocker);
     }
 }
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/native/sun/windows/awt_Dialog.h
--- a/jdk/src/windows/native/sun/windows/awt_Dialog.h	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/awt_Dialog.h	Wed Jul 05 17:32:27 2017 +0200
@@ -113,8 +113,8 @@
      */
     static void ModalPerformActivation(HWND hWnd);
 
-    static void PopupAllDialogs(HWND dialog, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar);
-    static void PopupOneDialog(HWND dialog, HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar);
+    static void PopupBlockers(HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar);
+    static void PopupBlocker(HWND blocker, HWND nextBlocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar);
 
 public:
 
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/native/sun/windows/awt_TextArea.h
--- a/jdk/src/windows/native/sun/windows/awt_TextArea.h	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/awt_TextArea.h	Wed Jul 05 17:32:27 2017 +0200
@@ -41,9 +41,6 @@
 
 class AwtTextArea : public AwtTextComponent {
 
-    // inner classes
-    class OleCallback;
-
 public:
 
     /* java.awt.TextArea fields ids */
@@ -89,6 +86,37 @@
     static void _ReplaceText(void *param);
 
 protected:
+
+    /*****************************************************************
+     * Inner class OleCallback declaration.
+     */
+    class OleCallback : public IRichEditOleCallback {
+    public:
+        OleCallback();
+
+        STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
+        STDMETHODIMP_(ULONG) AddRef();
+        STDMETHODIMP_(ULONG) Release();
+        STDMETHODIMP GetNewStorage(LPSTORAGE FAR * ppstg);
+        STDMETHODIMP GetInPlaceContext(LPOLEINPLACEFRAME FAR * ppipframe,
+                                       LPOLEINPLACEUIWINDOW FAR* ppipuiDoc,
+                                       LPOLEINPLACEFRAMEINFO pipfinfo);
+        STDMETHODIMP ShowContainerUI(BOOL fShow);
+        STDMETHODIMP QueryInsertObject(LPCLSID pclsid, LPSTORAGE pstg, LONG cp);
+        STDMETHODIMP DeleteObject(LPOLEOBJECT poleobj);
+        STDMETHODIMP QueryAcceptData(LPDATAOBJECT pdataobj, CLIPFORMAT *pcfFormat,
+                                     DWORD reco, BOOL fReally, HGLOBAL hMetaPict);
+        STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
+        STDMETHODIMP GetClipboardData(CHARRANGE *pchrg, DWORD reco,
+                                      LPDATAOBJECT *ppdataobj);
+        STDMETHODIMP GetDragDropEffect(BOOL fDrag, DWORD grfKeyState,
+                                       LPDWORD pdwEffect);
+        STDMETHODIMP GetContextMenu(WORD seltype, LPOLEOBJECT poleobj,
+                                    CHARRANGE FAR * pchrg, HMENU FAR * phmenu);
+    private:
+        ULONG             m_refs; // Reference count
+    };//OleCallback class
+
     INLINE static OleCallback& GetOleCallback() { return sm_oleCallback; }
     void EditSetSel(CHARRANGE &cr);
     void EditGetSel(CHARRANGE &cr);
@@ -114,37 +142,6 @@
 
     static OleCallback sm_oleCallback;
 
-    /*****************************************************************
-     * Inner class OleCallback declaration.
-     */
-
-    class AwtTextArea::OleCallback : public IRichEditOleCallback {
-    public:
-        OleCallback();
-
-        STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
-        STDMETHODIMP_(ULONG) AddRef();
-        STDMETHODIMP_(ULONG) Release();
-        STDMETHODIMP GetNewStorage(LPSTORAGE FAR * ppstg);
-        STDMETHODIMP GetInPlaceContext(LPOLEINPLACEFRAME FAR * ppipframe,
-                                       LPOLEINPLACEUIWINDOW FAR* ppipuiDoc,
-                                       LPOLEINPLACEFRAMEINFO pipfinfo);
-        STDMETHODIMP ShowContainerUI(BOOL fShow);
-        STDMETHODIMP QueryInsertObject(LPCLSID pclsid, LPSTORAGE pstg, LONG cp);
-        STDMETHODIMP DeleteObject(LPOLEOBJECT poleobj);
-        STDMETHODIMP QueryAcceptData(LPDATAOBJECT pdataobj, CLIPFORMAT *pcfFormat,
-                                     DWORD reco, BOOL fReally, HGLOBAL hMetaPict);
-        STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
-        STDMETHODIMP GetClipboardData(CHARRANGE *pchrg, DWORD reco,
-                                      LPDATAOBJECT *ppdataobj);
-        STDMETHODIMP GetDragDropEffect(BOOL fDrag, DWORD grfKeyState,
-                                       LPDWORD pdwEffect);
-        STDMETHODIMP GetContextMenu(WORD seltype, LPOLEOBJECT poleobj,
-                                    CHARRANGE FAR * pchrg, HMENU FAR * phmenu);
-    private:
-        ULONG             m_refs; // Reference count
-    };
-
 };
 
 #endif /* AWT_TEXTAREA_H */
diff -r 4d4f07f87e28 -r f1df06807698 jdk/src/windows/native/sun/windows/awt_Toolkit.h
--- a/jdk/src/windows/native/sun/windows/awt_Toolkit.h	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.h	Wed Jul 05 17:32:27 2017 +0200
@@ -110,7 +110,7 @@
       private:
         const CriticalSection& critSec;
     };
-    friend Lock;
+    friend class Lock;
 
   private:
     CRITICAL_SECTION rep;
diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/com/sun/awt/Translucency/WindowOpacity.java
--- a/jdk/test/com/sun/awt/Translucency/WindowOpacity.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/test/com/sun/awt/Translucency/WindowOpacity.java	Wed Jul 05 17:32:27 2017 +0200
@@ -64,6 +64,7 @@
         boolean passed;
 
         Frame f = new Frame("Opacity test");
+        f.setUndecorated(true);
 
         passed = false;
         try {
diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/awt/FontClass/FontPrivilege.java
--- a/jdk/test/java/awt/FontClass/FontPrivilege.java	Wed Jul 05 17:31:42 2017 +0200
+++ b/jdk/test/java/awt/FontClass/FontPrivilege.java	Wed Jul 05 17:32:27 2017 +0200
@@ -25,7 +25,7 @@
  * @test
  * @bug 5010310 6319835 6904882 6968373
  * @summary test fonts can be created in the presence of a security manager
- * @run main/othervm/secure=java.lang.SecurityManager FontPrivilege
+ * @run main FontPrivilege
  */
 
 import java.awt.Font;
@@ -33,6 +33,8 @@
 public class FontPrivilege {
 
     public static void main(String[] args) throws Exception {
+        System.setSecurityManager(new SecurityManager());
+
         new Font("Helvetica", Font.PLAIN, 12).getFamily();
         new Font("foo bar", Font.PLAIN, 12).getFamily();
    }
diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/awt/Graphics2D/DrawString/LCDTextSrcEa.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Graphics2D/DrawString/LCDTextSrcEa.java	Wed Jul 05 17:32:27 2017 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 6996867
+ * @summary Render as LCD Text in SrcEa composite mode.
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.*;
+
+public class LCDTextSrcEa extends Component {
+
+    static int SZ=150;
+    BufferedImage target =
+        new BufferedImage(SZ, SZ, BufferedImage.TYPE_INT_RGB);
+
+    public static void main(String args[]) {
+        Frame f = new Frame("LCD Text SrcEa Test");
+        f.addWindowListener(new WindowAdapter() {
+            @Override
+            public void windowClosing(WindowEvent e) {
+                System.exit(0);
+            }
+        });
+        LCDTextSrcEa td = new LCDTextSrcEa();
+        f.add("Center", td);
+        f.pack();
+        f.setVisible(true);
+    }
+
+    public Dimension getPreferredSize() {
+        return new Dimension(SZ,SZ);
+    }
+
+    public void paint(Graphics gx) {
+
+        Graphics2D g2d = (Graphics2D) target.getGraphics();
+        g2d.setColor(Color.white);
+        g2d.fillRect(0, 0, getWidth(), getHeight());
+
+        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0.01f));
+        g2d.setRenderingHint(
+                RenderingHints.KEY_TEXT_ANTIALIASING,
+                RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR);
+        g2d.setRenderingHint(
+               RenderingHints.KEY_ANTIALIASING,
+               RenderingHints.VALUE_ANTIALIAS_ON);
+
+        g2d.setColor(Color.black);
+        g2d.drawString("Some sample text.", 10, 20);
+        gx.drawImage(target, 0, 0, null);
+        boolean nongrey = false;
+        //Test BI: should be some non-greyscale color
+        for (int px=0;px> 16;
+                int g = (rgb & 0x00ff00) >> 8;
+                int b = (rgb & 0x0000ff);
+                if (r != g || r !=b || g != b) {
+                     nongrey=true;
+                     break;
+                }
+            }
+        }
+        if (!nongrey) {
+            throw new RuntimeException("No LCD text found");
+        }
+    }
+}
diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/awt/Graphics2D/RenderClipTest/6766342.tests
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Graphics2D/RenderClipTest/6766342.tests	Wed Jul 05 17:32:27 2017 +0200
@@ -0,0 +1,3 @@
+Filled AA Pure Rect(5, 29.4, 10, 10)
+Stroked AA Pure Rect(5, 4.4, 10, 10)
+Stroked AA Line(20, 20, -10, 20)
diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/awt/Graphics2D/RenderClipTest/RenderClipTest.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Graphics2D/RenderClipTest/RenderClipTest.java	Wed Jul 05 17:32:27 2017 +0200
@@ -0,0 +1,1634 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * 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 6766342
+ * @summary Tests clipping invariance for AA rectangle and line primitives
+ * @run main RenderClipTest -strict -readfile 6766342.tests
+ * @run main RenderClipTest -rectsuite -count 10
+ */
+
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.image.*;
+import java.awt.event.*;
+import java.util.Vector;
+import java.io.*;
+
+public class RenderClipTest {
+    public static double randDblCoord() {
+        return Math.random()*60 - 10;
+    }
+
+    public static float randFltCoord() {
+        return (float) randDblCoord();
+    }
+
+    public static int randIntCoord() {
+        return (int) Math.round(randDblCoord());
+    }
+
+    public static int randInt(int n) {
+        return ((int) (Math.random() * (n*4))) >> 2;
+    }
+
+    static int numtests;
+    static int numerrors;
+    static int numfillfailures;
+    static int numstrokefailures;
+    static int maxerr;
+
+    static boolean useAA;
+    static boolean strokePure;
+    static boolean testFill;
+    static boolean testDraw;
+    static boolean silent;
+    static boolean verbose;
+    static boolean strict;
+    static boolean showErrors;
+    static float lw;
+    static double rot;
+
+    static BufferedImage imgref;
+    static BufferedImage imgtst;
+
+    static Graphics2D grefclear;
+    static Graphics2D gtstclear;
+    static Graphics2D grefrender;
+    static Graphics2D gtstrender;
+
+    public static abstract class AnnotatedRenderOp {
+        public static AnnotatedRenderOp parse(String str) {
+            AnnotatedRenderOp ar;
+            if (((ar = Cubic.tryparse(str)) != null) ||
+                ((ar = Quad.tryparse(str)) != null) ||
+                ((ar = Poly.tryparse(str)) != null) ||
+                ((ar = Path.tryparse(str)) != null) ||
+                ((ar = Rect.tryparse(str)) != null) ||
+                ((ar = Line.tryparse(str)) != null) ||
+                ((ar = RectMethod.tryparse(str)) != null) ||
+                ((ar = LineMethod.tryparse(str)) != null))
+            {
+                return ar;
+            }
+            System.err.println("Unable to parse shape: "+str);
+            return null;
+        }
+
+        public abstract void randomize();
+
+        public abstract void fill(Graphics2D g2d);
+
+        public abstract void draw(Graphics2D g2d);
+    }
+
+    public static abstract class AnnotatedShapeOp extends AnnotatedRenderOp {
+        public abstract Shape getShape();
+
+        public void fill(Graphics2D g2d) {
+            g2d.fill(getShape());
+        }
+
+        public void draw(Graphics2D g2d) {
+            g2d.draw(getShape());
+        }
+    }
+
+    public static void usage(String err) {
+        if (err != null) {
+            System.err.println(err);
+        }
+        System.err.println("usage: java RenderClipTest "+
+                           "[-read[file F]] [-rectsuite] [-fill] [-draw]");
+        System.err.println("                           "+
+                           "[-aa] [-pure] [-lw N] [-rot N]");
+        System.err.println("                           "+
+                           "[-rectmethod] [-linemethod] [-rect] [-line]");
+        System.err.println("                           "+
+                           "[-cubic] [-quad] [-poly] [-path]");
+        System.err.println("                           "+
+                           "[-silent] [-verbose] [-showerr] [-count N]");
+        System.err.println("                           "+
+                           "[-strict] [-usage]");
+        System.err.println("    -read         Read test data from stdin");
+        System.err.println("    -readfile F   Read test data from file F");
+        System.err.println("    -rectsuite    Run a suite of rect/line tests");
+        System.err.println("    -fill         Test g.fill*(...)");
+        System.err.println("    -draw         Test g.draw*(...)");
+        System.err.println("    -aa           Use antialiased rendering");
+        System.err.println("    -pure         Use STROKE_PURE hint");
+        System.err.println("    -lw N         Test line widths of N "+
+                           "(default 1.0)");
+        System.err.println("    -rot N        Test rotation by N degrees "+
+                           "(default 0.0)");
+        System.err.println("    -rectmethod   Test fillRect/drawRect methods");
+        System.err.println("    -linemethod   Test drawLine method");
+        System.err.println("    -rect         Test Rectangle2D shapes");
+        System.err.println("    -line         Test Line2D shapes");
+        System.err.println("    -cubic        Test CubicCurve2D shapes");
+        System.err.println("    -quad         Test QuadCurve2D shapes");
+        System.err.println("    -poly         Test Polygon shapes");
+        System.err.println("    -path         Test GeneralPath shapes");
+        System.err.println("    -silent       Do not print out error curves");
+        System.err.println("    -verbose      Print out progress info");
+        System.err.println("    -showerr      Display errors on screen");
+        System.err.println("    -count N      N tests per shape, then exit "+
+                           "(default 1000)");
+        System.err.println("    -strict       All failures are important");
+        System.err.println("    -usage        Print this help, then exit");
+        System.exit((err != null) ? -1 : 0);
+    }
+
+    public static void main(String argv[]) {
+        boolean readTests = false;
+        String readFile = null;
+        boolean rectsuite = false;
+        int count = 1000;
+        lw = 1.0f;
+        rot = 0.0;
+        Vector testOps = new Vector();
+        for (int i = 0; i < argv.length; i++) {
+            String arg = argv[i].toLowerCase();
+            if (arg.equals("-aa")) {
+                useAA = true;
+            } else if (arg.equals("-pure")) {
+                strokePure = true;
+            } else if (arg.equals("-fill")) {
+                testFill = true;
+            } else if (arg.equals("-draw")) {
+                testDraw = true;
+            } else if (arg.equals("-lw")) {
+                if (i+1 >= argv.length) {
+                    usage("Missing argument: "+argv[i]);
+                }
+                lw = Float.parseFloat(argv[++i]);
+            } else if (arg.equals("-rot")) {
+                if (i+1 >= argv.length) {
+                    usage("Missing argument: "+argv[i]);
+                }
+                rot = Double.parseDouble(argv[++i]);
+            } else if (arg.equals("-cubic")) {
+                testOps.add(new Cubic());
+            } else if (arg.equals("-quad")) {
+                testOps.add(new Quad());
+            } else if (arg.equals("-poly")) {
+                testOps.add(new Poly());
+            } else if (arg.equals("-path")) {
+                testOps.add(new Path());
+            } else if (arg.equals("-rect")) {
+                testOps.add(new Rect());
+            } else if (arg.equals("-line")) {
+                testOps.add(new Line());
+            } else if (arg.equals("-rectmethod")) {
+                testOps.add(new RectMethod());
+            } else if (arg.equals("-linemethod")) {
+                testOps.add(new LineMethod());
+            } else if (arg.equals("-verbose")) {
+                verbose = true;
+            } else if (arg.equals("-strict")) {
+                strict = true;
+            } else if (arg.equals("-silent")) {
+                silent = true;
+            } else if (arg.equals("-showerr")) {
+                showErrors = true;
+            } else if (arg.equals("-readfile")) {
+                if (i+1 >= argv.length) {
+                    usage("Missing argument: "+argv[i]);
+                }
+                readTests = true;
+                readFile = argv[++i];
+            } else if (arg.equals("-read")) {
+                readTests = true;
+                readFile = null;
+            } else if (arg.equals("-rectsuite")) {
+                rectsuite = true;
+            } else if (arg.equals("-count")) {
+                if (i+1 >= argv.length) {
+                    usage("Missing argument: "+argv[i]);
+                }
+                count = Integer.parseInt(argv[++i]);
+            } else if (arg.equals("-usage")) {
+                usage(null);
+            } else {
+                usage("Unknown argument: "+argv[i]);
+            }
+        }
+        if (readTests) {
+            if (rectsuite || testDraw || testFill ||
+                useAA || strokePure ||
+                lw != 1.0f || rot != 0.0 ||
+                testOps.size() > 0)
+            {
+                usage("Should not specify test types with -read options");
+            }
+        } else if (rectsuite) {
+            if (testDraw || testFill ||
+                useAA || strokePure ||
+                lw != 1.0f || rot != 0.0 ||
+                testOps.size() > 0)
+            {
+                usage("Should not specify test types with -rectsuite option");
+            }
+        } else {
+            if (!testDraw && !testFill) {
+                usage("No work: Must specify one or both of "+
+                      "-fill or -draw");
+            }
+            if (testOps.size() == 0) {
+                usage("No work: Must specify one or more of "+
+                      "-rect[method], -line[method], "+
+                      "-cubic, -quad, -poly, or -path");
+            }
+        }
+        initImages();
+        if (readTests) {
+            try {
+                InputStream is;
+                if (readFile == null) {
+                    is = System.in;
+                } else {
+                    File f =
+                        new File(System.getProperty("test.src", "."),
+                                 readFile);
+                    is = new FileInputStream(f);
+                }
+                parseAndRun(is);
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        } else if (rectsuite) {
+            runRectSuite(count);
+        } else {
+            initGCs();
+            for (int k = 0; k < testOps.size(); k++) {
+                AnnotatedRenderOp ar = testOps.get(k);
+                runRandomTests(ar, count);
+            }
+            disposeGCs();
+        }
+        grefclear.dispose();
+        gtstclear.dispose();
+        grefclear = gtstclear = null;
+        reportStatistics();
+    }
+
+    public static int reportStatistics() {
+        String connector = "";
+        if (numfillfailures > 0) {
+            System.out.print(numfillfailures+" fills ");
+            connector = "and ";
+        }
+        if (numstrokefailures > 0) {
+            System.out.print(connector+numstrokefailures+" strokes ");
+        }
+        int totalfailures = numfillfailures + numstrokefailures;
+        if (totalfailures == 0) {
+            System.out.print("0 ");
+        }
+        System.out.println("out of "+numtests+" tests failed...");
+        int critical = numerrors;
+        if (strict) {
+            critical += totalfailures;
+        }
+        if (critical > 0) {
+            throw new RuntimeException(critical+" tests had critical errors");
+        }
+        System.out.println("No tests had critical errors");
+        return (numerrors+totalfailures);
+    }
+
+    public static void runRectSuite(int count) {
+        AnnotatedRenderOp ops[] = {
+            new Rect(),
+            new RectMethod(),
+            new Line(),
+            new LineMethod(),
+        };
+        // Sometimes different fill algorithms are chosen for
+        // thin and wide line modes, make sure we test both...
+        float filllinewidths[] = { 0.0f, 2.0f };
+        float drawlinewidths[] = { 0.0f, 0.5f, 1.0f,
+                                   2.0f, 2.5f,
+                                   5.0f, 5.3f };
+        double rotations[] = { 0.0, 15.0, 90.0,
+                               135.0, 180.0,
+                               200.0, 270.0,
+                               300.0};
+        for (AnnotatedRenderOp ar: ops) {
+            for (double r: rotations) {
+                rot = r;
+                for (int i = 0; i < 8; i++) {
+                    float linewidths[];
+                    if ((i & 1) == 0) {
+                        if ((ar instanceof Line) ||
+                            (ar instanceof LineMethod))
+                        {
+                            continue;
+                        }
+                        testFill = true;
+                        testDraw = false;
+                        linewidths = filllinewidths;
+                    } else {
+                        testFill = false;
+                        testDraw = true;
+                        linewidths = drawlinewidths;
+                    }
+                    useAA = ((i & 2) != 0);
+                    strokePure = ((i & 4) != 0);
+                    for (float w : linewidths) {
+                        lw = w;
+                        runSuiteTests(ar, count);
+                    }
+                }
+            }
+        }
+    }
+
+    public static void runSuiteTests(AnnotatedRenderOp ar, int count) {
+        if (verbose) {
+            System.out.print("Running ");
+            System.out.print(testFill ? "Fill " : "Draw ");
+            System.out.print(BaseName(ar));
+            if (useAA) {
+                System.out.print(" AA");
+            }
+            if (strokePure) {
+                System.out.print(" Pure");
+            }
+            if (lw != 1.0f) {
+                System.out.print(" lw="+lw);
+            }
+            if (rot != 0.0f) {
+                System.out.print(" rot="+rot);
+            }
+            System.out.println();
+        }
+        initGCs();
+        runRandomTests(ar, count);
+        disposeGCs();
+    }
+
+    public static String BaseName(AnnotatedRenderOp ar) {
+        String s = ar.toString();
+        int leftparen = s.indexOf('(');
+        if (leftparen >= 0) {
+            s = s.substring(0, leftparen);
+        }
+        return s;
+    }
+
+    public static void runRandomTests(AnnotatedRenderOp ar, int count) {
+        for (int i = 0; i < count; i++) {
+            ar.randomize();
+            if (testDraw) {
+                test(ar, false);
+            }
+            if (testFill) {
+                test(ar, true);
+            }
+        }
+    }
+
+    public static void initImages() {
+        imgref = new BufferedImage(40, 40, BufferedImage.TYPE_INT_RGB);
+        imgtst = new BufferedImage(40, 40, BufferedImage.TYPE_INT_RGB);
+        grefclear = imgref.createGraphics();
+        gtstclear = imgtst.createGraphics();
+        grefclear.setColor(Color.white);
+        gtstclear.setColor(Color.white);
+    }
+
+    public static void initGCs() {
+        grefrender = imgref.createGraphics();
+        gtstrender = imgtst.createGraphics();
+        gtstrender.clipRect(10, 10, 20, 20);
+        grefrender.setColor(Color.blue);
+        gtstrender.setColor(Color.blue);
+        if (lw != 1.0f) {
+            BasicStroke bs = new BasicStroke(lw);
+            grefrender.setStroke(bs);
+            gtstrender.setStroke(bs);
+        }
+        if (rot != 0.0) {
+            double rotrad = Math.toRadians(rot);
+            grefrender.rotate(rotrad, 20, 20);
+            gtstrender.rotate(rotrad, 20, 20);
+        }
+        if (strokePure) {
+            grefrender.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
+                                        RenderingHints.VALUE_STROKE_PURE);
+            gtstrender.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
+                                        RenderingHints.VALUE_STROKE_PURE);
+        }
+        if (useAA) {
+            grefrender.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                                        RenderingHints.VALUE_ANTIALIAS_ON);
+            gtstrender.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                                        RenderingHints.VALUE_ANTIALIAS_ON);
+            maxerr = 1;
+        }
+    }
+
+    public static void disposeGCs() {
+        grefrender.dispose();
+        gtstrender.dispose();
+        grefrender = gtstrender = null;
+    }
+
+    public static void parseAndRun(InputStream in) throws IOException {
+        BufferedReader br = new BufferedReader(new InputStreamReader(in));
+        String str;
+        while ((str = br.readLine()) != null) {
+            if (str.startsWith("Stroked ") || str.startsWith("Filled ")) {
+                parseTest(str);
+                continue;
+            }
+            if (str.startsWith("Running ")) {
+                continue;
+            }
+            if (str.startsWith("Failed: ")) {
+                continue;
+            }
+            if (str.indexOf(" out of ") > 0 &&
+                str.indexOf(" tests failed...") > 0)
+            {
+                continue;
+            }
+            if (str.indexOf(" tests had critical errors") > 0) {
+                continue;
+            }
+            System.err.println("Unparseable line: "+str);
+        }
+    }
+
+    public static void parseTest(String origstr) {
+        String str = origstr;
+        boolean isfill = false;
+        useAA = strokePure = false;
+        lw = 1.0f;
+        rot = 0.0;
+        if (str.startsWith("Stroked ")) {
+            str = str.substring(8);
+            isfill = false;
+        } else if (str.startsWith("Filled ")) {
+            str = str.substring(7);
+            isfill = true;
+        } else {
+            System.err.println("Unparseable test line: "+origstr);
+        }
+        if (str.startsWith("AA ")) {
+            str = str.substring(3);
+            useAA = true;
+        }
+        if (str.startsWith("Pure ")) {
+            str = str.substring(5);
+            strokePure = true;
+        }
+        if (str.startsWith("Lw=")) {
+            int index = str.indexOf(' ', 3);
+            if (index > 0) {
+                lw = Float.parseFloat(str.substring(3, index));
+                str = str.substring(index+1);
+            }
+        }
+        if (str.startsWith("Rot=")) {
+            int index = str.indexOf(' ', 4);
+            if (index > 0) {
+                rot = Double.parseDouble(str.substring(4, index));
+                str = str.substring(index+1);
+            }
+        }
+        AnnotatedRenderOp ar = AnnotatedRenderOp.parse(str);
+        if (ar != null) {
+            initGCs();
+            test(ar, isfill);
+            disposeGCs();
+        } else {
+            System.err.println("Unparseable test line: "+origstr);
+        }
+    }
+
+    public static void test(AnnotatedRenderOp ar, boolean isfill) {
+        grefclear.fillRect(0, 0, 40, 40);
+        gtstclear.fillRect(0, 0, 40, 40);
+        if (isfill) {
+            ar.fill(grefrender);
+            ar.fill(gtstrender);
+        } else {
+            ar.draw(grefrender);
+            ar.draw(gtstrender);
+        }
+        check(imgref, imgtst, ar, isfill);
+    }
+
+    public static int[] getData(BufferedImage img) {
+        Raster r = img.getRaster();
+        DataBufferInt dbi = (DataBufferInt) r.getDataBuffer();
+        return dbi.getData();
+    }
+
+    public static int getScan(BufferedImage img) {
+        Raster r = img.getRaster();
+        SinglePixelPackedSampleModel sppsm =
+            (SinglePixelPackedSampleModel) r.getSampleModel();
+        return sppsm.getScanlineStride();
+    }
+
+    public static int getOffset(BufferedImage img) {
+        Raster r = img.getRaster();
+        SinglePixelPackedSampleModel sppsm =
+            (SinglePixelPackedSampleModel) r.getSampleModel();
+        return sppsm.getOffset(-r.getSampleModelTranslateX(),
+                               -r.getSampleModelTranslateY());
+    }
+
+    final static int opaque = 0xff000000;
+    final static int whitergb = Color.white.getRGB();
+
+    public static final int maxdiff(int rgb1, int rgb2) {
+        int maxd = 0;
+        for (int i = 0; i < 32; i += 8) {
+            int c1 = (rgb1 >> i) & 0xff;
+            int c2 = (rgb2 >> i) & 0xff;
+            int d = Math.abs(c1-c2);
+            if (maxd < d) {
+                maxd = d;
+            }
+        }
+        return maxd;
+    }
+
+    public static void check(BufferedImage imgref, BufferedImage imgtst,
+                             AnnotatedRenderOp ar, boolean wasfill)
+    {
+        numtests++;
+        int dataref[] = getData(imgref);
+        int datatst[] = getData(imgtst);
+        int scanref = getScan(imgref);
+        int scantst = getScan(imgtst);
+        int offref = getOffset(imgref);
+        int offtst = getOffset(imgtst);
+
+        // We want to check for errors outside the clip at a higher
+        // priority than errors involving different pixels touched
+        // inside the clip.
+
+        // Check above clip
+        if (check(ar, wasfill,
+                  null, 0, 0,
+                  datatst, scantst, offtst,
+                  0, 0, 40, 10))
+        {
+            return;
+        }
+        // Check below clip
+        if (check(ar, wasfill,
+                  null, 0, 0,
+                  datatst, scantst, offtst,
+                  0, 30, 40, 40))
+        {
+            return;
+        }
+        // Check left of clip
+        if (check(ar, wasfill,
+                  null, 0, 0,
+                  datatst, scantst, offtst,
+                  0, 10, 10, 30))
+        {
+            return;
+        }
+        // Check right of clip
+        if (check(ar, wasfill,
+                  null, 0, 0,
+                  datatst, scantst, offtst,
+                  30, 10, 40, 30))
+        {
+            return;
+        }
+        // Check inside clip
+        check(ar, wasfill,
+              dataref, scanref, offref,
+              datatst, scantst, offtst,
+              10, 10, 30, 30);
+    }
+
+    public static boolean check(AnnotatedRenderOp ar, boolean wasfill,
+                                int dataref[], int scanref, int offref,
+                                int datatst[], int scantst, int offtst,
+                                int x0, int y0, int x1, int y1)
+    {
+        offref += scanref * y0;
+        offtst += scantst * y0;
+        for (int y = y0; y < y1; y++) {
+            for (int x = x0; x < x1; x++) {
+                boolean failed;
+                String reason;
+                int rgbref;
+                int rgbtst;
+
+                rgbtst = datatst[offtst+x] | opaque;
+                if (dataref == null) {
+                    /* Outside of clip, must be white, no error tolerance */
+                    rgbref = whitergb;
+                    failed = (rgbtst != rgbref);
+                    reason = "stray pixel rendered outside of clip";
+                } else {
+                    /* Inside of clip, check for maxerr delta in components */
+                    rgbref = dataref[offref+x] | opaque;
+                    failed = (rgbref != rgbtst &&
+                              maxdiff(rgbref, rgbtst) > maxerr);
+                    reason = "different pixel rendered inside clip";
+                }
+                if (failed) {
+                    if (dataref == null) {
+                        numerrors++;
+                    }
+                    if (wasfill) {
+                        numfillfailures++;
+                    } else {
+                        numstrokefailures++;
+                    }
+                    if (!silent) {
+                        System.out.println("Failed: "+reason+" at "+x+", "+y+
+                                           " ["+Integer.toHexString(rgbref)+
+                                           " != "+Integer.toHexString(rgbtst)+
+                                           "]");
+                        System.out.print(wasfill ? "Filled " : "Stroked ");
+                        if (useAA) System.out.print("AA ");
+                        if (strokePure) System.out.print("Pure ");
+                        if (lw != 1) System.out.print("Lw="+lw+" ");
+                        if (rot != 0) System.out.print("Rot="+rot+" ");
+                        System.out.println(ar);
+                    }
+                    if (showErrors) {
+                        show(imgref, imgtst);
+                    }
+                    return true;
+                }
+            }
+            offref += scanref;
+            offtst += scantst;
+        }
+        return false;
+    }
+
+    static ErrorWindow errw;
+
+    public static void show(BufferedImage imgref, BufferedImage imgtst) {
+        ErrorWindow errw = new ErrorWindow();
+        errw.setImages(imgref, imgtst);
+        errw.setVisible(true);
+        errw.waitForHide();
+        errw.dispose();
+    }
+
+    public static class Cubic extends AnnotatedShapeOp {
+        public static Cubic tryparse(String str) {
+            str = str.trim();
+            if (!str.startsWith("Cubic(")) {
+                return null;
+            }
+            str = str.substring(6);
+            double coords[] = new double[8];
+            boolean foundparen = false;
+            for (int i = 0; i < coords.length; i++) {
+                int index = str.indexOf(",");
+                if (index < 0) {
+                    if (i < coords.length-1) {
+                        return null;
+                    }
+                    index = str.indexOf(")");
+                    if (index < 0) {
+                        return null;
+                    }
+                    foundparen = true;
+                }
+                String num = str.substring(0, index);
+                try {
+                    coords[i] = Double.parseDouble(num);
+                } catch (NumberFormatException nfe) {
+                    return null;
+                }
+                str = str.substring(index+1);
+            }
+            if (!foundparen || str.length() > 0) {
+                return null;
+            }
+            Cubic c = new Cubic();
+            c.cubic.setCurve(coords[0], coords[1],
+                             coords[2], coords[3],
+                             coords[4], coords[5],
+                             coords[6], coords[7]);
+            return c;
+        }
+
+        private CubicCurve2D cubic = new CubicCurve2D.Double();
+
+        public void randomize() {
+            cubic.setCurve(randDblCoord(), randDblCoord(),
+                           randDblCoord(), randDblCoord(),
+                           randDblCoord(), randDblCoord(),
+                           randDblCoord(), randDblCoord());
+        }
+
+        public Shape getShape() {
+            return cubic;
+        }
+
+        public String toString() {
+            return ("Cubic("+
+                    cubic.getX1()+", "+
+                    cubic.getY1()+", "+
+                    cubic.getCtrlX1()+", "+
+                    cubic.getCtrlY1()+", "+
+                    cubic.getCtrlX2()+", "+
+                    cubic.getCtrlY2()+", "+
+                    cubic.getX2()+", "+
+                    cubic.getY2()
+                    +")");
+        }
+    }
+
+    public static class Quad extends AnnotatedShapeOp {
+        public static Quad tryparse(String str) {
+            str = str.trim();
+            if (!str.startsWith("Quad(")) {
+                return null;
+            }
+            str = str.substring(5);
+            double coords[] = new double[6];
+            boolean foundparen = false;
+            for (int i = 0; i < coords.length; i++) {
+                int index = str.indexOf(",");
+                if (index < 0) {
+                    if (i < coords.length-1) {
+                        return null;
+                    }
+                    index = str.indexOf(")");
+                    if (index < 0) {
+                        return null;
+                    }
+                    foundparen = true;
+                }
+                String num = str.substring(0, index);
+                try {
+                    coords[i] = Double.parseDouble(num);
+                } catch (NumberFormatException nfe) {
+                    return null;
+                }
+                str = str.substring(index+1);
+            }
+            if (!foundparen || str.length() > 0) {
+                return null;
+            }
+            Quad c = new Quad();
+            c.quad.setCurve(coords[0], coords[1],
+                            coords[2], coords[3],
+                            coords[4], coords[5]);
+            return c;
+        }
+
+        private QuadCurve2D quad = new QuadCurve2D.Double();
+
+        public void randomize() {
+            quad.setCurve(randDblCoord(), randDblCoord(),
+                          randDblCoord(), randDblCoord(),
+                          randDblCoord(), randDblCoord());
+        }
+
+        public Shape getShape() {
+            return quad;
+        }
+
+        public String toString() {
+            return ("Quad("+
+                    quad.getX1()+", "+
+                    quad.getY1()+", "+
+                    quad.getCtrlX()+", "+
+                    quad.getCtrlY()+", "+
+                    quad.getX2()+", "+
+                    quad.getY2()
+                    +")");
+        }
+    }
+
+    public static class Poly extends AnnotatedShapeOp {
+        public static Poly tryparse(String str) {
+            str = str.trim();
+            if (!str.startsWith("Poly(")) {
+                return null;
+            }
+            str = str.substring(5);
+            Polygon p = new Polygon();
+            while (true) {
+                int x, y;
+                str = str.trim();
+                if (str.startsWith(")")) {
+                    str = str.substring(1);
+                    break;
+                }
+                if (p.npoints > 0) {
+                    if (str.startsWith(",")) {
+                        str = str.substring(2).trim();
+                    } else {
+                        return null;
+                    }
+                }
+                if (str.startsWith("[")) {
+                    str = str.substring(1);
+                } else {
+                    return null;
+                }
+                int index = str.indexOf(",");
+                if (index < 0) {
+                    return null;
+                }
+                String num = str.substring(0, index);
+                try {
+                    x = Integer.parseInt(num);
+                } catch (NumberFormatException nfe) {
+                    return null;
+                }
+                str = str.substring(index+1);
+                index = str.indexOf("]");
+                if (index < 0) {
+                    return null;
+                }
+                num = str.substring(0, index).trim();
+                try {
+                    y = Integer.parseInt(num);
+                } catch (NumberFormatException nfe) {
+                    return null;
+                }
+                str = str.substring(index+1);
+                p.addPoint(x, y);
+            }
+            if (str.length() > 0) {
+                return null;
+            }
+            if (p.npoints < 3) {
+                return null;
+            }
+            return new Poly(p);
+        }
+
+        private Polygon poly;
+
+        public Poly() {
+            this.poly = new Polygon();
+        }
+
+        private Poly(Polygon p) {
+            this.poly = p;
+        }
+
+        public void randomize() {
+            poly.reset();
+            poly.addPoint(randIntCoord(), randIntCoord());
+            poly.addPoint(randIntCoord(), randIntCoord());
+            poly.addPoint(randIntCoord(), randIntCoord());
+            poly.addPoint(randIntCoord(), randIntCoord());
+            poly.addPoint(randIntCoord(), randIntCoord());
+        }
+
+        public Shape getShape() {
+            return poly;
+        }
+
+        public String toString() {
+            StringBuffer sb = new StringBuffer(100);
+            sb.append("Poly(");
+            for (int i = 0; i < poly.npoints; i++) {
+                if (i != 0) {
+                    sb.append(", ");
+                }
+                sb.append("[");
+                sb.append(poly.xpoints[i]);
+                sb.append(", ");
+                sb.append(poly.ypoints[i]);
+                sb.append("]");
+            }
+            sb.append(")");
+            return sb.toString();
+        }
+    }
+
+    public static class Path extends AnnotatedShapeOp {
+        public static Path tryparse(String str) {
+            str = str.trim();
+            if (!str.startsWith("Path(")) {
+                return null;
+            }
+            str = str.substring(5);
+            GeneralPath gp = new GeneralPath();
+            float coords[] = new float[6];
+            int numsegs = 0;
+            while (true) {
+                int type;
+                int n;
+                str = str.trim();
+                if (str.startsWith(")")) {
+                    str = str.substring(1);
+                    break;
+                }
+                if (str.startsWith("M[")) {
+                    type = PathIterator.SEG_MOVETO;
+                    n = 2;
+                } else if (str.startsWith("L[")) {
+                    type = PathIterator.SEG_LINETO;
+                    n = 2;
+                } else if (str.startsWith("Q[")) {
+                    type = PathIterator.SEG_QUADTO;
+                    n = 4;
+                } else if (str.startsWith("C[")) {
+                    type = PathIterator.SEG_CUBICTO;
+                    n = 6;
+                } else if (str.startsWith("E[")) {
+                    type = PathIterator.SEG_CLOSE;
+                    n = 0;
+                } else {
+                    return null;
+                }
+                str = str.substring(2);
+                if (n == 0) {
+                    if (str.startsWith("]")) {
+                        str = str.substring(1);
+                    } else {
+                        return null;
+                    }
+                }
+                for (int i = 0; i < n; i++) {
+                    int index;
+                    if (i < n-1) {
+                        index = str.indexOf(",");
+                    } else {
+                        index = str.indexOf("]");
+                    }
+                    if (index < 0) {
+                        return null;
+                    }
+                    String num = str.substring(0, index);
+                    try {
+                        coords[i] = Float.parseFloat(num);
+                    } catch (NumberFormatException nfe) {
+                        return null;
+                    }
+                    str = str.substring(index+1).trim();
+                }
+                switch (type) {
+                case PathIterator.SEG_MOVETO:
+                    gp.moveTo(coords[0], coords[1]);
+                    break;
+                case PathIterator.SEG_LINETO:
+                    gp.lineTo(coords[0], coords[1]);
+                    break;
+                case PathIterator.SEG_QUADTO:
+                    gp.quadTo(coords[0], coords[1],
+                              coords[2], coords[3]);
+                    break;
+                case PathIterator.SEG_CUBICTO:
+                    gp.curveTo(coords[0], coords[1],
+                               coords[2], coords[3],
+                               coords[4], coords[5]);
+                    break;
+                case PathIterator.SEG_CLOSE:
+                    gp.closePath();
+                    break;
+                }
+                numsegs++;
+            }
+            if (str.length() > 0) {
+                return null;
+            }
+            if (numsegs < 2) {
+                return null;
+            }
+            return new Path(gp);
+        }
+
+        private GeneralPath path;
+
+        public Path() {
+            this.path = new GeneralPath();
+        }
+
+        private Path(GeneralPath gp) {
+            this.path = gp;
+        }
+
+        public void randomize() {
+            path.reset();
+            path.moveTo(randFltCoord(), randFltCoord());
+            for (int i = randInt(5)+3; i > 0; --i) {
+                switch(randInt(5)) {
+                case 0:
+                    path.moveTo(randFltCoord(), randFltCoord());
+                    break;
+                case 1:
+                    path.lineTo(randFltCoord(), randFltCoord());
+                    break;
+                case 2:
+                    path.quadTo(randFltCoord(), randFltCoord(),
+                                randFltCoord(), randFltCoord());
+                    break;
+                case 3:
+                    path.curveTo(randFltCoord(), randFltCoord(),
+                                 randFltCoord(), randFltCoord(),
+                                 randFltCoord(), randFltCoord());
+                    break;
+                case 4:
+                    path.closePath();
+                    break;
+                }
+            }
+        }
+
+        public Shape getShape() {
+            return path;
+        }
+
+        public String toString() {
+            StringBuffer sb = new StringBuffer(100);
+            sb.append("Path(");
+            PathIterator pi = path.getPathIterator(null);
+            float coords[] = new float[6];
+            boolean first = true;
+            while (!pi.isDone()) {
+                int n;
+                char c;
+                switch(pi.currentSegment(coords)) {
+                case PathIterator.SEG_MOVETO:
+                    c = 'M';
+                    n = 2;
+                    break;
+                case PathIterator.SEG_LINETO:
+                    c = 'L';
+                    n = 2;
+                    break;
+                case PathIterator.SEG_QUADTO:
+                    c = 'Q';
+                    n = 4;
+                    break;
+                case PathIterator.SEG_CUBICTO:
+                    c = 'C';
+                    n = 6;
+                    break;
+                case PathIterator.SEG_CLOSE:
+                    c = 'E';
+                    n = 0;
+                    break;
+                default:
+                    throw new InternalError("Unknown segment!");
+                }
+                sb.append(c);
+                sb.append("[");
+                for (int i = 0; i < n; i++) {
+                    if (i != 0) {
+                        sb.append(",");
+                    }
+                    sb.append(coords[i]);
+                }
+                sb.append("]");
+                pi.next();
+            }
+            sb.append(")");
+            return sb.toString();
+        }
+    }
+
+    public static class Rect extends AnnotatedShapeOp {
+        public static Rect tryparse(String str) {
+            str = str.trim();
+            if (!str.startsWith("Rect(")) {
+                return null;
+            }
+            str = str.substring(5);
+            double coords[] = new double[4];
+            boolean foundparen = false;
+            for (int i = 0; i < coords.length; i++) {
+                int index = str.indexOf(",");
+                if (index < 0) {
+                    if (i < coords.length-1) {
+                        return null;
+                    }
+                    index = str.indexOf(")");
+                    if (index < 0) {
+                        return null;
+                    }
+                    foundparen = true;
+                }
+                String num = str.substring(0, index);
+                try {
+                    coords[i] = Double.parseDouble(num);
+                } catch (NumberFormatException nfe) {
+                    return null;
+                }
+                str = str.substring(index+1);
+            }
+            if (!foundparen || str.length() > 0) {
+                return null;
+            }
+            Rect r = new Rect();
+            r.rect.setRect(coords[0], coords[1],
+                           coords[2], coords[3]);
+            return r;
+        }
+
+        private Rectangle2D rect = new Rectangle2D.Double();
+
+        public void randomize() {
+            rect.setRect(randDblCoord(), randDblCoord(),
+                         randDblCoord(), randDblCoord());
+        }
+
+        public Shape getShape() {
+            return rect;
+        }
+
+        public String toString() {
+            return ("Rect("+
+                    rect.getX()+", "+
+                    rect.getY()+", "+
+                    rect.getWidth()+", "+
+                    rect.getHeight()
+                    +")");
+        }
+    }
+
+    public static class Line extends AnnotatedShapeOp {
+        public static Line tryparse(String str) {
+            str = str.trim();
+            if (!str.startsWith("Line(")) {
+                return null;
+            }
+            str = str.substring(5);
+            double coords[] = new double[4];
+            boolean foundparen = false;
+            for (int i = 0; i < coords.length; i++) {
+                int index = str.indexOf(",");
+                if (index < 0) {
+                    if (i < coords.length-1) {
+                        return null;
+                    }
+                    index = str.indexOf(")");
+                    if (index < 0) {
+                        return null;
+                    }
+                    foundparen = true;
+                }
+                String num = str.substring(0, index);
+                try {
+                    coords[i] = Double.parseDouble(num);
+                } catch (NumberFormatException nfe) {
+                    return null;
+                }
+                str = str.substring(index+1);
+            }
+            if (!foundparen || str.length() > 0) {
+                return null;
+            }
+            Line l = new Line();
+            l.line.setLine(coords[0], coords[1],
+                           coords[2], coords[3]);
+            return l;
+        }
+
+        private Line2D line = new Line2D.Double();
+
+        public void randomize() {
+            line.setLine(randDblCoord(), randDblCoord(),
+                         randDblCoord(), randDblCoord());
+        }
+
+        public Shape getShape() {
+            return line;
+        }
+
+        public String toString() {
+            return ("Line("+
+                    line.getX1()+", "+
+                    line.getY1()+", "+
+                    line.getX2()+", "+
+                    line.getY2()
+                    +")");
+        }
+    }
+
+    public static class RectMethod extends AnnotatedRenderOp {
+        public static RectMethod tryparse(String str) {
+            str = str.trim();
+            if (!str.startsWith("RectMethod(")) {
+                return null;
+            }
+            str = str.substring(11);
+            int coords[] = new int[4];
+            boolean foundparen = false;
+            for (int i = 0; i < coords.length; i++) {
+                int index = str.indexOf(",");
+                if (index < 0) {
+                    if (i < coords.length-1) {
+                        return null;
+                    }
+                    index = str.indexOf(")");
+                    if (index < 0) {
+                        return null;
+                    }
+                    foundparen = true;
+                }
+                String num = str.substring(0, index).trim();
+                try {
+                    coords[i] = Integer.parseInt(num);
+                } catch (NumberFormatException nfe) {
+                    return null;
+                }
+                str = str.substring(index+1);
+            }
+            if (!foundparen || str.length() > 0) {
+                return null;
+            }
+            RectMethod rm = new RectMethod();
+            rm.rect.setBounds(coords[0], coords[1],
+                              coords[2], coords[3]);
+            return rm;
+        }
+
+        private Rectangle rect = new Rectangle();
+
+        public void randomize() {
+            rect.setBounds(randIntCoord(), randIntCoord(),
+                           randIntCoord(), randIntCoord());
+        }
+
+        public void fill(Graphics2D g2d) {
+            g2d.fillRect(rect.x, rect.y, rect.width, rect.height);
+        }
+
+        public void draw(Graphics2D g2d) {
+            g2d.drawRect(rect.x, rect.y, rect.width, rect.height);
+        }
+
+        public String toString() {
+            return ("RectMethod("+
+                    rect.x+", "+
+                    rect.y+", "+
+                    rect.width+", "+
+                    rect.height
+                    +")");
+        }
+    }
+
+    public static class LineMethod extends AnnotatedRenderOp {
+        public static LineMethod tryparse(String str) {
+            str = str.trim();
+            if (!str.startsWith("LineMethod(")) {
+                return null;
+            }
+            str = str.substring(11);
+            int coords[] = new int[4];
+            boolean foundparen = false;
+            for (int i = 0; i < coords.length; i++) {
+                int index = str.indexOf(",");
+                if (index < 0) {
+                    if (i < coords.length-1) {
+                        return null;
+                    }
+                    index = str.indexOf(")");
+                    if (index < 0) {
+                        return null;
+                    }
+                    foundparen = true;
+                }
+                String num = str.substring(0, index).trim();
+                try {
+                    coords[i] = Integer.parseInt(num);
+                } catch (NumberFormatException nfe) {
+                    return null;
+                }
+                str = str.substring(index+1);
+            }
+            if (!foundparen || str.length() > 0) {
+                return null;
+            }
+            LineMethod lm = new LineMethod();
+            lm.line = coords;
+            return lm;
+        }
+
+        private int line[] = new int[4];
+
+        public void randomize() {
+            line[0] = randIntCoord();
+            line[1] = randIntCoord();
+            line[2] = randIntCoord();
+            line[3] = randIntCoord();
+        }
+
+        public void fill(Graphics2D g2d) {
+        }
+
+        public void draw(Graphics2D g2d) {
+            g2d.drawLine(line[0], line[1], line[2], line[3]);
+        }
+
+        public String toString() {
+            return ("LineMethod("+
+                    line[0]+", "+
+                    line[1]+", "+
+                    line[2]+", "+
+                    line[3]
+                    +")");
+        }
+    }
+
+    public static class ErrorWindow extends Frame {
+        ImageCanvas unclipped;
+        ImageCanvas reference;
+        ImageCanvas actual;
+        ImageCanvas diff;
+
+        public ErrorWindow() {
+            super("Error Comparison Window");
+
+            unclipped = new ImageCanvas();
+            reference = new ImageCanvas();
+            actual = new ImageCanvas();
+            diff = new ImageCanvas();
+
+            setLayout(new SmartGridLayout(0, 2, 5, 5));
+            addImagePanel(unclipped, "Unclipped rendering");
+            addImagePanel(reference, "Clipped reference");
+            addImagePanel(actual, "Actual clipped");
+            addImagePanel(diff, "Difference");
+
+            addWindowListener(new WindowAdapter() {
+                public void windowClosing(WindowEvent e) {
+                    setVisible(false);
+                }
+            });
+        }
+
+        public void addImagePanel(ImageCanvas ic, String label) {
+            add(ic);
+            add(new Label(label));
+        }
+
+        public void setImages(BufferedImage imgref, BufferedImage imgtst) {
+            unclipped.setImage(imgref);
+            reference.setReference(imgref);
+            actual.setImage(imgtst);
+            diff.setDiff(reference.getImage(), imgtst);
+            invalidate();
+            pack();
+            repaint();
+        }
+
+        public void setVisible(boolean vis) {
+            super.setVisible(vis);
+            synchronized (this) {
+                notifyAll();
+            }
+        }
+
+        public synchronized void waitForHide() {
+            while (isShowing()) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                    System.exit(2);
+                }
+            }
+        }
+    }
+
+    public static class SmartGridLayout implements LayoutManager {
+        int rows;
+        int cols;
+        int hgap;
+        int vgap;
+
+        public SmartGridLayout(int r, int c, int h, int v) {
+            this.rows = r;
+            this.cols = c;
+            this.hgap = h;
+            this.vgap = v;
+        }
+
+        public void addLayoutComponent(String name, Component comp) {
+        }
+
+        public void removeLayoutComponent(Component comp) {
+        }
+
+        public int[][] getGridSizes(Container parent, boolean min) {
+            int ncomponents = parent.getComponentCount();
+            int nrows = rows;
+            int ncols = cols;
+
+            if (nrows > 0) {
+                ncols = (ncomponents + nrows - 1) / nrows;
+            } else {
+                nrows = (ncomponents + ncols - 1) / ncols;
+            }
+            int widths[] = new int[ncols+1];
+            int heights[] = new int[nrows+1];
+            int x = 0;
+            int y = 0;
+            for (int i = 0 ; i < ncomponents ; i++) {
+                Component comp = parent.getComponent(i);
+                Dimension d = (min
+                               ? comp.getMinimumSize()
+                               : comp.getPreferredSize());
+                if (widths[x] < d.width) {
+                    widths[x] = d.width;
+                }
+                if (heights[y] < d.height) {
+                    heights[y] = d.height;
+                }
+                x++;
+                if (x >= ncols) {
+                    x = 0;
+                    y++;
+                }
+            }
+            for (int i = 0; i < ncols; i++) {
+                widths[ncols] += widths[i];
+            }
+            for (int i = 0; i < nrows; i++) {
+                heights[nrows] += heights[i];
+            }
+            return new int[][] { widths, heights };
+        }
+
+        public Dimension getSize(Container parent, boolean min) {
+            int sizes[][] = getGridSizes(parent, min);
+            int widths[] = sizes[0];
+            int heights[] = sizes[1];
+            int nrows = heights.length-1;
+            int ncols = widths.length-1;
+            int w = widths[ncols];
+            int h = heights[nrows];
+            Insets insets = parent.getInsets();
+            return new Dimension(insets.left+insets.right + w+(ncols+1)*hgap,
+                                 insets.top+insets.bottom + h+(nrows+1)*vgap);
+        }
+
+        public Dimension preferredLayoutSize(Container parent) {
+            return getSize(parent, false);
+        }
+
+        public Dimension minimumLayoutSize(Container parent) {
+            return getSize(parent, true);
+        }
+
+        public void layoutContainer(Container parent) {
+            int pref[][] = getGridSizes(parent, false);
+            int min[][] = getGridSizes(parent, true);
+            int minwidths[] = min[0];
+            int minheights[] = min[1];
+            int prefwidths[] = pref[0];
+            int prefheights[] = pref[1];
+            int nrows = minheights.length - 1;
+            int ncols = minwidths.length - 1;
+            Insets insets = parent.getInsets();
+            int w = parent.getWidth() - insets.left - insets.right;
+            int h = parent.getHeight() - insets.top - insets.bottom;
+            w = w - (ncols+1)*hgap;
+            h = h - (nrows+1)*vgap;
+            int widths[] = calculateSizes(w, ncols, minwidths, prefwidths);
+            int heights[] = calculateSizes(h, nrows, minheights, prefheights);
+            int ncomponents = parent.getComponentCount();
+            int x = insets.left + hgap;
+            int y = insets.top + vgap;
+            int r = 0;
+            int c = 0;
+            for (int i = 0; i < ncomponents; i++) {
+                parent.getComponent(i).setBounds(x, y, widths[c], heights[r]);
+                x += widths[c++] + hgap;
+                if (c >= ncols) {
+                    c = 0;
+                    x = insets.left + hgap;
+                    y += heights[r++] + vgap;
+                    if (r >= nrows) {
+                        // just in case
+                        break;
+                    }
+                }
+            }
+        }
+
+        public static int[] calculateSizes(int total, int num,
+                                           int minsizes[], int prefsizes[])
+        {
+            if (total <= minsizes[num]) {
+                return minsizes;
+            }
+            if (total >= prefsizes[num]) {
+                return prefsizes;
+            }
+            int sizes[] = new int[total];
+            int prevhappy = 0;
+            int nhappy = 0;
+            int happysize = 0;
+            do {
+                int addsize = (total - happysize) / (num - nhappy);
+                happysize = 0;
+                for (int i = 0; i < num; i++) {
+                    if (sizes[i] >= prefsizes[i] ||
+                        minsizes[i] + addsize > prefsizes[i])
+                    {
+                        happysize += (sizes[i] = prefsizes[i]);
+                        nhappy++;
+                    } else {
+                        sizes[i] = minsizes[i] + addsize;
+                    }
+                }
+            } while (nhappy < num && nhappy > prevhappy);
+            return sizes;
+        }
+    }
+
+    public static class ImageCanvas extends Canvas {
+        BufferedImage image;
+
+        public void setImage(BufferedImage img) {
+            this.image = img;
+        }
+
+        public BufferedImage getImage() {
+            return image;
+        }
+
+        public void checkImage(int w, int h) {
+            if (image == null ||
+                image.getWidth() < w ||
+                image.getHeight() < h)
+            {
+                image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
+            }
+        }
+
+        public void setReference(BufferedImage img) {
+            checkImage(img.getWidth(), img.getHeight());
+            Graphics g = image.createGraphics();
+            g.drawImage(img, 0, 0, null);
+            g.setColor(Color.white);
+            g.fillRect(0, 0, 30, 10);
+            g.fillRect(30, 0, 10, 30);
+            g.fillRect(10, 30, 30, 10);
+            g.fillRect(0, 10, 10, 30);
+            g.dispose();
+        }
+
+        public void setDiff(BufferedImage imgref, BufferedImage imgtst) {
+            int w = Math.max(imgref.getWidth(), imgtst.getWidth());
+            int h = Math.max(imgref.getHeight(), imgtst.getHeight());
+            checkImage(w, h);
+            Graphics g = image.createGraphics();
+            g.drawImage(imgref, 0, 0, null);
+            g.setXORMode(Color.white);
+            g.drawImage(imgtst, 0, 0, null);
+            g.setPaintMode();
+            g.setColor(new Color(1f, 1f, 0f, 0.25f));
+            g.fillRect(10, 10, 20, 20);
+            g.setColor(new Color(1f, 0f, 0f, 0.25f));
+            g.fillRect(0, 0, 30, 10);
+            g.fillRect(30, 0, 10, 30);
+            g.fillRect(10, 30, 30, 10);
+            g.fillRect(0, 10, 10, 30);
+            g.dispose();
+        }
+
+        public Dimension getPreferredSize() {
+            if (image == null) {
+                return new Dimension();
+            } else {
+                return new Dimension(image.getWidth(), image.getHeight());
+            }
+        }
+
+        public void paint(Graphics g) {
+            g.drawImage(image, 0, 0, null);
+        }
+    }
+}
diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/awt/Insets/WindowWithWarningTest/WindowWithWarningTest.html
--- a/jdk/test/java/awt/Insets/WindowWithWarningTest/WindowWithWarningTest.html	Wed Jul 05 17:31:42 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-
-
-
-  
-    WindowWithWarningTest
-  
-  
-  This test will run automatically.
-  
- - - - - diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/awt/Insets/WindowWithWarningTest/WindowWithWarningTest.java --- a/jdk/test/java/awt/Insets/WindowWithWarningTest/WindowWithWarningTest.java Wed Jul 05 17:31:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,315 +0,0 @@ -/* - * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved. - * 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 6391770 - @summary Content of the Window should be laid out in the area left after WarningWindow was added. - @author yuri nesterenko: area= - @run applet WindowWithWarningTest.html -*/ - -// Note there is no @ in front of test above. This is so that the -// harness will not mistake this file as a test file. It should -// only see the html file as a test file. (the harness runs all -// valid test files, so it would run this test twice if this file -// were valid as well as the html file.) -// Also, note the area= after Your Name in the author tag. Here, you -// should put which functional area the test falls in. See the -// AWT-core home page -> test areas and/or -> AWT team for a list of -// areas. -// Note also the 'AutomaticAppletTest.html' in the run tag. This should -// be changed to the name of the test. - - -/** - * WindowWithWarningTest.java - * - * summary: - */ - -import java.applet.Applet; -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -//Automated tests should run as applet tests if possible because they -// get their environments cleaned up, including AWT threads, any -// test created threads, and any system resources used by the test -// such as file descriptors. (This is normally not a problem as -// main tests usually run in a separate VM, however on some platforms -// such as the Mac, separate VMs are not possible and non-applet -// tests will cause problems). Also, you don't have to worry about -// synchronisation stuff in Applet tests they way you do in main -// tests... - - -public class WindowWithWarningTest extends Applet -{ - //Declare things used in the test, like buttons and labels here - boolean buttonClicked = false; - public static final int MAX_COUNT = 100; - - public void init() - { - //Create instructions for the user here, as well as set up - // the environment -- set the layout manager, add buttons, - // etc. - - this.setLayout (new BorderLayout ()); - - String[] instructions = - { - "This is an AUTOMATIC test", - "simply wait until it is done" - }; - //Sysout.createDialog( ); - //Sysout.printInstructions( instructions ); - - }//End init() - public void start () - { - //Get things going. Request focus, set size, et cetera - System.setSecurityManager( new SecurityManager() { - // deny AWTPermission("showWindowWithoutWarningBanner") - public boolean checkTopLevelWindow(Object window) { - return false; - } - }); - JFrame frame = new JFrame("Window Test"); - frame.setBounds(50, 50, 200, 200); - frame.show(); - - JWindow window = new JWindow( frame ); - JButton jbutton1 = new JButton( "First" ); - jbutton1.addMouseListener( new MouseAdapter() { - public void mousePressed( MouseEvent me ) { - buttonClicked = true; - } - }); - JButton jbutton2 = new JButton( "Second" ); - window.setLocation( 300, 300 ); - - window.add("North", jbutton1); - window.add("South", jbutton2); - - window.pack(); - window.show(); - //wait for frame to show: - getLocation( frame ); - window.toFront(); - - Dimension size0 = window.getSize(); - Dimension size1 = null; - try { - Robot robot = new Robot(); - - robot.delay(500); - window.pack(); - robot.delay(500); - window.pack(); - // size1 must be the same as size0 - size1 = window.getSize(); - robot.delay(500); - Point pt = jbutton1.getLocationOnScreen(); - robot.mouseMove((int) jbutton1.getLocationOnScreen().x + jbutton1.getWidth() / 2, - (int) jbutton1.getLocationOnScreen().y + jbutton1.getHeight() / 2); - robot.delay(500); - robot.mousePress(MouseEvent.BUTTON1_MASK); - robot.delay(100); - robot.mouseRelease(MouseEvent.BUTTON1_MASK); - robot.delay(2000); - }catch(Exception e) { - throw new RuntimeException( "Exception "+e ); - } - if( !size0.equals(size1) ) { - throw new RuntimeException( "Wrong Window size after multiple pack()s"); - } - if( !buttonClicked ) { - throw new RuntimeException( "Button was not clicked"); - } - window.dispose(); - frame.dispose(); - - System.out.println("Test Passed."); - }// start() - public static Point getLocation( Component co ) throws RuntimeException { - Point pt = null; - boolean bFound = false; - int count = 0; - while( !bFound ) { - try { - pt = co.getLocationOnScreen(); - bFound = true; - }catch( Exception ex ) { - bFound = false; - count++; - } - if( !bFound && count > MAX_COUNT ) { - throw new RuntimeException("don't see a component to get location"); - } - } - return pt; - } - - -}// class AutomaticAppletTest - - -/**************************************************** - Standard Test Machinery - DO NOT modify anything below -- it's a standard - chunk of code whose purpose is to make user - interaction uniform, and thereby make it simpler - to read and understand someone else's test. - ****************************************************/ - -/** - This is part of the standard test machinery. - It creates a dialog (with the instructions), and is the interface - for sending text messages to the user. - To print the instructions, send an array of strings to Sysout.createDialog - WithInstructions method. Put one line of instructions per array entry. - To display a message for the tester to see, simply call Sysout.println - with the string to be displayed. - This mimics System.out.println but works within the test harness as well - as standalone. - */ - -class Sysout -{ - private static TestDialog dialog; - - public static void createDialogWithInstructions( String[] instructions ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - dialog.printInstructions( instructions ); - dialog.setVisible(true); - println( "Any messages for the tester will display here." ); - } - - public static void createDialog( ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - String[] defInstr = { "Instructions will appear here. ", "" } ; - dialog.printInstructions( defInstr ); - dialog.setVisible(true); - println( "Any messages for the tester will display here." ); - } - - - public static void printInstructions( String[] instructions ) - { - dialog.printInstructions( instructions ); - } - - - public static void println( String messageIn ) - { - dialog.displayMessage( messageIn ); - } - -}// Sysout class - -/** - This is part of the standard test machinery. It provides a place for the - test instructions to be displayed, and a place for interactive messages - to the user to be displayed. - To have the test instructions displayed, see Sysout. - To have a message to the user be displayed, see Sysout. - Do not call anything in this dialog directly. - */ -class TestDialog extends Dialog -{ - - TextArea instructionsText; - TextArea messageText; - int maxStringLength = 80; - - //DO NOT call this directly, go through Sysout - public TestDialog( Frame frame, String name ) - { - super( frame, name ); - int scrollBoth = TextArea.SCROLLBARS_BOTH; - instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); - add( "North", instructionsText ); - - messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); - add("Center", messageText); - - pack(); - - show(); - }// TestDialog() - - //DO NOT call this directly, go through Sysout - public void printInstructions( String[] instructions ) - { - //Clear out any current instructions - instructionsText.setText( "" ); - - //Go down array of instruction strings - - String printStr, remainingStr; - for( int i=0; i < instructions.length; i++ ) - { - //chop up each into pieces maxSringLength long - remainingStr = instructions[ i ]; - while( remainingStr.length() > 0 ) - { - //if longer than max then chop off first max chars to print - if( remainingStr.length() >= maxStringLength ) - { - //Try to chop on a word boundary - int posOfSpace = remainingStr. - lastIndexOf( ' ', maxStringLength - 1 ); - - if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; - - printStr = remainingStr.substring( 0, posOfSpace + 1 ); - remainingStr = remainingStr.substring( posOfSpace + 1 ); - } - //else just print - else - { - printStr = remainingStr; - remainingStr = ""; - } - - instructionsText.append( printStr + "\n" ); - - }// while - - }// for - - }//printInstructions() - - //DO NOT call this directly, go through Sysout - public void displayMessage( String messageIn ) - { - messageText.append( messageIn + "\n" ); - System.out.println(messageIn); - } - -}// TestDialog class diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/awt/PrintJob/Text/StringWidth.java --- a/jdk/test/java/awt/PrintJob/Text/StringWidth.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/awt/PrintJob/Text/StringWidth.java Wed Jul 05 17:32:27 2017 +0200 @@ -60,7 +60,6 @@ pg.dispose(); pj.end(); setVisible(false); - System.exit(0); } public static void main(String[] args) { diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/awt/image/IncorrectSampleMaskTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/image/IncorrectSampleMaskTest.java Wed Jul 05 17:32:27 2017 +0200 @@ -0,0 +1,113 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6782574 + * @summary Test verifies that incorrect sample masks are correctly handled + * by the constructor of the SinglePixelPackedSampleModel class + * and do not cause internal error in the medialib glue code. + * + * @run main IncorrectSampleMaskTest + */ + +import java.awt.geom.AffineTransform; +import java.awt.image.AffineTransformOp; +import java.awt.image.BufferedImageOp; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.DataBufferInt; +import java.awt.image.DataBufferUShort; +import java.awt.image.Raster; +import java.awt.image.RasterOp; +import java.awt.image.WritableRaster; +import java.awt.image.SinglePixelPackedSampleModel; + +public class IncorrectSampleMaskTest { + public static void main(String[] args) { + int[] dataTypes = new int[] { + DataBuffer.TYPE_BYTE, + DataBuffer.TYPE_USHORT, + DataBuffer.TYPE_INT }; + + for (int type : dataTypes) { + doTest(type); + } + } + + private static final int w = 100; + private static final int h = 100; + + private static AffineTransform at = + AffineTransform.getScaleInstance(0.5, 0.5); + + private static RasterOp op = + new AffineTransformOp(at, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); + + private static void doTest(int dataType) { + int maxSize = DataBuffer.getDataTypeSize(dataType); + System.out.println("Type size: " + maxSize); + + int theMask = (int)(1L << (maxSize + 2)) - 1; + System.out.printf("theMask=%x\n", theMask); + + SinglePixelPackedSampleModel sm = + new SinglePixelPackedSampleModel(dataType, w, h, + new int[] { theMask }); + + + int[] sampleSize = sm.getSampleSize(); + for (int s : sampleSize) { + if (s > maxSize) { + throw new RuntimeException("Test failed: sample size is too big:" + s); + } + } + + System.out.println("Test medialib..."); + DataBuffer buf = createDataBuffer(dataType); + + WritableRaster wr = Raster.createWritableRaster(sm, buf, null); + + op.filter(wr, null); + System.out.println("Test PASSED."); + } + + private static DataBuffer createDataBuffer(int type) { + switch (type) { + case DataBuffer.TYPE_BYTE: { + byte[] buf = new byte[w * h]; + return new DataBufferByte(buf, buf.length); + } + case DataBuffer.TYPE_USHORT: { + short[] buf = new short[w * h]; + return new DataBufferUShort(buf, buf.length); + } + case DataBuffer.TYPE_INT: { + int[] buf = new int[w * h]; + return new DataBufferInt(buf, buf.length); + } + default : + throw new RuntimeException("Unsupported data type."); + } + } +} diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/awt/xembed/server/TestXEmbedServer.java --- a/jdk/test/java/awt/xembed/server/TestXEmbedServer.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/awt/xembed/server/TestXEmbedServer.java Wed Jul 05 17:32:27 2017 +0200 @@ -31,6 +31,9 @@ import java.awt.datatransfer.*; public abstract class TestXEmbedServer { + // vertical position of server AND client windows + private static final int VERTICAL_POSITION = 200; + private static final Logger log = Logger.getLogger("test.xembed"); Frame f; Canvas client; @@ -161,10 +164,10 @@ dummy = new JFrame("Dummy"); dummy.getContentPane().add(new JButton("Button")); dummy.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - dummy.setBounds(0, 0, 100, 100); + dummy.setBounds(0, VERTICAL_POSITION, 100, 100); dummy.setVisible(true); - f.setBounds(300, 0, 800, 300); + f.setBounds(300, VERTICAL_POSITION, 800, 300); f.setVisible(true); } diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/io/Serializable/NPEProvoker/NPEProvoker.java --- a/jdk/test/java/io/Serializable/NPEProvoker/NPEProvoker.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/io/Serializable/NPEProvoker/NPEProvoker.java Wed Jul 05 17:32:27 2017 +0200 @@ -56,7 +56,7 @@ public static void main(String[] args) { System.err.println("\n Regression test for bug 6541870\n"); try { - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList<>(); list.add(new NPEProvoker()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/lang/instrument/ilib/Inject.java --- a/jdk/test/java/lang/instrument/ilib/Inject.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/lang/instrument/ilib/Inject.java Wed Jul 05 17:32:27 2017 +0200 @@ -107,7 +107,7 @@ class IndexedInjector implements TrackerInjector { int counter = 0; int tracker; - List infoList = new ArrayList(); + List infoList = new ArrayList<>(); public int stackSize(int currentSize) { return currentSize + 1; diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/lang/instrument/ilib/InjectBytecodes.java --- a/jdk/test/java/lang/instrument/ilib/InjectBytecodes.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/lang/instrument/ilib/InjectBytecodes.java Wed Jul 05 17:32:27 2017 +0200 @@ -50,7 +50,7 @@ private final Injector[] after = new Injector[256]; private final String className; private final String methodName; - private final Map snippets = new HashMap(); + private final Map snippets = new HashMap<>(); private int pos; private int newPos; diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/lang/reflect/Generics/TestPlainArrayNotGeneric.java --- a/jdk/test/java/lang/reflect/Generics/TestPlainArrayNotGeneric.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/lang/reflect/Generics/TestPlainArrayNotGeneric.java Wed Jul 05 17:32:27 2017 +0200 @@ -103,7 +103,7 @@ } } - private static final Set checking = new HashSet(); + private static final Set checking = new HashSet<>(); private static void check(Type t, String what) { if (t == null || !checking.add(t)) diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/text/Format/DateFormat/ISO8601ZoneTest.java --- a/jdk/test/java/text/Format/DateFormat/ISO8601ZoneTest.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/text/Format/DateFormat/ISO8601ZoneTest.java Wed Jul 05 17:32:27 2017 +0200 @@ -60,48 +60,51 @@ "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", }; + // badData[][0] - format + // badData[][1] - (bad) text to be parsed + // badData[][2] - subtext at the end of which a parse error is detected static final String[][] badData = { - { "X", "1" }, - { "X", "+1" }, - { "X", "-2" }, - { "X", "-24" }, - { "X", "+24" }, + { "X", "1", "1" }, + { "X", "+1", "+1" }, + { "X", "-2", "-2" }, + { "X", "-24", "-2" }, + { "X", "+24", "+2" }, - { "XX", "9" }, - { "XX", "23" }, - { "XX", "234" }, - { "XX", "3456" }, - { "XX", "23456" }, - { "XX", "+1" }, - { "XX", "-12" }, - { "XX", "+123" }, - { "XX", "-12:34" }, - { "XX", "+12:34" }, - { "XX", "-2423" }, - { "XX", "+2423" }, - { "XX", "-1260" }, - { "XX", "+1260" }, + { "XX", "9", "9" }, + { "XX", "23", "2" }, + { "XX", "234", "2" }, + { "XX", "3456", "3" }, + { "XX", "23456", "2" }, + { "XX", "+1", "+1" }, + { "XX", "-12", "-12" }, + { "XX", "+123", "+123" }, + { "XX", "-12:34", "-12" }, + { "XX", "+12:34", "+12" }, + { "XX", "-2423", "-2" }, + { "XX", "+2423", "+2" }, + { "XX", "-1260", "-126" }, + { "XX", "+1260", "+126" }, - { "XXX", "9" }, - { "XXX", "23" }, - { "XXX", "234" }, - { "XXX", "3456" }, - { "XXX", "23456" }, - { "XXX", "2:34" }, - { "XXX", "12:4" }, - { "XXX", "12:34" }, - { "XXX", "-1" }, - { "XXX", "+1" }, - { "XXX", "-12" }, - { "XXX", "+12" }, - { "XXX", "-123" }, - { "XXX", "+123" }, - { "XXX", "-1234" }, - { "XXX", "+1234" }, - { "XXX", "+24:23" }, - { "XXX", "+12:60" }, - { "XXX", "+1:23" }, - { "XXX", "+12:3" }, + { "XXX", "9", "9" }, + { "XXX", "23", "2" }, + { "XXX", "234", "2" }, + { "XXX", "3456", "3" }, + { "XXX", "23456", "2" }, + { "XXX", "2:34", "2" }, + { "XXX", "12:4", "1" }, + { "XXX", "12:34", "1" }, + { "XXX", "-1", "-1" }, + { "XXX", "+1", "+1" }, + { "XXX", "-12", "-12" }, + { "XXX", "+12", "+12" }, + { "XXX", "-123", "-12" }, + { "XXX", "+123", "+12" }, + { "XXX", "-1234", "-12" }, + { "XXX", "+1234", "+12" }, + { "XXX", "+24:23", "+2" }, + { "XXX", "+12:60", "+12:6" }, + { "XXX", "+1:23", "+1" }, + { "XXX", "+12:3", "+12:3" }, }; static String[] badFormats = { @@ -110,6 +113,8 @@ public static void main(String[] args) throws Exception { TimeZone tz = TimeZone.getDefault(); + Locale loc = Locale.getDefault(); + Locale.setDefault(Locale.US); try { for (int i = 0; i < formatData.length; i++) { @@ -128,7 +133,7 @@ } for (String[] d : badData) { - badDataParsing(d[0], d[1]); + badDataParsing(d[0], d[1], d[2].length()); } for (String fmt : badFormats) { @@ -136,6 +141,7 @@ } } finally { TimeZone.setDefault(tz); + Locale.setDefault(loc); } } @@ -188,15 +194,24 @@ } - static void badDataParsing(String fmt, String text) { + static void badDataParsing(String fmt, String text, int expectedErrorIndex) { + SimpleDateFormat sdf = new SimpleDateFormat(fmt); try { - SimpleDateFormat sdf = new SimpleDateFormat(fmt); sdf.parse(text); throw new RuntimeException("didn't throw an exception: fmt=" + fmt + ", text=" + text); } catch (ParseException e) { // OK } + + ParsePosition pos = new ParsePosition(0); + Date d = sdf.parse(text, pos); + int errorIndex = pos.getErrorIndex(); + if (d != null || errorIndex != expectedErrorIndex) { + throw new RuntimeException("Bad error index=" + errorIndex + + ", expected=" + expectedErrorIndex + + ", fmt=" + fmt + ", text=" + text); + } } static void badFormat(String fmt) { diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/text/Format/MessageFormat/Bug7003643.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/text/Format/MessageFormat/Bug7003643.java Wed Jul 05 17:32:27 2017 +0200 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7003643 + * @summary Make sure MessageFormat.toPattern produces correct quoting. (SPI part is tested in PluggableLocale tests.) + */ + +import java.text.*; +import java.util.*; + +public class Bug7003643 { + private static final int N = 5; + + private static final String[] elements = { + "'{'", "'{", "{", "''", "}", "a", "'", + }; + + public static void main(String[] args) { + Random rand = new Random(); + int count = 0; + int max = (int) (Math.pow((double)elements.length, (double)N)/0.52); + while (count < max) { + // Create a random pattern. If the produced pattern is + // valid, then proceed with the round-trip testing. + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < N; i++) { + sb.append(elements[rand.nextInt(elements.length)]); + } + String pattern = sb.toString(); + MessageFormat mf = null; + try { + mf = new MessageFormat(pattern); + } catch (IllegalArgumentException e) { + // bad pattern data + } + if (mf == null) { + continue; + } + count++; + String res1 = MessageFormat.format(pattern, 123); + String toPattern = mf.toPattern(); + String res2 = MessageFormat.format(toPattern, 123); + if (!res1.equals(res2)) { + String s = String.format("Failed%n pattern=\"%s\" => result=\"%s\"%n" + + " toPattern()=\"%s\" => result=\"%s\"%n", + pattern, res1, toPattern, res2); + throw new RuntimeException(s); + } + } + } +} diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/util/Locale/LocaleTest.java --- a/jdk/test/java/util/Locale/LocaleTest.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/util/Locale/LocaleTest.java Wed Jul 05 17:32:27 2017 +0200 @@ -24,7 +24,8 @@ * @test * @bug 4052404 4052440 4084688 4092475 4101316 4105828 4107014 4107953 4110613 * 4118587 4118595 4122371 4126371 4126880 4135316 4135752 4139504 4139940 4143951 - * 4147315 4147317 4147552 4335196 4778440 5010672 6475525 6544471 6627549 6786276 + * 4147315 4147317 4147552 4335196 4778440 4940539 5010672 6475525 6544471 6627549 + * 6786276 * @summary test Locales */ /* @@ -895,17 +896,28 @@ } /** - * @bug 4147317 - * java.util.Locale.getISO3Language() works wrong for non ISO-3166 codes. - * Should throw an exception for unknown locales + * @bug 4147317 4940539 + * java.util.Locale.getISO3Language() works wrong for non ISO-639 codes. + * Should throw an exception for unknown locales, except they have three + * letter language codes. */ public void Test4147317() { - // Try with codes that are the wrong length but happen to match text - // at a valid offset in the mapping table + // Try a three letter language code, and check whether it is + // returned as is. Locale locale = new Locale("aaa", "CCC"); + String result = locale.getISO3Language(); + if (!result.equals("aaa")) { + errln("ERROR: getISO3Language() returns: " + result + + " for locale '" + locale + "' rather than returning it as is" ); + } + + // Try an invalid two letter language code, and check whether it + // throws a MissingResourceException. + locale = new Locale("zz", "CCC"); + try { - String result = locale.getISO3Language(); + result = locale.getISO3Language(); errln("ERROR: getISO3Language() returns: " + result + " for locale '" + locale + "' rather than exception" ); diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/util/PluggableLocale/DateFormatProviderTest.java --- a/jdk/test/java/util/PluggableLocale/DateFormatProviderTest.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/util/PluggableLocale/DateFormatProviderTest.java Wed Jul 05 17:32:27 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,7 @@ availableLocalesTest(); objectValidityTest(); extendedVariantTest(); + messageFormatTest(); } void availableLocalesTest() { @@ -118,4 +119,48 @@ } } } + + + private static final String[] TYPES = { + "date", + "time" + }; + private static final String[] MODIFIERS = { + "", + "short", + "medium", // Same as DEFAULT + "long", + "full" + }; + + void messageFormatTest() { + for (Locale target : providerloc) { + for (String type : TYPES) { + for (String modifier : MODIFIERS) { + String pattern, expected; + if (modifier.equals("")) { + pattern = String.format("%s={0,%s}", type, type); + } else { + pattern = String.format("%s={0,%s,%s}", type, type, modifier); + } + if (modifier.equals("medium")) { + // medium is default. + expected = String.format("%s={0,%s}", type, type); + } else { + expected = pattern; + } + MessageFormat mf = new MessageFormat(pattern, target); + Format[] fmts = mf.getFormats(); + if (fmts[0] instanceof SimpleDateFormat) { + continue; + } + String toPattern = mf.toPattern(); + if (!toPattern.equals(expected)) { + throw new RuntimeException("messageFormatTest: got '" + toPattern + + "', expected '" + expected + "'"); + } + } + } + } + } } diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/util/PluggableLocale/DateFormatProviderTest.sh --- a/jdk/test/java/util/PluggableLocale/DateFormatProviderTest.sh Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/util/PluggableLocale/DateFormatProviderTest.sh Wed Jul 05 17:32:27 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,6 @@ #!/bin/sh # # @test -# @bug 4052440 +# @bug 4052440 7003643 # @summary DateFormatProvider tests # @run shell ExecTest.sh foo DateFormatProviderTest true diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/util/PluggableLocale/NumberFormatProviderTest.java --- a/jdk/test/java/util/PluggableLocale/NumberFormatProviderTest.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/util/PluggableLocale/NumberFormatProviderTest.java Wed Jul 05 17:32:27 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ import sun.util.*; import sun.util.resources.*; +import com.foo.FooNumberFormat; + public class NumberFormatProviderTest extends ProviderTest { com.foo.NumberFormatProviderImpl nfp = new com.foo.NumberFormatProviderImpl(); @@ -43,6 +45,7 @@ NumberFormatProviderTest() { availableLocalesTest(); objectValidityTest(); + messageFormatTest(); } void availableLocalesTest() { @@ -72,14 +75,10 @@ } // result object - String resultCur = - ((DecimalFormat)NumberFormat.getCurrencyInstance(target)).toPattern(); - String resultInt = - ((DecimalFormat)NumberFormat.getIntegerInstance(target)).toPattern(); - String resultNum = - ((DecimalFormat)NumberFormat.getNumberInstance(target)).toPattern(); - String resultPer = - ((DecimalFormat)NumberFormat.getPercentInstance(target)).toPattern(); + String resultCur = getPattern(NumberFormat.getCurrencyInstance(target)); + String resultInt = getPattern(NumberFormat.getIntegerInstance(target)); + String resultNum = getPattern(NumberFormat.getNumberInstance(target)); + String resultPer = getPattern(NumberFormat.getPercentInstance(target)); // provider's object (if any) String providersCur = null; @@ -87,21 +86,21 @@ String providersNum = null; String providersPer = null; if (providerloc.contains(target)) { - DecimalFormat dfCur = (DecimalFormat)nfp.getCurrencyInstance(target); + NumberFormat dfCur = nfp.getCurrencyInstance(target); if (dfCur != null) { - providersCur = dfCur.toPattern(); + providersCur = getPattern(dfCur); } - DecimalFormat dfInt = (DecimalFormat)nfp.getIntegerInstance(target); + NumberFormat dfInt = nfp.getIntegerInstance(target); if (dfInt != null) { - providersInt = dfInt.toPattern(); + providersInt = getPattern(dfInt); } - DecimalFormat dfNum = (DecimalFormat)nfp.getNumberInstance(target); + NumberFormat dfNum = nfp.getNumberInstance(target); if (dfNum != null) { - providersNum = dfNum.toPattern(); + providersNum = getPattern(dfNum); } - DecimalFormat dfPer = (DecimalFormat)nfp.getPercentInstance(target); + NumberFormat dfPer = nfp.getPercentInstance(target); if (dfPer != null) { - providersPer = dfPer.toPattern(); + providersPer = getPattern(dfPer); } } @@ -174,4 +173,35 @@ } } } + + private static String getPattern(NumberFormat nf) { + if (nf instanceof DecimalFormat) { + return ((DecimalFormat)nf).toPattern(); + } + if (nf instanceof FooNumberFormat) { + return ((FooNumberFormat)nf).toPattern(); + } + return null; + } + + private static final String[] NUMBER_PATTERNS = { + "num={0,number}", + "num={0,number,currency}", + "num={0,number,percent}", + "num={0,number,integer}" + }; + + void messageFormatTest() { + for (Locale target : providerloc) { + for (String pattern : NUMBER_PATTERNS) { + MessageFormat mf = new MessageFormat(pattern, target); + String toPattern = mf.toPattern(); + if (!pattern.equals(toPattern)) { + throw new RuntimeException("MessageFormat.toPattern: got '" + + toPattern + + "', expected '" + pattern + "'"); + } + } + } + } } diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/util/PluggableLocale/NumberFormatProviderTest.sh --- a/jdk/test/java/util/PluggableLocale/NumberFormatProviderTest.sh Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/util/PluggableLocale/NumberFormatProviderTest.sh Wed Jul 05 17:32:27 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,6 @@ #!/bin/sh # # @test -# @bug 4052440 +# @bug 4052440 7003643 # @summary NumberFormatProvider tests # @run shell ExecTest.sh foo NumberFormatProviderTest true diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/util/PluggableLocale/fooprovider.jar Binary file jdk/test/java/util/PluggableLocale/fooprovider.jar has changed diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/util/PluggableLocale/providersrc/DateFormatProviderImpl.java --- a/jdk/test/java/util/PluggableLocale/providersrc/DateFormatProviderImpl.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/util/PluggableLocale/providersrc/DateFormatProviderImpl.java Wed Jul 05 17:32:27 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ static String[] datePattern = { "yyyy'\u5e74'M'\u6708'd'\u65e5'", // full date pattern - "yyyy/MM/dd", // long date pattern + "yyyy/MMM/dd", // long date pattern "yyyy/MM/dd", // medium date pattern "yy/MM/dd" // short date pattern }; @@ -68,7 +68,7 @@ public DateFormat getDateInstance(int style, Locale locale) { for (int i = 0; i < avail.length; i ++) { if (Utils.supportsLocale(avail[i], locale)) { - return new SimpleDateFormat(datePattern[style]+dialect[i], locale); + return new FooDateFormat(datePattern[style]+dialect[i], locale); } } throw new IllegalArgumentException("locale is not supported: "+locale); @@ -77,7 +77,7 @@ public DateFormat getTimeInstance(int style, Locale locale) { for (int i = 0; i < avail.length; i ++) { if (Utils.supportsLocale(avail[i], locale)) { - return new SimpleDateFormat(timePattern[style]+dialect[i], locale); + return new FooDateFormat(timePattern[style]+dialect[i], locale); } } throw new IllegalArgumentException("locale is not supported: "+locale); @@ -86,7 +86,7 @@ public DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale) { for (int i = 0; i < avail.length; i ++) { if (Utils.supportsLocale(avail[i], locale)) { - return new SimpleDateFormat( + return new FooDateFormat( datePattern[dateStyle]+" "+timePattern[timeStyle]+dialect[i], locale); } } diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/util/PluggableLocale/providersrc/FooDateFormat.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/util/PluggableLocale/providersrc/FooDateFormat.java Wed Jul 05 17:32:27 2017 +0200 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.foo; + +import java.text.*; +import java.util.*; + +/** + * FooDateFormat provides SimpleDateFormat methods required for the SPI testing. + */ +public class FooDateFormat extends DateFormat { + private SimpleDateFormat sdf; + + public FooDateFormat(String pattern, Locale loc) { + sdf = new SimpleDateFormat(pattern, loc); + } + + @Override + public StringBuffer format(Date date, + StringBuffer toAppendTo, + FieldPosition fieldPosition) { + return sdf.format(date, toAppendTo, fieldPosition); + } + + @Override + public Date parse(String source, ParsePosition pos) { + return sdf.parse(source, pos); + } + + @Override + public boolean equals(Object other) { + return other instanceof FooDateFormat + && sdf.equals(((FooDateFormat)other).sdf); + } + + @Override + public int hashCode() { + return sdf.hashCode(); + } +} diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/util/PluggableLocale/providersrc/FooNumberFormat.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/util/PluggableLocale/providersrc/FooNumberFormat.java Wed Jul 05 17:32:27 2017 +0200 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.foo; + +import java.text.*; + +/** + * FooNumberFormat provides DecimalFormat methods required for the SPI testing. + */ +public class FooNumberFormat extends NumberFormat { + private DecimalFormat df; + + public FooNumberFormat(String pattern, DecimalFormatSymbols dfs) { + df = new DecimalFormat(pattern, dfs); + } + + @Override + public StringBuffer format(double number, + StringBuffer toAppendTo, + FieldPosition pos) { + return df.format(number, toAppendTo, pos); + } + + @Override + public StringBuffer format(long number, + StringBuffer toAppendTo, + FieldPosition pos) { + return df.format(number, toAppendTo, pos); + } + + @Override + public Number parse(String source, ParsePosition parsePosition) { + return df.parse(source, parsePosition); + } + + @Override + public boolean equals(Object other) { + return other instanceof FooNumberFormat + && df.equals(((FooNumberFormat)other).df); + } + + @Override + public int hashCode() { + return df.hashCode(); + } + + // DecimalFormat specific methods required for testing + + public String toPattern() { + return df.toPattern(); + } + + public DecimalFormatSymbols getDecimalFormatSymbols() { + return df.getDecimalFormatSymbols(); + } + + public void setDecimalSeparatorAlwaysShown(boolean newValue) { + df.setDecimalSeparatorAlwaysShown(newValue); + } +} diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/util/PluggableLocale/providersrc/Makefile --- a/jdk/test/java/util/PluggableLocale/providersrc/Makefile Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/util/PluggableLocale/providersrc/Makefile Wed Jul 05 17:32:27 2017 +0200 @@ -28,6 +28,8 @@ DateFormatSymbolsProviderImpl.java \ DecimalFormatSymbolsProviderImpl.java \ NumberFormatProviderImpl.java \ + FooDateFormat.java \ + FooNumberFormat.java \ Utils.java BARFILES_JAVA = \ diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/util/PluggableLocale/providersrc/NumberFormatProviderImpl.java --- a/jdk/test/java/util/PluggableLocale/providersrc/NumberFormatProviderImpl.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/util/PluggableLocale/providersrc/NumberFormatProviderImpl.java Wed Jul 05 17:32:27 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,13 +49,15 @@ static String[] patterns = { "#,##0.###{0};-#,##0.###{1}", // decimal pattern + "#{0};(#){1}", // integer pattern "\u00A4#,##0{0};-\u00A4#,##0{1}", // currency pattern "#,##0%{0}" // percent pattern }; // Constants used by factory methods to specify a style of format. static final int NUMBERSTYLE = 0; - static final int CURRENCYSTYLE = 1; - static final int PERCENTSTYLE = 2; + static final int INTEGERSTYLE = 1; + static final int CURRENCYSTYLE = 2; + static final int PERCENTSTYLE = 3; public Locale[] getAvailableLocales() { return avail; @@ -68,10 +70,10 @@ MessageFormat.format(patterns[CURRENCYSTYLE], dialect[i], dialect[i]); - DecimalFormat df = new DecimalFormat(pattern, + FooNumberFormat nf = new FooNumberFormat(pattern, DecimalFormatSymbols.getInstance(locale)); - adjustForCurrencyDefaultFractionDigits(df); - return df; + adjustForCurrencyDefaultFractionDigits(nf); + return nf; } } throw new IllegalArgumentException("locale is not supported: "+locale); @@ -81,15 +83,15 @@ for (int i = 0; i < avail.length; i ++) { if (Utils.supportsLocale(avail[i], locale)) { String pattern = - MessageFormat.format(patterns[NUMBERSTYLE], + MessageFormat.format(patterns[INTEGERSTYLE], dialect[i], dialect[i]); - DecimalFormat df = new DecimalFormat(pattern, + FooNumberFormat nf = new FooNumberFormat(pattern, DecimalFormatSymbols.getInstance(locale)); - df.setMaximumFractionDigits(0); - df.setDecimalSeparatorAlwaysShown(false); - df.setParseIntegerOnly(true); - return df; + nf.setMaximumFractionDigits(0); + nf.setDecimalSeparatorAlwaysShown(false); + nf.setParseIntegerOnly(true); + return nf; } } throw new IllegalArgumentException("locale is not supported: "+locale); @@ -102,7 +104,7 @@ MessageFormat.format(patterns[NUMBERSTYLE], dialect[i], dialect[i]); - return new DecimalFormat(pattern, + return new FooNumberFormat(pattern, DecimalFormatSymbols.getInstance(locale)); } } @@ -115,7 +117,7 @@ String pattern = MessageFormat.format(patterns[PERCENTSTYLE], dialect[i]); - return new DecimalFormat(pattern, + return new FooNumberFormat(pattern, DecimalFormatSymbols.getInstance(locale)); } } @@ -126,8 +128,8 @@ * Adjusts the minimum and maximum fraction digits to values that * are reasonable for the currency's default fraction digits. */ - void adjustForCurrencyDefaultFractionDigits(DecimalFormat df) { - DecimalFormatSymbols dfs = df.getDecimalFormatSymbols(); + void adjustForCurrencyDefaultFractionDigits(FooNumberFormat nf) { + DecimalFormatSymbols dfs = nf.getDecimalFormatSymbols(); Currency currency = dfs.getCurrency(); if (currency == null) { try { @@ -138,15 +140,15 @@ if (currency != null) { int digits = currency.getDefaultFractionDigits(); if (digits != -1) { - int oldMinDigits = df.getMinimumFractionDigits(); + int oldMinDigits = nf.getMinimumFractionDigits(); // Common patterns are "#.##", "#.00", "#". // Try to adjust all of them in a reasonable way. - if (oldMinDigits == df.getMaximumFractionDigits()) { - df.setMinimumFractionDigits(digits); - df.setMaximumFractionDigits(digits); + if (oldMinDigits == nf.getMaximumFractionDigits()) { + nf.setMinimumFractionDigits(digits); + nf.setMaximumFractionDigits(digits); } else { - df.setMinimumFractionDigits(Math.min(digits, oldMinDigits)); - df.setMaximumFractionDigits(digits); + nf.setMinimumFractionDigits(Math.min(digits, oldMinDigits)); + nf.setMaximumFractionDigits(digits); } } } diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/util/Random/DistinctSeeds.java --- a/jdk/test/java/util/Random/DistinctSeeds.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/util/Random/DistinctSeeds.java Wed Jul 05 17:32:27 2017 +0200 @@ -59,7 +59,7 @@ } } final int threadCount = 2; - List collectors = new ArrayList(); + List collectors = new ArrayList<>(); List threads = new ArrayList(); for (int i = 0; i < threadCount; i++) { RandomCollector r = new RandomCollector(); diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/util/logging/ClassLoaderLeakTest.java --- a/jdk/test/java/util/logging/ClassLoaderLeakTest.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/java/util/logging/ClassLoaderLeakTest.java Wed Jul 05 17:32:27 2017 +0200 @@ -89,7 +89,7 @@ MyClassLoader appClassLoader = new MyClassLoader(urls, "test0"); WeakReference ref = - new WeakReference(appClassLoader); + new WeakReference<>(appClassLoader); Thread appThread = new Thread(appsThreadGroup, launcher, "AppThread-0"); diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/java/util/zip/ZipFile/FinalizeZipFile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/util/zip/ZipFile/FinalizeZipFile.java Wed Jul 05 17:32:27 2017 +0200 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 7007609 7009618 + * @summary Check that ZipFile objects are always collected + */ + +import java.io.*; +import java.nio.*; +import java.util.Random; +import java.util.zip.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class FinalizeZipFile { + + private final static CountDownLatch finalizersDone = new CountDownLatch(3); + + private static class InstrumentedZipFile extends ZipFile { + + public InstrumentedZipFile(File f) throws Exception { + super(f); + System.out.printf("Using %s%n", f.getPath()); + } + protected void finalize() throws IOException { + System.out.printf("Killing %s%n", getName()); + super.finalize(); + finalizersDone.countDown(); + } + } + + private static void makeGarbage() throws Throwable { + final Random rnd = new Random(); + final String javaHome = System.getProperty("java.home"); + // Create some ZipFiles. + // Find some .jar files in JDK's lib directory. + final File lib = new File(javaHome, "lib"); + check(lib.isDirectory()); + final File[] jars = lib.listFiles( + new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.endsWith(".jar");}}); + check(jars.length > 1); + + new InstrumentedZipFile(jars[rnd.nextInt(jars.length)]).close(); + new InstrumentedZipFile(jars[rnd.nextInt(jars.length)]).close(); + + // Create a ZipFile and get an input stream from it + ZipFile zf = new InstrumentedZipFile(jars[rnd.nextInt(jars.length)]); + ZipEntry ze = zf.getEntry("META-INF/MANIFEST.MF"); + InputStream is = zf.getInputStream(ze); + } + + public static void realMain(String[] args) throws Throwable { + makeGarbage(); + + System.gc(); + finalizersDone.await(5, TimeUnit.SECONDS); + + // Not all ZipFiles were collected? + equal(finalizersDone.getCount(), 0L); + } + + //--------------------- Infrastructure --------------------------- + static volatile int passed = 0, failed = 0; + static void pass() {passed++;} + static void fail() {failed++; Thread.dumpStack();} + static void fail(String msg) {System.out.println(msg); fail();} + static void unexpected(Throwable t) {failed++; t.printStackTrace();} + static void check(boolean cond) {if (cond) pass(); else fail();} + static void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + try {realMain(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} + diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/javax/script/E4XErrorTest.java --- a/jdk/test/javax/script/E4XErrorTest.java Wed Jul 05 17:31:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. - * 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 6346734 6705893 - * @summary We do *not* support E4X (ECMAScript for XML) in our - * implementation. We want to throw error on XML literals - * as early as possible rather than at "runtime" - i.e., when - * engine looks for "XML" constructor. - */ - -import javax.script.*; -import java.util.Locale; - -public class E4XErrorTest { - - public static void main(String[] args) throws Exception { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine jsengine = Helper.getJsEngine(manager); - if (jsengine == null) { - System.out.println("Warning: No js engine found; test vacuously passes."); - return; - } - - // The test below depends on the error message content - // that is loaded from resource bundles. So, we force - // English Locale to compare correct value.. - Locale.setDefault(Locale.US); - - try { - jsengine.eval("var v = ;"); - } catch (ScriptException se) { - String msg = se.getMessage(); - if (msg.indexOf("syntax error") == -1) { - throw new RuntimeException("syntax error expected, got " + - msg); - } - return; - } - // should not reach here.. exception should have been thrown. - throw new RuntimeException("Huh! E4X is supported??"); - } -} diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/javax/script/VersionTest.java --- a/jdk/test/javax/script/VersionTest.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/javax/script/VersionTest.java Wed Jul 05 17:32:27 2017 +0200 @@ -32,8 +32,8 @@ public class VersionTest { - private static final String JS_LANG_VERSION = "1.6"; - private static final String JS_ENGINE_VERSION = "1.6 release 2"; + private static final String JS_LANG_VERSION = "1.8"; + private static final String JS_ENGINE_VERSION = "1.7 release 3 PRERELEASE"; public static void main(String[] args) throws Exception { ScriptEngineManager manager = new ScriptEngineManager(); diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/javax/swing/JFileChooser/4847375/bug4847375.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/swing/JFileChooser/4847375/bug4847375.java Wed Jul 05 17:32:27 2017 +0200 @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4847375 + * @summary JFileChooser Create New Folder button is disabled incorrectly + * @author Pavel Porvatov + */ + +import sun.awt.OSInfo; +import sun.awt.shell.ShellFolder; + +import javax.swing.*; +import java.awt.*; +import java.lang.reflect.Method; + +public class bug4847375 { + private final String newFolderToolTipText; + + private final String lookAndFeel; + + public static void main(String[] args) throws Exception { + if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) { + System.out.println("The test is suitable only for Windows OS. Skipped."); + + return; + } + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + new bug4847375("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + + new bug4847375("javax.swing.plaf.metal.MetalLookAndFeel"); + } + }); + } + + private static Object[][] DIRECTORIES = new Object[][]{ + {"getDesktop", Boolean.TRUE}, + {"getDrives", Boolean.FALSE}, // My computer + {"getRecent", Boolean.TRUE}, + {"getNetwork", Boolean.FALSE}, + {"getPersonal", Boolean.TRUE}, + }; + + private bug4847375(String lookAndFeel) { + this.lookAndFeel = lookAndFeel; + + try { + UIManager.setLookAndFeel(lookAndFeel); + } catch (Exception e) { + fail("Cannot set LookAndFeel", e); + } + + JFileChooser fileChooser = new JFileChooser(); + + // Find button NewFolder + newFolderToolTipText = UIManager.getString("FileChooser.newFolderToolTipText", fileChooser.getLocale()); + + if (newFolderToolTipText == null || newFolderToolTipText.length() == 0) { + fail("Cannot find NewFolderButton in FileChooser (tooltip doesn't exist)"); + + return; + } + + JButton newFolderButton = findNewFolderButton(fileChooser); + + if (newFolderButton == null) { + fail("Cannot find NewFolderButton in FileChooser"); + + return; + } + + for (Object[] objects : DIRECTORIES) { + String getterName = (String) objects[0]; + Boolean enabledNewFolder = (Boolean) objects[1]; + + fileChooser.setCurrentDirectory(getWin32Folder(getterName)); + + if (newFolderButton.isEnabled() != enabledNewFolder) { + fail("Enabled state of NewFolderButton should be " + enabledNewFolder + + " for Win32ShellFolderManager2." + getterName + "()"); + } + } + } + + private JButton findNewFolderButton(Container container) { + JButton result = null; + + for (int i = 0; i < container.getComponentCount(); i++) { + Component c = container.getComponent(i); + + if (c instanceof JButton && newFolderToolTipText.equals(((JButton) c).getToolTipText())) { + if (result != null) { + fail("Two or more NewFolderButton found in FileChooser"); + } + + result = (JButton) c; + } + + if (c instanceof Container) { + JButton button = findNewFolderButton((Container) c); + + if (result == null) { + result = button; + } else { + if (button != null) { + fail("Two or more NewFolderButton found in FileChooser"); + } + } + } + } + + return result; + } + + private ShellFolder getWin32Folder(String getterName) { + try { + Class win32ShellFolderManager2 = Class.forName("sun.awt.shell.Win32ShellFolderManager2"); + + Method method = win32ShellFolderManager2.getDeclaredMethod(getterName); + method.setAccessible(true); + + return (ShellFolder) method.invoke(null); + } catch (Exception e) { + fail("Cannot call '" + getterName + "' in the Win32ShellFolderManager2 class", e); + + return null; + } + } + + private void fail(String s) { + throw new RuntimeException("Test failed: " + s); + } + + private void fail(String s, Throwable e) { + throw new RuntimeException("Test failed for LookAndFeel " + lookAndFeel + ": " + s, e); + } +} diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/javax/swing/JScrollBar/6542335/bug6542335.java --- a/jdk/test/javax/swing/JScrollBar/6542335/bug6542335.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/javax/swing/JScrollBar/6542335/bug6542335.java Wed Jul 05 17:32:27 2017 +0200 @@ -40,11 +40,13 @@ private static MyScrollBarUI ui; public static void main(String[] args) throws Exception { - Robot robot = new Robot(); + final Robot robot = new Robot(); robot.setAutoDelay(10); SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + final Rectangle[] thumbBounds = new Rectangle[1]; + SwingUtilities.invokeAndWait(new Runnable() { public void run() { final JFrame frame = new JFrame("bug6542335"); @@ -63,25 +65,39 @@ rangeModel.setValue(50); sb.setModel(rangeModel); - frame.add(sb); + frame.add(sb, BorderLayout.NORTH); frame.setSize(200, 100); frame.setVisible(true); + + thumbBounds[0] = new Rectangle(ui.getThumbBounds()); } }); - Rectangle thumbBounds = new Rectangle(ui.getThumbBounds()); + toolkit.realSync(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + Point l = sb.getLocationOnScreen(); + + robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight() / 2); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + } + }); toolkit.realSync(); - Point l = sb.getLocationOnScreen(); - robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight()/2); - robot.mousePress(InputEvent.BUTTON1_MASK); - robot.mouseRelease(InputEvent.BUTTON1_MASK); - toolkit.realSync(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + Rectangle newThumbBounds = ui.getThumbBounds(); - if (!thumbBounds.equals(ui.getThumbBounds())) { - throw new RuntimeException("Test failed"); - } + if (!thumbBounds[0].equals(newThumbBounds)) { + throw new RuntimeException("Test failed.\nOld bounds: " + thumbBounds[0] + + "\nNew bounds: " + newThumbBounds); + } + } + }); } static class MyScrollBarUI extends BasicScrollBarUI { diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/javax/swing/JSpinner/6532833/bug6532833.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/swing/JSpinner/6532833/bug6532833.java Wed Jul 05 17:32:27 2017 +0200 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 6532833 + @summary PIT: Metal LAF - The right side border is not shown for the Spinner after the removing the buttons + @author Pavel Porvatov +*/ + +import javax.swing.*; +import java.awt.*; + +public class bug6532833 { + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + JSpinner[] spinners = new JSpinner[2]; + + for (int i = 0; i < spinners.length; i++) { + JSpinner spinner = new JSpinner(); + + spinner.setValue(2010); + + Component arrowUp = spinner.getComponent(0); + Component arrowDown = spinner.getComponent(1); + + LayoutManager layout = spinner.getLayout(); + + layout.removeLayoutComponent(arrowUp); + layout.removeLayoutComponent(arrowDown); + + if (i == 1) { + spinner.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); + } + + spinners[i] = spinner; + } + + // Do layout of spinners components + JFrame frame = new JFrame(); + + for (JSpinner spinner : spinners) { + frame.getContentPane().add(spinner); + } + + frame.pack(); + + for (JSpinner spinner : spinners) { + Insets insets = spinner.getInsets(); + + if (spinner.getWidth() != insets.left + insets.right + spinner.getEditor().getWidth()) { + throw new RuntimeException("Spinner editor width is invalid"); + } + } + + frame.dispose(); + } + }); + } +} diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/javax/swing/SwingWorker/6480289/bug6480289.java --- a/jdk/test/javax/swing/SwingWorker/6480289/bug6480289.java Wed Jul 05 17:31:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * 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 6480289 - * @author Igor Kushnirskiy - * @summary tests if consequent workers are executed on the same thread and that VM can exit. - */ - -import java.util.*; -import javax.swing.SwingWorker; - -public class bug6480289 { - private static final int ITERATIONS = 5; - private static final Map threadMap = - Collections.synchronizedMap(new HashMap()); - public static void main(String[] args) throws Exception { - - for (int i = 0; i < ITERATIONS; i++) { - if (i != 0) { - Thread.sleep(1000 * 5); - } - SwingWorker worker = - new SwingWorker() { - @Override - protected Void doInBackground() { - Integer value = threadMap.get(Thread.currentThread()); - value = Integer.valueOf( - ((value == null) ? 0 : value.intValue()) - + 1); - threadMap.put(Thread.currentThread(), value); - return null; - } - }; - worker.execute(); - } - if (threadMap.keySet().size() != 1) { - throw new RuntimeException("failed. More than one thread."); - } - } -} diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/sun/security/krb5/auto/BasicKrb5Test.java --- a/jdk/test/sun/security/krb5/auto/BasicKrb5Test.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/sun/security/krb5/auto/BasicKrb5Test.java Wed Jul 05 17:32:27 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,34 @@ * @test * @bug 6706974 * @summary Add krb5 test infrastructure + * @run main/othervm BasicKrb5Test + * @run main/othervm BasicKrb5Test des-cbc-crc + * @run main/othervm BasicKrb5Test des-cbc-md5 + * @run main/othervm BasicKrb5Test des3-cbc-sha1 + * @run main/othervm BasicKrb5Test aes128-cts + * @run main/othervm BasicKrb5Test aes256-cts + * @run main/othervm BasicKrb5Test rc4-hmac + * @run main/othervm BasicKrb5Test -s + * @run main/othervm BasicKrb5Test des-cbc-crc -s + * @run main/othervm BasicKrb5Test des-cbc-md5 -s + * @run main/othervm BasicKrb5Test des3-cbc-sha1 -s + * @run main/othervm BasicKrb5Test aes128-cts -s + * @run main/othervm BasicKrb5Test aes256-cts -s + * @run main/othervm BasicKrb5Test rc4-hmac -s + * @run main/othervm BasicKrb5Test -C + * @run main/othervm BasicKrb5Test des-cbc-crc -C + * @run main/othervm BasicKrb5Test des-cbc-md5 -C + * @run main/othervm BasicKrb5Test des3-cbc-sha1 -C + * @run main/othervm BasicKrb5Test aes128-cts -C + * @run main/othervm BasicKrb5Test aes256-cts -C + * @run main/othervm BasicKrb5Test rc4-hmac -C + * @run main/othervm BasicKrb5Test -s -C + * @run main/othervm BasicKrb5Test des-cbc-crc -s -C + * @run main/othervm BasicKrb5Test des-cbc-md5 -s -C + * @run main/othervm BasicKrb5Test des3-cbc-sha1 -s -C + * @run main/othervm BasicKrb5Test aes128-cts -s -C + * @run main/othervm BasicKrb5Test aes256-cts -s -C + * @run main/othervm BasicKrb5Test rc4-hmac -s -C */ import org.ietf.jgss.GSSName; @@ -39,6 +67,7 @@ */ public class BasicKrb5Test { + private static boolean conf = true; /** * @param args empty or etype */ @@ -46,8 +75,10 @@ throws Exception { String etype = null; - if (args.length > 0) { - etype = args[0]; + for (String arg: args) { + if (arg.equals("-s")) Context.usingStream = true; + else if(arg.equals("-C")) conf = false; + else etype = arg; } // Creates and starts the KDC. This line must be put ahead of etype check @@ -56,8 +87,9 @@ System.out.println("Testing etype " + etype); if (etype != null && !EType.isSupported(Config.getInstance().getType(etype))) { + // aes256 is not enabled on all systems System.out.println("Not supported."); - System.exit(0); + return; } new BasicKrb5Test().go(OneKDC.SERVER, OneKDC.BACKEND); @@ -71,6 +103,7 @@ c.startAsClient(server, GSSUtil.GSS_KRB5_MECH_OID); c.x().requestCredDeleg(true); + c.x().requestConf(conf); s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); c.status(); @@ -90,6 +123,7 @@ s = null; s2.startAsClient(backend, GSSUtil.GSS_KRB5_MECH_OID); + s2.x().requestConf(conf); b.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); s2.status(); diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/sun/security/krb5/auto/Context.java --- a/jdk/test/sun/security/krb5/auto/Context.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/sun/security/krb5/auto/Context.java Wed Jul 05 17:32:27 2017 +0200 @@ -42,7 +42,8 @@ import com.sun.security.jgss.ExtendedGSSContext; import com.sun.security.jgss.InquireType; import com.sun.security.jgss.AuthorizationDataEntry; -import java.io.File; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; /** * Context of a JGSS subject, encapsulating Subject and GSSContext. @@ -78,6 +79,8 @@ private String name; private GSSCredential cred; // see static method delegated(). + static boolean usingStream = false; + private Context() {} /** @@ -365,7 +368,14 @@ public byte[] run(Context me, byte[] dummy) throws Exception { System.out.println("wrap"); MessageProp p1 = new MessageProp(0, true); - byte[] out = me.x.wrap(messageBytes, 0, messageBytes.length, p1); + byte[] out; + if (usingStream) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + me.x.wrap(new ByteArrayInputStream(messageBytes), os, p1); + out = os.toByteArray(); + } else { + out = me.x.wrap(messageBytes, 0, messageBytes.length, p1); + } System.out.println(printProp(p1)); return out; } @@ -375,27 +385,46 @@ @Override public byte[] run(Context me, byte[] input) throws Exception { MessageProp p1 = new MessageProp(0, true); - byte[] bytes = me.x.unwrap(input, 0, input.length, p1); + byte[] bytes; + if (usingStream) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + me.x.unwrap(new ByteArrayInputStream(input), os, p1); + bytes = os.toByteArray(); + } else { + bytes = me.x.unwrap(input, 0, input.length, p1); + } if (!Arrays.equals(messageBytes, bytes)) throw new Exception("wrap/unwrap mismatch"); System.out.println("unwrap"); System.out.println(printProp(p1)); p1 = new MessageProp(0, true); System.out.println("getMIC"); - bytes = me.x.getMIC(bytes, 0, bytes.length, p1); + if (usingStream) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + me.x.getMIC(new ByteArrayInputStream(messageBytes), os, p1); + bytes = os.toByteArray(); + } else { + bytes = me.x.getMIC(messageBytes, 0, messageBytes.length, p1); + } System.out.println(printProp(p1)); return bytes; } }, t); + // Re-unwrap should make p2.isDuplicateToken() returns true s1.doAs(new Action() { @Override public byte[] run(Context me, byte[] input) throws Exception { MessageProp p1 = new MessageProp(0, true); System.out.println("verifyMIC"); - me.x.verifyMIC(input, 0, input.length, - messageBytes, 0, messageBytes.length, - p1); + if (usingStream) { + me.x.verifyMIC(new ByteArrayInputStream(input), + new ByteArrayInputStream(messageBytes), p1); + } else { + me.x.verifyMIC(input, 0, input.length, + messageBytes, 0, messageBytes.length, + p1); + } System.out.println(printProp(p1)); return null; } @@ -416,7 +445,9 @@ sb.append(prop.isGapToken()?"gap, ":""); sb.append(prop.isOldToken()?"old, ":""); sb.append(prop.isUnseqToken()?"unseq, ":""); - sb.append(prop.getMinorString()+ "(" + prop.getMinorStatus()+")"); + if (prop.getMinorStatus() != 0) { + sb.append(prop.getMinorString()+ "(" + prop.getMinorStatus()+")"); + } return sb.toString(); } @@ -442,7 +473,13 @@ return null; } else { System.out.println(c.name + " call initSecContext"); - return me.x.initSecContext(input, 0, input.length); + if (usingStream) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + me.x.initSecContext(new ByteArrayInputStream(input), os); + return os.size() == 0 ? null : os.toByteArray(); + } else { + return me.x.initSecContext(input, 0, input.length); + } } } }, t); @@ -460,7 +497,13 @@ return null; } else { System.out.println(s.name + " called acceptSecContext"); - return me.x.acceptSecContext(input, 0, input.length); + if (usingStream) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + me.x.acceptSecContext(new ByteArrayInputStream(input), os); + return os.size() == 0 ? null : os.toByteArray(); + } else { + return me.x.acceptSecContext(input, 0, input.length); + } } } }, t); diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/sun/security/krb5/auto/basic.sh --- a/jdk/test/sun/security/krb5/auto/basic.sh Wed Jul 05 17:31:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -# -# Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. -# 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 6706974 -# @summary Add krb5 test infrastructure -# @run shell/timeout=300 basic.sh -# - -if [ "${TESTSRC}" = "" ] ; then - TESTSRC="." -fi -if [ "${TESTJAVA}" = "" ] ; then - echo "TESTJAVA not set. Test cannot execute." - echo "FAILED!!!" - exit 1 -fi - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - Windows_* ) - FS="\\" - SEP=";" - ;; - CYGWIN* ) - FS="/" - SEP=";" - ;; - * ) - FS="/" - SEP=":" - ;; -esac - -${TESTJAVA}${FS}bin${FS}javac -XDignore.symbol.file -d . \ - ${TESTSRC}${FS}BasicKrb5Test.java \ - ${TESTSRC}${FS}KDC.java \ - ${TESTSRC}${FS}OneKDC.java \ - ${TESTSRC}${FS}Action.java \ - ${TESTSRC}${FS}Context.java \ - || exit 10 - -# Add $TESTSRC to classpath so that customized nameservice can be used -J="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}. BasicKrb5Test" - -$J || exit 100 -$J des-cbc-crc || exit 1 -$J des-cbc-md5 || exit 3 -$J des3-cbc-sha1 || exit 16 -$J aes128-cts || exit 17 -$J aes256-cts || exit 18 -$J rc4-hmac || exit 23 - -exit 0 diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/sun/security/pkcs11/Provider/ConfigShortPath.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/pkcs11/Provider/ConfigShortPath.java Wed Jul 05 17:32:27 2017 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/** + * @test + * @bug 6581254 + * @summary Allow "~" in config to support windows short path + * @author Valerie Peng + */ + +import java.security.*; +import java.io.*; + +public class ConfigShortPath { + + public static void main(String[] args) { + String testSrc = System.getProperty("test.src", "."); + String configFile = testSrc + File.separator + "csp.cfg"; + System.out.println("Testing against " + configFile); + try { + Provider p = new sun.security.pkcs11.SunPKCS11(configFile); + } catch (ProviderException pe) { + String cause = pe.getCause().getMessage(); + if (cause.indexOf("Unexpected token") != -1) { + // re-throw to indicate test failure + throw pe; + } + } + } +} diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/sun/security/pkcs11/Provider/csp.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/pkcs11/Provider/csp.cfg Wed Jul 05 17:32:27 2017 +0200 @@ -0,0 +1,4 @@ +showInfo = false +name = NSSTrust +nssSecmodDirectory = C:/DOCUME~1/dtftest/LOCALS~1/Temp/Work/exec/jsn_7.0_int-7.0_nightly_sec_win_32_part2-2007-07-16-09-06-04-0209/dtftest.Windows_2003.x86/NSS//db +nssLibraryDirectory = Y:/xml/CC_DTF/knight_ws/suites/jsn_7.0_int/security/tools/lib/nss/WINNT/ diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/sun/tools/jstat/gcNewCapacityOutput1.awk --- a/jdk/test/sun/tools/jstat/gcNewCapacityOutput1.awk Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/sun/tools/jstat/gcNewCapacityOutput1.awk Wed Jul 05 17:32:27 2017 +0200 @@ -4,7 +4,7 @@ # specific values. # # NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC -# 2176.0 7232.0 2176.0 64.0 192.0 192.0 64.0 6848.0 2048.0 1 0 +# 2176.0 7232.0 2176.0 192.0 64.0 192.0 64.0 6848.0 2048.0 1 0 BEGIN { diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/tools/launcher/Settings.java --- a/jdk/test/tools/launcher/Settings.java Wed Jul 05 17:31:42 2017 +0200 +++ b/jdk/test/tools/launcher/Settings.java Wed Jul 05 17:32:27 2017 +0200 @@ -74,8 +74,15 @@ static void runTestOptionDefault() throws IOException { TestHelper.TestResult tr = null; - tr = TestHelper.doExec(TestHelper.javaCmd, "-Xmx512m", "-Xss128k", - "-XshowSettings", "-jar", testJar.getAbsolutePath()); + tr = TestHelper.doExec(TestHelper.javaCmd, "-Xms64m", "-Xmx512m", + "-Xss128k", "-XshowSettings", "-jar", testJar.getAbsolutePath()); + containsAllOptions(tr); + if (!tr.isOK()) { + System.out.println(tr.status); + throw new RuntimeException("test fails"); + } + tr = TestHelper.doExec(TestHelper.javaCmd, "-Xms65536k", "-Xmx712m", + "-Xss122880", "-XshowSettings", "-jar", testJar.getAbsolutePath()); containsAllOptions(tr); if (!tr.isOK()) { System.out.println(tr.status); diff -r 4d4f07f87e28 -r f1df06807698 jdk/test/tools/pack200/T7007157.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/pack200/T7007157.java Wed Jul 05 17:32:27 2017 +0200 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Map; +import java.util.jar.JarFile; +import java.util.jar.Pack200; +/* + * @test + * @bug 7007157 + * @summary make sure the strip command works on an attribute + * @compile -XDignore.symbol.file Utils.java T7007157.java + * @run main T7007157 + * @author ksrini + */ +public class T7007157 { + + public static void main(String... args) throws IOException { + File sdkHome = Utils.JavaSDK; + File testJar = new File(new File(sdkHome, "lib"), "tools.jar"); + JarFile jarFile = new JarFile(testJar); + File packFile = new File("foo.pack"); + Pack200.Packer packer = Pack200.newPacker(); + Map p = packer.properties(); + // Take the time optimization vs. space + p.put(packer.EFFORT, "1"); // CAUTION: do not use 0. + // Make the memory consumption as effective as possible + p.put(packer.SEGMENT_LIMIT, "10000"); + // ignore all JAR deflation requests to save time + p.put(packer.DEFLATE_HINT, packer.FALSE); + // save the file ordering of the original JAR + p.put(packer.KEEP_FILE_ORDER, packer.TRUE); + // strip the StackMapTables + p.put(packer.CODE_ATTRIBUTE_PFX + "StackMapTable", packer.STRIP); + FileOutputStream fos = null; + try { + // Write out to a jtreg scratch area + fos = new FileOutputStream(packFile); + // Call the packer + packer.pack(jarFile, fos); + } finally { + Utils.close(fos); + Utils.close(jarFile); + } + } +} diff -r 4d4f07f87e28 -r f1df06807698 langtools/.hgtags --- a/langtools/.hgtags Wed Jul 05 17:31:42 2017 +0200 +++ b/langtools/.hgtags Wed Jul 05 17:32:27 2017 +0200 @@ -99,3 +99,4 @@ 11e7b4c0476e4d6085d8d28c4aa2833d46714a2a jdk7-b122 a3b5b531542a372f30e014b1543a619a15a90780 jdk7-b123 4868a36f6fd8972505c466013813eeb28f0482ea jdk7-b124 +4b0560c72b529d4b952924b2da94d8436af79d05 jdk7-b125 diff -r 4d4f07f87e28 -r f1df06807698 langtools/make/Makefile --- a/langtools/make/Makefile Wed Jul 05 17:31:42 2017 +0200 +++ b/langtools/make/Makefile Wed Jul 05 17:32:27 2017 +0200 @@ -187,7 +187,7 @@ clobber: clean # All ant targets of interest -ANT_TARGETS = build clean sanity post-sanity diagnostics # for now +ANT_TARGETS = build clean sanity post-sanity diagnostics build-all-tools # for now # Create diagnostics log (careful, ant 1.8.0 -diagnostics always does an exit 1) $(OUTPUTDIR)/build/ant-diagnostics.log: diff -r 4d4f07f87e28 -r f1df06807698 langtools/make/build.xml diff -r 4d4f07f87e28 -r f1df06807698 langtools/src/share/bin/launcher.sh-template --- a/langtools/src/share/bin/launcher.sh-template Wed Jul 05 17:31:42 2017 +0200 +++ b/langtools/src/share/bin/launcher.sh-template Wed Jul 05 17:32:27 2017 +0200 @@ -26,6 +26,12 @@ # mydir="`dirname $0`" +case `uname -s` in + CYGWIN*) + mydir=`cygpath -m $mydir` + ;; +esac + mylib="`dirname $mydir`"/lib # By default, put the jar file and its dependencies on the bootclasspath. diff -r 4d4f07f87e28 -r f1df06807698 langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java --- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Wed Jul 05 17:31:42 2017 +0200 +++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Wed Jul 05 17:32:27 2017 +0200 @@ -266,82 +266,116 @@ System.out.println(message); } + /** - * Insert all files in subdirectory `subdirectory' of `directory' which end - * in one of the extensions in `extensions' into packageSym. + * Insert all files in subdirectory subdirectory of directory directory + * which match fileKinds into resultList */ private void listDirectory(File directory, RelativeDirectory subdirectory, Set fileKinds, boolean recurse, - ListBuffer l) { - Archive archive = archives.get(directory); + ListBuffer resultList) { + File d = subdirectory.getFile(directory); + if (!caseMapCheck(d, subdirectory)) + return; - boolean isFile = fsInfo.isFile(directory); + File[] files = d.listFiles(); + if (files == null) + return; - if (archive != null || isFile) { - if (archive == null) { - try { - archive = openArchive(directory); - } catch (IOException ex) { - log.error("error.reading.file", - directory, getMessage(ex)); - return; - } - } + if (sortFiles != null) + Arrays.sort(files, sortFiles); - List files = archive.getFiles(subdirectory); - if (files != null) { - for (String file; !files.isEmpty(); files = files.tail) { - file = files.head; - if (isValidFile(file, fileKinds)) { - l.append(archive.getFileObject(subdirectory, file)); - } + for (File f: files) { + String fname = f.getName(); + if (f.isDirectory()) { + if (recurse && SourceVersion.isIdentifier(fname)) { + listDirectory(directory, + new RelativeDirectory(subdirectory, fname), + fileKinds, + recurse, + resultList); } - } - if (recurse) { - for (RelativeDirectory s: archive.getSubdirectories()) { - if (subdirectory.contains(s)) { - // Because the archive map is a flat list of directories, - // the enclosing loop will pick up all child subdirectories. - // Therefore, there is no need to recurse deeper. - listDirectory(directory, s, fileKinds, false, l); - } - } - } - } else { - File d = subdirectory.getFile(directory); - if (!caseMapCheck(d, subdirectory)) - return; - - File[] files = d.listFiles(); - if (files == null) - return; - - if (sortFiles != null) - Arrays.sort(files, sortFiles); - - for (File f: files) { - String fname = f.getName(); - if (f.isDirectory()) { - if (recurse && SourceVersion.isIdentifier(fname)) { - listDirectory(directory, - new RelativeDirectory(subdirectory, fname), - fileKinds, - recurse, - l); - } - } else { - if (isValidFile(fname, fileKinds)) { - JavaFileObject fe = - new RegularFileObject(this, fname, new File(d, fname)); - l.append(fe); - } + } else { + if (isValidFile(fname, fileKinds)) { + JavaFileObject fe = + new RegularFileObject(this, fname, new File(d, fname)); + resultList.append(fe); } } } } + /** + * Insert all files in subdirectory subdirectory of archive archive + * which match fileKinds into resultList + */ + private void listArchive(Archive archive, + RelativeDirectory subdirectory, + Set fileKinds, + boolean recurse, + ListBuffer resultList) { + // Get the files directly in the subdir + List files = archive.getFiles(subdirectory); + if (files != null) { + for (; !files.isEmpty(); files = files.tail) { + String file = files.head; + if (isValidFile(file, fileKinds)) { + resultList.append(archive.getFileObject(subdirectory, file)); + } + } + } + if (recurse) { + for (RelativeDirectory s: archive.getSubdirectories()) { + if (subdirectory.contains(s)) { + // Because the archive map is a flat list of directories, + // the enclosing loop will pick up all child subdirectories. + // Therefore, there is no need to recurse deeper. + listArchive(archive, s, fileKinds, false, resultList); + } + } + } + } + + /** + * container is a directory, a zip file, or a non-existant path. + * Insert all files in subdirectory subdirectory of container which + * match fileKinds into resultList + */ + private void listContainer(File container, + RelativeDirectory subdirectory, + Set fileKinds, + boolean recurse, + ListBuffer resultList) { + Archive archive = archives.get(container); + if (archive == null) { + // archives are not created for directories. + if (fsInfo.isDirectory(container)) { + listDirectory(container, + subdirectory, + fileKinds, + recurse, + resultList); + return; + } + + // Not a directory; either a file or non-existant, create the archive + try { + archive = openArchive(container); + } catch (IOException ex) { + log.error("error.reading.file", + container, getMessage(ex)); + return; + } + } + listArchive(archive, + subdirectory, + fileKinds, + recurse, + resultList); + } + private boolean isValidFile(String s, Set fileKinds) { JavaFileObject.Kind kind = getKind(s); return fileKinds.contains(kind); @@ -434,95 +468,92 @@ private static final RelativeDirectory symbolFilePrefix = new RelativeDirectory("META-INF/sym/rt.jar/"); - /** Open a new zip file directory. + /** Open a new zip file directory, and cache it. */ protected Archive openArchive(File zipFileName) throws IOException { - Archive archive = archives.get(zipFileName); - if (archive == null) { - File origZipFileName = zipFileName; - if (!ignoreSymbolFile && paths.isBootClassPathRtJar(zipFileName)) { - File file = zipFileName.getParentFile().getParentFile(); // ${java.home} - if (new File(file.getName()).equals(new File("jre"))) - file = file.getParentFile(); - // file == ${jdk.home} - for (String name : symbolFileLocation) - file = new File(file, name); - // file == ${jdk.home}/lib/ct.sym - if (file.exists()) - zipFileName = file; - } + File origZipFileName = zipFileName; + if (!ignoreSymbolFile && paths.isBootClassPathRtJar(zipFileName)) { + File file = zipFileName.getParentFile().getParentFile(); // ${java.home} + if (new File(file.getName()).equals(new File("jre"))) + file = file.getParentFile(); + // file == ${jdk.home} + for (String name : symbolFileLocation) + file = new File(file, name); + // file == ${jdk.home}/lib/ct.sym + if (file.exists()) + zipFileName = file; + } - try { + Archive archive; + try { - ZipFile zdir = null; + ZipFile zdir = null; - boolean usePreindexedCache = false; - String preindexCacheLocation = null; + boolean usePreindexedCache = false; + String preindexCacheLocation = null; - if (!useZipFileIndex) { - zdir = new ZipFile(zipFileName); - } - else { - usePreindexedCache = options.isSet("usezipindex"); - preindexCacheLocation = options.get("java.io.tmpdir"); - String optCacheLoc = options.get("cachezipindexdir"); + if (!useZipFileIndex) { + zdir = new ZipFile(zipFileName); + } + else { + usePreindexedCache = options.isSet("usezipindex"); + preindexCacheLocation = options.get("java.io.tmpdir"); + String optCacheLoc = options.get("cachezipindexdir"); - if (optCacheLoc != null && optCacheLoc.length() != 0) { - if (optCacheLoc.startsWith("\"")) { - if (optCacheLoc.endsWith("\"")) { - optCacheLoc = optCacheLoc.substring(1, optCacheLoc.length() - 1); - } - else { - optCacheLoc = optCacheLoc.substring(1); - } + if (optCacheLoc != null && optCacheLoc.length() != 0) { + if (optCacheLoc.startsWith("\"")) { + if (optCacheLoc.endsWith("\"")) { + optCacheLoc = optCacheLoc.substring(1, optCacheLoc.length() - 1); + } + else { + optCacheLoc = optCacheLoc.substring(1); } + } - File cacheDir = new File(optCacheLoc); - if (cacheDir.exists() && cacheDir.canWrite()) { - preindexCacheLocation = optCacheLoc; - if (!preindexCacheLocation.endsWith("/") && - !preindexCacheLocation.endsWith(File.separator)) { - preindexCacheLocation += File.separator; - } + File cacheDir = new File(optCacheLoc); + if (cacheDir.exists() && cacheDir.canWrite()) { + preindexCacheLocation = optCacheLoc; + if (!preindexCacheLocation.endsWith("/") && + !preindexCacheLocation.endsWith(File.separator)) { + preindexCacheLocation += File.separator; } } } + } - if (origZipFileName == zipFileName) { - if (!useZipFileIndex) { - archive = new ZipArchive(this, zdir); - } else { - archive = new ZipFileIndexArchive(this, + if (origZipFileName == zipFileName) { + if (!useZipFileIndex) { + archive = new ZipArchive(this, zdir); + } else { + archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, null, usePreindexedCache, preindexCacheLocation, options.isSet("writezipindexfiles"))); - } + } + } else { + if (!useZipFileIndex) { + archive = new SymbolArchive(this, origZipFileName, zdir, symbolFilePrefix); } else { - if (!useZipFileIndex) { - archive = new SymbolArchive(this, origZipFileName, zdir, symbolFilePrefix); - } - else { - archive = new ZipFileIndexArchive(this, + archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, symbolFilePrefix, usePreindexedCache, preindexCacheLocation, options.isSet("writezipindexfiles"))); - } } - } catch (FileNotFoundException ex) { - archive = new MissingArchive(zipFileName); - } catch (IOException ex) { - if (zipFileName.exists()) - log.error("error.reading.file", zipFileName, getMessage(ex)); - archive = new MissingArchive(zipFileName); } + } catch (FileNotFoundException ex) { + archive = new MissingArchive(zipFileName); + } catch (IOException ex) { + if (zipFileName.exists()) + log.error("error.reading.file", zipFileName, getMessage(ex)); + archive = new MissingArchive(zipFileName); + } - archives.put(origZipFileName, archive); - } + archives.put(origZipFileName, archive); return archive; } @@ -589,8 +620,7 @@ ListBuffer results = new ListBuffer(); for (File directory : path) - listDirectory(directory, subdirectory, kinds, recurse, results); - + listContainer(directory, subdirectory, kinds, recurse, results); return results.toList(); } @@ -659,19 +689,22 @@ return null; for (File dir: path) { - if (dir.isDirectory()) { - File f = name.getFile(dir); - if (f.exists()) - return new RegularFileObject(this, f); - } else { - Archive a = openArchive(dir); - if (a.contains(name)) { - return a.getFileObject(name.dirname(), name.basename()); + Archive a = archives.get(dir); + if (a == null) { + if (fsInfo.isDirectory(dir)) { + File f = name.getFile(dir); + if (f.exists()) + return new RegularFileObject(this, f); + continue; } - + // Not a directory, create the archive + a = openArchive(dir); + } + // Process the archive + if (a.contains(name)) { + return a.getFileObject(name.dirname(), name.basename()); } } - return null; } @@ -836,8 +869,9 @@ return false; if (!path.equals(uri.getPath())) // implicitly checks for embedded . and .. return false; - char first = path.charAt(0); - return first != '.' && first != '/'; + if (path.startsWith("/") || path.startsWith("./") || path.startsWith("../")) + return false; + return true; } // Convenience method diff -r 4d4f07f87e28 -r f1df06807698 langtools/src/share/classes/com/sun/tools/javac/file/Paths.java --- a/langtools/src/share/classes/com/sun/tools/javac/file/Paths.java Wed Jul 05 17:31:42 2017 +0200 +++ b/langtools/src/share/classes/com/sun/tools/javac/file/Paths.java Wed Jul 05 17:32:27 2017 +0200 @@ -286,9 +286,8 @@ } public void addFile(File file, boolean warn) { - File canonFile = fsInfo.getCanonicalFile(file); - if (contains(file) || canonicalValues.contains(canonFile)) { - /* Discard duplicates and avoid infinite recursion */ + if (contains(file)) { + // discard duplicates return; } @@ -298,7 +297,17 @@ log.warning(Lint.LintCategory.PATH, "path.element.not.found", file); } - } else if (fsInfo.isFile(file)) { + super.add(file); + return; + } + + File canonFile = fsInfo.getCanonicalFile(file); + if (canonicalValues.contains(canonFile)) { + /* Discard duplicates and avoid infinite recursion */ + return; + } + + if (fsInfo.isFile(file)) { /* File is an ordinary file. */ if (!isArchive(file)) { /* Not a recognized extension; open it to see if @@ -322,11 +331,11 @@ } /* Now what we have left is either a directory or a file name - confirming to archive naming convention */ + conforming to archive naming convention */ super.add(file); canonicalValues.add(canonFile); - if (expandJarClassPaths && fsInfo.exists(file) && fsInfo.isFile(file)) + if (expandJarClassPaths && fsInfo.isFile(file)) addJarClassPath(file, warn); } diff -r 4d4f07f87e28 -r f1df06807698 langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Jul 05 17:31:42 2017 +0200 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Jul 05 17:32:27 2017 +0200 @@ -77,6 +77,8 @@ protected static final Context.Key classReaderKey = new Context.Key(); + public static final int INITIAL_BUFFER_SIZE = 0x0fff0; + Annotate annotate; /** Switch: verbose output. @@ -185,7 +187,7 @@ /** The buffer containing the currently read class file. */ - byte[] buf = new byte[0x0fff0]; + byte[] buf = new byte[INITIAL_BUFFER_SIZE]; /** The current input pointer. */ @@ -2419,8 +2421,14 @@ } } } + /* + * ensureCapacity will increase the buffer as needed, taking note that + * the new buffer will always be greater than the needed and never + * exactly equal to the needed size or bp. If equal then the read (above) + * will infinitely loop as buf.length - bp == 0. + */ private static byte[] ensureCapacity(byte[] buf, int needed) { - if (buf.length < needed) { + if (buf.length <= needed) { byte[] old = buf; buf = new byte[Integer.highestOneBit(needed) << 1]; System.arraycopy(old, 0, buf, 0, old.length); diff -r 4d4f07f87e28 -r f1df06807698 langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java --- a/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Wed Jul 05 17:31:42 2017 +0200 +++ b/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Wed Jul 05 17:32:27 2017 +0200 @@ -376,7 +376,8 @@ new SimpleFileVisitor() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { - if (SourceVersion.isIdentifier(dir.getName().toString())) // JSR 292? + Path name = dir.getName(); + if (name == null || SourceVersion.isIdentifier(name.toString())) // JSR 292? return FileVisitResult.CONTINUE; else return FileVisitResult.SKIP_SUBTREE; diff -r 4d4f07f87e28 -r f1df06807698 langtools/test/tools/javac/6567415/T6567415.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6567415/T6567415.java Wed Jul 05 17:32:27 2017 +0200 @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6567415 + * @summary Test to ensure javac does not go into an infinite loop, while + * reading a classfile of a specific length. + * @compile -XDignore.symbol.file T6567415.java + * @run main T6567415 + * @author ksrini + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; + +/* + * this test compiles Bar.java into a classfile and enlarges the file to the + * magic file length, then use this mutated file on the classpath to compile + * Foo.java which references Bar.java and Ka-boom. QED. + */ +public class T6567415 { + final static String TEST_FILE_NAME = "Bar"; + final static String TEST_JAVA = TEST_FILE_NAME + ".java"; + final static String TEST_CLASS = TEST_FILE_NAME + ".class"; + + final static String TEST2_FILE_NAME = "Foo"; + final static String TEST2_JAVA = TEST2_FILE_NAME + ".java"; + + /* + * the following is the initial buffer length set in ClassReader.java + * thus this value needs to change if ClassReader buf length changes. + */ + + final static int BAD_FILE_LENGTH = + com.sun.tools.javac.jvm.ClassReader.INITIAL_BUFFER_SIZE; + + static void createClassFile() throws IOException { + FileOutputStream fos = null; + try { + fos = new FileOutputStream(TEST_JAVA); + PrintStream ps = new PrintStream(fos); + ps.println("public class " + TEST_FILE_NAME + " {}"); + } finally { + fos.close(); + } + String cmds[] = {TEST_JAVA}; + com.sun.tools.javac.Main.compile(cmds); + } + + static void enlargeClassFile() throws IOException { + File f = new File(TEST_CLASS); + if (!f.exists()) { + System.out.println("file not found: " + TEST_CLASS); + System.exit(1); + } + File tfile = new File(f.getAbsolutePath() + ".tmp"); + f.renameTo(tfile); + + RandomAccessFile raf = null; + FileChannel wfc = null; + + FileInputStream fis = null; + FileChannel rfc = null; + + try { + raf = new RandomAccessFile(f, "rw"); + wfc = raf.getChannel(); + + fis = new FileInputStream(tfile); + rfc = fis.getChannel(); + + ByteBuffer bb = MappedByteBuffer.allocate(BAD_FILE_LENGTH); + rfc.read(bb); + bb.rewind(); + wfc.write(bb); + wfc.truncate(BAD_FILE_LENGTH); + } finally { + wfc.close(); + raf.close(); + rfc.close(); + fis.close(); + } + System.out.println("file length = " + f.length()); + } + + static void createJavaFile() throws IOException { + FileOutputStream fos = null; + try { + fos = new FileOutputStream(TEST2_JAVA); + PrintStream ps = new PrintStream(fos); + ps.println("public class " + TEST2_FILE_NAME + + " {" + TEST_FILE_NAME + " b = new " + + TEST_FILE_NAME + " ();}"); + } finally { + fos.close(); + } + } + + public static void main(String... args) throws Exception { + createClassFile(); + enlargeClassFile(); + createJavaFile(); + Thread t = new Thread () { + @Override + public void run() { + String cmds[] = {"-verbose", "-cp", ".", TEST2_JAVA}; + int ret = com.sun.tools.javac.Main.compile(cmds); + System.out.println("test compilation returns: " + ret); + } + }; + t.start(); + t.join(1000*10); + System.out.println(t.getState()); + if (t.isAlive()) { + throw new RuntimeException("Error: compilation is looping"); + } + } +} diff -r 4d4f07f87e28 -r f1df06807698 langtools/test/tools/javac/diags/examples/TypeParameterOnPolymorphicSignature.java --- a/langtools/test/tools/javac/diags/examples/TypeParameterOnPolymorphicSignature.java Wed Jul 05 17:31:42 2017 +0200 +++ b/langtools/test/tools/javac/diags/examples/TypeParameterOnPolymorphicSignature.java Wed Jul 05 17:32:27 2017 +0200 @@ -24,8 +24,10 @@ // key: compiler.warn.type.parameter.on.polymorphic.signature // key: compiler.err.unreported.exception.need.to.catch.or.throw -import java.dyn.InvokeDynamic; +import java.dyn.MethodHandle; class TypeParameterOnPolymorphicSignature { - { InvokeDynamic.call("",123); } + void test(MethodHandle mh) { + mh.invokeExact("",123); + } } diff -r 4d4f07f87e28 -r f1df06807698 langtools/test/tools/javac/failover/CheckAttributedTree.java --- a/langtools/test/tools/javac/failover/CheckAttributedTree.java Wed Jul 05 17:31:42 2017 +0200 +++ b/langtools/test/tools/javac/failover/CheckAttributedTree.java Wed Jul 05 17:32:27 2017 +0200 @@ -252,6 +252,13 @@ error("File " + file + " ignored"); } + // See CR: 6982992 Tests CheckAttributedTree.java, JavacTreeScannerTest.java, and SourceTreeeScannerTest.java timeout + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + Reporter r = new Reporter(pw); + JavacTool tool = JavacTool.create(); + StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null); + /** * Read a file. * @param file the file to be read @@ -260,12 +267,8 @@ * @throws TreePosTest.ParseException if any errors occur while parsing the file */ List> read(File file) throws IOException, AttributionException { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - Reporter r = new Reporter(pw); JavacTool tool = JavacTool.create(); - Charset cs = (encoding == null ? null : Charset.forName(encoding)); - StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null); + r.errors = 0; Iterable files = fm.getJavaFileObjects(file); String[] opts = { "-XDshouldStopPolicy=ATTR", "-XDverboseCompilePolicy" }; JavacTask task = tool.getTask(pw, fm, r, Arrays.asList(opts), null, files); diff -r 4d4f07f87e28 -r f1df06807698 langtools/test/tools/javac/meth/InvokeDyn.java --- a/langtools/test/tools/javac/meth/InvokeDyn.java Wed Jul 05 17:31:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 6754038 6979327 - * @summary Generate call sites for method handle - * @author jrose - * - * @library .. - * @compile -source 7 -target 7 -XDinvokedynamic -XDallowTransitionalJSR292=no InvokeDyn.java - */ -//No: @run main/othervm -XX:+EnableInvokeDynamic meth.InvokeDyn - -/* - * Standalone testing: - * - * $ cd $MY_REPO_DIR/langtools - * $ (cd make; make) - * $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/meth/InvokeDyn.java - * $ javap -c -classpath dist meth.InvokeDyn - * - */ - -package meth; - -import java.dyn.*; - -public class InvokeDyn { - class CS extends CallSite { - CS(Object x, Object y, Object z) { throw new RuntimeException(); } - } - //@BootstrapMethod(CS.class) //note: requires 6964498 - void test() throws Throwable { - Object x = "hello"; - Object ojunk; int ijunk; - ojunk = InvokeDynamic.greet(x, "world", 123); - ojunk = InvokeDynamic.greet(x, "mundus", 456); - ojunk = InvokeDynamic.greet(x, "kosmos", 789); - ojunk = (String) InvokeDynamic.cogitate(10.11121, 3.14); - //InvokeDynamic.#"yow: what I mean to say is, please treat this one specially"(null); - ijunk = (int) InvokeDynamic.invoke("goodbye"); - } -} diff -r 4d4f07f87e28 -r f1df06807698 langtools/test/tools/javac/meth/InvokeDynTrans.java --- a/langtools/test/tools/javac/meth/InvokeDynTrans.java Wed Jul 05 17:31:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 6754038 6979327 - * @summary Generate call sites for method handle - * @author jrose - * - * @library .. - * @compile/fail/ref=InvokeDynTrans.out -Werror -XDrawDiagnostics -source 7 -target 7 InvokeDynTrans.java - */ -//No: @run main/othervm -XX:+EnableInvokeDynamic meth.InvokeDyn - -/* - * Standalone testing: - * - * $ cd $MY_REPO_DIR/langtools - * $ (cd make; make) - * $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/meth/InvokeDyn.java - * $ javap -c -classpath dist meth.InvokeDyn - * - */ - -package meth; - -import java.dyn.InvokeDynamic; - -public class InvokeDynTrans { - void test() throws Throwable { - Object x = "hello"; - InvokeDynamic.greet(x, "world", 123); - InvokeDynamic.greet(x, "mundus", 456); - InvokeDynamic.greet(x, "kosmos", 789); - InvokeDynamic.cogitate(10.11121, 3.14); - //InvokeDynamic.#"yow: what I mean to say is, please treat this one specially"(null); - InvokeDynamic.invoke("goodbye"); - } -} diff -r 4d4f07f87e28 -r f1df06807698 langtools/test/tools/javac/meth/XlintWarn.java --- a/langtools/test/tools/javac/meth/XlintWarn.java Wed Jul 05 17:31:42 2017 +0200 +++ b/langtools/test/tools/javac/meth/XlintWarn.java Wed Jul 05 17:32:27 2017 +0200 @@ -23,7 +23,7 @@ /* * @test - * @bug 6999067 + * @bug 6999067 7010194 * @summary cast for invokeExact call gets redundant cast to warnings * @author mcimadamore * @@ -34,9 +34,7 @@ class XlintWarn { void test(MethodHandle mh) throws Throwable { - int i1 = (int)mh.invoke(); - int i2 = (int)mh.invokeExact(); - int i3 = (int)mh.invokeVarargs(); - int i4 = (int)InvokeDynamic.test(); + int i1 = (int)mh.invokeExact(); + int i2 = (int)mh.invokeVarargs(); } } diff -r 4d4f07f87e28 -r f1df06807698 langtools/test/tools/javac/nio/compileTest/CompileTest.java --- a/langtools/test/tools/javac/nio/compileTest/CompileTest.java Wed Jul 05 17:31:42 2017 +0200 +++ b/langtools/test/tools/javac/nio/compileTest/CompileTest.java Wed Jul 05 17:32:27 2017 +0200 @@ -23,7 +23,7 @@ /** * @test - * @bug 6906175 6915476 6915497 + * @bug 6906175 6915476 6915497 7006564 * @summary Path-based JavaFileManager * @compile -g HelloPathWorld.java * @run main CompileTest diff -r 4d4f07f87e28 -r f1df06807698 langtools/test/tools/javac/processing/filer/TestValidRelativeNames.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/filer/TestValidRelativeNames.java Wed Jul 05 17:32:27 2017 +0200 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6999891 + * @summary Test valid relative names for Filer.createResource and Filer.getResource + * @library ../../lib + * @build JavacTestingAbstractProcessor + * @compile TestValidRelativeNames.java + * @compile/process -processor TestValidRelativeNames -Amode=create java.lang.Object + * @compile/process -processor TestValidRelativeNames -Amode=get java.lang.Object + */ + +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.tools.Diagnostic; +import javax.tools.StandardLocation; + +@SupportedOptions("mode") +public class TestValidRelativeNames extends JavacTestingAbstractProcessor { + enum Kind { READER_WRITER, INPUT_OUTPUT_STREAM }; + + static final String[] validRelativeNames = { + "foo", "foo.bar", ".foo", ".foo.bar", "foodir/bar", "foodir/.bar" + }; + + public boolean process(Set annotations, RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) { + String mode = options.get("mode"); + for (String relativeBase: validRelativeNames) { + for (Kind kind: Kind.values()) { + if (mode.equals("create")) + testCreate(relativeBase, kind); + else + testGet(relativeBase, kind); + } + } + } + + return true; + } + + void testCreate(String relativeBase, Kind kind) { + String relative = getRelative(relativeBase, kind); + System.out.println("test create relative path: " + relative + ", kind: " + kind); + try { + switch (kind) { + case READER_WRITER: + try (Writer writer = filer.createResource( + StandardLocation.CLASS_OUTPUT, "", relative).openWriter()) { + writer.write(relative); + } + break; + + case INPUT_OUTPUT_STREAM: + try (OutputStream out = filer.createResource( + StandardLocation.CLASS_OUTPUT, "", relative).openOutputStream()) { + out.write(relative.getBytes()); + } + break; + } + } catch (Exception e) { + messager.printMessage(Diagnostic.Kind.ERROR, + "relative path: " + relative + ", kind: " + kind + ", unexpected exception: " + e); + } + } + + void testGet(String relativeBase, Kind kind) { + String relative = getRelative(relativeBase, kind); + System.out.println("test get relative path: " + relative + ", kind: " + kind); + try { + switch (kind) { + case READER_WRITER: + try (Reader reader = new BufferedReader(filer.getResource( + StandardLocation.CLASS_OUTPUT, "", relative).openReader(true))) { + StringBuilder sb = new StringBuilder(); + char[] buf = new char[1024]; + int n; + while ((n = reader.read(buf, 0, buf.length)) > 0) + sb.append(new String(buf, 0, n)); + if (!sb.toString().equals(relative)) { + messager.printMessage(Diagnostic.Kind.ERROR, "unexpected content: " + sb); + } + } + break; + + case INPUT_OUTPUT_STREAM: + try (InputStream in = new DataInputStream(filer.getResource( + StandardLocation.CLASS_OUTPUT, "", relative).openInputStream())) { + StringBuilder sb = new StringBuilder(); + byte[] buf = new byte[1024]; + int n; + while ((n = in.read(buf, 0, buf.length)) > 0) + sb.append(new String(buf, 0, n)); + if (!sb.toString().equals(relative)) { + messager.printMessage(Diagnostic.Kind.ERROR, "unexpected content: " + sb); + } + } + break; + } + } catch (Exception e) { + messager.printMessage(Diagnostic.Kind.ERROR, + "relative path: " + relative + ", kind: " + kind + ", unexpected exception: " + e); + } + } + + String getRelative(String relativeBase, Kind kind) { + String suffix = (kind == Kind.READER_WRITER ? "RW" : "IOS"); + return relativeBase.replace("foo", "foo" + suffix); + } +} + diff -r 4d4f07f87e28 -r f1df06807698 langtools/test/tools/javac/tree/AbstractTreeScannerTest.java --- a/langtools/test/tools/javac/tree/AbstractTreeScannerTest.java Wed Jul 05 17:31:42 2017 +0200 +++ b/langtools/test/tools/javac/tree/AbstractTreeScannerTest.java Wed Jul 05 17:32:27 2017 +0200 @@ -143,6 +143,13 @@ abstract int test(JCCompilationUnit t); + // See CR: 6982992 Tests CheckAttributedTree.java, JavacTreeScannerTest.java, and SourceTreeeScannerTest.java timeout + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + Reporter r = new Reporter(pw); + JavacTool tool = JavacTool.create(); + StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null); + /** * Read a file. * @param file the file to be read @@ -151,11 +158,8 @@ * @throws TreePosTest.ParseException if any errors occur while parsing the file */ JCCompilationUnit read(File file) throws IOException, ParseException { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - Reporter r = new Reporter(pw); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null); + r.errors = 0; Iterable files = fm.getJavaFileObjects(file); JavacTask task = tool.getTask(pw, fm, r, Collections.emptyList(), null, files); Iterable trees = task.parse(); diff -r 4d4f07f87e28 -r f1df06807698 langtools/test/tools/javac/tree/TreePosTest.java --- a/langtools/test/tools/javac/tree/TreePosTest.java Wed Jul 05 17:31:42 2017 +0200 +++ b/langtools/test/tools/javac/tree/TreePosTest.java Wed Jul 05 17:32:27 2017 +0200 @@ -249,6 +249,13 @@ error("File " + file + " ignored"); } + // See CR: 6982992 Tests CheckAttributedTree.java, JavacTreeScannerTest.java, and SourceTreeeScannerTest.java timeout + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + Reporter r = new Reporter(pw); + JavacTool tool = JavacTool.create(); + StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null); + /** * Read a file. * @param file the file to be read @@ -257,12 +264,8 @@ * @throws TreePosTest.ParseException if any errors occur while parsing the file */ JCCompilationUnit read(File file) throws IOException, ParseException { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - Reporter r = new Reporter(pw); JavacTool tool = JavacTool.create(); - Charset cs = (encoding == null ? null : Charset.forName(encoding)); - StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null); + r.errors = 0; Iterable files = fm.getJavaFileObjects(file); JavacTask task = tool.getTask(pw, fm, r, Collections.emptyList(), null, files); Iterable trees = task.parse();