OpenJDK / jdk / jdk
changeset 6325:adf468d05745
Merge
author | lana |
---|---|
date | Sun, 29 Aug 2010 22:41:28 -0700 |
parents | 044d31b99ef5 b624b3a4e6e8 |
children | 047748ce0a45 f8eac76fb676 78d56f33c3a7 85f30f8aa7f3 7bbabd9b79e6 d1c0054bff1c 7b6911d709ed 1c545d70a157 |
files | jdk/src/share/classes/sun/java2d/pisces/PiscesMath.java jdk/src/share/classes/sun/java2d/pisces/Transform4.java jdk/test/tools/pack200/Pack200Simple.sh jdk/test/tools/pack200/SegmentLimit.java |
diffstat | 99 files changed, 13047 insertions(+), 2727 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/make/common/shared/Defs-windows.gmk Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/make/common/shared/Defs-windows.gmk Sun Aug 29 22:41:28 2010 -0700 @@ -89,7 +89,7 @@ $(shell $(CYGPATH_CMD) $1 2> $(DEV_NULL)) endef define OptFullPath -$(shell if [ "$1" != "" -a -d "$1" ]; then $(CYGPATH_CMD) "$1"; else echo "$1"; fi) +$(shell if [ "$1" != "" -a -d "$1" ]; then $(CYGPATH_CMD) "$1" 2> $(DEV_NULL); else echo "$1"; fi) endef else # Temporary until we upgrade to MKS 8.7, MKS pwd returns mixed mode path
--- a/jdk/make/common/shared/Defs.gmk Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/make/common/shared/Defs.gmk Sun Aug 29 22:41:28 2010 -0700 @@ -136,15 +136,20 @@ $(shell echo $1 | sed -e 's@[^0-9]*\([0-9][0-9]*\.[0-9][.0-9]*\).*@\1@' ) endef +# Return one part of the version numbers, watch out for non digits. +define VersionWord # Number Version +$(word $1,$(subst ., ,$(subst -, ,$2))) +endef + # Given a major.minor.micro version, return the major, minor, or micro number define MajorVersion -$(if $(word 1, $(subst ., ,$1)),$(word 1, $(subst ., ,$1)),0) +$(if $(call VersionWord,1,$1),$(call VersionWord,1,$1),0) endef define MinorVersion -$(if $(word 2, $(subst ., ,$1)),$(word 2, $(subst ., ,$1)),0) +$(if $(call VersionWord,2,$1),$(call VersionWord,2,$1),0) endef define MicroVersion -$(if $(word 3, $(subst ., ,$1)),$(word 3, $(subst ., ,$1)),0) +$(if $(call VersionWord,3,$1),$(call VersionWord,3,$1),0) endef # Macro that returns missing, same, newer, or older $1=version $2=required
--- a/jdk/make/jdk_generic_profile.sh Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/make/jdk_generic_profile.sh Sun Aug 29 22:41:28 2010 -0700 @@ -340,6 +340,10 @@ export PATH # Export variables required for Zero +if [ "${SHARK_BUILD}" = true ] ; then + ZERO_BUILD=true + export ZERO_BUILD +fi if [ "${ZERO_BUILD}" = true ] ; then # ZERO_LIBARCH is the name of the architecture-specific # subdirectory under $JAVA_HOME/jre/lib @@ -417,4 +421,55 @@ fi export LIBFFI_CFLAGS export LIBFFI_LIBS + + # LLVM_CFLAGS, LLVM_LDFLAGS and LLVM_LIBS tell the compiler how to + # compile and link against LLVM + if [ "${SHARK_BUILD}" = true ] ; then + if [ "${LLVM_CONFIG}" = "" ] ; then + LLVM_CONFIG=$(which llvm-config 2>/dev/null) + fi + if [ ! -x "${LLVM_CONFIG}" ] ; then + echo "ERROR: Unable to locate llvm-config" + exit 1 + fi + llvm_components="jit engine nativecodegen" + + unset LLVM_CFLAGS + for flag in $("${LLVM_CONFIG}" --cxxflags $llvm_components); do + if echo "${flag}" | grep -q '^-[ID]'; then + if [ "${flag}" != "-D_DEBUG" ] ; then + if [ "${LLVM_CFLAGS}" != "" ] ; then + LLVM_CFLAGS="${LLVM_CFLAGS} " + fi + LLVM_CFLAGS="${LLVM_CFLAGS}${flag}" + fi + fi + done + llvm_version=$("${LLVM_CONFIG}" --version | sed 's/\.//; s/svn.*//') + LLVM_CFLAGS="${LLVM_CFLAGS} -DSHARK_LLVM_VERSION=${llvm_version}" + + unset LLVM_LDFLAGS + for flag in $("${LLVM_CONFIG}" --ldflags $llvm_components); do + if echo "${flag}" | grep -q '^-L'; then + if [ "${LLVM_LDFLAGS}" != "" ] ; then + LLVM_LDFLAGS="${LLVM_LDFLAGS} " + fi + LLVM_LDFLAGS="${LLVM_LDFLAGS}${flag}" + fi + done + + unset LLVM_LIBS + for flag in $("${LLVM_CONFIG}" --libs $llvm_components); do + if echo "${flag}" | grep -q '^-l'; then + if [ "${LLVM_LIBS}" != "" ] ; then + LLVM_LIBS="${LLVM_LIBS} " + fi + LLVM_LIBS="${LLVM_LIBS}${flag}" + fi + done + + export LLVM_CFLAGS + export LLVM_LDFLAGS + export LLVM_LIBS + fi fi
--- a/jdk/make/sun/javazic/tzdata/VERSION Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/make/sun/javazic/tzdata/VERSION Sun Aug 29 22:41:28 2010 -0700 @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2010i +tzdata2010l
--- a/jdk/make/sun/javazic/tzdata/africa Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/make/sun/javazic/tzdata/africa Sun Aug 29 22:41:28 2010 -0700 @@ -316,8 +316,25 @@ # and can be found by searching for "winter" in their search engine # (at least today). +# From Alexander Krivenyshev (2010-07-20): +# According to News from Egypt - Al-Masry Al-Youm Egypt's cabinet has +# decided that Daylight Saving Time will not be used in Egypt during +# Ramadan. +# +# Arabic translation: +# "Clocks to go back during Ramadan--and then forward again" +# <a href="http://www.almasryalyoum.com/en/news/clocks-go-back-during-ramadan-and-then-forward-again"> +# http://www.almasryalyoum.com/en/news/clocks-go-back-during-ramadan-and-then-forward-again +# </a> +# or +# <a href="http://www.worldtimezone.com/dst_news/dst_news_egypt02.html"> +# http://www.worldtimezone.com/dst_news/dst_news_egypt02.html +# </a> + Rule Egypt 2008 only - Aug lastThu 23:00s 0 - Rule Egypt 2009 only - Aug 20 23:00s 0 - +Rule Egypt 2010 only - Aug 11 0:00 0 - +Rule Egypt 2010 only - Sep 10 0:00 1:00 S Rule Egypt 2010 max - Sep lastThu 23:00s 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL]
--- a/jdk/make/sun/javazic/tzdata/asia Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/make/sun/javazic/tzdata/asia Sun Aug 29 22:41:28 2010 -0700 @@ -2200,6 +2200,18 @@ # "At 12:01am Friday, clocks in Israel and the West Bank will change to # 1:01am, while Gaza clocks will change at 12:01am Saturday morning." +# From Steffen Thorsen (2010-08-11): +# According to several sources, including +# <a href="http://www.maannews.net/eng/ViewDetails.aspx?ID=306795"> +# http://www.maannews.net/eng/ViewDetails.aspx?ID=306795 +# </a> +# the clocks were set back one hour at 2010-08-11 00:00:00 local time in +# Gaza and the West Bank. +# Some more background info: +# <a href="http://www.timeanddate.com/news/time/westbank-gaza-end-dst-2010.html"> +# http://www.timeanddate.com/news/time/westbank-gaza-end-dst-2010.html +# </a> + # The rules for Egypt are stolen from the `africa' file. # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule EgyptAsia 1957 only - May 10 0:00 1:00 S @@ -2220,6 +2232,7 @@ Rule Palestine 2009 only - Mar lastFri 0:00 1:00 S Rule Palestine 2010 max - Mar lastSat 0:01 1:00 S Rule Palestine 2009 max - Sep Fri>=1 2:00 0 - +Rule Palestine 2010 only - Aug 11 0:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Gaza 2:17:52 - LMT 1900 Oct
--- a/jdk/make/sun/javazic/tzdata/australasia Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/make/sun/javazic/tzdata/australasia Sun Aug 29 22:41:28 2010 -0700 @@ -368,10 +368,10 @@ # Micronesia # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Pacific/Truk 10:07:08 - LMT 1901 - 10:00 - TRUT # Truk Time -Zone Pacific/Ponape 10:32:52 - LMT 1901 # Kolonia - 11:00 - PONT # Ponape Time +Zone Pacific/Chuuk 10:07:08 - LMT 1901 + 10:00 - CHUT # Chuuk Time +Zone Pacific/Pohnpei 10:32:52 - LMT 1901 # Kolonia + 11:00 - PONT # Pohnpei Time Zone Pacific/Kosrae 10:51:56 - LMT 1901 11:00 - KOST 1969 Oct # Kosrae Time 12:00 - KOST 1999
--- a/jdk/make/sun/javazic/tzdata/backward Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/make/sun/javazic/tzdata/backward Sun Aug 29 22:41:28 2010 -0700 @@ -112,7 +112,9 @@ Link America/Denver Navajo Link Asia/Shanghai PRC Link Pacific/Pago_Pago Pacific/Samoa -Link Pacific/Truk Pacific/Yap +Link Pacific/Chuuk Pacific/Yap +Link Pacific/Chuuk Pacific/Truk +Link Pacific/Pohnpei Pacific/Ponape Link Europe/Warsaw Poland Link Europe/Lisbon Portugal Link Asia/Taipei ROC
--- a/jdk/make/sun/javazic/tzdata/europe Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/make/sun/javazic/tzdata/europe Sun Aug 29 22:41:28 2010 -0700 @@ -1035,22 +1035,47 @@ 2:00 EU EE%sT # Finland -# + # From Hannu Strang (1994-09-25 06:03:37 UTC): # Well, here in Helsinki we're just changing from summer time to regular one, # and it's supposed to change at 4am... + +# From Janne Snabb (2010-0715): # -# From Paul Eggert (2006-03-22): -# Shanks & Pottenger say Finland has switched at 02:00 standard time -# since 1981. Go with Strang instead. +# I noticed that the Finland data is not accurate for years 1981 and 1982. +# During these two first trial years the DST adjustment was made one hour +# earlier than in forthcoming years. Starting 1983 the adjustment was made +# according to the central European standards. +# +# This is documented in Heikki Oja: Aikakirja 2007, published by The Almanac +# Office of University of Helsinki, ISBN 952-10-3221-9, available online (in +# Finnish) at +# +# <a href="http://almanakka.helsinki.fi/aikakirja/Aikakirja2007kokonaan.pdf"> +# http://almanakka.helsinki.fi/aikakirja/Aikakirja2007kokonaan.pdf +# </a> # +# Page 105 (56 in PDF version) has a handy table of all past daylight savings +# transitions. It is easy enough to interpret without Finnish skills. +# +# This is also confirmed by Finnish Broadcasting Company's archive at: +# +# <a href="http://www.yle.fi/elavaarkisto/?s=s&g=1&ag=5&t=&a=3401"> +# http://www.yle.fi/elavaarkisto/?s=s&g=1&ag=5&t=&a=3401 +# </a> +# +# The news clip from 1981 says that "the time between 2 and 3 o'clock does not +# exist tonight." + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Finland 1942 only - Apr 3 0:00 1:00 S Rule Finland 1942 only - Oct 3 0:00 0 - +Rule Finland 1981 1982 - Mar lastSun 2:00 1:00 S +Rule Finland 1981 1982 - Sep lastSun 3:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Europe/Helsinki 1:39:52 - LMT 1878 May 31 1:39:52 - HMT 1921 May # Helsinki Mean Time - 2:00 Finland EE%sT 1981 Mar 29 2:00 + 2:00 Finland EE%sT 1983 2:00 EU EE%sT # Aaland Is
--- a/jdk/make/sun/javazic/tzdata/leapseconds Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/make/sun/javazic/tzdata/leapseconds Sun Aug 29 22:41:28 2010 -0700 @@ -82,9 +82,9 @@ # FAX : 33 (0) 1 40 51 22 91 # Internet : services.iers@obspm.fr # -# Paris, 4 July 2009 +# Paris, 14 July 2010 # -# Bulletin C 38 +# Bulletin C 40 # # To authorities responsible # for the measurement and @@ -92,9 +92,9 @@ # # INFORMATION ON UTC - TAI # -# NO positive leap second will be introduced at the end of December 2009. +# NO positive leap second will be introduced at the end of December 2010. # The difference between Coordinated Universal Time UTC and the -# International Atomic Time TAI is : +# International Atomic Time TAI is : # # from 2009 January 1, 0h UTC, until further notice : UTC-TAI = -34 s # @@ -104,6 +104,6 @@ # will be no time step at the next possible date. # # Daniel GAMBIS -# Director +# Director # Earth Orientation Center of IERS # Observatoire de Paris, France
--- a/jdk/make/sun/javazic/tzdata/northamerica Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/make/sun/javazic/tzdata/northamerica Sun Aug 29 22:41:28 2010 -0700 @@ -1346,6 +1346,83 @@ # entry since our cutoff date of 1970, so we can move # America/Coral_Harbour to the 'backward' file. +# From Mark Brader (2010-03-06): +# +# Currently the database has: +# +# # Ontario +# +# # From Paul Eggert (2006-07-09): +# # Shanks & Pottenger write that since 1970 most of Ontario has been like +# # Toronto. +# # Thunder Bay skipped DST in 1973. +# # Many smaller locales did not observe peacetime DST until 1974; +# # Nipigon (EST) and Rainy River (CST) are the largest that we know of. +# +# In the (Toronto) Globe and Mail for Saturday, 1955-09-24, in the bottom +# right corner of page 1, it says that Toronto will return to standard +# time at 2 am Sunday morning (which agrees with the database), and that: +# +# The one-hour setback will go into effect throughout most of Ontario, +# except in areas like Windsor which remains on standard time all year. +# +# Windsor is, of course, a lot larger than Nipigon. +# +# I only came across this incidentally. I don't know if Windsor began +# observing DST when Detroit did, or in 1974, or on some other date. +# +# By the way, the article continues by noting that: +# +# Some cities in the United States have pushed the deadline back +# three weeks and will change over from daylight saving in October. + +# From Arthur David Olson (2010-07-17): +# +# "Standard Time and Time Zones in Canada" appeared in +# The Journal of The Royal Astronomical Society of Canada, +# volume 26, number 2 (February 1932) and, as of 2010-07-17, +# was available at +# <a href="http://adsabs.harvard.edu/full/1932JRASC..26...49S"> +# http://adsabs.harvard.edu/full/1932JRASC..26...49S +# </a> +# +# It includes the text below (starting on page 57): +# +# A list of the places in Canada using daylight saving time would +# require yearly revision. From information kindly furnished by +# the provincial governments and by the postmasters in many cities +# and towns, it is found that the following places used daylight sav- +# ing in 1930. The information for the province of Quebec is definite, +# for the other provinces only approximate: +# +# Province Daylight saving time used +# Prince Edward Island Not used. +# Nova Scotia In Halifax only. +# New Brunswick In St. John only. +# Quebec In the following places: +# Montreal Lachine +# Quebec Mont-Royal +# Levis Iberville +# St. Lambert Cap de la Madeleine +# Verdun Loretteville +# Westmount Richmond +# Outremont St. Jerome +# Longueuil Greenfield Park +# Arvida Waterloo +# Chambly-Canton Beaulieu +# Melbourne La Tuque +# St. Theophile Buckingham +# Ontario Used generally in the cities and towns along +# the southerly part of the province. Not +# used in the northwesterlhy part. +# Manitoba Not used. +# Saskatchewan In Regina only. +# Alberta Not used. +# British Columbia Not used. +# +# With some exceptions, the use of daylight saving may be said to be limited +# to those cities and towns lying between Quebec city and Windsor, Ont. + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Toronto 1919 only - Mar 30 23:30 1:00 D Rule Toronto 1919 only - Oct 26 0:00 0 S @@ -2111,7 +2188,44 @@ -8:00 - PST 1970 -7:00 Mexico M%sT 1999 -7:00 - MST + +# From Alexander Krivenyshev (2010-04-21): +# According to news, Bahía de Banderas (Mexican state of Nayarit) +# changed time zone UTC-7 to new time zone UTC-6 on April 4, 2010 (to +# share the same time zone as nearby city Puerto Vallarta, Jalisco). +# +# (Spanish) +# Bahía de Banderas homologa su horario al del centro del +# país, a partir de este domingo +# <a href="http://www.nayarit.gob.mx/notes.asp?id=20748"> +# http://www.nayarit.gob.mx/notes.asp?id=20748 +# </a> +# +# Bahía de Banderas homologa su horario con el del Centro del +# País +# <a href="http://www.bahiadebanderas.gob.mx/principal/index.php?option=com_content&view=article&id=261:bahia-de-banderas-homologa-su-horario-con-el-del-centro-del-pais&catid=42:comunicacion-social&Itemid=50"> +# http://www.bahiadebanderas.gob.mx/principal/index.php?option=com_content&view=article&id=261:bahia-de-banderas-homologa-su-horario-con-el-del-centro-del-pais&catid=42:comunicacion-social&Itemid=50" +# </a> +# +# (English) +# Puerto Vallarta and Bahía de Banderas: One Time Zone +# <a href="http://virtualvallarta.com/puertovallarta/puertovallarta/localnews/2009-12-03-Puerto-Vallarta-and-Bahia-de-Banderas-One-Time-Zone.shtml"> +# http://virtualvallarta.com/puertovallarta/puertovallarta/localnews/2009-12-03-Puerto-Vallarta-and-Bahia-de-Banderas-One-Time-Zone.shtml +# </a> +# +# or +# <a href="http://www.worldtimezone.com/dst_news/dst_news_mexico08.html"> +# http://www.worldtimezone.com/dst_news/dst_news_mexico08.html +# </a> +# +# "Mexico's Senate approved the amendments to the Mexican Schedule System that +# will allow Bahía de Banderas and Puerto Vallarta to share the same time +# zone ..." # Baja California Sur, Nayarit, Sinaloa + +# From Arthur David Olson (2010-05-01): +# Use "Bahia_Banderas" to keep the name to fourteen characters. + Zone America/Mazatlan -7:05:40 - LMT 1921 Dec 31 23:54:20 -7:00 - MST 1927 Jun 10 23:00 -6:00 - CST 1930 Nov 15 @@ -2122,6 +2236,19 @@ -7:00 - MST 1949 Jan 14 -8:00 - PST 1970 -7:00 Mexico M%sT + +Zone America/Bahia_Banderas -7:01:00 - LMT 1921 Dec 31 23:59:00 + -7:00 - MST 1927 Jun 10 23:00 + -6:00 - CST 1930 Nov 15 + -7:00 - MST 1931 May 1 23:00 + -6:00 - CST 1931 Oct + -7:00 - MST 1932 Apr 1 + -6:00 - CST 1942 Apr 24 + -7:00 - MST 1949 Jan 14 + -8:00 - PST 1970 + -7:00 Mexico M%sT 2010 Apr 4 2:00 + -6:00 Mexico C%sT + # Baja California (near US border) Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 0:11:56 -7:00 - MST 1924
--- a/jdk/make/sun/javazic/tzdata/zone.tab Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/make/sun/javazic/tzdata/zone.tab Sun Aug 29 22:41:28 2010 -0700 @@ -199,8 +199,8 @@ FI +6010+02458 Europe/Helsinki FJ -1808+17825 Pacific/Fiji FK -5142-05751 Atlantic/Stanley -FM +0725+15147 Pacific/Truk Truk (Chuuk) and Yap -FM +0658+15813 Pacific/Ponape Ponape (Pohnpei) +FM +0725+15147 Pacific/Chuuk Chuuk (Truk) and Yap +FM +0658+15813 Pacific/Pohnpei Pohnpei (Ponape) FM +0519+16259 Pacific/Kosrae Kosrae FO +6201-00646 Atlantic/Faroe FR +4852+00220 Europe/Paris @@ -310,6 +310,7 @@ MX +2904-11058 America/Hermosillo Mountain Standard Time - Sonora MX +3232-11701 America/Tijuana US Pacific Time - Baja California near US border MX +3018-11452 America/Santa_Isabel Mexican Pacific Time - Baja California away from US border +MX +2048-10515 America/Bahia_Banderas Mexican Central Time - Bahia de Banderas MY +0310+10142 Asia/Kuala_Lumpur peninsular Malaysia MY +0133+11020 Asia/Kuching Sabah & Sarawak MZ -2558+03235 Africa/Maputo
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2005, 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 @@ -27,7 +27,6 @@ import java.io.*; import java.util.*; -import com.sun.java.util.jar.pack.Package.Class; import com.sun.java.util.jar.pack.ConstantPool.*; /** @@ -96,20 +95,20 @@ return this.def.compareTo(that.def); } - static private final byte[] noBytes = {}; - static private final HashMap canonLists = new HashMap(); - static private final HashMap attributes = new HashMap(); - static private final HashMap standardDefs = new HashMap(); + private static final byte[] noBytes = {}; + private static final Map<List<Attribute>, List<Attribute>> canonLists = new HashMap<>(); + private static final Map<Layout, Attribute> attributes = new HashMap<>(); + private static final Map<Layout, Attribute> standardDefs = new HashMap<>(); // Canonicalized lists of trivial attrs (Deprecated, etc.) // 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<Attribute> al) { synchronized (canonLists) { - List cl = (List) canonLists.get(al); + List<Attribute> cl = canonLists.get(al); if (cl == null) { - cl = new ArrayList(al.size()); + cl = new ArrayList<>(al.size()); cl.addAll(al); cl = Collections.unmodifiableList(cl); canonLists.put(al, cl); @@ -122,7 +121,7 @@ public static Attribute find(int ctype, String name, String layout) { Layout key = Layout.makeKey(ctype, name, layout); synchronized (attributes) { - Attribute a = (Attribute) attributes.get(key); + Attribute a = attributes.get(key); if (a == null) { a = new Layout(ctype, name, layout).canonicalInstance(); attributes.put(key, a); @@ -131,24 +130,29 @@ } } - public static Object keyForLookup(int ctype, String name) { + public static Layout keyForLookup(int ctype, String name) { return Layout.makeKey(ctype, name); } // Find canonical empty attribute with given ctype and name, // and with the standard layout. - public static Attribute lookup(Map defs, int ctype, String name) { - if (defs == null) defs = standardDefs; - return (Attribute) defs.get(Layout.makeKey(ctype, name)); + public static Attribute lookup(Map<Layout, Attribute> defs, int ctype, + String name) { + if (defs == null) { + defs = standardDefs; + } + return defs.get(Layout.makeKey(ctype, name)); } - public static Attribute define(Map defs, int ctype, String name, String layout) { + + public static Attribute define(Map<Layout, Attribute> defs, int ctype, + String name, String layout) { Attribute a = find(ctype, name, layout); defs.put(Layout.makeKey(ctype, name), a); return a; } static { - Map sd = standardDefs; + Map<Layout, Attribute> sd = standardDefs; define(sd, ATTR_CONTEXT_CLASS, "Signature", "RSH"); define(sd, ATTR_CONTEXT_CLASS, "Synthetic", ""); define(sd, ATTR_CONTEXT_CLASS, "Deprecated", ""); @@ -244,7 +248,7 @@ +"\n ()[] ]" ) }; - Map sd = standardDefs; + Map<Layout, Attribute> sd = standardDefs; String defaultLayout = mdLayouts[2]; String annotationsLayout = mdLayouts[1] + mdLayouts[2]; String paramsLayout = mdLayouts[0] + annotationsLayout; @@ -275,10 +279,6 @@ return null; } - public static Map getStandardDefs() { - return new HashMap(standardDefs); - } - /** Base class for any attributed object (Class, Field, Method, Code). * Flags are included because they are used to help transmit the * presence of attributes. That is, flags are a mix of modifier @@ -291,7 +291,7 @@ protected abstract Entry[] getCPMap(); protected int flags; // defined here for convenience - protected List attributes; + protected List<Attribute> attributes; public int attributeSize() { return (attributes == null) ? 0 : attributes.size(); @@ -301,16 +301,15 @@ if (attributes == null) { return; } - if (attributes.size() == 0) { + if (attributes.isEmpty()) { attributes = null; return; } if (attributes instanceof ArrayList) { - ArrayList al = (ArrayList) attributes; + ArrayList<Attribute> al = (ArrayList<Attribute>)attributes; al.trimToSize(); boolean allCanon = true; - for (Iterator i = al.iterator(); i.hasNext(); ) { - Attribute a = (Attribute) i.next(); + for (Attribute a : al) { if (!a.isCanonical()) { allCanon = false; } @@ -330,9 +329,9 @@ public void addAttribute(Attribute a) { if (attributes == null) - attributes = new ArrayList(3); + attributes = new ArrayList<>(3); else if (!(attributes instanceof ArrayList)) - attributes = new ArrayList(attributes); // unfreeze it + attributes = new ArrayList<>(attributes); // unfreeze it attributes.add(a); } @@ -340,32 +339,31 @@ if (attributes == null) return null; if (!attributes.contains(a)) return null; if (!(attributes instanceof ArrayList)) - attributes = new ArrayList(attributes); // unfreeze it + attributes = new ArrayList<>(attributes); // unfreeze it attributes.remove(a); return a; } public Attribute getAttribute(int n) { - return (Attribute) attributes.get(n); + return attributes.get(n); } - protected void visitRefs(int mode, Collection refs) { + protected void visitRefs(int mode, Collection<Entry> refs) { if (attributes == null) return; - for (Iterator i = attributes.iterator(); i.hasNext(); ) { - Attribute a = (Attribute) i.next(); + for (Attribute a : attributes) { a.visitRefs(this, mode, refs); } } - static final List noAttributes = Arrays.asList(new Object[0]); + static final List<Attribute> noAttributes = Arrays.asList(new Attribute[0]); - public List getAttributes() { + public List<Attribute> getAttributes() { if (attributes == null) return noAttributes; return attributes; } - public void setAttributes(List attrList) { + public void setAttributes(List<Attribute> attrList) { if (attrList.isEmpty()) attributes = null; else @@ -374,8 +372,7 @@ public Attribute getAttribute(String attrName) { if (attributes == null) return null; - for (Iterator i = attributes.iterator(); i.hasNext(); ) { - Attribute a = (Attribute) i.next(); + for (Attribute a : attributes) { if (a.name().equals(attrName)) return a; } @@ -384,8 +381,7 @@ public Attribute getAttribute(Layout attrDef) { if (attributes == null) return null; - for (Iterator i = attributes.iterator(); i.hasNext(); ) { - Attribute a = (Attribute) i.next(); + for (Attribute a : attributes) { if (a.layout() == attrDef) return a; } @@ -457,14 +453,8 @@ public String layout() { return layout; } public Attribute canonicalInstance() { return canon; } - // Cache of name reference. - private Entry nameRef; // name, for use by visitRefs public Entry getNameRef() { - Entry nameRef = this.nameRef; - if (nameRef == null) { - this.nameRef = nameRef = ConstantPool.getUtf8Entry(name()); - } - return nameRef; + return ConstantPool.getUtf8Entry(name()); } public boolean isEmpty() { return layout == ""; } @@ -834,14 +824,14 @@ */ static //private Layout.Element[] tokenizeLayout(Layout self, int curCble, String layout) { - ArrayList col = new ArrayList(layout.length()); + ArrayList<Layout.Element> 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, ArrayList<Layout.Element> col) { boolean prevBCI = false; for (int len = layout.length(), i = 0; i < len; ) { int start = i; @@ -899,7 +889,7 @@ case 'T': // union: 'T' any_int union_case* '(' ')' '[' body ']' kind = EK_UN; i = tokenizeSInt(e, layout, i); - ArrayList cases = new ArrayList(); + ArrayList<Layout.Element> cases = new ArrayList<>(); for (;;) { // Keep parsing cases until we hit the default case. if (layout.charAt(i++) != '(') @@ -1053,7 +1043,7 @@ } static //private String[] splitBodies(String layout) { - ArrayList bodies = new ArrayList(); + ArrayList<String> bodies = new ArrayList<>(); // Parse several independent layout bodies: "[foo][bar]...[baz]" for (int i = 0; i < layout.length(); i++) { if (layout.charAt(i++) != '[') @@ -1132,7 +1122,9 @@ int parseIntBefore(String layout, int dash) { int end = dash; int beg = end; - while (beg > 0 && isDigit(layout.charAt(beg-1))) --beg; + while (beg > 0 && isDigit(layout.charAt(beg-1))) { + --beg; + } if (beg == end) return Integer.parseInt("empty"); // skip backward over a sign if (beg >= 1 && layout.charAt(beg-1) == '-') --beg; @@ -1145,7 +1137,9 @@ int end = beg; int limit = layout.length(); if (end < limit && layout.charAt(end) == '-') ++end; - while (end < limit && isDigit(layout.charAt(end))) ++end; + while (end < limit && isDigit(layout.charAt(end))) { + ++end; + } if (beg == end) return Integer.parseInt("empty"); return Integer.parseInt(layout.substring(beg, end)); }
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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,7 +25,6 @@ package com.sun.java.util.jar.pack; -import java.io.*; import java.util.*; /** @@ -40,20 +39,13 @@ return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE); } - // Uniquification tables for factory methods: - private static final HashMap utf8Entries = new HashMap(); - private static final HashMap classEntries = new HashMap(); - private static final HashMap literalEntries = new HashMap(); - private static final HashMap signatureEntries = new HashMap(); - private static final HashMap descriptorEntries = new HashMap(); - private static final HashMap memberEntries = new HashMap(); - /** Factory for Utf8 string constants. * Used for well-known strings like "SourceFile", "<init>", etc. * Also used to back up more complex constant pool entries, like Class. */ public static synchronized Utf8Entry getUtf8Entry(String value) { - Utf8Entry e = (Utf8Entry) utf8Entries.get(value); + Map<String, Utf8Entry> utf8Entries = Utils.getUtf8Entries(); + Utf8Entry e = utf8Entries.get(value); if (e == null) { e = new Utf8Entry(value); utf8Entries.put(e.stringValue(), e); @@ -62,9 +54,10 @@ } /** Factory for Class constants. */ public static synchronized ClassEntry getClassEntry(String name) { - ClassEntry e = (ClassEntry) classEntries.get(name); + Map<String, ClassEntry> classEntries = Utils.getClassEntries(); + ClassEntry e = classEntries.get(name); if (e == null) { - e = (ClassEntry) new ClassEntry(getUtf8Entry(name)); + e = new ClassEntry(getUtf8Entry(name)); assert(name.equals(e.stringValue())); classEntries.put(e.stringValue(), e); } @@ -72,7 +65,8 @@ } /** Factory for literal constants (String, Integer, etc.). */ public static synchronized LiteralEntry getLiteralEntry(Comparable value) { - LiteralEntry e = (LiteralEntry) literalEntries.get(value); + Map<Object, LiteralEntry> literalEntries = Utils.getLiteralEntries(); + LiteralEntry e = literalEntries.get(value); if (e == null) { if (value instanceof String) e = new StringEntry(getUtf8Entry((String)value)); @@ -89,7 +83,8 @@ /** Factory for signature (type) constants. */ public static synchronized SignatureEntry getSignatureEntry(String type) { - SignatureEntry e = (SignatureEntry) signatureEntries.get(type); + Map<String, SignatureEntry> signatureEntries = Utils.getSignatureEntries(); + SignatureEntry e = signatureEntries.get(type); if (e == null) { e = new SignatureEntry(type); assert(e.stringValue().equals(type)); @@ -104,8 +99,9 @@ /** Factory for descriptor (name-and-type) constants. */ public static synchronized DescriptorEntry getDescriptorEntry(Utf8Entry nameRef, SignatureEntry typeRef) { + Map<String, DescriptorEntry> descriptorEntries = Utils.getDescriptorEntries(); String key = DescriptorEntry.stringValueOf(nameRef, typeRef); - DescriptorEntry e = (DescriptorEntry) descriptorEntries.get(key); + DescriptorEntry e = descriptorEntries.get(key); if (e == null) { e = new DescriptorEntry(nameRef, typeRef); assert(e.stringValue().equals(key)) @@ -121,8 +117,9 @@ /** Factory for member reference constants. */ public static synchronized MemberEntry getMemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) { + Map<String, MemberEntry> memberEntries = Utils.getMemberEntries(); String key = MemberEntry.stringValueOf(tag, classRef, descRef); - MemberEntry e = (MemberEntry) memberEntries.get(key); + MemberEntry e = memberEntries.get(key); if (e == null) { e = new MemberEntry(tag, classRef, descRef); assert(e.stringValue().equals(key)) @@ -489,8 +486,9 @@ String[] parts = structureSignature(value); formRef = getUtf8Entry(parts[0]); classRefs = new ClassEntry[parts.length-1]; - for (int i = 1; i < parts.length; i++) - classRefs[i-1] = getClassEntry(parts[i]); + for (int i = 1; i < parts.length; i++) { + classRefs[i - 1] = getClassEntry(parts[i]); + } hashCode(); // force computation of valueHash } protected int computeValueHash() { @@ -527,8 +525,9 @@ String stringValueOf(Utf8Entry formRef, ClassEntry[] classRefs) { String[] parts = new String[1+classRefs.length]; parts[0] = formRef.stringValue(); - for (int i = 1; i < parts.length; i++) - parts[i] = classRefs[i-1].stringValue(); + for (int i = 1; i < parts.length; i++) { + parts[i] = classRefs[i - 1].stringValue(); + } return flattenSignature(parts).intern(); } @@ -543,19 +542,23 @@ int size = 0; for (int i = min; i < max; i++) { switch (form.charAt(i)) { - case 'D': - case 'J': - if (countDoublesTwice) size++; - break; - case '[': - // Skip rest of array info. - while (form.charAt(i) == '[') ++i; - break; - case ';': - continue; - default: - assert(0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i))); - break; + case 'D': + case 'J': + if (countDoublesTwice) { + size++; + } + break; + case '[': + // Skip rest of array info. + while (form.charAt(i) == '[') { + ++i; + } + break; + case ';': + continue; + default: + assert (0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i))); + break; } size++; } @@ -586,8 +589,9 @@ s = "/" + formRef.stringValue(); } int i; - while ((i = s.indexOf(';')) >= 0) - s = s.substring(0,i) + s.substring(i+1); + while ((i = s.indexOf(';')) >= 0) { + s = s.substring(0, i) + s.substring(i + 1); + } return s; } } @@ -732,11 +736,11 @@ clearIndex(); this.cpMap = cpMap; } - protected Index(String debugName, Collection cpMapList) { + protected Index(String debugName, Collection<Entry> cpMapList) { this(debugName); setMap(cpMapList); } - protected void setMap(Collection cpMapList) { + protected void setMap(Collection<Entry> cpMapList) { cpMap = new Entry[cpMapList.size()]; cpMapList.toArray(cpMap); setMap(cpMap); @@ -756,11 +760,13 @@ // // As a special hack, if flattenSigs, signatures are // treated as equivalent entries of cpMap. This is wrong - // fron a Collection point of view, because contains() + // from a Collection point of view, because contains() // reports true for signatures, but the iterator() // never produces them! private int findIndexOf(Entry e) { - if (indexKey == null) initializeIndex(); + if (indexKey == null) { + initializeIndex(); + } int probe = findIndexLocation(e); if (indexKey[probe] != e) { if (flattenSigs && e.tag == CONSTANT_Signature) { @@ -832,7 +838,9 @@ System.out.println("initialize Index "+debugName+" ["+size()+"]"); int hsize0 = (int)((cpMap.length + 10) * 1.5); int hsize = 1; - while (hsize < hsize0) hsize <<= 1; + while (hsize < hsize0) { + hsize <<= 1; + } indexKey = new Entry[hsize]; indexValue = new int[hsize]; for (int i = 0; i < cpMap.length; i++) { @@ -855,7 +863,7 @@ return toArray(new Entry[size()]); } public Object clone() { - return new Index(debugName, (Entry[]) cpMap.clone()); + return new Index(debugName, cpMap.clone()); } public String toString() { return "Index "+debugName+" ["+size()+"]"; @@ -901,22 +909,24 @@ public static Index[] partition(Index ix, int[] keys) { // %%% Should move this into class Index. - ArrayList parts = new ArrayList(); + ArrayList<List<Entry>> parts = new ArrayList<>(); Entry[] cpMap = ix.cpMap; assert(keys.length == cpMap.length); for (int i = 0; i < keys.length; i++) { int key = keys[i]; if (key < 0) continue; - while (key >= parts.size()) parts.add(null); - ArrayList part = (ArrayList) parts.get(key); + while (key >= parts.size()) { + parts.add(null); + } + List<Entry> part = parts.get(key); if (part == null) { - parts.set(key, part = new ArrayList()); + parts.set(key, part = new ArrayList<>()); } part.add(cpMap[i]); } Index[] indexes = new Index[parts.size()]; for (int key = 0; key < indexes.length; key++) { - ArrayList part = (ArrayList) parts.get(key); + List<Entry> part = parts.get(key); if (part == null) continue; indexes[key] = new Index(ix.debugName+"/part#"+key, part); assert(indexes[key].indexOf(part.get(0)) == 0); @@ -1048,9 +1058,10 @@ whichClasses[i] = whichClass; } perClassIndexes = partition(allMembers, whichClasses); - for (int i = 0; i < perClassIndexes.length; i++) - assert(perClassIndexes[i]==null - || perClassIndexes[i].assertIsSorted()); + for (int i = 0; i < perClassIndexes.length; i++) { + assert (perClassIndexes[i] == null || + perClassIndexes[i].assertIsSorted()); + } indexByTagAndClass[tag] = perClassIndexes; } int whichClass = allClasses.indexOf(classRef); @@ -1113,7 +1124,7 @@ * Also, discard null from cpRefs. */ public static - void completeReferencesIn(Set cpRefs, boolean flattenSigs) { + void completeReferencesIn(Set<Entry> cpRefs, boolean flattenSigs) { cpRefs.remove(null); for (ListIterator work = new ArrayList(cpRefs).listIterator(cpRefs.size());
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Driver.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Driver.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2005, 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 @@ -25,7 +25,6 @@ package com.sun.java.util.jar.pack; -import java.lang.Error; import java.io.*; import java.text.MessageFormat; import java.util.*; @@ -35,10 +34,11 @@ /** Command line interface for Pack200. */ class Driver { - private static final ResourceBundle RESOURCE= ResourceBundle.getBundle("com.sun.java.util.jar.pack.DriverResource"); + private static final ResourceBundle RESOURCE = + ResourceBundle.getBundle("com.sun.java.util.jar.pack.DriverResource"); public static void main(String[] ava) throws IOException { - ArrayList<String> av = new ArrayList<String>(Arrays.asList(ava)); + ArrayList<String> av = new ArrayList<>(Arrays.asList(ava)); boolean doPack = true; boolean doUnpack = false; @@ -61,7 +61,7 @@ } // Collect engine properties here: - HashMap<String,String> engProps = new HashMap<String,String>(); + HashMap<String,String> engProps = new HashMap<>(); engProps.put(verboseProp, System.getProperty(verboseProp)); String optionMap; @@ -75,7 +75,7 @@ } // Collect argument properties here: - HashMap<String,String> avProps = new HashMap<String,String>(); + HashMap<String,String> avProps = new HashMap<>(); try { for (;;) { String state = parseCommandOptions(av, optionMap, avProps); @@ -133,8 +133,9 @@ if (engProps.get(verboseProp) != null) fileProps.list(System.out); propIn.close(); - for (Map.Entry<Object,Object> me : fileProps.entrySet()) - engProps.put((String)me.getKey(), (String)me.getValue()); + for (Map.Entry<Object,Object> me : fileProps.entrySet()) { + engProps.put((String) me.getKey(), (String) me.getValue()); + } } else if (state == "--version") { System.out.println(MessageFormat.format(RESOURCE.getString(DriverResource.VERSION), Driver.class.getName(), "1.31, 07/05/05")); return; @@ -493,7 +494,7 @@ String resultString = null; // Convert options string into optLines dictionary. - TreeMap<String,String[]> optmap = new TreeMap<String,String[]>(); + TreeMap<String,String[]> optmap = new TreeMap<>(); loadOptmap: for (String optline : options.split("\n")) { String[] words = optline.split("\\p{Space}+"); @@ -687,7 +688,9 @@ // Report number of arguments consumed. args.subList(0, argp.nextIndex()).clear(); // Report any unconsumed partial argument. - while (pbp.hasPrevious()) args.add(0, pbp.previous()); + while (pbp.hasPrevious()) { + args.add(0, pbp.previous()); + } //System.out.println(args+" // "+properties+" -> "+resultString); return resultString; }
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, 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 @@ -28,13 +28,8 @@ import java.nio.*; import java.io.*; -import java.nio.channels.*; -import java.util.Date; import java.util.jar.*; import java.util.zip.*; -import java.util.*; -//import com.sun.java.util.jar.pack.Pack200; - class NativeUnpack { // Pointer to the native unpacker obj @@ -91,13 +86,13 @@ NativeUnpack(UnpackerImpl p200) { super(); _p200 = p200; - _props = p200._props; + _props = p200.props; p200._nunp = this; } // for JNI callbacks static private Object currentInstance() { - UnpackerImpl p200 = (UnpackerImpl) Utils.currentInstance.get(); + UnpackerImpl p200 = (UnpackerImpl) Utils.getTLGlobals(); return (p200 == null)? null: p200._nunp; } @@ -216,10 +211,10 @@ ++_fileCount; updateProgress(); } + presetInput = getUnusedInput(); long consumed = finish(); if (_verbose > 0) Utils.log.info("bytes consumed = "+consumed); - presetInput = getUnusedInput(); if (presetInput == null && !Utils.isPackMagic(Utils.readMagic(in))) { break;
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java Sun Aug 29 22:41:28 2010 -0700 @@ -25,9 +25,9 @@ package com.sun.java.util.jar.pack; +import com.sun.java.util.jar.pack.Attribute.Layout; import java.lang.reflect.Modifier; import java.util.*; -import java.util.zip.*; import java.util.jar.*; import java.io.*; import com.sun.java.util.jar.pack.ConstantPool.*; @@ -77,10 +77,11 @@ cp = new ConstantPool.IndexGroup(); classes.clear(); files.clear(); + BandStructure.nextSeqForDebug = 0; } int getPackageVersion() { - return (package_majver << 16) + (int)package_minver; + return (package_majver << 16) + package_minver; } // Special empty versions of Code and InnerClasses, used for markers. @@ -89,7 +90,7 @@ public static final Attribute.Layout attrSourceFileSpecial; public static final Map attrDefs; static { - HashMap ad = new HashMap(2); + HashMap<Layout, Attribute> ad = new HashMap<>(3); attrCodeEmpty = Attribute.define(ad, ATTR_CONTEXT_METHOD, "Code", "").layout(); attrInnerClassesEmpty = Attribute.define(ad, ATTR_CONTEXT_CLASS, @@ -159,9 +160,9 @@ } } - ArrayList classes = new ArrayList(); + ArrayList<Package.Class> classes = new ArrayList<>(); - public List getClasses() { + public List<Package.Class> getClasses() { return classes; } @@ -186,11 +187,11 @@ ClassEntry[] interfaces; // Class parts - ArrayList fields; - ArrayList methods; + ArrayList<Field> fields; + ArrayList<Method> methods; //ArrayList attributes; // in Attribute.Holder.this.attributes // Note that InnerClasses may be collected at the package level. - ArrayList innerClasses; + ArrayList<InnerClass> innerClasses; Class(int flags, ClassEntry thisClass, ClassEntry superClass, ClassEntry[] interfaces) { this.magic = JAVA_MAGIC; @@ -270,7 +271,7 @@ if (a != olda) { if (verbose > 2) Utils.log.fine("recoding obvious SourceFile="+obvious); - List newAttrs = new ArrayList(getAttributes()); + List<Attribute> newAttrs = new ArrayList<>(getAttributes()); int where = newAttrs.indexOf(olda); newAttrs.set(where, a); setAttributes(newAttrs); @@ -295,12 +296,12 @@ boolean hasInnerClasses() { return innerClasses != null; } - List getInnerClasses() { + List<InnerClass> getInnerClasses() { return innerClasses; } - public void setInnerClasses(Collection ics) { - innerClasses = (ics == null) ? null : new ArrayList(ics); + public void setInnerClasses(Collection<InnerClass> ics) { + innerClasses = (ics == null) ? null : new ArrayList<InnerClass>(ics); // Edit the attribute list, if necessary. Attribute a = getAttribute(attrInnerClassesEmpty); if (innerClasses != null && a == null) @@ -318,19 +319,18 @@ * The order of the resulting list is consistent * with that of Package.this.allInnerClasses. */ - public List computeGloballyImpliedICs() { - HashSet cpRefs = new HashSet(); + public List<InnerClass> computeGloballyImpliedICs() { + HashSet<Entry> cpRefs = new HashSet<>(); { // This block temporarily displaces this.innerClasses. - ArrayList innerClassesSaved = innerClasses; + ArrayList<InnerClass> innerClassesSaved = innerClasses; innerClasses = null; // ignore for the moment visitRefs(VRM_CLASSIC, cpRefs); innerClasses = innerClassesSaved; } ConstantPool.completeReferencesIn(cpRefs, true); - HashSet icRefs = new HashSet(); - for (Iterator i = cpRefs.iterator(); i.hasNext(); ) { - Entry e = (Entry) i.next(); + HashSet<Entry> icRefs = new HashSet<>(); + for (Entry e : cpRefs) { // Restrict cpRefs to InnerClasses entries only. if (!(e instanceof ClassEntry)) continue; // For every IC reference, add its outers also. @@ -345,9 +345,8 @@ // This loop is structured this way so as to accumulate // entries into impliedICs in an order which reflects // the order of allInnerClasses. - ArrayList impliedICs = new ArrayList(); - for (Iterator i = allInnerClasses.iterator(); i.hasNext(); ) { - InnerClass ic = (InnerClass) i.next(); + ArrayList<InnerClass> impliedICs = new ArrayList<>(); + for (InnerClass ic : allInnerClasses) { // This one is locally relevant if it describes // a member of the current class, or if the current // class uses it somehow. In the particular case @@ -366,10 +365,11 @@ // Helper for both minimizing and expanding. // Computes a symmetric difference. - private List computeICdiff() { - List impliedICs = computeGloballyImpliedICs(); - List actualICs = getInnerClasses(); - if (actualICs == null) actualICs = Collections.EMPTY_LIST; + private List<InnerClass> computeICdiff() { + List<InnerClass> impliedICs = computeGloballyImpliedICs(); + List<InnerClass> actualICs = getInnerClasses(); + if (actualICs == null) + actualICs = Collections.EMPTY_LIST; // Symmetric difference is calculated from I, A like this: // diff = (I+A) - (I*A) @@ -388,8 +388,8 @@ // Diff is A since I is empty. } // (I*A) is non-trivial - HashSet center = new HashSet(actualICs); - center.retainAll(new HashSet(impliedICs)); + HashSet<InnerClass> center = new HashSet<>(actualICs); + center.retainAll(new HashSet<>(impliedICs)); impliedICs.addAll(actualICs); impliedICs.removeAll(center); // Diff is now I^A = (I+A)-(I*A). @@ -407,9 +407,9 @@ * to use the globally implied ICs changed. */ void minimizeLocalICs() { - List diff = computeICdiff(); - List actualICs = innerClasses; - List localICs; // will be the diff, modulo edge cases + List<InnerClass> diff = computeICdiff(); + List<InnerClass> actualICs = innerClasses; + List<InnerClass> localICs; // will be the diff, modulo edge cases if (diff.isEmpty()) { // No diff, so transmit no attribute. localICs = null; @@ -439,12 +439,12 @@ * Otherwise, return positive if any IC tuples were added. */ int expandLocalICs() { - List localICs = innerClasses; - List actualICs; + List<InnerClass> localICs = innerClasses; + List<InnerClass> actualICs; int changed; if (localICs == null) { // Diff was empty. (Common case.) - List impliedICs = computeGloballyImpliedICs(); + List<InnerClass> impliedICs = computeGloballyImpliedICs(); if (impliedICs.isEmpty()) { actualICs = null; changed = 0; @@ -490,7 +490,7 @@ protected Entry[] getCPMap() { return cpMap; } - protected void visitRefs(int mode, Collection refs) { + protected void visitRefs(int mode, Collection<Entry> refs) { if (verbose > 2) Utils.log.fine("visitRefs "+this); // Careful: The descriptor is used by the package, // but the classfile breaks it into component refs. @@ -518,7 +518,7 @@ super(flags, descriptor); assert(!descriptor.isMethod()); if (fields == null) - fields = new ArrayList(); + fields = new ArrayList<>(); boolean added = fields.add(this); assert(added); order = fields.size(); @@ -543,7 +543,7 @@ super(flags, descriptor); assert(descriptor.isMethod()); if (methods == null) - methods = new ArrayList(); + methods = new ArrayList<>(); boolean added = methods.add(this); assert(added); } @@ -573,7 +573,7 @@ code.strip(attrName); super.strip(attrName); } - protected void visitRefs(int mode, Collection refs) { + protected void visitRefs(int mode, Collection<Entry> refs) { super.visitRefs(mode, refs); if (code != null) { if (mode == VRM_CLASSIC) { @@ -614,7 +614,7 @@ super.strip(attrName); } - protected void visitRefs(int mode, Collection refs) { + protected void visitRefs(int mode, Collection<Entry> refs) { if (verbose > 2) Utils.log.fine("visitRefs "+this); refs.add(thisClass); refs.add(superClass); @@ -641,7 +641,7 @@ super.visitRefs(mode, refs); } - protected void visitInnerClassRefs(int mode, Collection refs) { + protected void visitInnerClassRefs(int mode, Collection<Entry> refs) { Package.visitInnerClassRefs(innerClasses, mode, refs); } @@ -713,16 +713,15 @@ } // What non-class files are in this unit? - ArrayList files = new ArrayList(); + ArrayList<File> files = new ArrayList<>(); - public List getFiles() { + public List<File> getFiles() { return files; } - public List getClassStubs() { - ArrayList classStubs = new ArrayList(classes.size()); - for (Iterator i = classes.iterator(); i.hasNext(); ) { - Class cls = (Class) i.next(); + public List<File> getClassStubs() { + ArrayList<File> classStubs = new ArrayList<>(classes.size()); + for (Class cls : classes) { assert(cls.file.isClassStub()); classStubs.add(cls.file); } @@ -840,7 +839,7 @@ public InputStream getInputStream() { InputStream in = new ByteArrayInputStream(append.toByteArray()); if (prepend.size() == 0) return in; - ArrayList isa = new ArrayList(prepend.size()+1); + ArrayList<InputStream> isa = new ArrayList<>(prepend.size()+1); for (Iterator i = prepend.iterator(); i.hasNext(); ) { byte[] bytes = (byte[]) i.next(); isa.add(new ByteArrayInputStream(bytes)); @@ -849,7 +848,7 @@ return new SequenceInputStream(Collections.enumeration(isa)); } - protected void visitRefs(int mode, Collection refs) { + protected void visitRefs(int mode, Collection<Entry> refs) { assert(name != null); refs.add(name); } @@ -877,8 +876,8 @@ } // Is there a globally declared table of inner classes? - ArrayList allInnerClasses = new ArrayList(); - HashMap allInnerClassesByThis; + ArrayList<InnerClass> allInnerClasses = new ArrayList<>(); + HashMap<ClassEntry, InnerClass> allInnerClassesByThis; public List getAllInnerClasses() { @@ -886,15 +885,14 @@ } public - void setAllInnerClasses(Collection ics) { + void setAllInnerClasses(Collection<InnerClass> ics) { assert(ics != allInnerClasses); allInnerClasses.clear(); allInnerClasses.addAll(ics); // Make an index: - allInnerClassesByThis = new HashMap(allInnerClasses.size()); - for (Iterator i = allInnerClasses.iterator(); i.hasNext(); ) { - InnerClass ic = (InnerClass) i.next(); + allInnerClassesByThis = new HashMap<>(allInnerClasses.size()); + for (InnerClass ic : allInnerClasses) { Object pic = allInnerClassesByThis.put(ic.thisClass, ic); assert(pic == null); // caller must ensure key uniqueness! } @@ -904,7 +902,7 @@ public InnerClass getGlobalInnerClass(Entry thisClass) { assert(thisClass instanceof ClassEntry); - return (InnerClass) allInnerClassesByThis.get(thisClass); + return allInnerClassesByThis.get(thisClass); } static @@ -963,7 +961,7 @@ return this.thisClass.compareTo(that.thisClass); } - protected void visitRefs(int mode, Collection refs) { + protected void visitRefs(int mode, Collection<Entry> refs) { refs.add(thisClass); if (mode == VRM_CLASSIC || !predictable) { // If the name can be demangled, the package omits @@ -980,7 +978,7 @@ // Helper for building InnerClasses attributes. static private - void visitInnerClassRefs(Collection innerClasses, int mode, Collection refs) { + void visitInnerClassRefs(Collection innerClasses, int mode, Collection<Entry> refs) { if (innerClasses == null) { return; // no attribute; nothing to do } @@ -1165,9 +1163,8 @@ } } - protected void visitRefs(int mode, Collection refs) { - for (Iterator i = classes.iterator(); i.hasNext(); ) { - Class c = (Class)i.next(); + protected void visitRefs(int mode, Collection<Entry> refs) { + for ( Class c : classes) { c.visitRefs(mode, refs); } if (mode != VRM_CLASSIC) { @@ -1259,7 +1256,7 @@ } // Use this before writing the package file. - void buildGlobalConstantPool(Set requiredEntries) { + void buildGlobalConstantPool(Set<Entry> requiredEntries) { if (verbose > 1) Utils.log.fine("Checking for unused CP entries"); requiredEntries.add(getRefString("")); // uconditionally present @@ -1291,9 +1288,8 @@ // Use this before writing the class files. void ensureAllClassFiles() { - HashSet fileSet = new HashSet(files); - for (Iterator i = classes.iterator(); i.hasNext(); ) { - Class cls = (Class) i.next(); + HashSet<File> fileSet = new HashSet<>(files); + for (Class cls : classes) { // Add to the end of ths list: if (!fileSet.contains(cls.file)) files.add(cls.file);
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2005, 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 @@ -25,12 +25,11 @@ package com.sun.java.util.jar.pack; +import com.sun.java.util.jar.pack.Attribute.Layout; import java.util.*; import java.util.jar.*; -import java.util.zip.*; import java.io.*; import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeEvent; /* @@ -41,31 +40,22 @@ */ -public class PackerImpl implements Pack200.Packer { +public class PackerImpl extends TLGlobals implements Pack200.Packer { /** * Constructs a Packer object and sets the initial state of * the packer engines. */ - public PackerImpl() { - _props = new PropMap(); - //_props.getProperty() consults defaultProps invisibly. - //_props.putAll(defaultProps); - } - - - // Private stuff. - final PropMap _props; + public PackerImpl() {} /** * 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() { - return _props; + public SortedMap<String, String> properties() { + return props; } - //Driver routines /** @@ -78,21 +68,22 @@ */ public void pack(JarFile in, OutputStream out) throws IOException { assert(Utils.currentInstance.get() == null); - TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : - TimeZone.getDefault(); + TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) + ? null + : TimeZone.getDefault(); try { Utils.currentInstance.set(this); if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) { + if ("0".equals(props.getProperty(Pack200.Packer.EFFORT))) { Utils.copyJarFile(in, out); } else { (new DoPack()).run(in, out); - in.close(); } } finally { Utils.currentInstance.set(null); if (tz != null) TimeZone.setDefault(tz); + in.close(); } } @@ -112,21 +103,20 @@ */ public void pack(JarInputStream in, OutputStream out) throws IOException { assert(Utils.currentInstance.get() == null); - TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : + TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : TimeZone.getDefault(); try { Utils.currentInstance.set(this); if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) { + if ("0".equals(props.getProperty(Pack200.Packer.EFFORT))) { Utils.copyJarFile(in, out); } else { (new DoPack()).run(in, out); - in.close(); } } finally { Utils.currentInstance.set(null); if (tz != null) TimeZone.setDefault(tz); - + in.close(); } } /** @@ -134,7 +124,7 @@ * @param listener An object to be invoked when a property is changed. */ public void addPropertyChangeListener(PropertyChangeListener listener) { - _props.addListener(listener); + props.addListener(listener); } /** @@ -142,7 +132,7 @@ * @param listener The PropertyChange listener to be removed. */ public void removePropertyChangeListener(PropertyChangeListener listener) { - _props.removeListener(listener); + props.removeListener(listener); } @@ -151,11 +141,11 @@ // The packer worker. private class DoPack { - final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE); + final int verbose = props.getInteger(Utils.DEBUG_VERBOSE); { - _props.setInteger(Pack200.Packer.PROGRESS, 0); - if (verbose > 0) Utils.log.info(_props.toString()); + props.setInteger(Pack200.Packer.PROGRESS, 0); + if (verbose > 0) Utils.log.info(props.toString()); } // Here's where the bits are collected before getting packed: @@ -163,7 +153,7 @@ final String unknownAttrCommand; { - String uaMode = _props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS); + String uaMode = props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS); if (!(Pack200.Packer.STRIP.equals(uaMode) || Pack200.Packer.PASS.equals(uaMode) || Pack200.Packer.ERROR.equals(uaMode))) { @@ -191,13 +181,12 @@ }; for (int i = 0; i < ctypes.length; i++) { String pfx = keys[i]; - Map map = _props.prefixMap(pfx); - for (Iterator j = map.keySet().iterator(); j.hasNext(); ) { - String key = (String) j.next(); + Map<String, String> map = props.prefixMap(pfx); + for (String key : map.keySet()) { assert(key.startsWith(pfx)); String name = key.substring(pfx.length()); - String layout = _props.getProperty(key); - Object lkey = Attribute.keyForLookup(ctypes[i], name); + String layout = props.getProperty(key); + Layout lkey = Attribute.keyForLookup(ctypes[i], name); if (Pack200.Packer.STRIP.equals(layout) || Pack200.Packer.PASS.equals(layout) || Pack200.Packer.ERROR.equals(layout)) { @@ -222,25 +211,25 @@ } final boolean keepFileOrder - = _props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER); + = props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER); final boolean keepClassOrder - = _props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER); + = props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER); final boolean keepModtime - = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME)); + = Pack200.Packer.KEEP.equals(props.getProperty(Pack200.Packer.MODIFICATION_TIME)); final boolean latestModtime - = Pack200.Packer.LATEST.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME)); + = Pack200.Packer.LATEST.equals(props.getProperty(Pack200.Packer.MODIFICATION_TIME)); final boolean keepDeflateHint - = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.DEFLATE_HINT)); + = Pack200.Packer.KEEP.equals(props.getProperty(Pack200.Packer.DEFLATE_HINT)); { if (!keepModtime && !latestModtime) { - int modtime = _props.getTime(Pack200.Packer.MODIFICATION_TIME); + int modtime = props.getTime(Pack200.Packer.MODIFICATION_TIME); if (modtime != Constants.NO_MODTIME) { pkg.default_modtime = modtime; } } if (!keepDeflateHint) { - boolean deflate_hint = _props.getBoolean(Pack200.Packer.DEFLATE_HINT); + boolean deflate_hint = props.getBoolean(Pack200.Packer.DEFLATE_HINT); if (deflate_hint) { pkg.default_options |= Constants.AO_DEFLATE_HINT; } @@ -254,10 +243,10 @@ final long segmentLimit; { long limit; - if (_props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals("")) + if (props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals("")) limit = -1; else - limit = _props.getLong(Pack200.Packer.SEGMENT_LIMIT); + limit = props.getLong(Pack200.Packer.SEGMENT_LIMIT); limit = Math.min(Integer.MAX_VALUE, limit); limit = Math.max(-1, limit); if (limit == -1) @@ -265,10 +254,10 @@ segmentLimit = limit; } - final List passFiles; // parsed pack.pass.file options + final List<String> passFiles; // parsed pack.pass.file options { // Which class files will be passed through? - passFiles = _props.getProperties(Pack200.Packer.PASS_FILE_PFX); + passFiles = props.getProperties(Pack200.Packer.PASS_FILE_PFX); for (ListIterator i = passFiles.listIterator(); i.hasNext(); ) { String file = (String) i.next(); if (file == null) { i.remove(); continue; } @@ -283,28 +272,28 @@ { // Fill in permitted range of major/minor version numbers. int ver; - if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0) + if ((ver = props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0) pkg.min_class_majver = (short) ver; - if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0) + if ((ver = props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0) pkg.min_class_minver = (short) ver; - if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0) + if ((ver = props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0) pkg.max_class_majver = (short) ver; - if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0) + if ((ver = props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0) pkg.max_class_minver = (short) ver; - if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0) + if ((ver = props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0) pkg.package_minver = (short) ver; - if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0) + if ((ver = props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0) pkg.package_majver = (short) ver; } { // Hook for testing: Forces use of special archive modes. - int opt = _props.getInteger(Utils.COM_PREFIX+"archive.options"); + int opt = props.getInteger(Utils.COM_PREFIX+"archive.options"); if (opt != 0) pkg.default_options |= opt; } - // (Done collecting options from _props.) + // (Done collecting options from props.) boolean isClassFile(String name) { if (!name.endsWith(".class")) return false; @@ -423,16 +412,18 @@ Package.File file = null; // (5078608) : discount the resource files in META-INF // from segment computation. - long inflen = (isMetaInfFile(name)) ? 0L : - inFile.getInputLength(); + long inflen = (isMetaInfFile(name)) + ? 0L + : inFile.getInputLength(); if ((segmentSize += inflen) > segmentLimit) { segmentSize -= inflen; int nextCount = -1; // don't know; it's a stream flushPartial(out, nextCount); } - if (verbose > 1) + if (verbose > 1) { Utils.log.fine("Reading " + name); + } assert(je.isDirectory() == name.endsWith("/")); @@ -450,18 +441,18 @@ } void run(JarFile in, OutputStream out) throws IOException { - List inFiles = scanJar(in); + List<InFile> inFiles = scanJar(in); if (verbose > 0) Utils.log.info("Reading " + inFiles.size() + " files..."); int numDone = 0; - for (Iterator i = inFiles.iterator(); i.hasNext(); ) { - InFile inFile = (InFile) i.next(); + for (InFile inFile : inFiles) { String name = inFile.name; // (5078608) : discount the resource files completely from segmenting - long inflen = (isMetaInfFile(name)) ? 0L : - inFile.getInputLength() ; + long inflen = (isMetaInfFile(name)) + ? 0L + : inFile.getInputLength() ; if ((segmentSize += inflen) > segmentLimit) { segmentSize -= inflen; // Estimate number of remaining segments: @@ -530,11 +521,11 @@ } void flushPartial(OutputStream out, int nextCount) throws IOException { - if (pkg.files.size() == 0 && pkg.classes.size() == 0) { + if (pkg.files.isEmpty() && pkg.classes.isEmpty()) { return; // do not flush an empty segment } flushPackage(out, Math.max(1, nextCount)); - _props.setInteger(Pack200.Packer.PROGRESS, 25); + props.setInteger(Pack200.Packer.PROGRESS, 25); // In case there will be another segment: makeNextPackage(); segmentCount += 1; @@ -543,10 +534,10 @@ } void flushAll(OutputStream out) throws IOException { - _props.setInteger(Pack200.Packer.PROGRESS, 50); + props.setInteger(Pack200.Packer.PROGRESS, 50); flushPackage(out, 0); out.flush(); - _props.setInteger(Pack200.Packer.PROGRESS, 100); + props.setInteger(Pack200.Packer.PROGRESS, 100); segmentCount += 1; segmentTotalSize += segmentSize; segmentSize = 0; @@ -582,11 +573,11 @@ pkg.trimStubs(); // Do some stripping, maybe. - if (_props.getBoolean(Utils.COM_PREFIX+"strip.debug")) pkg.stripAttributeKind("Debug"); - if (_props.getBoolean(Utils.COM_PREFIX+"strip.compile")) pkg.stripAttributeKind("Compile"); - if (_props.getBoolean(Utils.COM_PREFIX+"strip.constants")) pkg.stripAttributeKind("Constant"); - if (_props.getBoolean(Utils.COM_PREFIX+"strip.exceptions")) pkg.stripAttributeKind("Exceptions"); - if (_props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses"); + if (props.getBoolean(Utils.COM_PREFIX+"strip.debug")) pkg.stripAttributeKind("Debug"); + if (props.getBoolean(Utils.COM_PREFIX+"strip.compile")) pkg.stripAttributeKind("Compile"); + if (props.getBoolean(Utils.COM_PREFIX+"strip.constants")) pkg.stripAttributeKind("Constant"); + if (props.getBoolean(Utils.COM_PREFIX+"strip.exceptions")) pkg.stripAttributeKind("Exceptions"); + if (props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses"); // Must choose an archive version; PackageWriter does not. if (pkg.package_majver <= 0) pkg.choosePackageVersion(); @@ -606,11 +597,10 @@ } } - List scanJar(JarFile jf) throws IOException { + List<InFile> scanJar(JarFile jf) throws IOException { // Collect jar entries, preserving order. - List inFiles = new ArrayList(); - for (Enumeration e = jf.entries(); e.hasMoreElements(); ) { - JarEntry je = (JarEntry) e.nextElement(); + List<InFile> inFiles = new ArrayList<>(); + for (JarEntry je : Collections.list(jf.entries())) { InFile inFile = new InFile(jf, je); assert(je.isDirectory() == inFile.name.endsWith("/")); inFiles.add(inFile);
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java Sun Aug 29 22:41:28 2010 -0700 @@ -91,7 +91,7 @@ String.valueOf(Boolean.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))); // The segment size is unlimited - props.put(Pack200.Packer.SEGMENT_LIMIT, ""); + props.put(Pack200.Packer.SEGMENT_LIMIT, "-1"); // Preserve file ordering by default. props.put(Pack200.Packer.KEEP_FILE_ORDER, Pack200.Packer.TRUE);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/TLGlobals.java Sun Aug 29 22:41:28 2010 -0700 @@ -0,0 +1,97 @@ +/* + * 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 com.sun.java.util.jar.pack.ConstantPool.ClassEntry; +import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry; +import com.sun.java.util.jar.pack.ConstantPool.LiteralEntry; +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.util.HashMap; +import java.util.Map; +import java.util.SortedMap; + +/* + * @author ksrini + */ + +/* + * This class provides a container to hold the global variables, for packer + * and unpacker instances. This is typically stashed away in a ThreadLocal, + * and the storage is destroyed upon completion. Therefore any local + * references to these members must be eliminated appropriately to prevent a + * memory leak. + */ +class TLGlobals { + // Global environment + final PropMap props; + + // Needed by ConstantPool.java + private final Map<String, Utf8Entry> utf8Entries; + private final Map<String, ClassEntry> classEntries; + private final Map<Object, LiteralEntry> literalEntries; + private final Map<String, SignatureEntry> signatureEntries; + private final Map<String, DescriptorEntry> descriptorEntries; + private final Map<String, MemberEntry> memberEntries; + + TLGlobals() { + utf8Entries = new HashMap<>(); + classEntries = new HashMap<>(); + literalEntries = new HashMap<>(); + signatureEntries = new HashMap<>(); + descriptorEntries = new HashMap<>(); + memberEntries = new HashMap<>(); + props = new PropMap(); + } + + SortedMap<Object, Object> getPropMap() { + return props; + } + + Map<String, Utf8Entry> getUtf8Entries() { + return utf8Entries; + } + + Map<String, ClassEntry> getClassEntries() { + return classEntries; + } + + Map<Object, LiteralEntry> getLiteralEntries() { + return literalEntries; + } + + Map<String, DescriptorEntry> getDescriptorEntries() { + return descriptorEntries; + } + + Map<String, SignatureEntry> getSignatureEntries() { + return signatureEntries; + } + + Map<String, MemberEntry> getMemberEntries() { + return memberEntries; + } +}
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 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 @@ -30,7 +30,6 @@ import java.util.zip.*; import java.io.*; import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeEvent; /* * Implementation of the Pack provider. @@ -40,7 +39,7 @@ */ -public class UnpackerImpl implements Pack200.Unpacker { +public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker { /** @@ -48,7 +47,7 @@ * @param listener An object to be invoked when a property is changed. */ public void addPropertyChangeListener(PropertyChangeListener listener) { - _props.addListener(listener); + props.addListener(listener); } @@ -57,25 +56,19 @@ * @param listener The PropertyChange listener to be removed. */ public void removePropertyChangeListener(PropertyChangeListener listener) { - _props.removeListener(listener); + props.removeListener(listener); } - public UnpackerImpl() { - _props = new PropMap(); - //_props.getProperty() consults defaultProps invisibly. - //_props.putAll(defaultProps); - } + public UnpackerImpl() {} - // Private stuff. - final PropMap _props; /** * 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() { - return _props; + public SortedMap<String, String> properties() { + return props; } // Back-pointer to NativeUnpacker, when active. @@ -101,19 +94,20 @@ */ public void unpack(InputStream in0, JarOutputStream out) throws IOException { assert(Utils.currentInstance.get() == null); - TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : - TimeZone.getDefault(); + TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) + ? null + : TimeZone.getDefault(); try { Utils.currentInstance.set(this); if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE); + final int verbose = props.getInteger(Utils.DEBUG_VERBOSE); BufferedInputStream in = new BufferedInputStream(in0); if (Utils.isJarMagic(Utils.readMagic(in))) { if (verbose > 0) Utils.log.info("Copying unpacked JAR file..."); Utils.copyJarFile(new JarInputStream(in), out); - } else if (_props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) { + } else if (props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) { (new DoUnpack()).run(in, out); in.close(); Utils.markJarFile(out); @@ -142,36 +136,38 @@ // %%% Reconsider if native unpacker learns to memory-map the file. FileInputStream instr = new FileInputStream(in); unpack(instr, out); - if (_props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) { + if (props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) { in.delete(); } } private class DoUnpack { - final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE); + final int verbose = props.getInteger(Utils.DEBUG_VERBOSE); { - _props.setInteger(Pack200.Unpacker.PROGRESS, 0); + props.setInteger(Pack200.Unpacker.PROGRESS, 0); } // Here's where the bits are read from disk: final Package pkg = new Package(); final boolean keepModtime - = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP)); + = Pack200.Packer.KEEP.equals( + props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP)); final boolean keepDeflateHint - = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP)); + = Pack200.Packer.KEEP.equals( + props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP)); final int modtime; final boolean deflateHint; { if (!keepModtime) { - modtime = _props.getTime(Utils.UNPACK_MODIFICATION_TIME); + modtime = props.getTime(Utils.UNPACK_MODIFICATION_TIME); } else { modtime = pkg.default_modtime; } deflateHint = (keepDeflateHint) ? false : - _props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT); + props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT); } // Checksum apparatus. @@ -181,7 +177,7 @@ public void run(BufferedInputStream in, JarOutputStream out) throws IOException { if (verbose > 0) { - _props.list(System.out); + props.list(System.out); } for (int seg = 1; ; seg++) { unpackSegment(in, out); @@ -194,25 +190,26 @@ } private void unpackSegment(InputStream in, JarOutputStream out) throws IOException { - _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0"); + props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0"); // Process the output directory or jar output. new PackageReader(pkg, in).read(); - if (_props.getBoolean("unpack.strip.debug")) pkg.stripAttributeKind("Debug"); - if (_props.getBoolean("unpack.strip.compile")) pkg.stripAttributeKind("Compile"); - _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50"); + if (props.getBoolean("unpack.strip.debug")) pkg.stripAttributeKind("Debug"); + if (props.getBoolean("unpack.strip.compile")) pkg.stripAttributeKind("Compile"); + props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50"); pkg.ensureAllClassFiles(); // Now write out the files. - HashSet classesToWrite = new HashSet(pkg.getClasses()); + HashSet<Package.Class> classesToWrite = new HashSet<>(pkg.getClasses()); for (Iterator i = pkg.getFiles().iterator(); i.hasNext(); ) { Package.File file = (Package.File) i.next(); String name = file.nameString; JarEntry je = new JarEntry(Utils.getJarEntryName(name)); boolean deflate; - deflate = (keepDeflateHint) ? (((file.options & Constants.FO_DEFLATE_HINT) != 0) || - ((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0)) : - deflateHint; + deflate = (keepDeflateHint) + ? (((file.options & Constants.FO_DEFLATE_HINT) != 0) || + ((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0)) + : deflateHint; boolean needCRC = !deflate; // STORE mode requires CRC @@ -250,7 +247,7 @@ Utils.log.info("Writing "+Utils.zeString((ZipEntry)je)); } assert(classesToWrite.isEmpty()); - _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100"); + props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100"); pkg.reset(); // reset for the next segment, if any } }
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2005, 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 @@ -25,6 +25,13 @@ package com.sun.java.util.jar.pack; +import com.sun.java.util.jar.pack.Attribute.Layout; +import com.sun.java.util.jar.pack.ConstantPool.ClassEntry; +import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry; +import com.sun.java.util.jar.pack.ConstantPool.LiteralEntry; +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.util.*; import java.util.jar.*; import java.util.zip.*; @@ -113,17 +120,46 @@ */ static final String PACK_ZIP_ARCHIVE_MARKER_COMMENT = "PACK200"; - // Keep a TLS point to the current Packer or Unpacker. - // This makes it simpler to supply environmental options + // Keep a TLS point to the global data and environment. + // This makes it simpler to supply environmental options // to the engine code, especially the native code. - static final ThreadLocal currentInstance = new ThreadLocal(); + static final ThreadLocal<TLGlobals> currentInstance = new ThreadLocal<>(); + + // convenience methods to access the TL globals + static TLGlobals getTLGlobals() { + return currentInstance.get(); + } + + static Map<String, Utf8Entry> getUtf8Entries() { + return getTLGlobals().getUtf8Entries(); + } + + static Map<String, ClassEntry> getClassEntries() { + return getTLGlobals().getClassEntries(); + } + + static Map<Object, LiteralEntry> getLiteralEntries() { + return getTLGlobals().getLiteralEntries(); + } + + static Map<String, DescriptorEntry> getDescriptorEntries() { + return getTLGlobals().getDescriptorEntries(); + } + + static Map<String, SignatureEntry> getSignatureEntries() { + return getTLGlobals().getSignatureEntries(); + } + + static Map<String, MemberEntry> getMemberEntries() { + return getTLGlobals().getMemberEntries(); + } static PropMap currentPropMap() { Object obj = currentInstance.get(); if (obj instanceof PackerImpl) - return ((PackerImpl)obj)._props; + return ((PackerImpl)obj).props; if (obj instanceof UnpackerImpl) - return ((UnpackerImpl)obj)._props; + return ((UnpackerImpl)obj).props; return null; }
--- a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java Sun Aug 29 22:41:28 2010 -0700 @@ -813,7 +813,8 @@ try { while (true) { try { - inbuf = new byte[10]; + // type and length (at most 128 octets for long form) + inbuf = new byte[129]; offset = 0; seqlen = 0;
--- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java Sun Aug 29 22:41:28 2010 -0700 @@ -470,7 +470,7 @@ public AbstractStringBuilder append(CharSequence s, int start, int end) { if (s == null) s = "null"; - if ((start < 0) || (end < 0) || (start > end) || (end > s.length())) + if ((start < 0) || (start > end) || (end > s.length())) throw new IndexOutOfBoundsException( "start " + start + ", end " + end + ", s.length() " + s.length()); @@ -529,7 +529,8 @@ * or {@code offset+len > str.length} */ public AbstractStringBuilder append(char str[], int offset, int len) { - ensureCapacityInternal(count + len); + if (len > 0) // let arraycopy report AIOOBE for len < 0 + ensureCapacityInternal(count + len); System.arraycopy(str, offset, value, count, len); count += len; return this;
--- a/jdk/src/share/classes/java/lang/Thread.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/java/lang/Thread.java Sun Aug 29 22:41:28 2010 -0700 @@ -414,6 +414,18 @@ } /** + * Throws CloneNotSupportedException as a Thread can not be meaningfully + * cloned. Construct a new Thread instead. + * + * @throws CloneNotSupportedException + * always + */ + @Override + protected Object clone() throws CloneNotSupportedException { + throw new CloneNotSupportedException(); + } + + /** * Allocates a new {@code Thread} object. This constructor has the same * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} * {@code (null, null, gname)}, where {@code gname} is a newly generated
--- a/jdk/src/share/classes/java/lang/Throwable.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/java/lang/Throwable.java Sun Aug 29 22:41:28 2010 -0700 @@ -200,7 +200,16 @@ * @serial * @since 1.7 */ - private List<Throwable> suppressedExceptions = Collections.emptyList(); + private List<Throwable> suppressedExceptions = null; + /* + * This field is lazily initialized when the first suppressed + * exception is added. + * + * OutOfMemoryError is preallocated in the VM for better OOM + * diagnosability during VM initialization. Constructor can't + * be not invoked. If a new field to be added in the future must + * be initialized to non-null, it requires a synchronized VM change. + */ /** Message for trying to suppress a null exception. */ private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception."; @@ -329,7 +338,7 @@ * cause is nonexistent or unknown. * @since 1.4 */ - public Throwable getCause() { + public synchronized Throwable getCause() { return (cause==this ? null : cause); } @@ -563,7 +572,7 @@ s.println("\tat " + traceElement); // Print suppressed exceptions, if any - for (Throwable se : suppressedExceptions) + for (Throwable se : getSuppressedExceptions()) se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu); // Print cause, if any @@ -604,7 +613,7 @@ s.println(prefix + "\t... " + framesInCommon + " more"); // Print suppressed exceptions, if any - for (Throwable se : suppressedExceptions) + for (Throwable se : getSuppressedExceptions()) se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, prefix +"\t", dejaVu); @@ -747,7 +756,9 @@ if (defensiveCopy[i] == null) throw new NullPointerException("stackTrace[" + i + "]"); - this.stackTrace = defensiveCopy; + synchronized (this) { + this.stackTrace = defensiveCopy; + } } /** @@ -772,11 +783,11 @@ private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); // read in all fields - List<Throwable> suppressed = Collections.emptyList(); + List<Throwable> suppressed = null; if (suppressedExceptions != null && !suppressedExceptions.isEmpty()) { // Copy Throwables to new list suppressed = new ArrayList<Throwable>(); - for(Throwable t : suppressedExceptions) { + for (Throwable t : suppressedExceptions) { if (t == null) throw new NullPointerException(NULL_CAUSE_MESSAGE); suppressed.add(t); @@ -819,7 +830,7 @@ if (exception == this) throw new IllegalArgumentException("Self-suppression not permitted"); - if (suppressedExceptions.size() == 0) + if (suppressedExceptions == null) suppressedExceptions = new ArrayList<Throwable>(); suppressedExceptions.add(exception); } @@ -835,7 +846,10 @@ * suppressed to deliver this exception. * @since 1.7 */ - public Throwable[] getSuppressedExceptions() { - return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY); + public synchronized Throwable[] getSuppressedExceptions() { + if (suppressedExceptions == null) + return EMPTY_THROWABLE_ARRAY; + else + return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY); } }
--- a/jdk/src/share/classes/java/net/HttpCookie.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/java/net/HttpCookie.java Sun Aug 29 22:41:28 2010 -0700 @@ -1093,14 +1093,8 @@ return sb.toString(); } - private static SimpleDateFormat[] cDateFormats = null; - static { - cDateFormats = new SimpleDateFormat[COOKIE_DATE_FORMATS.length]; - for (int i = 0; i < COOKIE_DATE_FORMATS.length; i++) { - cDateFormats[i] = new SimpleDateFormat(COOKIE_DATE_FORMATS[i], Locale.US); - cDateFormats[i].setTimeZone(TimeZone.getTimeZone("GMT")); - } - } + static final TimeZone GMT = TimeZone.getTimeZone("GMT"); + /* * @param dateString a date string in one of the formats * defined in Netscape cookie spec @@ -1109,12 +1103,14 @@ * time and the time specified by dateString */ private long expiryDate2DeltaSeconds(String dateString) { - for (SimpleDateFormat df : cDateFormats) { + for (int i = 0; i < COOKIE_DATE_FORMATS.length; i++) { + SimpleDateFormat df = new SimpleDateFormat(COOKIE_DATE_FORMATS[i], Locale.US); + df.setTimeZone(GMT); try { Date date = df.parse(dateString); return (date.getTime() - whenCreated) / 1000; } catch (Exception e) { - + // Ignore, try the next date format } } return 0;
--- a/jdk/src/share/classes/java/net/URI.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/java/net/URI.java Sun Aug 29 22:41:28 2010 -0700 @@ -856,9 +856,7 @@ try { return new URI(str); } catch (URISyntaxException x) { - IllegalArgumentException y = new IllegalArgumentException(); - y.initCause(x); - throw y; + throw new IllegalArgumentException(x.getMessage(), x); } }
--- a/jdk/src/share/classes/java/security/KeyStore.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/java/security/KeyStore.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -131,17 +131,19 @@ * to read existing entries from the keystore, or to write new entries * into the keystore: * <pre> + * KeyStore.ProtectionParameter protParam = + * new KeyStore.PasswordProtection(password); + * * // get my private key * KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) - * ks.getEntry("privateKeyAlias", password); + * ks.getEntry("privateKeyAlias", protParam); * PrivateKey myPrivateKey = pkEntry.getPrivateKey(); * * // save my secret key * javax.crypto.SecretKey mySecretKey; * KeyStore.SecretKeyEntry skEntry = * new KeyStore.SecretKeyEntry(mySecretKey); - * ks.setEntry("secretKeyAlias", skEntry, - * new KeyStore.PasswordProtection(password)); + * ks.setEntry("secretKeyAlias", skEntry, protParam); * * // store away the keystore * java.io.FileOutputStream fos = null;
--- a/jdk/src/share/classes/java/sql/Date.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/java/sql/Date.java Sun Aug 29 22:41:28 2010 -0700 @@ -103,27 +103,46 @@ * JDBC date escape format (yyyy-mm-dd) */ public static Date valueOf(String s) { - int year; - int month; - int day; + final int YEAR_LENGTH = 4; + final int MONTH_LENGTH = 2; + final int DAY_LENGTH = 2; + final int MAX_MONTH = 12; + final int MAX_DAY = 31; int firstDash; int secondDash; - - if (s == null) throw new java.lang.IllegalArgumentException(); + Date d = null; - firstDash = s.indexOf('-'); - secondDash = s.indexOf('-', firstDash+1); - if ((firstDash > 0) & (secondDash > 0) & (secondDash < s.length()-1)) { - year = Integer.parseInt(s.substring(0, firstDash)) - 1900; - month = Integer.parseInt(s.substring(firstDash+1, secondDash)) - 1; - day = Integer.parseInt(s.substring(secondDash+1)); - } else { + if (s == null) { throw new java.lang.IllegalArgumentException(); } - return new Date(year, month, day); + firstDash = s.indexOf('-'); + secondDash = s.indexOf('-', firstDash + 1); + + if ((firstDash > 0) && (secondDash > 0) && (secondDash < s.length() - 1)) { + String yyyy = s.substring(0, firstDash); + String mm = s.substring(firstDash + 1, secondDash); + String dd = s.substring(secondDash + 1); + if (yyyy.length() == YEAR_LENGTH && mm.length() == MONTH_LENGTH && + dd.length() == DAY_LENGTH) { + int year = Integer.parseInt(yyyy); + int month = Integer.parseInt(mm); + int day = Integer.parseInt(dd); + + if ((month >= 1 && month <= MAX_MONTH) && (day >= 1 && day <= MAX_DAY)) { + d = new Date(year - 1900, month - 1, day); + } + } + } + if (d == null) { + throw new java.lang.IllegalArgumentException(); + } + + return d; + } + /** * Formats a date in the date escape format yyyy-mm-dd. * <P>
--- a/jdk/src/share/classes/javax/swing/JTable.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/javax/swing/JTable.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -946,7 +946,6 @@ /** * Returns the height of a table row, in pixels. - * The default row height is 16.0. * * @return the height in pixels of a table row * @see #setRowHeight
--- a/jdk/src/share/classes/sun/java2d/pisces/Dasher.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/pisces/Dasher.java Sun Aug 29 22:41:28 2010 -0700 @@ -36,117 +36,71 @@ * semantics are unclear. * */ -public class Dasher extends LineSink { +public class Dasher implements LineSink { + private final LineSink output; + private final float[] dash; + private final float startPhase; + private final boolean startDashOn; + private final int startIdx; - LineSink output; - int[] dash; - int startPhase; - boolean startDashOn; - int startIdx; - - int idx; - boolean dashOn; - int phase; - - int sx, sy; - int x0, y0; + private final float m00, m10, m01, m11; + private final float det; - int m00, m01; - int m10, m11; - - Transform4 transform; - - boolean symmetric; - long ldet; + private boolean firstDashOn; + private boolean starting; - boolean firstDashOn; - boolean starting; - int sx1, sy1; + private int idx; + private boolean dashOn; + private float phase; - /** - * Empty constructor. <code>setOutput</code> and - * <code>setParameters</code> must be called prior to calling any - * other methods. - */ - public Dasher() {} + private float sx, sy; + private float x0, y0; + private float sx1, sy1; + /** * Constructs a <code>Dasher</code>. * * @param output an output <code>LineSink</code>. - * @param dash an array of <code>int</code>s containing the dash - * pattern in S15.16 format. - * @param phase an <code>int</code> containing the dash phase in - * S15.16 format. + * @param dash an array of <code>int</code>s containing the dash pattern + * @param phase an <code>int</code> containing the dash phase * @param transform a <code>Transform4</code> object indicating * the transform that has been previously applied to all incoming * coordinates. This is required in order to compute dash lengths * properly. */ public Dasher(LineSink output, - int[] dash, int phase, - Transform4 transform) { - setOutput(output); - setParameters(dash, phase, transform); - } - - /** - * Sets the output <code>LineSink</code> of this - * <code>Dasher</code>. - * - * @param output an output <code>LineSink</code>. - */ - public void setOutput(LineSink output) { - this.output = output; - } - - /** - * Sets the parameters of this <code>Dasher</code>. - * - * @param dash an array of <code>int</code>s containing the dash - * pattern in S15.16 format. - * @param phase an <code>int</code> containing the dash phase in - * S15.16 format. - * @param transform a <code>Transform4</code> object indicating - * the transform that has been previously applied to all incoming - * coordinates. This is required in order to compute dash lengths - * properly. - */ - public void setParameters(int[] dash, int phase, - Transform4 transform) { + float[] dash, float phase, + float a00, float a01, float a10, float a11) { if (phase < 0) { throw new IllegalArgumentException("phase < 0 !"); } + this.output = output; + // Normalize so 0 <= phase < dash[0] int idx = 0; dashOn = true; - int d; + float d; while (phase >= (d = dash[idx])) { phase -= d; idx = (idx + 1) % dash.length; dashOn = !dashOn; } - this.dash = new int[dash.length]; - for (int i = 0; i < dash.length; i++) { - this.dash[i] = dash[i]; - } + this.dash = dash; this.startPhase = this.phase = phase; this.startDashOn = dashOn; this.startIdx = idx; - this.transform = transform; - - this.m00 = transform.m00; - this.m01 = transform.m01; - this.m10 = transform.m10; - this.m11 = transform.m11; - this.ldet = ((long)m00*m11 - (long)m01*m10) >> 16; - this.symmetric = (m00 == m11 && m10 == -m01); + m00 = a00; + m01 = a01; + m10 = a10; + m11 = a11; + det = m00 * m11 - m01 * m10; } - public void moveTo(int x0, int y0) { + public void moveTo(float x0, float y0) { output.moveTo(x0, y0); this.idx = startIdx; this.dashOn = this.startDashOn; @@ -160,7 +114,7 @@ output.lineJoin(); } - private void goTo(int x1, int y1) { + private void goTo(float x1, float y1) { if (dashOn) { if (starting) { this.sx1 = x1; @@ -180,52 +134,64 @@ this.y0 = y1; } - public void lineTo(int x1, int y1) { - while (true) { - int d = dash[idx] - phase; - int lx = x1 - x0; - int ly = y1 - y0; + public void lineTo(float x1, float y1) { + // The widened line is squished to a 0 width one, so no drawing is done + if (det == 0) { + goTo(x1, y1); + return; + } + float dx = x1 - x0; + float dy = y1 - y0; - // Compute segment length in the untransformed - // coordinate system - // IMPL NOTE - use fixed point + + // Compute segment length in the untransformed + // coordinate system - int l; - if (symmetric) { - l = (int)((PiscesMath.hypot(lx, ly)*65536L)/ldet); - } else{ - long la = ((long)ly*m00 - (long)lx*m10)/ldet; - long lb = ((long)ly*m01 - (long)lx*m11)/ldet; - l = (int)PiscesMath.hypot(la, lb); - } + float la = (dy*m00 - dx*m10)/det; + float lb = (dy*m01 - dx*m11)/det; + float origLen = (float) Math.hypot(la, lb); - if (l < d) { + if (origLen == 0) { + // Let the output LineSink deal with cases where dx, dy are 0. + goTo(x1, y1); + return; + } + + // The scaling factors needed to get the dx and dy of the + // transformed dash segments. + float cx = dx / origLen; + float cy = dy / origLen; + + while (true) { + float leftInThisDashSegment = dash[idx] - phase; + if (origLen < leftInThisDashSegment) { goTo(x1, y1); // Advance phase within current dash segment - phase += l; + phase += origLen; + return; + } else if (origLen == leftInThisDashSegment) { + goTo(x1, y1); + phase = 0f; + idx = (idx + 1) % dash.length; + dashOn = !dashOn; return; } - long t; - int xsplit, ysplit; -// // For zero length dashses, SE appears to move 1/8 unit -// // in device space -// if (d == 0) { -// double dlx = lx/65536.0; -// double dly = ly/65536.0; -// len = PiscesMath.hypot(dlx, dly); -// double dt = 1.0/(8*len); -// double dxsplit = (x0/65536.0) + dt*dlx; -// double dysplit = (y0/65536.0) + dt*dly; -// xsplit = (int)(dxsplit*65536.0); -// ysplit = (int)(dysplit*65536.0); -// } else { - t = ((long)d << 16)/l; - xsplit = x0 + (int)(t*(x1 - x0) >> 16); - ysplit = y0 + (int)(t*(y1 - y0) >> 16); -// } - goTo(xsplit, ysplit); + float dashx, dashy; + float dashdx = dash[idx] * cx; + float dashdy = dash[idx] * cy; + if (phase == 0) { + dashx = x0 + dashdx; + dashy = y0 + dashdy; + } else { + float p = (leftInThisDashSegment) / dash[idx]; + dashx = x0 + p * dashdx; + dashy = y0 + p * dashdy; + } + goTo(dashx, dashy); + + origLen -= (dash[idx] - phase); // Advance to next dash segment idx = (idx + 1) % dash.length; dashOn = !dashOn; @@ -233,6 +199,7 @@ } } + public void close() { lineTo(sx, sy); if (firstDashOn) {
--- a/jdk/src/share/classes/sun/java2d/pisces/LineSink.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/pisces/LineSink.java Sun Aug 29 22:41:28 2010 -0700 @@ -39,16 +39,16 @@ * <code>LineSink</code> interface. * */ -public abstract class LineSink { +public interface LineSink { /** * Moves the current drawing position to the point <code>(x0, * y0)</code>. * - * @param x0 the X coordinate in S15.16 format - * @param y0 the Y coordinate in S15.16 format + * @param x0 the X coordinate + * @param y0 the Y coordinate */ - public abstract void moveTo(int x0, int y0); + public void moveTo(float x0, float y0); /** * Provides a hint that the current segment should be joined to @@ -65,29 +65,29 @@ * <p> Other <code>LineSink</code> classes should simply pass this * hint to their output sink as needed. */ - public abstract void lineJoin(); + public void lineJoin(); /** * Draws a line from the current drawing position to the point * <code>(x1, y1)</code> and sets the current drawing position to * <code>(x1, y1)</code>. * - * @param x1 the X coordinate in S15.16 format - * @param y1 the Y coordinate in S15.16 format + * @param x1 the X coordinate + * @param y1 the Y coordinate */ - public abstract void lineTo(int x1, int y1); + public void lineTo(float x1, float y1); /** * Closes the current path by drawing a line from the current * drawing position to the point specified by the moset recent * <code>moveTo</code> command. */ - public abstract void close(); + public void close(); /** * Ends the current path. It may be necessary to end a path in * order to allow end caps to be drawn. */ - public abstract void end(); + public void end(); }
--- a/jdk/src/share/classes/sun/java2d/pisces/PiscesMath.java Wed Jul 05 17:20:50 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,155 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.java2d.pisces; - -public class PiscesMath { - - private PiscesMath() {} - - private static final int SINTAB_LG_ENTRIES = 10; - private static final int SINTAB_ENTRIES = 1 << SINTAB_LG_ENTRIES; - private static int[] sintab; - - public static final int PI = (int)(Math.PI*65536.0); - public static final int TWO_PI = (int)(2.0*Math.PI*65536.0); - public static final int PI_OVER_TWO = (int)((Math.PI/2.0)*65536.0); - public static final int SQRT_TWO = (int)(Math.sqrt(2.0)*65536.0); - - static { - sintab = new int[SINTAB_ENTRIES + 1]; - for (int i = 0; i < SINTAB_ENTRIES + 1; i++) { - double theta = i*(Math.PI/2.0)/SINTAB_ENTRIES; - sintab[i] = (int)(Math.sin(theta)*65536.0); - } - } - - public static int sin(int theta) { - int sign = 1; - if (theta < 0) { - theta = -theta; - sign = -1; - } - // 0 <= theta - while (theta >= TWO_PI) { - theta -= TWO_PI; - } - // 0 <= theta < 2*PI - if (theta >= PI) { - theta = TWO_PI - theta; - sign = -sign; - } - // 0 <= theta < PI - if (theta > PI_OVER_TWO) { - theta = PI - theta; - } - // 0 <= theta <= PI/2 - int itheta = (int)((long)theta*SINTAB_ENTRIES/(PI_OVER_TWO)); - return sign*sintab[itheta]; - } - - public static int cos(int theta) { - return sin(PI_OVER_TWO - theta); - } - -// public static double sqrt(double x) { -// double dsqrt = Math.sqrt(x); -// int ix = (int)(x*65536.0); -// Int Isqrt = Isqrt(Ix); - -// Long Lx = (Long)(X*65536.0); -// Long Lsqrt = Lsqrt(Lx); - -// System.Out.Println(); -// System.Out.Println("X = " + X); -// System.Out.Println("Dsqrt = " + Dsqrt); - -// System.Out.Println("Ix = " + Ix); -// System.Out.Println("Isqrt = " + Isqrt/65536.0); - -// System.Out.Println("Lx = " + Lx); -// System.Out.Println("Lsqrt = " + Lsqrt/65536.0); - -// Return Dsqrt; -// } - - // From Ken Turkowski, _Fixed-Point Square Root_, In Graphics Gems V - public static int isqrt(int x) { - int fracbits = 16; - - int root = 0; - int remHi = 0; - int remLo = x; - int count = 15 + fracbits/2; - - do { - remHi = (remHi << 2) | (remLo >>> 30); // N.B. - unsigned shift R - remLo <<= 2; - root <<= 1; - int testdiv = (root << 1) + 1; - if (remHi >= testdiv) { - remHi -= testdiv; - root++; - } - } while (count-- != 0); - - return root; - } - - public static long lsqrt(long x) { - int fracbits = 16; - - long root = 0; - long remHi = 0; - long remLo = x; - int count = 31 + fracbits/2; - - do { - remHi = (remHi << 2) | (remLo >>> 62); // N.B. - unsigned shift R - remLo <<= 2; - root <<= 1; - long testDiv = (root << 1) + 1; - if (remHi >= testDiv) { - remHi -= testDiv; - root++; - } - } while (count-- != 0); - - return root; - } - - public static double hypot(double x, double y) { - // new RuntimeException().printStackTrace(); - return Math.sqrt(x*x + y*y); - } - - public static int hypot(int x, int y) { - return (int)((lsqrt((long)x*x + (long)y*y) + 128) >> 8); - } - - public static long hypot(long x, long y) { - return (lsqrt(x*x + y*y) + 128) >> 8; - } -}
--- a/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java Sun Aug 29 22:41:28 2010 -0700 @@ -27,6 +27,7 @@ import java.awt.Shape; import java.awt.BasicStroke; +import java.awt.geom.FlatteningPathIterator; import java.awt.geom.Path2D; import java.awt.geom.AffineTransform; import java.awt.geom.PathIterator; @@ -37,23 +38,9 @@ import sun.java2d.pipe.AATileGenerator; public class PiscesRenderingEngine extends RenderingEngine { - public static Transform4 IdentT4 = new Transform4(); public static double defaultFlat = 0.1; - static int FloatToS15_16(float flt) { - flt = flt * 65536f + 0.5f; - if (flt <= -(65536f * 65536f)) { - return Integer.MIN_VALUE; - } else if (flt >= (65536f * 65536f)) { - return Integer.MAX_VALUE; - } else { - return (int) Math.floor(flt); - } - } - - static float S15_16ToFloat(int fix) { - return (fix / 65536f); - } + private static enum NormMode {OFF, ON_NO_AA, ON_WITH_AA} /** * Create a widened path as specified by the parameters. @@ -85,18 +72,19 @@ strokeTo(src, null, width, + NormMode.OFF, caps, join, miterlimit, dashes, dashphase, new LineSink() { - public void moveTo(int x0, int y0) { - p2d.moveTo(S15_16ToFloat(x0), S15_16ToFloat(y0)); + public void moveTo(float x0, float y0) { + p2d.moveTo(x0, y0); } public void lineJoin() {} - public void lineTo(int x1, int y1) { - p2d.lineTo(S15_16ToFloat(x1), S15_16ToFloat(y1)); + public void lineTo(float x1, float y1) { + p2d.lineTo(x1, y1); } public void close() { p2d.closePath(); @@ -142,14 +130,17 @@ boolean antialias, final PathConsumer2D consumer) { - strokeTo(src, at, bs, thin, normalize, antialias, + NormMode norm = (normalize) ? + ((antialias) ? NormMode.ON_WITH_AA : NormMode.ON_NO_AA) + : NormMode.OFF; + strokeTo(src, at, bs, thin, norm, antialias, new LineSink() { - public void moveTo(int x0, int y0) { - consumer.moveTo(S15_16ToFloat(x0), S15_16ToFloat(y0)); + public void moveTo(float x0, float y0) { + consumer.moveTo(x0, y0); } public void lineJoin() {} - public void lineTo(int x1, int y1) { - consumer.lineTo(S15_16ToFloat(x1), S15_16ToFloat(y1)); + public void lineTo(float x1, float y1) { + consumer.lineTo(x1, y1); } public void close() { consumer.closePath(); @@ -164,7 +155,7 @@ AffineTransform at, BasicStroke bs, boolean thin, - boolean normalize, + NormMode normalize, boolean antialias, LineSink lsink) { @@ -181,6 +172,7 @@ strokeTo(src, at, lw, + normalize, bs.getEndCap(), bs.getLineJoin(), bs.getMiterLimit(), @@ -258,6 +250,7 @@ void strokeTo(Shape src, AffineTransform at, float width, + NormMode normalize, int caps, int join, float miterlimit, @@ -265,36 +258,139 @@ float dashphase, LineSink lsink) { - Transform4 t4; - - if (at == null || at.isIdentity()) { - t4 = IdentT4; + float a00 = 1f, a01 = 0f, a10 = 0f, a11 = 1f; + if (at != null && !at.isIdentity()) { + a00 = (float)at.getScaleX(); + a01 = (float)at.getShearX(); + a10 = (float)at.getShearY(); + a11 = (float)at.getScaleY(); + } + lsink = new Stroker(lsink, width, caps, join, miterlimit, a00, a01, a10, a11); + if (dashes != null) { + lsink = new Dasher(lsink, dashes, dashphase, a00, a01, a10, a11); + } + PathIterator pi; + if (normalize != NormMode.OFF) { + pi = new FlatteningPathIterator( + new NormalizingPathIterator(src.getPathIterator(at), normalize), + defaultFlat); } else { - t4 = new Transform4(FloatToS15_16((float) at.getScaleX()), - FloatToS15_16((float) at.getShearX()), - FloatToS15_16((float) at.getShearY()), - FloatToS15_16((float) at.getScaleY())); + pi = src.getPathIterator(at, defaultFlat); + } + pathTo(pi, lsink); + } + + private static class NormalizingPathIterator implements PathIterator { + + private final PathIterator src; + + // the adjustment applied to the current position. + private float curx_adjust, cury_adjust; + // the adjustment applied to the last moveTo position. + private float movx_adjust, movy_adjust; + + // constants used in normalization computations + private final float lval, rval; + + NormalizingPathIterator(PathIterator src, NormMode mode) { + this.src = src; + switch (mode) { + case ON_NO_AA: + // round to nearest (0.25, 0.25) pixel + lval = rval = 0.25f; + break; + case ON_WITH_AA: + // round to nearest pixel center + lval = 0f; + rval = 0.5f; + break; + case OFF: + throw new InternalError("A NormalizingPathIterator should " + + "not be created if no normalization is being done"); + default: + throw new InternalError("Unrecognized normalization mode"); + } } - lsink = new Stroker(lsink, - FloatToS15_16(width), - caps, - join, - FloatToS15_16(miterlimit), - t4); - if (dashes != null) { - int fdashes[] = new int[dashes.length]; - for (int i = 0; i < dashes.length; i++) { - fdashes[i] = FloatToS15_16(dashes[i]); + public int currentSegment(float[] coords) { + int type = src.currentSegment(coords); + + int lastCoord; + switch(type) { + case PathIterator.SEG_CUBICTO: + lastCoord = 4; + break; + case PathIterator.SEG_QUADTO: + lastCoord = 2; + break; + case PathIterator.SEG_LINETO: + case PathIterator.SEG_MOVETO: + lastCoord = 0; + break; + case PathIterator.SEG_CLOSE: + // we don't want to deal with this case later. We just exit now + curx_adjust = movx_adjust; + cury_adjust = movy_adjust; + return type; + default: + throw new InternalError("Unrecognized curve type"); } - lsink = new Dasher(lsink, - fdashes, - FloatToS15_16(dashphase), - t4); + + // normalize endpoint + float x_adjust = (float)Math.floor(coords[lastCoord] + lval) + rval - + coords[lastCoord]; + float y_adjust = (float)Math.floor(coords[lastCoord+1] + lval) + rval - + coords[lastCoord + 1]; + + coords[lastCoord ] += x_adjust; + coords[lastCoord + 1] += y_adjust; + + // now that the end points are done, normalize the control points + switch(type) { + case PathIterator.SEG_CUBICTO: + coords[0] += curx_adjust; + coords[1] += cury_adjust; + coords[2] += x_adjust; + coords[3] += y_adjust; + break; + case PathIterator.SEG_QUADTO: + coords[0] += (curx_adjust + x_adjust) / 2; + coords[1] += (cury_adjust + y_adjust) / 2; + break; + case PathIterator.SEG_LINETO: + break; + case PathIterator.SEG_MOVETO: + movx_adjust = x_adjust; + movy_adjust = y_adjust; + break; + case PathIterator.SEG_CLOSE: + throw new InternalError("This should be handled earlier."); + } + curx_adjust = x_adjust; + cury_adjust = y_adjust; + return type; } - PathIterator pi = src.getPathIterator(at, defaultFlat); - pathTo(pi, lsink); + public int currentSegment(double[] coords) { + float[] tmp = new float[6]; + int type = this.currentSegment(tmp); + for (int i = 0; i < 6; i++) { + coords[i] = (float) tmp[i]; + } + return type; + } + + public int getWindingRule() { + return src.getWindingRule(); + } + + public boolean isDone() { + return src.isDone(); + } + + public void next() { + src.next(); + } } void pathTo(PathIterator pi, LineSink lsink) { @@ -302,13 +398,11 @@ while (!pi.isDone()) { switch (pi.currentSegment(coords)) { case PathIterator.SEG_MOVETO: - lsink.moveTo(FloatToS15_16(coords[0]), - FloatToS15_16(coords[1])); + lsink.moveTo(coords[0], coords[1]); break; case PathIterator.SEG_LINETO: lsink.lineJoin(); - lsink.lineTo(FloatToS15_16(coords[0]), - FloatToS15_16(coords[1])); + lsink.lineTo(coords[0], coords[1]); break; case PathIterator.SEG_CLOSE: lsink.lineJoin(); @@ -378,18 +472,28 @@ int bbox[]) { PiscesCache pc = PiscesCache.createInstance(); - Renderer r = new Renderer(); - r.setCache(pc); - r.setAntialiasing(3, 3); - r.beginRendering(clip.getLoX(), clip.getLoY(), - clip.getWidth(), clip.getHeight()); + Renderer r; + NormMode norm = (normalize) ? NormMode.ON_WITH_AA : NormMode.OFF; if (bs == null) { - PathIterator pi = s.getPathIterator(at, defaultFlat); - r.setWindingRule(pi.getWindingRule()); + PathIterator pi; + if (normalize) { + pi = new FlatteningPathIterator( + new NormalizingPathIterator(s.getPathIterator(at), norm), + defaultFlat); + } else { + pi = s.getPathIterator(at, defaultFlat); + } + r = new Renderer(3, 3, + clip.getLoX(), clip.getLoY(), + clip.getWidth(), clip.getHeight(), + pi.getWindingRule(), pc); pathTo(pi, r); } else { - r.setWindingRule(PathIterator.WIND_NON_ZERO); - strokeTo(s, at, bs, thin, normalize, true, r); + r = new Renderer(3, 3, + clip.getLoX(), clip.getLoY(), + clip.getWidth(), clip.getHeight(), + PathIterator.WIND_NON_ZERO, pc); + strokeTo(s, at, bs, thin, norm, true, r); } r.endRendering(); PiscesTileGenerator ptg = new PiscesTileGenerator(pc, r.MAX_AA_ALPHA); @@ -420,3 +524,4 @@ } } } +
--- a/jdk/src/share/classes/sun/java2d/pisces/Renderer.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/pisces/Renderer.java Sun Aug 29 22:41:28 2010 -0700 @@ -25,446 +25,440 @@ package sun.java2d.pisces; -public class Renderer extends LineSink { +import java.util.Arrays; + +public class Renderer implements LineSink { + +/////////////////////////////////////////////////////////////////////////////// +// Scan line iterator and edge crossing data. +////////////////////////////////////////////////////////////////////////////// + + private int[] crossings; + + // This is an array of indices into the edge array. It is initialized to + // [i * SIZEOF_STRUCT_EDGE for i in range(0, edgesSize/SIZEOF_STRUCT_EDGE)] + // (where range(i, j) is i,i+1,...,j-1 -- just like in python). + // The reason for keeping this is because we need the edges array sorted + // by y0, but we don't want to move all that data around, so instead we + // sort the indices into the edge array, and use edgeIndices to access + // the edges array. This is meant to simulate a pointer array (hence the name) + private int[] edgePtrs; + + // crossing bounds. The bounds are not necessarily tight (the scan line + // at minY, for example, might have no crossings). The x bounds will + // be accumulated as crossings are computed. + private int minY, maxY; + private int minX, maxX; + private int nextY; + + // indices into the edge pointer list. They indicate the "active" sublist in + // the edge list (the portion of the list that contains all the edges that + // cross the next scan line). + private int lo, hi; + + private static final int INIT_CROSSINGS_SIZE = 50; + private void ScanLineItInitialize() { + crossings = new int[INIT_CROSSINGS_SIZE]; + edgePtrs = new int[edgesSize / SIZEOF_STRUCT_EDGE]; + for (int i = 0; i < edgePtrs.length; i++) { + edgePtrs[i] = i * SIZEOF_STRUCT_EDGE; + } + + qsort(0, edgePtrs.length - 1); + + // We don't care if we clip some of the line off with ceil, since + // no scan line crossings will be eliminated (in fact, the ceil is + // the y of the first scan line crossing). + nextY = minY = Math.max(boundsMinY, (int)Math.ceil(edgeMinY)); + maxY = Math.min(boundsMaxY, (int)Math.ceil(edgeMaxY)); + + for (lo = 0; lo < edgePtrs.length && edges[edgePtrs[lo]+Y1] <= nextY; lo++) + ; + for (hi = lo; hi < edgePtrs.length && edges[edgePtrs[hi]+CURY] <= nextY; hi++) + ; // the active list is *edgePtrs[lo] (inclusive) *edgePtrs[hi] (exclusive) + for (int i = lo; i < hi; i++) { + setCurY(edgePtrs[i], nextY); + } + + // We accumulate X in the iterator because accumulating it in addEdge + // like we do with Y does not do much good: if there's an edge + // (0,0)->(1000,10000), and if y gets clipped to 1000, then the x + // bound should be 100, but the accumulator from addEdge would say 1000, + // so we'd still have to accumulate the X bounds as we add crossings. + minX = boundsMinX; + maxX = boundsMaxX; + } + + private int ScanLineItCurrentY() { + return nextY - 1; + } + + private int ScanLineItGoToNextYAndComputeCrossings() { + // we go through the active list and remove the ones that don't cross + // the nextY scanline. + int crossingIdx = 0; + for (int i = lo; i < hi; i++) { + if (edges[edgePtrs[i]+Y1] <= nextY) { + edgePtrs[i] = edgePtrs[lo++]; + } + } + if (hi - lo > crossings.length) { + int newSize = Math.max(hi - lo, crossings.length * 2); + crossings = Arrays.copyOf(crossings, newSize); + } + // Now every edge between lo and hi crosses nextY. Compute it's + // crossing and put it in the crossings array. + for (int i = lo; i < hi; i++) { + addCrossing(nextY, getCurCrossing(edgePtrs[i]), (int)edges[edgePtrs[i]+OR], crossingIdx); + gotoNextY(edgePtrs[i]); + crossingIdx++; + } + + nextY++; + // Expand active list to include new edges. + for (; hi < edgePtrs.length && edges[edgePtrs[hi]+CURY] <= nextY; hi++) { + setCurY(edgePtrs[hi], nextY); + } + + Arrays.sort(crossings, 0, crossingIdx); + return crossingIdx; + } + + private boolean ScanLineItHasNext() { + return nextY < maxY; + } + + private void addCrossing(int y, int x, int or, int idx) { + if (x < minX) { + minX = x; + } + if (x > maxX) { + maxX = x; + } + x <<= 1; + crossings[idx] = ((or == 1) ? (x | 0x1) : x); + } + + + // quicksort implementation for sorting the edge indices ("pointers") + // by increasing y0. first, last are indices into the "pointer" array + // It sorts the pointer array from first (inclusive) to last (inclusive) + private void qsort(int first, int last) { + if (last > first) { + int p = partition(first, last); + if (first < p - 1) { + qsort(first, p - 1); + } + if (p < last) { + qsort(p, last); + } + } + } + + // i, j are indices into edgePtrs. + private int partition(int i, int j) { + int pivotVal = edgePtrs[i]; + while (i <= j) { + // edges[edgePtrs[i]+1] is equivalent to (*(edgePtrs[i])).y0 in C + while (edges[edgePtrs[i]+CURY] < edges[pivotVal+CURY]) { i++; } + while (edges[edgePtrs[j]+CURY] > edges[pivotVal+CURY]) { j--; } + if (i <= j) { + int tmp = edgePtrs[i]; + edgePtrs[i] = edgePtrs[j]; + edgePtrs[j] = tmp; + i++; + j--; + } + } + return i; + } + +//============================================================================ + + +////////////////////////////////////////////////////////////////////////////// +// EDGE LIST +////////////////////////////////////////////////////////////////////////////// + + private static final int INIT_NUM_EDGES = 1000; + private static final int SIZEOF_STRUCT_EDGE = 5; + + // The following array is a poor man's struct array: + // it simulates a struct array by having + // edges[SIZEOF_STRUCT_EDGE * i + j] be the jth field in the ith element + // of an array of edge structs. + private float[] edges; + private int edgesSize; // size of the edge list. + private static final int Y1 = 0; + private static final int SLOPE = 1; + private static final int OR = 2; // the orientation. This can be -1 or 1. + // -1 means up, 1 means down. + private static final int CURY = 3; // j = 5 corresponds to the "current Y". + // Each edge keeps track of the last scanline + // crossing it computed, and this is the y coord of + // that scanline. + private static final int CURX = 4; //the x coord of the current crossing. + + // Note that while the array is declared as a float[] not all of it's + // elements should be floats. currentY and Orientation should be ints (or int and + // byte respectively), but they all need to be the same type. This isn't + // really a problem because floats can represent exactly all 23 bit integers, + // which should be more than enough. + // Note, also, that we only need x1 for slope computation, so we don't need + // to store it. x0, y0 don't need to be stored either. They can be put into + // curx, cury, and it's ok if they're lost when curx and cury are changed. + // We take this undeniably ugly and error prone approach (instead of simply + // making an Edge class) for performance reasons. Also, it would probably be nicer + // to have one array for each field, but that would defeat the purpose because + // it would make poor use of the processor cache, since we tend to access + // all the fields for one edge at a time. + + private float edgeMinY; + private float edgeMaxY; + + + private void addEdge(float x0, float y0, float x1, float y1) { + float or = (y0 < y1) ? 1f : -1f; // orientation: 1 = UP; -1 = DOWN + if (or == -1) { + float tmp = y0; + y0 = y1; + y1 = tmp; + tmp = x0; + x0 = x1; + x1 = tmp; + } + // skip edges that don't cross a scanline + if (Math.ceil(y0) >= Math.ceil(y1)) { + return; + } + + int newSize = edgesSize + SIZEOF_STRUCT_EDGE; + if (edges.length < newSize) { + edges = Arrays.copyOf(edges, newSize * 2); + } + edges[edgesSize+CURX] = x0; + edges[edgesSize+CURY] = y0; + edges[edgesSize+Y1] = y1; + edges[edgesSize+SLOPE] = (x1 - x0) / (y1 - y0); + edges[edgesSize+OR] = or; + // the crossing values can't be initialized meaningfully yet. This + // will have to wait until setCurY is called + edgesSize += SIZEOF_STRUCT_EDGE; + + // Accumulate edgeMinY and edgeMaxY + if (y0 < edgeMinY) { edgeMinY = y0; } + if (y1 > edgeMaxY) { edgeMaxY = y1; } + } + + // As far as the following methods care, this edges extends to infinity. + // They can compute the x intersect of any horizontal line. + // precondition: idx is the index to the start of the desired edge. + // So, if the ith edge is wanted, idx should be SIZEOF_STRUCT_EDGE * i + private void setCurY(int idx, int y) { + // compute the x crossing of edge at idx and horizontal line y + // currentXCrossing = (y - y0)*slope + x0 + edges[idx + CURX] = (y - edges[idx + CURY]) * edges[idx + SLOPE] + edges[idx+CURX]; + edges[idx + CURY] = (float)y; + } + + private void gotoNextY(int idx) { + edges[idx + CURY] += 1f; // i.e. curY += 1 + edges[idx + CURX] += edges[idx + SLOPE]; // i.e. curXCrossing += slope + } + + private int getCurCrossing(int idx) { + return (int)edges[idx + CURX]; + } +//==================================================================================== + public static final int WIND_EVEN_ODD = 0; public static final int WIND_NON_ZERO = 1; - // Initial edge list size - // IMPL_NOTE - restore size after growth - public static final int INITIAL_EDGES = 1000; - - // Recommended maximum scratchpad sizes. The arrays will grow - // larger if needed, but when finished() is called they will be released - // if they have grown larger than these sizes. - public static final int DEFAULT_INDICES_SIZE = 8192; - public static final int DEFAULT_CROSSINGS_SIZE = 32*1024; - // Antialiasing - private int SUBPIXEL_LG_POSITIONS_X; - private int SUBPIXEL_LG_POSITIONS_Y; - private int SUBPIXEL_MASK_X; - private int SUBPIXEL_MASK_Y; - private int SUBPIXEL_POSITIONS_X; - private int SUBPIXEL_POSITIONS_Y; - int MAX_AA_ALPHA; - private int MAX_AA_ALPHA_DENOM; - private int HALF_MAX_AA_ALPHA_DENOM; - private int XSHIFT; - private int YSHIFT; - private int YSTEP; - private int HYSTEP; - private int YMASK; - - private static final int MIN_QUAD_OPT_WIDTH = 100 << 16; + final private int SUBPIXEL_LG_POSITIONS_X; + final private int SUBPIXEL_LG_POSITIONS_Y; + final private int SUBPIXEL_POSITIONS_X; + final private int SUBPIXEL_POSITIONS_Y; + final private int SUBPIXEL_MASK_X; + final private int SUBPIXEL_MASK_Y; + final int MAX_AA_ALPHA; // Cache to store RLE-encoded coverage mask of the current primitive - PiscesCache cache; + final PiscesCache cache; - // Bounds of the drawing region, at S15.16 precsion - private int boundsMinX, boundsMinY, boundsMaxX, boundsMaxY; - - // Bounds of the current primitive, at subsample precision - private int rasterMinX, rasterMaxX, rasterMinY, rasterMaxY; + // Bounds of the drawing region, at subpixel precision. + final private int boundsMinX, boundsMinY, boundsMaxX, boundsMaxY; // Pixel bounding box for current primitive - private int bboxX0, bboxY0, bboxX1, bboxY1; + private int pix_bboxX0, pix_bboxY0, pix_bboxX1, pix_bboxY1; // Current winding rule - private int windingRule; + final private int windingRule; // Current drawing position, i.e., final point of last segment - private int x0, y0; + private float x0, y0; // Position of most recent 'moveTo' command - private int sx0, sy0; - - // Buffer to be filled with one row's worth of alpha values - private byte[] rowAA; // needs to be short if 16x16 subsampling + private float pix_sx0, pix_sy0; - // Track the number of vertical extrema of the incoming edge list - // in order to determine the maximum number of crossings of a - // scanline - private int firstOrientation; - private int lastOrientation; - private int flips; - - // Parameters for emitRow - private int alphaWidth; - - public Renderer() { - } - - public void setAntialiasing(int subpixelLgPositionsX, - int subpixelLgPositionsY) { + public Renderer(int subpixelLgPositionsX, int subpixelLgPositionsY, + int pix_boundsX, int pix_boundsY, + int pix_boundsWidth, int pix_boundsHeight, + int windingRule, + PiscesCache cache) { this.SUBPIXEL_LG_POSITIONS_X = subpixelLgPositionsX; this.SUBPIXEL_LG_POSITIONS_Y = subpixelLgPositionsY; + this.SUBPIXEL_MASK_X = (1 << (SUBPIXEL_LG_POSITIONS_X)) - 1; + this.SUBPIXEL_MASK_Y = (1 << (SUBPIXEL_LG_POSITIONS_Y)) - 1; + this.SUBPIXEL_POSITIONS_X = 1 << (SUBPIXEL_LG_POSITIONS_X); + this.SUBPIXEL_POSITIONS_Y = 1 << (SUBPIXEL_LG_POSITIONS_Y); + this.MAX_AA_ALPHA = (SUBPIXEL_POSITIONS_X * SUBPIXEL_POSITIONS_Y); - this.SUBPIXEL_MASK_X = - (1 << (SUBPIXEL_LG_POSITIONS_X)) - 1; - this.SUBPIXEL_MASK_Y = - (1 << (SUBPIXEL_LG_POSITIONS_Y)) - 1; - this.SUBPIXEL_POSITIONS_X = - 1 << (SUBPIXEL_LG_POSITIONS_X); - this.SUBPIXEL_POSITIONS_Y = - 1 << (SUBPIXEL_LG_POSITIONS_Y); - this.MAX_AA_ALPHA = - (SUBPIXEL_POSITIONS_X*SUBPIXEL_POSITIONS_Y); - this.MAX_AA_ALPHA_DENOM = 255*MAX_AA_ALPHA; - this.HALF_MAX_AA_ALPHA_DENOM = MAX_AA_ALPHA_DENOM/2; - this.XSHIFT = 16 - SUBPIXEL_LG_POSITIONS_X; - this.YSHIFT = 16 - SUBPIXEL_LG_POSITIONS_Y; - this.YSTEP = 1 << YSHIFT; - this.HYSTEP = 1 << (YSHIFT - 1); - this.YMASK = ~(YSTEP - 1); - } + this.edges = new float[SIZEOF_STRUCT_EDGE * INIT_NUM_EDGES]; + edgeMinY = Float.POSITIVE_INFINITY; + edgeMaxY = Float.NEGATIVE_INFINITY; + edgesSize = 0; + + this.windingRule = windingRule; + this.cache = cache; - public int getSubpixelLgPositionsX() { - return SUBPIXEL_LG_POSITIONS_X; - } + this.boundsMinX = pix_boundsX * SUBPIXEL_POSITIONS_X; + this.boundsMinY = pix_boundsY * SUBPIXEL_POSITIONS_Y; + this.boundsMaxX = (pix_boundsX + pix_boundsWidth) * SUBPIXEL_POSITIONS_X; + this.boundsMaxY = (pix_boundsY + pix_boundsHeight) * SUBPIXEL_POSITIONS_Y; - public int getSubpixelLgPositionsY() { - return SUBPIXEL_LG_POSITIONS_Y; - } - - public void setWindingRule(int windingRule) { - this.windingRule = windingRule; - } - - public int getWindingRule() { - return windingRule; + this.pix_bboxX0 = pix_boundsX; + this.pix_bboxY0 = pix_boundsY; + this.pix_bboxX1 = pix_boundsX + pix_boundsWidth; + this.pix_bboxY1 = pix_boundsY + pix_boundsHeight; } - public void beginRendering(int boundsX, int boundsY, - int boundsWidth, int boundsHeight) { - lastOrientation = 0; - flips = 0; - - resetEdges(); - - this.boundsMinX = boundsX << 16; - this.boundsMinY = boundsY << 16; - this.boundsMaxX = (boundsX + boundsWidth) << 16; - this.boundsMaxY = (boundsY + boundsHeight) << 16; - - this.bboxX0 = boundsX; - this.bboxY0 = boundsY; - this.bboxX1 = boundsX + boundsWidth; - this.bboxY1 = boundsY + boundsHeight; + private float tosubpixx(float pix_x) { + return pix_x * SUBPIXEL_POSITIONS_X; + } + private float tosubpixy(float pix_y) { + return pix_y * SUBPIXEL_POSITIONS_Y; } - public void moveTo(int x0, int y0) { - // System.out.println("Renderer: moveTo " + x0/65536.0 + " " + y0/65536.0); + public void moveTo(float pix_x0, float pix_y0) { close(); - this.sx0 = this.x0 = x0; - this.sy0 = this.y0 = y0; - this.lastOrientation = 0; + this.pix_sx0 = pix_x0; + this.pix_sy0 = pix_y0; + this.y0 = tosubpixy(pix_y0); + this.x0 = tosubpixx(pix_x0); } - public void lineJoin() { - // System.out.println("Renderer: lineJoin"); - // do nothing - } + public void lineJoin() { /* do nothing */ } - public void lineTo(int x1, int y1) { - // System.out.println("Renderer: lineTo " + x1/65536.0 + " " + y1/65536.0); + public void lineTo(float pix_x1, float pix_y1) { + float x1 = tosubpixx(pix_x1); + float y1 = tosubpixy(pix_y1); // Ignore horizontal lines - // Next line will count flip if (y0 == y1) { this.x0 = x1; return; } - int orientation = (y0 < y1) ? 1 : -1; - if (lastOrientation == 0) { - firstOrientation = orientation; - } else if (orientation != lastOrientation) { - ++flips; - } - lastOrientation = orientation; - - // Bias Y by 1 ULP so endpoints never lie on a scanline - addEdge(x0, y0 | 0x1, x1, y1 | 0x1); + addEdge(x0, y0, x1, y1); this.x0 = x1; this.y0 = y1; } public void close() { - // System.out.println("Renderer: close"); - - int orientation = lastOrientation; - if (y0 != sy0) { - orientation = (y0 < sy0) ? 1 : -1; - } - if (orientation != firstOrientation) { - ++flips; - } - lineTo(sx0, sy0); + // lineTo expects its input in pixel coordinates. + lineTo(pix_sx0, pix_sy0); } public void end() { close(); - // System.out.println("Renderer: end"); - // do nothing - } - - // Scan convert a single edge - private void computeCrossingsForEdge(int index, - int boundsMinY, int boundsMaxY) { - int iy0 = edges[index + 1]; - int iy1 = edges[index + 3]; - - // Clip to valid Y range - int clipy0 = (iy0 > boundsMinY) ? iy0 : boundsMinY; - int clipy1 = (iy1 < boundsMaxY) ? iy1 : boundsMaxY; - - int minY = ((clipy0 + HYSTEP) & YMASK) + HYSTEP; - int maxY = ((clipy1 - HYSTEP) & YMASK) + HYSTEP; - - // IMPL_NOTE - If line falls outside the valid X range, could - // draw a vertical line instead - - // Exit if no scanlines are crossed - if (minY > maxY) { - return; - } - - // Scan convert line using a DDA approach - - int ix0 = edges[index]; - int ix1 = edges[index + 2]; - long dx = ((long) ix1) - ix0; - long dy = ((long) iy1) - iy0; - - // Compute first crossing point at y = minY - int orientation = edges[index + 4]; - int y = minY; - long lx = (((long) y) - iy0)*dx/dy + ix0; - addCrossing(y >> YSHIFT, (int)(lx >> XSHIFT), orientation); - - // Advance y to next scanline, exit if past endpoint - y += YSTEP; - if (y > maxY) { - return; - } - - // Compute xstep only if additional scanlines are crossed - // For each scanline, add xstep to lx and YSTEP to y and - // emit the new crossing - long xstep = ((long)YSTEP*dx)/dy; - for (; y <= maxY; y += YSTEP) { - lx += xstep; - addCrossing(y >> YSHIFT, (int)(lx >> XSHIFT), orientation); - } - } - - private void computeBounds() { - rasterMinX = crossingMinX & ~SUBPIXEL_MASK_X; - rasterMaxX = crossingMaxX | SUBPIXEL_MASK_X; - rasterMinY = crossingMinY & ~SUBPIXEL_MASK_Y; - rasterMaxY = crossingMaxY | SUBPIXEL_MASK_Y; - - // If nothing was drawn, we have: - // minX = Integer.MAX_VALUE and maxX = Integer.MIN_VALUE - // so nothing to render - if (rasterMinX > rasterMaxX || rasterMinY > rasterMaxY) { - rasterMinX = 0; - rasterMaxX = -1; - rasterMinY = 0; - rasterMaxY = -1; - return; - } - - if (rasterMinX < boundsMinX >> XSHIFT) { - rasterMinX = boundsMinX >> XSHIFT; - } - if (rasterMinY < boundsMinY >> YSHIFT) { - rasterMinY = boundsMinY >> YSHIFT; - } - if (rasterMaxX > boundsMaxX >> XSHIFT) { - rasterMaxX = boundsMaxX >> XSHIFT; - } - if (rasterMaxY > boundsMaxY >> YSHIFT) { - rasterMaxY = boundsMaxY >> YSHIFT; - } - } - - private int clamp(int x, int min, int max) { - if (x < min) { - return min; - } else if (x > max) { - return max; - } - return x; } private void _endRendering() { - if (flips == 0) { - bboxX0 = bboxY0 = 0; - bboxX1 = bboxY1 = -1; - return; - } + // Mask to determine the relevant bit of the crossing sum + // 0x1 if EVEN_ODD, all bits if NON_ZERO + int mask = (windingRule == WIND_EVEN_ODD) ? 0x1 : ~0x0; + + // add 1 to better deal with the last pixel in a pixel row. + int width = ((boundsMaxX - boundsMinX) >> SUBPIXEL_LG_POSITIONS_X) + 1; + byte[] alpha = new byte[width+1]; - // Special case for filling a single rect with a flat, opaque color - // REMIND: This special case was not originally written to fill a - // cache object and called directly to a Blit - it needs some code - // to fill the cache instead to be useful for this usage... - if (false /* Does not work with cache (yet?) */ && - edgeIdx == 10 && - edges[0] == edges[2] && - edges[1] == edges[6] && - edges[3] == edges[8] && - edges[5] == edges[7] && - Math.abs(edges[0] - edges[5]) > MIN_QUAD_OPT_WIDTH) - { + // Now we iterate through the scanlines. We must tell emitRow the coord + // of the first non-transparent pixel, so we must keep accumulators for + // the first and last pixels of the section of the current pixel row + // that we will emit. + // We also need to accumulate pix_bbox*, but the iterator does it + // for us. We will just get the values from it once this loop is done + int pix_maxX = Integer.MIN_VALUE; + int pix_minX = Integer.MAX_VALUE; - int x0 = edges[0] >> XSHIFT; - int y0 = edges[1] >> YSHIFT; - int x1 = edges[5] >> XSHIFT; - int y1 = edges[3] >> YSHIFT; + int y = boundsMinY; // needs to be declared here so we emit the last row properly. + ScanLineItInitialize(); + for ( ; ScanLineItHasNext(); ) { + int numCrossings = ScanLineItGoToNextYAndComputeCrossings(); + y = ScanLineItCurrentY(); - if (x0 > x1) { - int tmp = x0; - x0 = x1; - x1 = tmp; - } - if (y0 > y1) { - int tmp = y0; - y0 = y1; - y1 = tmp; + if (numCrossings > 0) { + int lowx = crossings[0] >> 1; + int highx = crossings[numCrossings - 1] >> 1; + int x0 = Math.max(lowx, boundsMinX); + int x1 = Math.min(highx, boundsMaxX); + + pix_minX = Math.min(pix_minX, x0 >> SUBPIXEL_LG_POSITIONS_X); + pix_maxX = Math.max(pix_maxX, x1 >> SUBPIXEL_LG_POSITIONS_X); } - int bMinX = this.boundsMinX >> XSHIFT; - int bMinY = this.boundsMinY >> YSHIFT; - int bMaxX = this.boundsMaxX >> XSHIFT; - int bMaxY = this.boundsMaxY >> YSHIFT; + int sum = 0; + int prev = boundsMinX; + for (int i = 0; i < numCrossings; i++) { + int curxo = crossings[i]; + int curx = curxo >> 1; + int crorientation = ((curxo & 0x1) == 0x1) ? 1 : -1; + if ((sum & mask) != 0) { + int x0 = Math.max(prev, boundsMinX); + int x1 = Math.min(curx, boundsMaxX); + if (x0 < x1) { + x0 -= boundsMinX; // turn x0, x1 from coords to indeces + x1 -= boundsMinX; // in the alpha array. - // Clip to image bounds in supersampled coordinates - x0 = clamp(x0, bMinX, bMaxX); - x1 = clamp(x1, bMinX, bMaxX); - y0 = clamp(y0, bMinY, bMaxY); - y1 = clamp(y1, bMinY, bMaxY); + int pix_x = x0 >> SUBPIXEL_LG_POSITIONS_X; + int pix_xmaxm1 = (x1 - 1) >> SUBPIXEL_LG_POSITIONS_X; - /* - * REMIND: Need to fill the cache here instead... - Blit.fillRectSrcOver(this, - imageData, imageType, - imageOffset, - imageScanlineStride, imagePixelStride, - width, height, - x0, y0, x1, y1, - cred, cgreen, cblue); - */ + if (pix_x == pix_xmaxm1) { + // Start and end in same pixel + alpha[pix_x] += (x1 - x0); + alpha[pix_x+1] -= (x1 - x0); + } else { + int pix_xmax = x1 >> SUBPIXEL_LG_POSITIONS_X; + alpha[pix_x] += SUBPIXEL_POSITIONS_X - (x0 & SUBPIXEL_MASK_X); + alpha[pix_x+1] += (x0 & SUBPIXEL_MASK_X); + alpha[pix_xmax] -= SUBPIXEL_POSITIONS_X - (x1 & SUBPIXEL_MASK_X); + alpha[pix_xmax+1] -= (x1 & SUBPIXEL_MASK_X); + } + } + } + sum += crorientation; + prev = curx; + } - bboxX0 = x0 >> SUBPIXEL_LG_POSITIONS_X; - bboxY0 = y0 >> SUBPIXEL_LG_POSITIONS_Y; - bboxX1 = (x1 + SUBPIXEL_POSITIONS_X - 1) - >> SUBPIXEL_LG_POSITIONS_X; - bboxY1 = (y1 + SUBPIXEL_POSITIONS_Y - 1) - >> SUBPIXEL_LG_POSITIONS_Y; - - return; - } - - int minY = (edgeMinY > boundsMinY) ? edgeMinY : boundsMinY; - int maxY = (edgeMaxY < boundsMaxY) ? edgeMaxY : boundsMaxY; - - // Check for empty intersection of primitive with the drawing area - if (minY > maxY) { - bboxX0 = bboxY0 = 0; - bboxX1 = bboxY1 = -1; - return; + if ((y & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) { + emitRow(alpha, y >> SUBPIXEL_LG_POSITIONS_Y, pix_minX, pix_maxX); + pix_minX = Integer.MAX_VALUE; + pix_maxX = Integer.MIN_VALUE; + } } - // Compute Y extent in subpixel coordinates - int iminY = (minY >> YSHIFT) & ~SUBPIXEL_MASK_Y; - int imaxY = (maxY >> YSHIFT) | SUBPIXEL_MASK_Y; - int yextent = (imaxY - iminY) + 1; - - // Maximum number of crossings - int size = flips*yextent; - - int bmax = (boundsMaxY >> YSHIFT) - 1; - if (imaxY > bmax) { - imaxY = bmax; + // Emit final row + if (pix_maxX >= pix_minX) { + emitRow(alpha, y >> SUBPIXEL_LG_POSITIONS_Y, pix_minX, pix_maxX); } - - // Initialize X bounds, will be refined for each strip - bboxX0 = Integer.MAX_VALUE; - bboxX1 = Integer.MIN_VALUE; - - // Set Y bounds - bboxY0 = iminY >> SUBPIXEL_LG_POSITIONS_Y; - bboxY1 = (imaxY + SUBPIXEL_POSITIONS_Y - 1) >> SUBPIXEL_LG_POSITIONS_Y; - - // Compute number of rows that can be processing using - // a crossings table no larger than DEFAULT_CROSSINGS_SIZE. - // However, we must process at least one row, so we grow the table - // temporarily if needed. This would require an object with a - // huge number of flips. - int rows = DEFAULT_CROSSINGS_SIZE/(flips*SUBPIXEL_POSITIONS_Y); - rows = Math.min(rows, yextent); - rows = Math.max(rows, 1); - for (int i = iminY; i <= imaxY; i += rows*SUBPIXEL_POSITIONS_Y) { - // Compute index of last scanline to be processed in this pass - int last = Math.min(i + rows*SUBPIXEL_POSITIONS_Y - 1, imaxY); - setCrossingsExtents(i, last, flips); - - int bminY = i << YSHIFT; - int bmaxY = (last << YSHIFT) | ~YMASK; + pix_bboxX0 = minX >> SUBPIXEL_LG_POSITIONS_X; + pix_bboxX1 = maxX >> SUBPIXEL_LG_POSITIONS_X; + pix_bboxY0 = minY >> SUBPIXEL_LG_POSITIONS_Y; + pix_bboxY1 = maxY >> SUBPIXEL_LG_POSITIONS_Y; + } - // Process edges from the edge list - int maxIdx = edgeIdx; - for (int index = 0; index < maxIdx; index += 5) { - // Test y1 < min: - // - // If edge lies entirely above current strip, - // discard it - if (edges[index + 3] < bminY) { - // Overwrite the edge with the last edge - edgeIdx -= 5; - int fidx = edgeIdx; - int tidx = index; - edges[tidx++] = edges[fidx++]; - edges[tidx++] = edges[fidx++]; - edges[tidx++] = edges[fidx++]; - edges[tidx++] = edges[fidx++]; - edges[tidx ] = edges[fidx ]; - - maxIdx -= 5; - index -= 5; - continue; - } - - // Test y0 > max: - // - // If edge lies entirely below current strip, - // skip it for now - if (edges[index + 1] > bmaxY) { - continue; - } - - computeCrossingsForEdge(index, bminY, bmaxY); - } - - computeBounds(); - if (rasterMaxX < rasterMinX) { - continue; - } - - bboxX0 = Math.min(bboxX0, - rasterMinX >> SUBPIXEL_LG_POSITIONS_X); - bboxX1 = Math.max(bboxX1, - (rasterMaxX + SUBPIXEL_POSITIONS_X - 1) - >> SUBPIXEL_LG_POSITIONS_X); - renderStrip(); - } - - // Free up any unusually large scratchpad memory used by the - // preceding primitive - crossingListFinished(); - } public void endRendering() { // Set up the cache to accumulate the bounding box @@ -478,176 +472,31 @@ _endRendering(); } - public void getBoundingBox(int[] bbox) { - bbox[0] = bboxX0; - bbox[1] = bboxY0; - bbox[2] = bboxX1 - bboxX0; - bbox[3] = bboxY1 - bboxY0; + public void getBoundingBox(int[] pix_bbox) { + pix_bbox[0] = pix_bboxX0; + pix_bbox[1] = pix_bboxY0; + pix_bbox[2] = pix_bboxX1 - pix_bboxX0; + pix_bbox[3] = pix_bboxY1 - pix_bboxY0; } - private void renderStrip() { - // Grow rowAA according to the raster width - int width = (rasterMaxX - rasterMinX + 1) >> SUBPIXEL_LG_POSITIONS_X; - alphaWidth = width; - - // Allocate one extra entry in rowAA to avoid a conditional in - // the rendering loop - int bufLen = width + 1; - if (this.rowAA == null || this.rowAA.length < bufLen) { - this.rowAA = new byte[bufLen]; - } - - // Mask to determine the relevant bit of the crossing sum - // 0x1 if EVEN_ODD, all bits if NON_ZERO - int mask = (windingRule == WIND_EVEN_ODD) ? 0x1 : ~0x0; - - int y = 0; - int prevY = rasterMinY - 1; - - int minX = Integer.MAX_VALUE; - int maxX = Integer.MIN_VALUE; - - iterateCrossings(); - while (hasMoreCrossingRows()) { - y = crossingY; - - // Emit any skipped rows - for (int j = prevY + 1; j < y; j++) { - if (((j & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) || - (j == rasterMaxY)) { - emitRow(j >> SUBPIXEL_LG_POSITIONS_Y, 0, -1); - } - } - prevY = y; - - if (crossingRowIndex < crossingRowCount) { - int lx = crossings[crossingRowOffset + crossingRowIndex]; - lx >>= 1; - int hx = crossings[crossingRowOffset + crossingRowCount - 1]; - hx >>= 1; - int x0 = lx > rasterMinX ? lx : rasterMinX; - int x1 = hx < rasterMaxX ? hx : rasterMaxX; - x0 -= rasterMinX; - x1 -= rasterMinX; - - minX = Math.min(minX, x0 >> SUBPIXEL_LG_POSITIONS_X); - maxX = Math.max(maxX, x1 >> SUBPIXEL_LG_POSITIONS_X); - } - - int sum = 0; - int prev = rasterMinX; - while (crossingRowIndex < crossingRowCount) { - int crxo = crossings[crossingRowOffset + crossingRowIndex]; - crossingRowIndex++; - - int crx = crxo >> 1; - int crorientation = ((crxo & 0x1) == 0x1) ? 1 : -1; - - if ((sum & mask) != 0) { - // Clip to active X range, if x1 < x0 loop will - // have no effect - int x0 = prev > rasterMinX ? prev : rasterMinX; - int x1 = crx < rasterMaxX ? crx : rasterMaxX; - - // Empty spans - if (x1 > x0) { - x0 -= rasterMinX; - x1 -= rasterMinX; - - // Accumulate alpha, equivalent to: - // for (int x = x0; x < x1; x++) { - // ++rowAA[x >> SUBPIXEL_LG_POSITIONS_X]; - // } - // - // In the middle of the span, we can update a full - // pixel at a time (i.e., SUBPIXEL_POSITIONS_X - // subpixels) - - int x = x0 >> SUBPIXEL_LG_POSITIONS_X; - int xmaxm1 = (x1 - 1) >> SUBPIXEL_LG_POSITIONS_X; - if (x == xmaxm1) { - // Start and end in same pixel - rowAA[x] += x1 - x0; - } else { - // Start and end in different pixels - rowAA[x++] += SUBPIXEL_POSITIONS_X - - (x0 & SUBPIXEL_MASK_X); - int xmax = x1 >> SUBPIXEL_LG_POSITIONS_X; - while (x < xmax) { - rowAA[x++] += SUBPIXEL_POSITIONS_X; - } - // Note - at this point it is possible that - // x == width, which implies that - // x1 & SUBPIXEL_MASK_X == 0. We allocate - // one extra entry in rowAA so this - // assignment will be harmless. The alternative - // is an extra conditional here, or some other - // scheme to deal with the last pixel better. - rowAA[x] += x1 & SUBPIXEL_MASK_X; - } - } - } - sum += crorientation; - prev = crx; - } - - // Every SUBPIXEL_POSITIONS rows, output an antialiased row - if (((y & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) || - (y == rasterMaxY)) { - emitRow(y >> SUBPIXEL_LG_POSITIONS_Y, minX, maxX); - minX = Integer.MAX_VALUE; - maxX = Integer.MIN_VALUE; - } - } - - // Emit final row - for (int j = prevY + 1; j <= rasterMaxY; j++) { - if (((j & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) || - (j == rasterMaxY)) { - emitRow(j >> SUBPIXEL_LG_POSITIONS_Y, minX, maxX); - minX = Integer.MAX_VALUE; - maxX = Integer.MIN_VALUE; - } - } - } - - private void clearAlpha(byte[] alpha, - int width, - int minX, int maxX) { - if (maxX >= minX) { - int w = maxX - minX + 1; - if (w + minX > width) { - w = width - minX; - } - - int aidx = minX; - for (int i = 0; i < w; i++, aidx++) { - alpha[aidx] = (byte)0; - } - } - } - - private void emitRow(int y, int minX, int maxX) { + private void emitRow(byte[] alphaRow, int pix_y, int pix_from, int pix_to) { // Copy rowAA data into the cache if one is present if (cache != null) { - if (maxX >= minX) { - int x0 = minX + (rasterMinX >> SUBPIXEL_LG_POSITIONS_X); - int x1 = maxX + (rasterMinX >> SUBPIXEL_LG_POSITIONS_X); + if (pix_to >= pix_from) { + cache.startRow(pix_y, pix_from, pix_to); - cache.startRow(y, x0, x1); - int srcIdx = minX; + // Perform run-length encoding and store results in the cache + int from = pix_from - (boundsMinX >> SUBPIXEL_LG_POSITIONS_X); + int to = pix_to - (boundsMinX >> SUBPIXEL_LG_POSITIONS_X); - // Perform run-length encoding - // and store results in the cache - byte startVal = rowAA[srcIdx++]; int runLen = 1; - while (srcIdx <= maxX) { - byte nextVal = rowAA[srcIdx++]; + byte startVal = alphaRow[from]; + for (int i = from + 1; i <= to; i++) { + byte nextVal = (byte)(startVal + alphaRow[i]); if (nextVal == startVal && runLen < 255) { - ++runLen; + runLen++; } else { cache.addRLERun(startVal, runLen); - runLen = 1; startVal = nextVal; } @@ -656,190 +505,6 @@ cache.addRLERun((byte)0, 0); } } - - clearAlpha(rowAA, - alphaWidth, - minX, maxX); - } - - public void setCache(PiscesCache cache) { - this.cache = cache; - } - - // Edge list data - - private int[] edges = new int[5*INITIAL_EDGES]; - private int edgeIdx = 0; - private int edgeMinY = Integer.MAX_VALUE; - private int edgeMaxY = Integer.MIN_VALUE; - - private void addEdge(int x0, int y0, int x1, int y1) { - int newLen = edgeIdx + 5; - if (edges.length < newLen) { - int[] tmp = new int[Math.max(11*edges.length/10, newLen)]; - System.arraycopy(edges, 0, tmp, 0, edgeIdx); - this.edges = tmp; - } - - int orientation = 1; - if (y0 > y1) { - int tmp = y0; - y0 = y1; - y1 = tmp; - - orientation = -1; - } - - // Skip edges that don't cross a subsampled scanline - int eminY = ((y0 + HYSTEP) & YMASK); - int emaxY = ((y1 - HYSTEP) & YMASK); - if (eminY > emaxY) { - return; - } - - if (orientation == -1) { - int tmp = x0; - x0 = x1; - x1 = tmp; - } - - edges[edgeIdx++] = x0; - edges[edgeIdx++] = y0; - edges[edgeIdx++] = x1; - edges[edgeIdx++] = y1; - edges[edgeIdx++] = orientation; - - // Update Y bounds of primitive - if (y0 < edgeMinY) { - edgeMinY = y0; - } - if (y1 > edgeMaxY) { - edgeMaxY = y1; - } - } - - private void resetEdges() { - this.edgeIdx = 0; - this.edgeMinY = Integer.MAX_VALUE; - this.edgeMaxY = Integer.MIN_VALUE; - } - - // Crossing list data - - private int[] crossingIndices; - private int[] crossings; - private int crossingMinY; - private int crossingMaxY; - private int crossingMinX = Integer.MAX_VALUE; - private int crossingMaxX = Integer.MIN_VALUE; - private int crossingMaxXEntries; - private int numCrossings = 0; - private boolean crossingsSorted = false; - - private int crossingY; - private int crossingRowCount; - private int crossingRowOffset; - private int crossingRowIndex; - - private void setCrossingsExtents(int minY, int maxY, int maxXEntries) { - int yextent = maxY - minY + 1; - - // Grow indices array as needed - if (crossingIndices == null || crossingIndices.length < yextent) { - this.crossingIndices = - new int[Math.max(yextent, DEFAULT_INDICES_SIZE)]; - } - // Grow crossings array as needed - if (crossings == null || crossings.length < yextent*maxXEntries) { - this.crossings = new int[Math.max(yextent*maxXEntries, - DEFAULT_CROSSINGS_SIZE)]; - } - this.crossingMinY = minY; - this.crossingMaxY = maxY; - this.crossingMaxXEntries = maxXEntries; - resetCrossings(); - } - - private void resetCrossings() { - int yextent = crossingMaxY - crossingMinY + 1; - int start = 0; - for (int i = 0; i < yextent; i++) { - crossingIndices[i] = start; - start += crossingMaxXEntries; - } - crossingMinX = Integer.MAX_VALUE; - crossingMaxX = Integer.MIN_VALUE; - numCrossings = 0; - crossingsSorted = false; - } - - // Free sorting arrays if larger than maximum size - private void crossingListFinished() { - if (crossings != null && crossings.length > DEFAULT_CROSSINGS_SIZE) { - crossings = new int[DEFAULT_CROSSINGS_SIZE]; - } - if (crossingIndices != null && - crossingIndices.length > DEFAULT_INDICES_SIZE) - { - crossingIndices = new int[DEFAULT_INDICES_SIZE]; - } - } - - private void sortCrossings(int[] x, int off, int len) { - for (int i = off + 1; i < off + len; i++) { - int j = i; - int xj = x[j]; - int xjm1; - - while (j > off && (xjm1 = x[j - 1]) > xj) { - x[j] = xjm1; - x[j - 1] = xj; - j--; - } - } - } - - private void sortCrossings() { - int start = 0; - for (int i = 0; i <= crossingMaxY - crossingMinY; i++) { - sortCrossings(crossings, start, crossingIndices[i] - start); - start += crossingMaxXEntries; - } - } - - private void addCrossing(int y, int x, int orientation) { - if (x < crossingMinX) { - crossingMinX = x; - } - if (x > crossingMaxX) { - crossingMaxX = x; - } - - int index = crossingIndices[y - crossingMinY]++; - x <<= 1; - crossings[index] = (orientation == 1) ? (x | 0x1) : x; - - ++numCrossings; - } - - private void iterateCrossings() { - if (!crossingsSorted) { - sortCrossings(); - crossingsSorted = true; - } - crossingY = crossingMinY - 1; - crossingRowOffset = -crossingMaxXEntries; - } - - private boolean hasMoreCrossingRows() { - if (++crossingY <= crossingMaxY) { - crossingRowOffset += crossingMaxXEntries; - int y = crossingY - crossingMinY; - crossingRowCount = crossingIndices[y] - y*crossingMaxXEntries; - crossingRowIndex = 0; - return true; - } else { - return false; - } + java.util.Arrays.fill(alphaRow, (byte)0); } }
--- a/jdk/src/share/classes/sun/java2d/pisces/Stroker.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/pisces/Stroker.java Sun Aug 29 22:41:28 2010 -0700 @@ -25,7 +25,7 @@ package sun.java2d.pisces; -public class Stroker extends LineSink { +public class Stroker implements LineSink { private static final int MOVE_TO = 0; private static final int LINE_TO = 1; @@ -61,19 +61,15 @@ */ public static final int CAP_SQUARE = 2; - LineSink output; + private final LineSink output; - int lineWidth; - int capStyle; - int joinStyle; - int miterLimit; + private final int capStyle; + private final int joinStyle; - Transform4 transform; - int m00, m01; - int m10, m11; + private final float m00, m01, m10, m11, det; - int lineWidth2; - long scaledLineWidth2; + private final float lineWidth2; + private final float scaledLineWidth2; // For any pen offset (pen_dx, pen_dy) that does not depend on // the line orientation, the pen should be transformed so that: @@ -88,143 +84,86 @@ // // pen_dx'(r, theta) = r*(m00*cos(theta) + m01*sin(theta)) // pen_dy'(r, theta) = r*(m10*cos(theta) + m11*sin(theta)) - int numPenSegments; - int[] pen_dx; - int[] pen_dy; - boolean[] penIncluded; - int[] join; + private int numPenSegments; + private final float[] pen_dx; + private final float[] pen_dy; + private boolean[] penIncluded; + private final float[] join; - int[] offset = new int[2]; - int[] reverse = new int[100]; - int[] miter = new int[2]; - long miterLimitSq; + private final float[] offset = new float[2]; + private float[] reverse = new float[100]; + private final float[] miter = new float[2]; + private final float miterLimitSq; - int prev; - int rindex; - boolean started; - boolean lineToOrigin; - boolean joinToOrigin; - - int sx0, sy0, sx1, sy1, x0, y0, x1, y1; - int mx0, my0, mx1, my1, omx, omy; - int lx0, ly0, lx1, ly1, lx0p, ly0p, px0, py0; + private int prev; + private int rindex; + private boolean started; + private boolean lineToOrigin; + private boolean joinToOrigin; - double m00_2_m01_2; - double m10_2_m11_2; - double m00_m10_m01_m11; + private float sx0, sy0, sx1, sy1, x0, y0, px0, py0; + private float mx0, my0, omx, omy; - /** - * Empty constructor. <code>setOutput</code> and - * <code>setParameters</code> must be called prior to calling any - * other methods. - */ - public Stroker() {} + private float m00_2_m01_2; + private float m10_2_m11_2; + private float m00_m10_m01_m11; /** * Constructs a <code>Stroker</code>. * * @param output an output <code>LineSink</code>. - * @param lineWidth the desired line width in pixels, in S15.16 - * format. + * @param lineWidth the desired line width in pixels * @param capStyle the desired end cap style, one of * <code>CAP_BUTT</code>, <code>CAP_ROUND</code> or * <code>CAP_SQUARE</code>. * @param joinStyle the desired line join style, one of * <code>JOIN_MITER</code>, <code>JOIN_ROUND</code> or * <code>JOIN_BEVEL</code>. - * @param miterLimit the desired miter limit, in S15.16 format. + * @param miterLimit the desired miter limit * @param transform a <code>Transform4</code> object indicating * the transform that has been previously applied to all incoming * coordinates. This is required in order to produce consistently * shaped end caps and joins. */ public Stroker(LineSink output, - int lineWidth, + float lineWidth, int capStyle, int joinStyle, - int miterLimit, - Transform4 transform) { - setOutput(output); - setParameters(lineWidth, capStyle, joinStyle, miterLimit, transform); - } - - /** - * Sets the output <code>LineSink</code> of this - * <code>Stroker</code>. - * - * @param output an output <code>LineSink</code>. - */ - public void setOutput(LineSink output) { + float miterLimit, + float m00, float m01, float m10, float m11) { this.output = output; - } - /** - * Sets the parameters of this <code>Stroker</code>. - * @param lineWidth the desired line width in pixels, in S15.16 - * format. - * @param capStyle the desired end cap style, one of - * <code>CAP_BUTT</code>, <code>CAP_ROUND</code> or - * <code>CAP_SQUARE</code>. - * @param joinStyle the desired line join style, one of - * <code>JOIN_MITER</code>, <code>JOIN_ROUND</code> or - * <code>JOIN_BEVEL</code>. - * @param miterLimit the desired miter limit, in S15.16 format. - * @param transform a <code>Transform4</code> object indicating - * the transform that has been previously applied to all incoming - * coordinates. This is required in order to produce consistently - * shaped end caps and joins. - */ - public void setParameters(int lineWidth, - int capStyle, - int joinStyle, - int miterLimit, - Transform4 transform) { - this.lineWidth = lineWidth; - this.lineWidth2 = lineWidth >> 1; - this.scaledLineWidth2 = ((long)transform.m00*lineWidth2) >> 16; + this.lineWidth2 = lineWidth / 2; + this.scaledLineWidth2 = m00 * lineWidth2; this.capStyle = capStyle; this.joinStyle = joinStyle; - this.miterLimit = miterLimit; - this.transform = transform; - this.m00 = transform.m00; - this.m01 = transform.m01; - this.m10 = transform.m10; - this.m11 = transform.m11; - - this.m00_2_m01_2 = (double)m00*m00 + (double)m01*m01; - this.m10_2_m11_2 = (double)m10*m10 + (double)m11*m11; - this.m00_m10_m01_m11 = (double)m00*m10 + (double)m01*m11; + m00_2_m01_2 = m00*m00 + m01*m01; + m10_2_m11_2 = m10*m10 + m11*m11; + m00_m10_m01_m11 = m00*m10 + m01*m11; - double dm00 = m00/65536.0; - double dm01 = m01/65536.0; - double dm10 = m10/65536.0; - double dm11 = m11/65536.0; - double determinant = dm00*dm11 - dm01*dm10; + this.m00 = m00; + this.m01 = m01; + this.m10 = m10; + this.m11 = m11; + det = m00*m11 - m01*m10; - if (joinStyle == JOIN_MITER) { - double limit = - (miterLimit/65536.0)*(lineWidth2/65536.0)*determinant; - double limitSq = limit*limit; - this.miterLimitSq = (long)(limitSq*65536.0*65536.0); - } + float limit = miterLimit * lineWidth2 * det; + this.miterLimitSq = limit*limit; - this.numPenSegments = (int)(3.14159f*lineWidth/65536.0f); - if (pen_dx == null || pen_dx.length < numPenSegments) { - this.pen_dx = new int[numPenSegments]; - this.pen_dy = new int[numPenSegments]; - this.penIncluded = new boolean[numPenSegments]; - this.join = new int[2*numPenSegments]; - } + this.numPenSegments = (int)(3.14159f * lineWidth); + this.pen_dx = new float[numPenSegments]; + this.pen_dy = new float[numPenSegments]; + this.penIncluded = new boolean[numPenSegments]; + this.join = new float[2*numPenSegments]; for (int i = 0; i < numPenSegments; i++) { - double r = lineWidth/2.0; - double theta = (double)i*2.0*Math.PI/numPenSegments; + double theta = (i * 2.0 * Math.PI)/numPenSegments; double cos = Math.cos(theta); double sin = Math.sin(theta); - pen_dx[i] = (int)(r*(dm00*cos + dm01*sin)); - pen_dy[i] = (int)(r*(dm10*cos + dm11*sin)); + pen_dx[i] = (float)(lineWidth2 * (m00*cos + m01*sin)); + pen_dy[i] = (float)(lineWidth2 * (m10*cos + m11*sin)); } prev = CLOSE; @@ -233,32 +172,31 @@ lineToOrigin = false; } - private void computeOffset(int x0, int y0, int x1, int y1, int[] m) { - long lx = (long)x1 - (long)x0; - long ly = (long)y1 - (long)y0; + private void computeOffset(float x0, float y0, + float x1, float y1, float[] m) { + float lx = x1 - x0; + float ly = y1 - y0; - int dx, dy; + float dx, dy; if (m00 > 0 && m00 == m11 && m01 == 0 & m10 == 0) { - long ilen = PiscesMath.hypot(lx, ly); + float ilen = (float)Math.hypot(lx, ly); if (ilen == 0) { dx = dy = 0; } else { - dx = (int)( (ly*scaledLineWidth2)/ilen); - dy = (int)(-(lx*scaledLineWidth2)/ilen); + dx = (ly * scaledLineWidth2)/ilen; + dy = -(lx * scaledLineWidth2)/ilen; } } else { - double dlx = x1 - x0; - double dly = y1 - y0; - double det = (double)m00*m11 - (double)m01*m10; int sdet = (det > 0) ? 1 : -1; - double a = dly*m00 - dlx*m10; - double b = dly*m01 - dlx*m11; - double dh = PiscesMath.hypot(a, b); - double div = sdet*lineWidth2/(65536.0*dh); - double ddx = dly*m00_2_m01_2 - dlx*m00_m10_m01_m11; - double ddy = dly*m00_m10_m01_m11 - dlx*m10_2_m11_2; - dx = (int)(ddx*div); - dy = (int)(ddy*div); + float a = ly * m00 - lx * m10; + float b = ly * m01 - lx * m11; + float dh = (float)Math.hypot(a, b); + float div = sdet * lineWidth2/dh; + + float ddx = ly * m00_2_m01_2 - lx * m00_m10_m01_m11; + float ddy = ly * m00_m10_m01_m11 - lx * m10_2_m11_2; + dx = ddx*div; + dy = ddy*div; } m[0] = dx; @@ -267,58 +205,43 @@ private void ensureCapacity(int newrindex) { if (reverse.length < newrindex) { - int[] tmp = new int[Math.max(newrindex, 6*reverse.length/5)]; - System.arraycopy(reverse, 0, tmp, 0, rindex); - this.reverse = tmp; + reverse = java.util.Arrays.copyOf(reverse, 6*reverse.length/5); } } - private boolean isCCW(int x0, int y0, - int x1, int y1, - int x2, int y2) { - int dx0 = x1 - x0; - int dy0 = y1 - y0; - int dx1 = x2 - x1; - int dy1 = y2 - y1; - return (long)dx0*dy1 < (long)dy0*dx1; + private boolean isCCW(float x0, float y0, + float x1, float y1, + float x2, float y2) { + return (x1 - x0) * (y2 - y1) < (y1 - y0) * (x2 - x1); } - private boolean side(int x, int y, int x0, int y0, int x1, int y1) { - long lx = x; - long ly = y; - long lx0 = x0; - long ly0 = y0; - long lx1 = x1; - long ly1 = y1; - - return (ly0 - ly1)*lx + (lx1 - lx0)*ly + (lx0*ly1 - lx1*ly0) > 0; + private boolean side(float x, float y, + float x0, float y0, + float x1, float y1) { + return (y0 - y1)*x + (x1 - x0)*y + (x0*y1 - x1*y0) > 0; } - private int computeRoundJoin(int cx, int cy, - int xa, int ya, - int xb, int yb, + private int computeRoundJoin(float cx, float cy, + float xa, float ya, + float xb, float yb, int side, boolean flip, - int[] join) { - int px, py; + float[] join) { + float px, py; int ncoords = 0; boolean centerSide; if (side == 0) { centerSide = side(cx, cy, xa, ya, xb, yb); } else { - centerSide = (side == 1) ? true : false; + centerSide = (side == 1); } for (int i = 0; i < numPenSegments; i++) { px = cx + pen_dx[i]; py = cy + pen_dy[i]; boolean penSide = side(px, py, xa, ya, xb, yb); - if (penSide != centerSide) { - penIncluded[i] = true; - } else { - penIncluded[i] = false; - } + penIncluded[i] = (penSide != centerSide); } int start = -1, end = -1; @@ -338,10 +261,10 @@ } if (start != -1 && end != -1) { - long dxa = cx + pen_dx[start] - xa; - long dya = cy + pen_dy[start] - ya; - long dxb = cx + pen_dx[start] - xb; - long dyb = cy + pen_dy[start] - yb; + float dxa = cx + pen_dx[start] - xa; + float dya = cy + pen_dy[start] - ya; + float dxb = cx + pen_dx[start] - xb; + float dyb = cy + pen_dy[start] - yb; boolean rev = (dxa*dxa + dya*dya > dxb*dxb + dyb*dyb); int i = rev ? end : start; @@ -362,22 +285,25 @@ return ncoords/2; } - private static final long ROUND_JOIN_THRESHOLD = 1000L; - private static final long ROUND_JOIN_INTERNAL_THRESHOLD = 1000000000L; + // pisces used to use fixed point arithmetic with 16 decimal digits. I + // didn't want to change the values of the constants below when I converted + // it to floating point, so that's why the divisions by 2^16 are there. + private static final float ROUND_JOIN_THRESHOLD = 1000/65536f; + private static final float ROUND_JOIN_INTERNAL_THRESHOLD = 1000000000/65536f; - private void drawRoundJoin(int x, int y, - int omx, int omy, int mx, int my, + private void drawRoundJoin(float x, float y, + float omx, float omy, float mx, float my, int side, boolean flip, boolean rev, - long threshold) { + float threshold) { if ((omx == 0 && omy == 0) || (mx == 0 && my == 0)) { return; } - long domx = (long)omx - mx; - long domy = (long)omy - my; - long len = domx*domx + domy*domy; + float domx = omx - mx; + float domy = omy - my; + float len = domx*domx + domy*domy; if (len < threshold) { return; } @@ -389,10 +315,10 @@ my = -my; } - int bx0 = x + omx; - int by0 = y + omy; - int bx1 = x + mx; - int by1 = y + my; + float bx0 = x + omx; + float by0 = y + omy; + float bx1 = x + mx; + float by1 = y + my; int npoints = computeRoundJoin(x, y, bx0, by0, bx1, by1, side, flip, @@ -404,40 +330,30 @@ // Return the intersection point of the lines (ix0, iy0) -> (ix1, iy1) // and (ix0p, iy0p) -> (ix1p, iy1p) in m[0] and m[1] - private void computeMiter(int ix0, int iy0, int ix1, int iy1, - int ix0p, int iy0p, int ix1p, int iy1p, - int[] m) { - long x0 = ix0; - long y0 = iy0; - long x1 = ix1; - long y1 = iy1; + private void computeMiter(float x0, float y0, float x1, float y1, + float x0p, float y0p, float x1p, float y1p, + float[] m) { + float x10 = x1 - x0; + float y10 = y1 - y0; + float x10p = x1p - x0p; + float y10p = y1p - y0p; - long x0p = ix0p; - long y0p = iy0p; - long x1p = ix1p; - long y1p = iy1p; - - long x10 = x1 - x0; - long y10 = y1 - y0; - long x10p = x1p - x0p; - long y10p = y1p - y0p; - - long den = (x10*y10p - x10p*y10) >> 16; + float den = x10*y10p - x10p*y10; if (den == 0) { - m[0] = ix0; - m[1] = iy0; + m[0] = x0; + m[1] = y0; return; } - long t = (x1p*(y0 - y0p) - x0*y10p + x0p*(y1p - y0)) >> 16; - m[0] = (int)(x0 + (t*x10)/den); - m[1] = (int)(y0 + (t*y10)/den); + float t = x1p*(y0 - y0p) - x0*y10p + x0p*(y1p - y0); + m[0] = x0 + (t*x10)/den; + m[1] = y0 + (t*y10)/den; } - private void drawMiter(int px0, int py0, - int x0, int y0, - int x1, int y1, - int omx, int omy, int mx, int my, + private void drawMiter(float px0, float py0, + float x0, float y0, + float x1, float y1, + float omx, float omy, float mx, float my, boolean rev) { if (mx == omx && my == omy) { return; @@ -461,11 +377,11 @@ miter); // Compute miter length in untransformed coordinates - long dx = (long)miter[0] - x0; - long dy = (long)miter[1] - y0; - long a = (dy*m00 - dx*m10) >> 16; - long b = (dy*m01 - dx*m11) >> 16; - long lenSq = a*a + b*b; + float dx = miter[0] - x0; + float dy = miter[1] - y0; + float a = dy*m00 - dx*m10; + float b = dy*m01 - dx*m11; + float lenSq = a*a + b*b; if (lenSq < miterLimitSq) { emitLineTo(miter[0], miter[1], rev); @@ -473,7 +389,7 @@ } - public void moveTo(int x0, int y0) { + public void moveTo(float x0, float y0) { // System.out.println("Stroker.moveTo(" + x0/65536.0 + ", " + y0/65536.0 + ")"); if (lineToOrigin) { @@ -501,7 +417,7 @@ this.joinSegment = true; } - public void lineTo(int x1, int y1) { + public void lineTo(float x1, float y1) { // System.out.println("Stroker.lineTo(" + x1/65536.0 + ", " + y1/65536.0 + ")"); if (lineToOrigin) { @@ -526,10 +442,10 @@ joinSegment = false; } - private void lineToImpl(int x1, int y1, boolean joinSegment) { + private void lineToImpl(float x1, float y1, boolean joinSegment) { computeOffset(x0, y0, x1, y1, offset); - int mx = offset[0]; - int my = offset[1]; + float mx = offset[0]; + float my = offset[1]; if (!started) { emitMoveTo(x0 + mx, y0 + my); @@ -567,10 +483,6 @@ emitLineTo(x0 - mx, y0 - my, true); emitLineTo(x1 - mx, y1 - my, true); - lx0 = x1 + mx; ly0 = y1 + my; - lx0p = x1 - mx; ly0p = y1 - my; - lx1 = x1; ly1 = y1; - this.omx = mx; this.omy = my; this.px0 = x0; @@ -594,8 +506,8 @@ } computeOffset(x0, y0, sx0, sy0, offset); - int mx = offset[0]; - int my = offset[1]; + float mx = offset[0]; + float my = offset[1]; // Draw penultimate join boolean ccw = isCCW(px0, py0, x0, y0, sx0, sy0); @@ -678,12 +590,10 @@ this.prev = MOVE_TO; } - long lineLength(long ldx, long ldy) { - long ldet = ((long)m00*m11 - (long)m01*m10) >> 16; - long la = ((long)ldy*m00 - (long)ldx*m10)/ldet; - long lb = ((long)ldy*m01 - (long)ldx*m11)/ldet; - long llen = (int)PiscesMath.hypot(la, lb); - return llen; + double userSpaceLineLength(double dx, double dy) { + double a = (dy*m00 - dx*m10)/det; + double b = (dy*m01 - dx*m11)/det; + return Math.hypot(a, b); } private void finish() { @@ -692,13 +602,13 @@ omx, omy, -omx, -omy, 1, false, false, ROUND_JOIN_THRESHOLD); } else if (capStyle == CAP_SQUARE) { - long ldx = (long)(px0 - x0); - long ldy = (long)(py0 - y0); - long llen = lineLength(ldx, ldy); - long s = (long)lineWidth2*65536/llen; + float dx = px0 - x0; + float dy = py0 - y0; + float len = (float)userSpaceLineLength(dx, dy); + float s = lineWidth2/len; - int capx = x0 - (int)(ldx*s >> 16); - int capy = y0 - (int)(ldy*s >> 16); + float capx = x0 - dx*s; + float capy = y0 - dy*s; emitLineTo(capx + omx, capy + omy); emitLineTo(capx - omx, capy - omy); @@ -714,13 +624,13 @@ -mx0, -my0, mx0, my0, 1, false, false, ROUND_JOIN_THRESHOLD); } else if (capStyle == CAP_SQUARE) { - long ldx = (long)(sx1 - sx0); - long ldy = (long)(sy1 - sy0); - long llen = lineLength(ldx, ldy); - long s = (long)lineWidth2*65536/llen; + float dx = sx1 - sx0; + float dy = sy1 - sy0; + float len = (float)userSpaceLineLength(dx, dy); + float s = lineWidth2/len; - int capx = sx0 - (int)(ldx*s >> 16); - int capy = sy0 - (int)(ldy*s >> 16); + float capx = sx0 - dx*s; + float capy = sy0 - dy*s; emitLineTo(capx - mx0, capy - my0); emitLineTo(capx + mx0, capy + my0); @@ -730,17 +640,17 @@ this.joinSegment = false; } - private void emitMoveTo(int x0, int y0) { + private void emitMoveTo(float x0, float y0) { // System.out.println("Stroker.emitMoveTo(" + x0/65536.0 + ", " + y0/65536.0 + ")"); output.moveTo(x0, y0); } - private void emitLineTo(int x1, int y1) { + private void emitLineTo(float x1, float y1) { // System.out.println("Stroker.emitLineTo(" + x0/65536.0 + ", " + y0/65536.0 + ")"); output.lineTo(x1, y1); } - private void emitLineTo(int x1, int y1, boolean rev) { + private void emitLineTo(float x1, float y1, boolean rev) { if (rev) { ensureCapacity(rindex + 2); reverse[rindex++] = x1; @@ -755,3 +665,4 @@ output.close(); } } +
--- a/jdk/src/share/classes/sun/java2d/pisces/Transform4.java Wed Jul 05 17:20:50 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.java2d.pisces; - -public class Transform4 { - - public int m00, m01, m10, m11; -// double det; // det*65536 - - public Transform4() { - this(1 << 16, 0, 0, 1 << 16); - } - - public Transform4(int m00, int m01, - int m10, int m11) { - this.m00 = m00; - this.m01 = m01; - this.m10 = m10; - this.m11 = m11; - -// this.det = (double)m00*m11 - (double)m01*m10; - } - -// public Transform4 createInverse() { -// double dm00 = m00/65536.0; -// double dm01 = m01/65536.0; -// double dm10 = m10/65536.0; -// double dm11 = m11/65536.0; - -// double invdet = 65536.0/(dm00*dm11 - dm01*dm10); - -// int im00 = (int)( dm11*invdet); -// int im01 = (int)(-dm01*invdet); -// int im10 = (int)(-dm10*invdet); -// int im11 = (int)( dm00*invdet); - -// return new Transform4(im00, im01, im10, im11); -// } - -// public void transform(int[] point) { -// } - -// /** -// * Returns the length of the line segment obtained by inverse -// * transforming the points <code>(x0, y0)</code> and <code>(x1, -// * y1)</code>. -// */ -// public int getTransformedLength(int x0, int x1, int y0, int y1) { -// int lx = x1 - x0; -// int ly = y1 - y0; - -// double a = (double)m00*ly - (double)m10*lx; -// double b = (double)m01*ly - (double)m11*lx; -// double len = PiscesMath.sqrt((a*a + b*b)/(det*det)); -// return (int)(len*65536.0); -// } - -// public int getType() { -// } - -}
--- a/jdk/src/share/classes/sun/net/www/protocol/file/FileURLConnection.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/net/www/protocol/file/FileURLConnection.java Sun Aug 29 22:41:28 2010 -0700 @@ -59,7 +59,7 @@ String filename; boolean isDirectory = false; boolean exists = false; - List files; + List<String> files; long length = -1; long lastModified = 0; @@ -81,7 +81,10 @@ filename = file.toString(); isDirectory = file.isDirectory(); if (isDirectory) { - files = (List) Arrays.asList(file.list()); + String[] fileList = file.list(); + if (fileList == null) + throw new FileNotFoundException(filename + " exists, but is not accessible"); + files = Arrays.<String>asList(fileList); } else { is = new BufferedInputStream(new FileInputStream(filename)); @@ -197,7 +200,7 @@ Collections.sort(files, Collator.getInstance()); for (int i = 0 ; i < files.size() ; i++) { - String fileName = (String)files.get(i); + String fileName = files.get(i); buf.append(fileName); buf.append("\n"); }
--- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Sun Aug 29 22:41:28 2010 -0700 @@ -1768,6 +1768,10 @@ // Not really necessary for a tunnel, but can't hurt requests.setIfNotSet("Accept", acceptString); + if (http.getHttpKeepAliveSet()) { + requests.setIfNotSet("Proxy-Connection", "keep-alive"); + } + setPreemptiveProxyAuthentication(requests); /* Log the CONNECT request */
--- a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Sun Aug 29 22:41:28 2010 -0700 @@ -536,9 +536,11 @@ } } - private long read0(ByteBuffer[] bufs) throws IOException { - if (bufs == null) - throw new NullPointerException(); + public long read(ByteBuffer[] dsts, int offset, int length) + throws IOException + { + if ((offset < 0) || (length < 0) || (offset > dsts.length - length)) + throw new IndexOutOfBoundsException(); synchronized (readLock) { synchronized (stateLock) { ensureOpen(); @@ -552,7 +554,7 @@ return 0; readerThread = NativeThread.current(); do { - n = IOUtil.read(fd, bufs, nd); + n = IOUtil.read(fd, dsts, offset, length, nd); } while ((n == IOStatus.INTERRUPTED) && isOpen()); return IOStatus.normalize(n); } finally { @@ -563,15 +565,6 @@ } } - public long read(ByteBuffer[] dsts, int offset, int length) - throws IOException - { - if ((offset < 0) || (length < 0) || (offset > dsts.length - length)) - throw new IndexOutOfBoundsException(); - // ## Fix IOUtil.write so that we can avoid this array copy - return read0(Util.subsequence(dsts, offset, length)); - } - public int write(ByteBuffer buf) throws IOException { if (buf == null) throw new NullPointerException(); @@ -599,9 +592,11 @@ } } - private long write0(ByteBuffer[] bufs) throws IOException { - if (bufs == null) - throw new NullPointerException(); + public long write(ByteBuffer[] srcs, int offset, int length) + throws IOException + { + if ((offset < 0) || (length < 0) || (offset > srcs.length - length)) + throw new IndexOutOfBoundsException(); synchronized (writeLock) { synchronized (stateLock) { ensureOpen(); @@ -615,7 +610,7 @@ return 0; writerThread = NativeThread.current(); do { - n = IOUtil.write(fd, bufs, nd); + n = IOUtil.write(fd, srcs, offset, length, nd); } while ((n == IOStatus.INTERRUPTED) && isOpen()); return IOStatus.normalize(n); } finally { @@ -626,15 +621,6 @@ } } - public long write(ByteBuffer[] srcs, int offset, int length) - throws IOException - { - if ((offset < 0) || (length < 0) || (offset > srcs.length - length)) - throw new IndexOutOfBoundsException(); - // ## Fix IOUtil.write so that we can avoid this array copy - return write0(Util.subsequence(srcs, offset, length)); - } - protected void implConfigureBlocking(boolean block) throws IOException { IOUtil.configureBlocking(fd, block); }
--- a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java Sun Aug 29 22:41:28 2010 -0700 @@ -143,7 +143,11 @@ } } - private long read0(ByteBuffer[] dsts) throws IOException { + public long read(ByteBuffer[] dsts, int offset, int length) + throws IOException + { + if ((offset < 0) || (length < 0) || (offset > dsts.length - length)) + throw new IndexOutOfBoundsException(); ensureOpen(); if (!readable) throw new NonReadableChannelException(); @@ -156,7 +160,7 @@ if (!isOpen()) return 0; do { - n = IOUtil.read(fd, dsts, nd); + n = IOUtil.read(fd, dsts, offset, length, nd); } while ((n == IOStatus.INTERRUPTED) && isOpen()); return IOStatus.normalize(n); } finally { @@ -167,15 +171,6 @@ } } - public long read(ByteBuffer[] dsts, int offset, int length) - throws IOException - { - if ((offset < 0) || (length < 0) || (offset > dsts.length - length)) - throw new IndexOutOfBoundsException(); - // ## Fix IOUtil.write so that we can avoid this array copy - return read0(Util.subsequence(dsts, offset, length)); - } - public int write(ByteBuffer src) throws IOException { ensureOpen(); if (!writable) @@ -200,7 +195,11 @@ } } - private long write0(ByteBuffer[] srcs) throws IOException { + public long write(ByteBuffer[] srcs, int offset, int length) + throws IOException + { + if ((offset < 0) || (length < 0) || (offset > srcs.length - length)) + throw new IndexOutOfBoundsException(); ensureOpen(); if (!writable) throw new NonWritableChannelException(); @@ -213,7 +212,7 @@ if (!isOpen()) return 0; do { - n = IOUtil.write(fd, srcs, nd); + n = IOUtil.write(fd, srcs, offset, length, nd); } while ((n == IOStatus.INTERRUPTED) && isOpen()); return IOStatus.normalize(n); } finally { @@ -224,16 +223,6 @@ } } - public long write(ByteBuffer[] srcs, int offset, int length) - throws IOException - { - if ((offset < 0) || (length < 0) || (offset > srcs.length - length)) - throw new IndexOutOfBoundsException(); - // ## Fix IOUtil.write so that we can avoid this array copy - return write0(Util.subsequence(srcs, offset, length)); - } - - // -- Other operations -- public long position() throws IOException { @@ -440,24 +429,45 @@ } } - private long transferToTrustedChannel(long position, int icount, + // Maximum size to map when using a mapped buffer + private static final long MAPPED_TRANSFER_SIZE = 8L*1024L*1024L; + + private long transferToTrustedChannel(long position, long count, WritableByteChannel target) throws IOException { - if ( !((target instanceof FileChannelImpl) - || (target instanceof SelChImpl))) + boolean isSelChImpl = (target instanceof SelChImpl); + if (!((target instanceof FileChannelImpl) || isSelChImpl)) return IOStatus.UNSUPPORTED; // Trusted target: Use a mapped buffer - MappedByteBuffer dbb = null; - try { - dbb = map(MapMode.READ_ONLY, position, icount); - // ## Bug: Closing this channel will not terminate the write - return target.write(dbb); - } finally { - if (dbb != null) - unmap(dbb); + long remaining = count; + while (remaining > 0L) { + long size = Math.min(remaining, MAPPED_TRANSFER_SIZE); + try { + MappedByteBuffer dbb = map(MapMode.READ_ONLY, position, size); + try { + // ## Bug: Closing this channel will not terminate the write + int n = target.write(dbb); + assert n >= 0; + remaining -= n; + if (isSelChImpl) { + // one attempt to write to selectable channel + break; + } + assert n > 0; + position += n; + } finally { + unmap(dbb); + } + } catch (IOException ioe) { + // Only throw exception if no bytes have been written + if (remaining == count) + throw ioe; + break; + } } + return count - remaining; } private long transferToArbitraryChannel(long position, int icount, @@ -535,20 +545,34 @@ long position, long count) throws IOException { - // Note we could loop here to accumulate more at once synchronized (src.positionLock) { - long p = src.position(); - int icount = (int)Math.min(Math.min(count, Integer.MAX_VALUE), - src.size() - p); - // ## Bug: Closing this channel will not terminate the write - MappedByteBuffer bb = src.map(MapMode.READ_ONLY, p, icount); - try { - long n = write(bb, position); - src.position(p + n); - return n; - } finally { - unmap(bb); + long pos = src.position(); + long max = Math.min(count, src.size() - pos); + + long remaining = max; + long p = pos; + while (remaining > 0L) { + long size = Math.min(remaining, MAPPED_TRANSFER_SIZE); + // ## Bug: Closing this channel will not terminate the write + MappedByteBuffer bb = src.map(MapMode.READ_ONLY, p, size); + try { + long n = write(bb, position); + assert n > 0; + p += n; + position += n; + remaining -= n; + } catch (IOException ioe) { + // Only throw exception if no bytes have been written + if (remaining == max) + throw ioe; + break; + } finally { + unmap(bb); + } } + long nwritten = max - remaining; + src.position(pos + nwritten); + return nwritten; } }
--- a/jdk/src/share/classes/sun/nio/ch/IOUtil.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/nio/ch/IOUtil.java Sun Aug 29 22:41:28 2010 -0700 @@ -38,34 +38,6 @@ private IOUtil() { } // No instantiation - /* - * Returns the index of first buffer in bufs with remaining, - * or -1 if there is nothing left - */ - private static int remaining(ByteBuffer[] bufs) { - int numBufs = bufs.length; - for (int i=0; i<numBufs; i++) { - if (bufs[i].hasRemaining()) { - return i; - } - } - return -1; - } - - /* - * Returns a new ByteBuffer array with only unfinished buffers in it - */ - private static ByteBuffer[] skipBufs(ByteBuffer[] bufs, - int nextWithRemaining) - { - int newSize = bufs.length - nextWithRemaining; - ByteBuffer[] temp = new ByteBuffer[newSize]; - for (int i=0; i<newSize; i++) { - temp[i] = bufs[i + nextWithRemaining]; - } - return temp; - } - static int write(FileDescriptor fd, ByteBuffer src, long position, NativeDispatcher nd, Object lock) throws IOException @@ -93,7 +65,7 @@ } return n; } finally { - Util.releaseTemporaryDirectBuffer(bb); + Util.offerFirstTemporaryDirectBuffer(bb); } } @@ -125,88 +97,81 @@ static long write(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd) throws IOException { - int nextWithRemaining = remaining(bufs); - // if all bufs are empty we should return immediately - if (nextWithRemaining < 0) - return 0; - // If some bufs are empty we should skip them - if (nextWithRemaining > 0) - bufs = skipBufs(bufs, nextWithRemaining); + return write(fd, bufs, 0, bufs.length, nd); + } - int numBufs = bufs.length; + static long write(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length, + NativeDispatcher nd) + throws IOException + { + IOVecWrapper vec = IOVecWrapper.get(length); - // Create shadow to ensure DirectByteBuffers are used - ByteBuffer[] shadow = new ByteBuffer[numBufs]; + boolean completed = false; + int iov_len = 0; try { - for (int i=0; i<numBufs; i++) { - if (!(bufs[i] instanceof DirectBuffer)) { - int pos = bufs[i].position(); - int lim = bufs[i].limit(); - assert (pos <= lim); - int rem = (pos <= lim ? lim - pos : 0); + + // Iterate over buffers to populate native iovec array. + int count = offset + length; + for (int i=offset; i<count; i++) { + ByteBuffer buf = bufs[i]; + int pos = buf.position(); + int lim = buf.limit(); + assert (pos <= lim); + int rem = (pos <= lim ? lim - pos : 0); + if (rem > 0) { + vec.setBuffer(iov_len, buf, pos, rem); + + // allocate shadow buffer to ensure I/O is done with direct buffer + if (!(buf instanceof DirectBuffer)) { + ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem); + shadow.put(buf); + shadow.flip(); + vec.setShadow(iov_len, shadow); + buf.position(pos); // temporarily restore position in user buffer + buf = shadow; + pos = shadow.position(); + } - ByteBuffer bb = Util.getTemporaryDirectBuffer(rem); - shadow[i] = bb; - // Leave slow buffer position untouched; it will be updated - // after we see how many bytes were really written out - bb.put(bufs[i]); - bufs[i].position(pos); - bb.flip(); - } else { - shadow[i] = bufs[i]; + vec.putBase(iov_len, ((DirectBuffer)buf).address() + pos); + vec.putLen(iov_len, rem); + iov_len++; } } + if (iov_len == 0) + return 0L; + + long bytesWritten = nd.writev(fd, vec.address, iov_len); + + // Notify the buffers how many bytes were taken + long left = bytesWritten; + for (int j=0; j<iov_len; j++) { + if (left > 0) { + ByteBuffer buf = vec.getBuffer(j); + int pos = vec.getPosition(j); + int rem = vec.getRemaining(j); + int n = (left > rem) ? rem : (int)left; + buf.position(pos + n); + left -= n; + } + // return shadow buffers to buffer pool + ByteBuffer shadow = vec.getShadow(j); + if (shadow != null) + Util.offerLastTemporaryDirectBuffer(shadow); + vec.clearRefs(j); + } - IOVecWrapper vec = null; - long bytesWritten = 0; - try { - // Create a native iovec array - vec= new IOVecWrapper(numBufs); - - // Fill in the iovec array with appropriate data - for (int i=0; i<numBufs; i++) { - ByteBuffer nextBuffer = shadow[i]; - // put in the buffer addresses - long pos = nextBuffer.position(); - long len = nextBuffer.limit() - pos; - vec.putBase(i, ((DirectBuffer)nextBuffer).address() + pos); - vec.putLen(i, len); - } - - // Invoke native call to fill the buffers - bytesWritten = nd.writev(fd, vec.address, numBufs); - } finally { - vec.free(); - } - long returnVal = bytesWritten; + completed = true; + return bytesWritten; - // Notify the buffers how many bytes were taken - for (int i=0; i<numBufs; i++) { - ByteBuffer nextBuffer = bufs[i]; - int pos = nextBuffer.position(); - int lim = nextBuffer.limit(); - assert (pos <= lim); - int len = (pos <= lim ? lim - pos : lim); - if (bytesWritten >= len) { - bytesWritten -= len; - int newPosition = pos + len; - nextBuffer.position(newPosition); - } else { // Buffers not completely filled - if (bytesWritten > 0) { - assert(pos + bytesWritten < (long)Integer.MAX_VALUE); - int newPosition = (int)(pos + bytesWritten); - nextBuffer.position(newPosition); - } - break; - } - } - return returnVal; } finally { - // return any substituted buffers to cache - for (int i=0; i<numBufs; i++) { - ByteBuffer bb = shadow[i]; - if (bb != null && bb != bufs[i]) { - Util.releaseTemporaryDirectBuffer(bb); + // if an error occurred then clear refs to buffers and return any shadow + // buffers to cache + if (!completed) { + for (int j=0; j<iov_len; j++) { + ByteBuffer shadow = vec.getShadow(j); + if (shadow != null) + Util.offerLastTemporaryDirectBuffer(shadow); + vec.clearRefs(j); } } } @@ -231,7 +196,7 @@ dst.put(bb); return n; } finally { - Util.releaseTemporaryDirectBuffer(bb); + Util.offerFirstTemporaryDirectBuffer(bb); } } @@ -262,92 +227,85 @@ static long read(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd) throws IOException { - int nextWithRemaining = remaining(bufs); - // if all bufs are empty we should return immediately - if (nextWithRemaining < 0) - return 0; - // If some bufs are empty we should skip them - if (nextWithRemaining > 0) - bufs = skipBufs(bufs, nextWithRemaining); + return read(fd, bufs, 0, bufs.length, nd); + } + + static long read(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length, + NativeDispatcher nd) + throws IOException + { + IOVecWrapper vec = IOVecWrapper.get(length); + + boolean completed = false; + int iov_len = 0; + try { - int numBufs = bufs.length; + // Iterate over buffers to populate native iovec array. + int count = offset + length; + for (int i=offset; i<count; i++) { + ByteBuffer buf = bufs[i]; + if (buf.isReadOnly()) + throw new IllegalArgumentException("Read-only buffer"); + int pos = buf.position(); + int lim = buf.limit(); + assert (pos <= lim); + int rem = (pos <= lim ? lim - pos : 0); + + if (rem > 0) { + vec.setBuffer(iov_len, buf, pos, rem); - // Read into the shadow to ensure DirectByteBuffers are used - ByteBuffer[] shadow = new ByteBuffer[numBufs]; - boolean usingSlowBuffers = false; - try { - for (int i=0; i<numBufs; i++) { - if (bufs[i].isReadOnly()) - throw new IllegalArgumentException("Read-only buffer"); - if (!(bufs[i] instanceof DirectBuffer)) { - shadow[i] = Util.getTemporaryDirectBuffer(bufs[i].remaining()); - usingSlowBuffers = true; - } else { - shadow[i] = bufs[i]; + // allocate shadow buffer to ensure I/O is done with direct buffer + if (!(buf instanceof DirectBuffer)) { + ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem); + vec.setShadow(iov_len, shadow); + buf = shadow; + pos = shadow.position(); + } + + vec.putBase(iov_len, ((DirectBuffer)buf).address() + pos); + vec.putLen(iov_len, rem); + iov_len++; } } + if (iov_len == 0) + return 0L; + + long bytesRead = nd.readv(fd, vec.address, iov_len); + + // Notify the buffers how many bytes were read + long left = bytesRead; + for (int j=0; j<iov_len; j++) { + ByteBuffer shadow = vec.getShadow(j); + if (left > 0) { + ByteBuffer buf = vec.getBuffer(j); + int rem = vec.getRemaining(j); + int n = (left > rem) ? rem : (int)left; + if (shadow == null) { + int pos = vec.getPosition(j); + buf.position(pos + n); + } else { + shadow.limit(shadow.position() + n); + buf.put(shadow); + } + left -= n; + } + if (shadow != null) + Util.offerLastTemporaryDirectBuffer(shadow); + vec.clearRefs(j); + } - IOVecWrapper vec = null; - long bytesRead = 0; - try { - // Create a native iovec array - vec = new IOVecWrapper(numBufs); - - // Fill in the iovec array with appropriate data - for (int i=0; i<numBufs; i++) { - ByteBuffer nextBuffer = shadow[i]; - // put in the buffer addresses - long pos = nextBuffer.position(); - long len = nextBuffer.remaining(); - vec.putBase(i, ((DirectBuffer)nextBuffer).address() + pos); - vec.putLen(i, len); - } - - // Invoke native call to fill the buffers - bytesRead = nd.readv(fd, vec.address, numBufs); - } finally { - vec.free(); - } - long returnVal = bytesRead; + completed = true; + return bytesRead; - // Notify the buffers how many bytes were read - for (int i=0; i<numBufs; i++) { - ByteBuffer nextBuffer = shadow[i]; - // Note: should this have been cached from above? - int pos = nextBuffer.position(); - int len = nextBuffer.remaining(); - if (bytesRead >= len) { - bytesRead -= len; - int newPosition = pos + len; - nextBuffer.position(newPosition); - } else { // Buffers not completely filled - if (bytesRead > 0) { - assert(pos + bytesRead < (long)Integer.MAX_VALUE); - int newPosition = (int)(pos + bytesRead); - nextBuffer.position(newPosition); - } - break; - } - } - - // Put results from shadow into the slow buffers - if (usingSlowBuffers) { - for (int i=0; i<numBufs; i++) { - if (!(bufs[i] instanceof DirectBuffer)) { - shadow[i].flip(); - bufs[i].put(shadow[i]); - } - } - } - return returnVal; } finally { - // return any substituted buffers to cache - if (usingSlowBuffers) { - for (int i=0; i<numBufs; i++) { - ByteBuffer bb = shadow[i]; - if (bb != null && bb != bufs[i]) { - Util.releaseTemporaryDirectBuffer(bb); - } + // if an error occurred then clear refs to buffers and return any shadow + // buffers to cache + if (!completed) { + for (int j=0; j<iov_len; j++) { + ByteBuffer shadow = vec.getShadow(j); + if (shadow != null) + Util.offerLastTemporaryDirectBuffer(shadow); + vec.clearRefs(j); } } }
--- a/jdk/src/share/classes/sun/nio/ch/IOVecWrapper.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/nio/ch/IOVecWrapper.java Sun Aug 29 22:41:28 2010 -0700 @@ -25,6 +25,7 @@ package sun.nio.ch; +import java.nio.ByteBuffer; import sun.misc.*; @@ -43,23 +44,98 @@ class IOVecWrapper { // Miscellaneous constants - static int BASE_OFFSET = 0; - static int LEN_OFFSET; - static int SIZE_IOVEC; + private static final int BASE_OFFSET = 0; + private static final int LEN_OFFSET; + private static final int SIZE_IOVEC; // The iovec array - private AllocatedNativeObject vecArray; + private final AllocatedNativeObject vecArray; + + // Number of elements in iovec array + private final int size; + + // Buffers and position/remaining corresponding to elements in iovec array + private final ByteBuffer[] buf; + private final int[] position; + private final int[] remaining; + + // Shadow buffers for cases when original buffer is substituted + private final ByteBuffer[] shadow; // Base address of this array - long address; + final long address; // Address size in bytes static int addressSize; - IOVecWrapper(int newSize) { - newSize = (newSize + 1) * SIZE_IOVEC; - vecArray = new AllocatedNativeObject(newSize, false); - address = vecArray.address(); + private static class Deallocator implements Runnable { + private final AllocatedNativeObject obj; + Deallocator(AllocatedNativeObject obj) { + this.obj = obj; + } + public void run() { + obj.free(); + } + } + + // per thread IOVecWrapper + private static final ThreadLocal<IOVecWrapper> cached = + new ThreadLocal<IOVecWrapper>(); + + private IOVecWrapper(int size) { + this.size = size; + this.buf = new ByteBuffer[size]; + this.position = new int[size]; + this.remaining = new int[size]; + this.shadow = new ByteBuffer[size]; + this.vecArray = new AllocatedNativeObject(size * SIZE_IOVEC, false); + this.address = vecArray.address(); + } + + static IOVecWrapper get(int size) { + IOVecWrapper wrapper = cached.get(); + if (wrapper != null && wrapper.size < size) { + // not big enough; eagerly release memory + wrapper.vecArray.free(); + wrapper = null; + } + if (wrapper == null) { + wrapper = new IOVecWrapper(size); + Cleaner.create(wrapper, new Deallocator(wrapper.vecArray)); + cached.set(wrapper); + } + return wrapper; + } + + void setBuffer(int i, ByteBuffer buf, int pos, int rem) { + this.buf[i] = buf; + this.position[i] = pos; + this.remaining[i] = rem; + } + + void setShadow(int i, ByteBuffer buf) { + shadow[i] = buf; + } + + ByteBuffer getBuffer(int i) { + return buf[i]; + } + + int getPosition(int i) { + return position[i]; + } + + int getRemaining(int i) { + return remaining[i]; + } + + ByteBuffer getShadow(int i) { + return shadow[i]; + } + + void clearRefs(int i) { + buf[i] = null; + shadow[i] = null; } void putBase(int i, long base) { @@ -78,10 +154,6 @@ vecArray.putLong(offset, len); } - void free() { - vecArray.free(); - } - static { addressSize = Util.unsafe().addressSize(); LEN_OFFSET = addressSize;
--- a/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java Sun Aug 29 22:41:28 2010 -0700 @@ -385,9 +385,11 @@ } } - private long read0(ByteBuffer[] bufs) throws IOException { - if (bufs == null) - throw new NullPointerException(); + public long read(ByteBuffer[] dsts, int offset, int length) + throws IOException + { + if ((offset < 0) || (length < 0) || (offset > dsts.length - length)) + throw new IndexOutOfBoundsException(); synchronized (readLock) { if (!ensureReadOpen()) return -1; @@ -401,7 +403,7 @@ } for (;;) { - n = IOUtil.read(fd, bufs, nd); + n = IOUtil.read(fd, dsts, offset, length, nd); if ((n == IOStatus.INTERRUPTED) && isOpen()) continue; return IOStatus.normalize(n); @@ -418,15 +420,6 @@ } } - public long read(ByteBuffer[] dsts, int offset, int length) - throws IOException - { - if ((offset < 0) || (length < 0) || (offset > dsts.length - length)) - throw new IndexOutOfBoundsException(); - // ## Fix IOUtil.write so that we can avoid this array copy - return read0(Util.subsequence(dsts, offset, length)); - } - public int write(ByteBuffer buf) throws IOException { if (buf == null) throw new NullPointerException(); @@ -458,9 +451,11 @@ } } - public long write0(ByteBuffer[] bufs) throws IOException { - if (bufs == null) - throw new NullPointerException(); + public long write(ByteBuffer[] srcs, int offset, int length) + throws IOException + { + if ((offset < 0) || (length < 0) || (offset > srcs.length - length)) + throw new IndexOutOfBoundsException(); synchronized (writeLock) { ensureWriteOpen(); long n = 0; @@ -472,7 +467,7 @@ writerThread = NativeThread.current(); } for (;;) { - n = IOUtil.write(fd, bufs, nd); + n = IOUtil.write(fd, srcs, offset, length, nd); if ((n == IOStatus.INTERRUPTED) && isOpen()) continue; return IOStatus.normalize(n); @@ -489,15 +484,6 @@ } } - public long write(ByteBuffer[] srcs, int offset, int length) - throws IOException - { - if ((offset < 0) || (length < 0) || (offset > srcs.length - length)) - throw new IndexOutOfBoundsException(); - // ## Fix IOUtil.write so that we can avoid this array copy - return write0(Util.subsequence(srcs, offset, length)); - } - // package-private int sendOutOfBandData(byte b) throws IOException { synchronized (writeLock) {
--- a/jdk/src/share/classes/sun/nio/ch/Util.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/nio/ch/Util.java Sun Aug 29 22:41:28 2010 -0700 @@ -41,67 +41,180 @@ class Util { - // -- Caches -- // The number of temp buffers in our pool - private static final int TEMP_BUF_POOL_SIZE = 3; + private static final int TEMP_BUF_POOL_SIZE = 8; - // Per-thread soft cache of the last temporary direct buffer - private static ThreadLocal<SoftReference<ByteBuffer>>[] bufferPool; + // Per-thread cache of temporary direct buffers + private static ThreadLocal<BufferCache> bufferCache = + new ThreadLocal<BufferCache>() + { + @Override + protected BufferCache initialValue() { + return new BufferCache(); + } + }; + + /** + * A simple cache of direct buffers. + */ + private static class BufferCache { + // the array of buffers + private ByteBuffer[] buffers; - @SuppressWarnings("unchecked") - static ThreadLocal<SoftReference<ByteBuffer>>[] createThreadLocalBufferPool() { - return new ThreadLocal[TEMP_BUF_POOL_SIZE]; - } + // the number of buffers in the cache + private int count; + + // the index of the first valid buffer (undefined if count == 0) + private int start; + + private int next(int i) { + return (i + 1) % TEMP_BUF_POOL_SIZE; + } + + BufferCache() { + buffers = new ByteBuffer[TEMP_BUF_POOL_SIZE]; + } + + /** + * Removes and returns a buffer from the cache of at least the given + * size (or null if no suitable buffer is found). + */ + ByteBuffer get(int size) { + if (count == 0) + return null; // cache is empty - static { - bufferPool = createThreadLocalBufferPool(); - for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) - bufferPool[i] = new ThreadLocal<SoftReference<ByteBuffer>>(); - } + ByteBuffer[] buffers = this.buffers; - static ByteBuffer getTemporaryDirectBuffer(int size) { - ByteBuffer buf = null; - // Grab a buffer if available - for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) { - SoftReference<ByteBuffer> ref = bufferPool[i].get(); - if ((ref != null) && ((buf = ref.get()) != null) && - (buf.capacity() >= size)) { - buf.rewind(); - buf.limit(size); - bufferPool[i].set(null); - return buf; + // search for suitable buffer (often the first buffer will do) + ByteBuffer buf = buffers[start]; + if (buf.capacity() < size) { + buf = null; + int i = start; + while ((i = next(i)) != start) { + ByteBuffer bb = buffers[i]; + if (bb == null) + break; + if (bb.capacity() >= size) { + buf = bb; + break; + } + } + if (buf == null) + return null; + // move first element to here to avoid re-packing + buffers[i] = buffers[start]; + } + + // remove first element + buffers[start] = null; + start = next(start); + count--; + + // prepare the buffer and return it + buf.rewind(); + buf.limit(size); + return buf; + } + + boolean offerFirst(ByteBuffer buf) { + if (count >= TEMP_BUF_POOL_SIZE) { + return false; + } else { + start = (start + TEMP_BUF_POOL_SIZE - 1) % TEMP_BUF_POOL_SIZE; + buffers[start] = buf; + count++; + return true; } } - // Make a new one - return ByteBuffer.allocateDirect(size); - } - - static void releaseTemporaryDirectBuffer(ByteBuffer buf) { - if (buf == null) - return; - // Put it in an empty slot if such exists - for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) { - SoftReference<ByteBuffer> ref = bufferPool[i].get(); - if ((ref == null) || (ref.get() == null)) { - bufferPool[i].set(new SoftReference<ByteBuffer>(buf)); - return; - } - } - // Otherwise replace a smaller one in the cache if such exists - for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) { - SoftReference<ByteBuffer> ref = bufferPool[i].get(); - ByteBuffer inCacheBuf = ref.get(); - if ((inCacheBuf == null) || (buf.capacity() > inCacheBuf.capacity())) { - bufferPool[i].set(new SoftReference<ByteBuffer>(buf)); - return; + boolean offerLast(ByteBuffer buf) { + if (count >= TEMP_BUF_POOL_SIZE) { + return false; + } else { + int next = (start + count) % TEMP_BUF_POOL_SIZE; + buffers[next] = buf; + count++; + return true; } } - // release memory - ((DirectBuffer)buf).cleaner().clean(); + boolean isEmpty() { + return count == 0; + } + + ByteBuffer removeFirst() { + assert count > 0; + ByteBuffer buf = buffers[start]; + buffers[start] = null; + start = next(start); + count--; + return buf; + } + } + + /** + * Returns a temporary buffer of at least the given size + */ + static ByteBuffer getTemporaryDirectBuffer(int size) { + BufferCache cache = bufferCache.get(); + ByteBuffer buf = cache.get(size); + if (buf != null) { + return buf; + } else { + // No suitable buffer in the cache so we need to allocate a new + // one. To avoid the cache growing then we remove the first + // buffer from the cache and free it. + if (!cache.isEmpty()) { + buf = cache.removeFirst(); + free(buf); + } + return ByteBuffer.allocateDirect(size); + } + } + + /** + * Releases a temporary buffer by returning to the cache or freeing it. + */ + static void releaseTemporaryDirectBuffer(ByteBuffer buf) { + offerFirstTemporaryDirectBuffer(buf); + } + + /** + * Releases a temporary buffer by returning to the cache or freeing it. If + * returning to the cache then insert it at the start so that it is + * likely to be returned by a subsequent call to getTemporaryDirectBuffer. + */ + static void offerFirstTemporaryDirectBuffer(ByteBuffer buf) { + assert buf != null; + BufferCache cache = bufferCache.get(); + if (!cache.offerFirst(buf)) { + // cache is full + free(buf); + } + } + + /** + * Releases a temporary buffer by returning to the cache or freeing it. If + * returning to the cache then insert it at the end. This makes it + * suitable for scatter/gather operations where the buffers are returned to + * cache in same order that they were obtained. + */ + static void offerLastTemporaryDirectBuffer(ByteBuffer buf) { + assert buf != null; + BufferCache cache = bufferCache.get(); + if (!cache.offerLast(buf)) { + // cache is full + free(buf); + } + } + + /** + * Frees the memory for the given direct buffer + */ + private static void free(ByteBuffer buf) { + ((DirectBuffer)buf).cleaner().clean(); } private static class SelectorWrapper {
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -75,6 +75,8 @@ "Central European Summer Time", "CEST"}; String CHAST[] = new String[] {"Chatham Standard Time", "CHAST", "Chatham Daylight Time", "CHADT"}; + String CHUT[] = new String[] {"Chuuk Time", "CHUT", + "Chuuk Summer Time", "CHUST"}; String CIT[] = new String[] {"Central Indonesia Time", "CIT", "Central Indonesia Summer Time", "CIST"}; String CLT[] = new String[] {"Chile Time", "CLT", @@ -153,6 +155,8 @@ "Pitcairn Daylight Time", "PDT"}; String PKT[] = new String[] {"Pakistan Time", "PKT", "Pakistan Summer Time", "PKST"}; + String PONT[] = new String[] {"Pohnpei Time", "PONT", + "Pohnpei Summer Time", "PONST"}; String PST[] = new String[] {"Pacific Standard Time", "PST", "Pacific Daylight Time", "PDT"}; String RST[] = new String[] {"Eastern Standard Time", "EST", @@ -169,8 +173,6 @@ "Eastern Summer Time (Tasmania)", "EST"}; String TMT[] = new String[] {"Turkmenistan Time", "TMT", "Turkmenistan Summer Time", "TMST"}; - String TRUT[] = new String[] {"Truk Time", "TRUT", - "Truk Summer Time", "TRUST"}; String ULAT[]= new String[] {"Ulaanbaatar Time", "ULAT", "Ulaanbaatar Summer Time", "ULAST"}; String WART[] = new String[] {"Western Argentine Time", "WART", @@ -309,6 +311,7 @@ {"America/Atikokan", EST}, {"America/Atka", HAST}, {"America/Bahia", BRT}, + {"America/Bahia_Banderas", CST}, {"America/Barbados", AST}, {"America/Belem", BRT}, {"America/Belize", CST}, @@ -755,6 +758,7 @@ {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, {"Pacific/Chatham", CHAST}, + {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, {"Pacific/Efate", new String[] {"Vanuatu Time", "VUT", "Vanuatu Summer Time", "VUST"}}, @@ -793,8 +797,8 @@ {"Pacific/Palau", new String[] {"Palau Time", "PWT", "Palau Summer Time", "PWST"}}, {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Ponape", new String[] {"Ponape Time", "PONT", - "Ponape Summer Time", "PONST"}}, + {"Pacific/Pohnpei", PONT}, + {"Pacific/Ponape", PONT}, {"Pacific/Port_Moresby", new String[] {"Papua New Guinea Time", "PGT", "Papua New Guinea Summer Time", "PGST"}}, {"Pacific/Rarotonga", new String[] {"Cook Is. Time", "CKT", @@ -807,12 +811,12 @@ "Gilbert Is. Summer Time", "GILST"}}, {"Pacific/Tongatapu", new String[] {"Tonga Time", "TOT", "Tonga Summer Time", "TOST"}}, - {"Pacific/Truk", TRUT}, + {"Pacific/Truk", CHUT}, {"Pacific/Wake", new String[] {"Wake Time", "WAKT", "Wake Summer Time", "WAKST"}}, {"Pacific/Wallis", new String[] {"Wallis & Futuna Time", "WFT", "Wallis & Futuna Summer Time", "WFST"}}, - {"Pacific/Yap", TRUT}, + {"Pacific/Yap", CHUT}, {"Poland", CET}, {"PRC", CTT}, {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -75,6 +75,8 @@ "Mitteleurop\u00e4ische Sommerzeit", "MESZ"}; String CHAST[] = new String[] {"Chatham Normalzeit", "CHAST", "Chatham Sommerzeit", "CHADT"}; + String CHUT[] = new String[] {"Chuuk Time", "CHUT", + "Chuuk Summer Time", "CHUST"}; String CIT[] = new String[] {"Zentralindonesische Zeit", "CIT", "Zentralindonesische Sommerzeit", "CIST"}; String CLT[] = new String[] {"Chilenische Zeit", "CLT", @@ -153,6 +155,8 @@ "Pitcairn Sommerzeit", "PDT"}; String PKT[] = new String[] {"Pakistanische Zeit", "PKT", "Pakistanische Sommerzeit", "PKST"}; + String PONT[] = new String[] {"Pohnpei Time", "PONT", + "Pohnpei Summer Time", "PONST"}; String PST[] = new String[] {"Pazifische Normalzeit", "PST", "Pazifische Sommerzeit", "PDT"}; String RST[] = new String[] {"\u00d6stliche Normalzeit", "EST", @@ -169,8 +173,6 @@ "\u00d6stliche Sommerzeit (Tasmanien)", "EST"}; String TMT[] = new String[] {"Turkmenische Zeit", "TMT", "Turkmenische Sommerzeit", "TMST"}; - String TRUT[] = new String[] {"Truk Zeit", "TRUT", - "Truk Sommerzeit", "TRUST"}; String ULAT[]= new String[] {"Ulaanbaatar Zeit", "ULAT", "Ulaanbaatar Sommerzeit", "ULAST"}; String WART[] = new String[] {"Westargentinische Zeit", "WART", @@ -309,6 +311,7 @@ {"America/Atikokan", EST}, {"America/Atka", HAST}, {"America/Bahia", BRT}, + {"America/Bahia_Banderas", CST}, {"America/Barbados", AST}, {"America/Belem", BRT}, {"America/Belize", CST}, @@ -446,10 +449,13 @@ {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, + {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"Davis Zeit", "DAVT", "Davis Sommerzeit", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville Zeit", "DDUT", "Dumont-d'Urville Sommerzeit", "DDUST"}}, + {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST", + "Macquarie Island Summer Time", "MIST"}}, {"Antarctica/Mawson", new String[] {"Mawson Zeit", "MAWT", "Mawson Sommerzeit", "MAWST"}}, {"Antarctica/McMurdo", NZST}, @@ -752,6 +758,7 @@ {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, {"Pacific/Chatham", CHAST}, + {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, {"Pacific/Efate", new String[] {"Vanuatu Zeit", "VUT", "Vanuatu Sommerzeit", "VUST"}}, @@ -790,8 +797,8 @@ {"Pacific/Palau", new String[] {"Palau Zeit", "PWT", "Palau Sommerzeit", "PWST"}}, {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Ponape", new String[] {"Ponape Zeit", "PONT", - "Ponape Sommerzeit", "PONST"}}, + {"Pacific/Pohnpei", PONT}, + {"Pacific/Ponape", PONT}, {"Pacific/Port_Moresby", new String[] {"Papua-Neuguinea Zeit", "PGT", "Papua-Neuguinea Sommerzeit", "PGST"}}, {"Pacific/Rarotonga", new String[] {"Cook-Inseln Zeit", "CKT", @@ -804,12 +811,12 @@ "Gilbert-Inseln Sommerzeit", "GILST"}}, {"Pacific/Tongatapu", new String[] {"Tonga Zeit", "TOT", "Tonga Sommerzeit", "TOST"}}, - {"Pacific/Truk", TRUT}, + {"Pacific/Truk", CHUT}, {"Pacific/Wake", new String[] {"Wake Zeit", "WAKT", "Wake Sommerzeit", "WAKST"}}, {"Pacific/Wallis", new String[] {"Wallis u. Futuna Zeit", "WFT", "Wallis u. Futuna Sommerzeit", "WFST"}}, - {"Pacific/Yap", TRUT}, + {"Pacific/Yap", CHUT}, {"Poland", CET}, {"PRC", CTT}, {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -75,6 +75,8 @@ "Hora de verano de Europa Central", "CEST"}; String CHAST[] = new String[] {"Hora est\u00e1ndar de Chatham", "CHAST", "Hora de verano de Chatham", "CHADT"}; + String CHUT[] = new String[] {"Chuuk Time", "CHUT", + "Chuuk Summer Time", "CHUST"}; String CIT[] = new String[] {"Hora de Indonesia Central", "CIT", "Hora de verano de Indonesia Central", "CIST"}; String CLT[] = new String[] {"Hora de Chile", "CLT", @@ -153,6 +155,8 @@ "Hora de verano de Pitcairn", "PDT"}; String PKT[] = new String[] {"Hora de Pakist\u00e1n", "PKT", "Hora de verano de Pakist\u00e1n", "PKST"}; + String PONT[] = new String[] {"Pohnpei Time", "PONT", + "Pohnpei Summer Time", "PONST"}; String PST[] = new String[] {"Hora est\u00e1ndar del Pac\u00edfico", "PST", "Hora de verano del Pac\u00edfico", "PDT"}; String RST[] = new String[] {"Hora est\u00e1ndar Oriental", "EST", @@ -169,8 +173,6 @@ "Hora de verano del Este (Tasmania)", "EST"}; String TMT[] = new String[] {"Hora de Turkmenist\u00e1n", "TMT", "Hora de verano de Turkmenist\u00e1n", "TMST"}; - String TRUT[] =new String[] {"Hora de Truk", "TRUT", - "Hora de verano de Truk", "TRUST"}; String ULAT[]= new String[] {"Hora de Ulan Bator", "ULAT", "Hora de verano de Ulan Bator", "ULAST"}; String WART[] = new String[] {"Hora de Argentina Occidental", "WART", @@ -309,6 +311,7 @@ {"America/Atikokan", EST}, {"America/Atka", HAST}, {"America/Bahia", BRT}, + {"America/Bahia_Banderas", CST}, {"America/Barbados", AST}, {"America/Belem", BRT}, {"America/Belize", CST}, @@ -446,10 +449,13 @@ {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, + {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"Hora de Davis", "DAVT", "Hora de verano de Davis", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"Hora de Dumont-d'Urville", "DDUT", "Hora de verano de Dumont-d'Urville", "DDUST"}}, + {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST", + "Macquarie Island Summer Time", "MIST"}}, {"Antarctica/Mawson", new String[] {"Hora de Mawson", "MAWT", "Hora de verano de Mawson", "MAWST"}}, {"Antarctica/McMurdo", NZST}, @@ -533,7 +539,6 @@ "Hora de verano de Filipinas", "PHST"}}, {"Asia/Muscat", GST}, {"Asia/Nicosia", EET}, - {"Asia/Novokuznetsk", NOVT}, {"Asia/Novosibirsk", NOVT}, {"Asia/Oral", new String[] {"Hora de Uralsk", "ORAT", @@ -753,6 +758,7 @@ {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, {"Pacific/Chatham", CHAST}, + {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, {"Pacific/Efate", new String[] {"Hora de Vanuatu", "VUT", "Hora de verano de Vanuatu", "VUST"}}, @@ -791,8 +797,8 @@ {"Pacific/Palau", new String[] {"Hora de Palau", "PWT", "Hora de verano de Palau", "PWST"}}, {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Ponape", new String[] {"Hora de Ponape", "PONT", - "Hora de verano de Ponape", "PONST"}}, + {"Pacific/Pohnpei", PONT}, + {"Pacific/Ponape", PONT}, {"Pacific/Port_Moresby", new String[] {"Hora de Pap\u00faa-Nueva Guinea", "PGT", "Hora de verano de Pap\u00faa-Nueva Guinea", "PGST"}}, {"Pacific/Rarotonga", new String[] {"Hora de las islas Cook", "CKT", @@ -805,12 +811,12 @@ "Hora de verano de las islas Gilbert", "GILST"}}, {"Pacific/Tongatapu", new String[] {"Hora de Tonga", "TOT", "Hora de verano de Tonga", "TOST"}}, - {"Pacific/Truk", TRUT}, + {"Pacific/Truk", CHUT}, {"Pacific/Wake", new String[] {"Hora de Wake", "WAKT", "Hora de verano de Wake", "WAKST"}}, {"Pacific/Wallis", new String[] {"Hora de Wallis y Futuna", "WFT", "Hora de verano de Wallis y Futuna", "WFST"}}, - {"Pacific/Yap", TRUT}, + {"Pacific/Yap", CHUT}, {"Poland", CET}, {"PRC", CTT}, {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -75,6 +75,8 @@ "Heure d'\u00e9t\u00e9 d'Europe centrale", "CEST"} ; String CHAST[] = new String[] {"Heure standard de Chatham", "CHAST", "Heure avanc\u00e9e de Chatham", "CHADT"}; + String CHUT[] = new String[] {"Chuuk Time", "CHUT", + "Chuuk Summer Time", "CHUST"}; String CIT[] = new String[] {"Heure d'Indon\u00e9sie centrale", "CIT", "Heure d'\u00e9t\u00e9 d'Indon\u00e9sie centrale", "CIST"}; String CLT[] = new String[] {"Heure du Chili", "CLT", @@ -153,6 +155,8 @@ "heure avanc\u00e9e des Pitcairn", "PDT"}; String PKT[] = new String[] {"Heure du Pakistan", "PKT", "Heure d'\u00e9t\u00e9 du Pakistan", "PKST"} ; + String PONT[] = new String[] {"Pohnpei Time", "PONT", + "Pohnpei Summer Time", "PONST"}; String PST[] = new String[] {"Heure normale du Pacifique", "PST", "Heure avanc\u00e9e du Pacifique", "PDT"} ; String RST[] = new String[] {"Heure normale de l'Est", "EST", @@ -169,8 +173,6 @@ "Heure d'\u00e9t\u00e9 d'Australie orientale (Tasmanie)", "EST"}; String TMT[] = new String[] {"Heure du Turkm\u00e9nistan", "TMT", "Heure d'\u00e9t\u00e9 du Turkm\u00e9nistan", "TMST"} ; - String TRUT[] = new String[] {"Heure de Truk", "TRUT", - "Heure d'\u00e9t\u00e9 de Truk", "TRUST"}; String ULAT[]= new String[] {"Heure de l'Ulaanbaatar", "ULAT", "Heure d'\u00e9t\u00e9 de l'Ulaanbaatar", "ULAST"} ; String WART[] = new String[] {"Heure D'Argentine de l'Ouest", "WART", @@ -309,6 +311,7 @@ {"America/Atikokan", EST}, {"America/Atka", HAST}, {"America/Bahia", BRT}, + {"America/Bahia_Banderas", CST}, {"America/Barbados", AST}, {"America/Belem", BRT}, {"America/Belize", CST}, @@ -446,10 +449,13 @@ {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, + {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"Heure de Davis", "DAVT", "Heure d'\u00e9t\u00e9 de Davis", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"Heure de Dumont-d'Urville", "DDUT", "Heure d'\u00e9t\u00e9 de Dumont-d'Urville", "DDUST"}}, + {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST", + "Macquarie Island Summer Time", "MIST"}}, {"Antarctica/Mawson", new String[] {"Heure de Mawson", "MAWT", "Heure d'\u00e9t\u00e9 de Mawson", "MAWST"}}, {"Antarctica/McMurdo", NZST}, @@ -752,6 +758,7 @@ {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, {"Pacific/Chatham", CHAST}, + {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, {"Pacific/Efate", new String[] {"Heure du Vanuatu", "VUT", "Heure d'\u00e9t\u00e9 du Vanuatu", "VUST"}}, @@ -790,8 +797,8 @@ {"Pacific/Palau", new String[] {"Heure de Palaos", "PWT", "Heure d'\u00e9t\u00e9 de Palaos", "PWST"}}, {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Ponape", new String[] {"Heure de Ponap\u00e9", "PONT", - "Heure d'\u00e9t\u00e9 de Ponap\u00e9", "PONST"}}, + {"Pacific/Pohnpei", PONT}, + {"Pacific/Ponape", PONT}, {"Pacific/Port_Moresby", new String[] {"Heure de Papouasie-Nouvelle-Guin\u00e9e", "PGT", "Heure d'\u00e9t\u00e9 de de Papouasie-Nouvelle-Guin\u00e9e", "PGST"}}, {"Pacific/Rarotonga", new String[] {"Heure des \u00celes Cook", "CKT", @@ -804,12 +811,12 @@ "Heure d'\u00e9t\u00e9 de Kiribati", "GILST"}}, {"Pacific/Tongatapu", new String[] {"Heure de Tonga", "TOT", "Heure d'\u00e9t\u00e9 de Tonga", "TOST"}}, - {"Pacific/Truk", TRUT}, + {"Pacific/Truk", CHUT}, {"Pacific/Wake", new String[] {"Heure de Wake", "WAKT", "Heure d'\u00e9t\u00e9 de Wake", "WAKST"}}, {"Pacific/Wallis", new String[] {"Heure de Wallis et Futuna", "WFT", "Heure d'\u00e9t\u00e9 de Wallis et Futuna", "WFST"}}, - {"Pacific/Yap", TRUT}, + {"Pacific/Yap", CHUT}, {"Poland", CET}, {"PRC", CTT}, {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -75,6 +75,8 @@ "Ora estiva dell'Europa centrale", "CEST"}; String CHAST[] = new String[] {"Ora di Chatham standard", "CHAST", "Ora legale di Chatham", "CHADT"}; + String CHUT[] = new String[] {"Chuuk Time", "CHUT", + "Chuuk Summer Time", "CHUST"}; String CIT[] = new String[] {"Ora dell'Indonesia centrale", "CIT", "Ora estiva dell'Indonesia centrale", "CIST"}; String CLT[] = new String[] {"Ora del Cile", "CLT", @@ -153,6 +155,8 @@ "Ora legale di Pitcairn", "PDT"}; String PKT[] = new String[] {"Ora del Pakistan", "PKT", "Ora estiva del Pakistan", "PKST"}; + String PONT[] = new String[] {"Pohnpei Time", "PONT", + "Pohnpei Summer Time", "PONST"}; String PST[] = new String[] {"Ora solare della costa occidentale USA", "PST", "Ora legale della costa occidentale USA", "PDT"}; String RST[] = new String[] {"Ora solare USA orientale", "EST", @@ -169,8 +173,6 @@ "Ora estiva orientale (Tasmania)", "EST"}; String TMT[] = new String[] {"Ora del Turkmenistan", "TMT", "Ora estiva del Turkmenistan", "TMST"}; - String TRUT[] = new String[] {"Ora di Truk", "TRUT", - "Ora estiva di Truk", "TRUST"}; String ULAT[]= new String[] {"Ora di Ulaanbaatar", "ULAT", "Ora estiva di Ulaanbaatar", "ULAST"}; String WART[] = new String[] {"Ora dell'Argentina occidentale", "WART", @@ -309,6 +311,7 @@ {"America/Atikokan", EST}, {"America/Atka", HAST}, {"America/Bahia", BRT}, + {"America/Bahia_Banderas", CST}, {"America/Barbados", AST}, {"America/Belem", BRT}, {"America/Belize", CST}, @@ -446,10 +449,13 @@ {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, + {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"Ora di Davis", "DAVT", "Ora estiva di Davis", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"Ora di Dumont-d'Urville", "DDUT", "Ora estiva di Dumont-d'Urville", "DDUST"}}, + {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST", + "Macquarie Island Summer Time", "MIST"}}, {"Antarctica/Mawson", new String[] {"Ora di Mawson", "MAWT", "Ora estiva di Mawson", "MAWST"}}, {"Antarctica/McMurdo", NZST}, @@ -752,6 +758,7 @@ {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, {"Pacific/Chatham", CHAST}, + {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, {"Pacific/Efate", new String[] {"Ora di Vanuatu", "VUT", "Ora estiva di Vanuatu", "VUST"}}, @@ -790,8 +797,8 @@ {"Pacific/Palau", new String[] {"Ora di Palau", "PWT", "Ora estiva di Palau", "PWST"}}, {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Ponape", new String[] {"Ora di Ponape", "PONT", - "Ora estiva di Ponape", "PONST"}}, + {"Pacific/Pohnpei", PONT}, + {"Pacific/Ponape", PONT}, {"Pacific/Port_Moresby", new String[] {"Ora di Papua Nuova Guinea", "PGT", "Ora estiva di Papua Nuova Guinea", "PGST"}}, {"Pacific/Rarotonga", new String[] {"Ora delle Isole Cook", "CKT", @@ -804,12 +811,12 @@ "Ora estiva delle Isole Gilbert", "GILST"}}, {"Pacific/Tongatapu", new String[] {"Ora di Tonga", "TOT", "Ora estiva di Tonga", "TOST"}}, - {"Pacific/Truk", TRUT}, + {"Pacific/Truk", CHUT}, {"Pacific/Wake", new String[] {"Ora di Wake", "WAKT", "Ora estiva di Wake", "WAKST"}}, {"Pacific/Wallis", new String[] {"Ora di Wallis e Futuna", "WFT", "Ora estiva di Wallis e Futuna", "WFST"}}, - {"Pacific/Yap", TRUT}, + {"Pacific/Yap", CHUT}, {"Poland", CET}, {"PRC", CTT}, {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -75,6 +75,8 @@ "\u4e2d\u90e8\u30e8\u30fc\u30ed\u30c3\u30d1\u590f\u6642\u9593", "CEST"}; String CHAST[] = new String[] {"\u30c1\u30e3\u30bf\u30e0\u6a19\u6e96\u6642", "CHAST", "\u30c1\u30e3\u30bf\u30e0\u590f\u6642\u9593", "CHADT"}; + String CHUT[] = new String[] {"Chuuk Time", "CHUT", + "Chuuk Summer Time", "CHUST"}; String CIT[] = new String[] {"\u4e2d\u592e\u30a4\u30f3\u30c9\u30cd\u30b7\u30a2\u6642\u9593", "CIT", "\u4e2d\u592e\u30a4\u30f3\u30c9\u30cd\u30b7\u30a2\u590f\u6642\u9593", "CIST"}; String CLT[] = new String[] {"\u30c1\u30ea\u6642\u9593", "CLT", @@ -153,6 +155,8 @@ "\u30d4\u30c8\u30b1\u30eb\u30f3\u5cf6\u590f\u6642\u9593", "PDT"}; String PKT[] = new String[] {"\u30d1\u30ad\u30b9\u30bf\u30f3\u6642\u9593", "PKT", "\u30d1\u30ad\u30b9\u30bf\u30f3\u590f\u6642\u9593", "PKST"}; + String PONT[] = new String[] {"Pohnpei Time", "PONT", + "Pohnpei Summer Time", "PONST"}; String PST[] = new String[] {"\u592a\u5e73\u6d0b\u6a19\u6e96\u6642", "PST", "\u592a\u5e73\u6d0b\u590f\u6642\u9593", "PDT"}; String RST[] = new String[] {"\u6771\u90e8\u6a19\u6e96\u6642", "EST", @@ -169,8 +173,6 @@ "\u6771\u90e8\u590f\u6642\u9593 (\u30bf\u30b9\u30de\u30cb\u30a2)", "EST"}; String TMT[] = new String[] {"\u30c8\u30eb\u30af\u30e1\u30cb\u30b9\u30bf\u30f3\u6642\u9593", "TMT", "\u30c8\u30eb\u30af\u30e1\u30cb\u30b9\u30bf\u30f3\u590f\u6642\u9593", "TMST"}; - String TRUT[] = new String[] {"\u30c8\u30e9\u30c3\u30af\u6642\u9593", "TRUT", - "\u30c8\u30e9\u30c3\u30af\u590f\u6642\u9593", "TRUST"}; String ULAT[]= new String[] {"\u30a6\u30e9\u30fc\u30f3\u30d0\u30fc\u30c8\u30eb\u6642\u9593", "ULAT", "\u30a6\u30e9\u30fc\u30f3\u30d0\u30fc\u30c8\u30eb\u590f\u6642\u9593", "ULAST"}; String WART[] = new String[] {"\u897f\u30a2\u30eb\u30bc\u30f3\u30c1\u30f3\u6642\u9593", "WART", @@ -309,6 +311,7 @@ {"America/Atikokan", EST}, {"America/Atka", HAST}, {"America/Bahia", BRT}, + {"America/Bahia_Banderas", CST}, {"America/Barbados", AST}, {"America/Belem", BRT}, {"America/Belize", CST}, @@ -446,10 +449,13 @@ {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, + {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"\u30c7\u30a4\u30d3\u30b9\u6642\u9593", "DAVT", "\u30c7\u30a4\u30d3\u30b9\u590f\u6642\u9593", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"\u30c7\u30e5\u30e2\u30f3\u30c7\u30e5\u30eb\u30f4\u30a3\u30eb\u6642\u9593", "DDUT", "\u30c7\u30e5\u30e2\u30f3\u30c7\u30e5\u30eb\u30f4\u30a3\u30eb\u590f\u6642\u9593", "DDUST"}}, + {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST", + "Macquarie Island Summer Time", "MIST"}}, {"Antarctica/Mawson", new String[] {"\u30e2\u30fc\u30bd\u30f3\u6642\u9593", "MAWT", "\u30e2\u30fc\u30bd\u30f3\u590f\u6642\u9593", "MAWST"}}, {"Antarctica/McMurdo", NZST}, @@ -752,6 +758,7 @@ {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, {"Pacific/Chatham", CHAST}, + {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, {"Pacific/Efate", new String[] {"\u30d0\u30cc\u30a2\u30c4\u6642\u9593", "VUT", "\u30d0\u30cc\u30a2\u30c4\u590f\u6642\u9593", "VUST"}}, @@ -790,8 +797,8 @@ {"Pacific/Palau", new String[] {"\u30d1\u30e9\u30aa\u6642\u9593", "PWT", "\u30d1\u30e9\u30aa\u590f\u6642\u9593", "PWST"}}, {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Ponape", new String[] {"\u30dd\u30ca\u30da\u6642\u9593", "PONT", - "\u30dd\u30ca\u30da\u590f\u6642\u9593", "PONST"}}, + {"Pacific/Pohnpei", PONT}, + {"Pacific/Ponape", PONT}, {"Pacific/Port_Moresby", new String[] {"\u30d1\u30d7\u30a2\u30cb\u30e5\u30fc\u30ae\u30cb\u30a2\u6642\u9593", "PGT", "\u30d1\u30d7\u30a2\u30cb\u30e5\u30fc\u30ae\u30cb\u30a2\u590f\u6642\u9593", "PGST"}}, {"Pacific/Rarotonga", new String[] {"\u30af\u30c3\u30af\u8af8\u5cf6\u6642\u9593", "CKT", @@ -804,12 +811,12 @@ "\u30ae\u30eb\u30d0\u30fc\u30c8\u8af8\u5cf6\u590f\u6642\u9593", "GILST"}}, {"Pacific/Tongatapu", new String[] {"\u30c8\u30f3\u30ac\u6642\u9593", "TOT", "\u30c8\u30f3\u30ac\u590f\u6642\u9593", "TOST"}}, - {"Pacific/Truk", TRUT}, + {"Pacific/Truk", CHUT}, {"Pacific/Wake", new String[] {"\u30a6\u30a7\u30fc\u30af\u6642\u9593", "WAKT", "\u30a6\u30a7\u30fc\u30af\u590f\u6642\u9593", "WAKST"}}, {"Pacific/Wallis", new String[] {"\u30ef\u30ea\u30b9\u53ca\u3073\u30d5\u30c4\u30ca\u6642\u9593", "WFT", "\u30ef\u30ea\u30b9\u53ca\u3073\u30d5\u30c4\u30ca\u590f\u6642\u9593", "WFST"}}, - {"Pacific/Yap", TRUT}, + {"Pacific/Yap", CHUT}, {"Poland", CET}, {"PRC", CTT}, {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -75,6 +75,8 @@ "\uc911\uc559 \uc720\ub7fd \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CEST"}; String CHAST[] = new String[] {"Chatham \ud45c\uc900\uc2dc", "CHAST", "Chatham \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CHADT"}; + String CHUT[] = new String[] {"Chuuk Time", "CHUT", + "Chuuk Summer Time", "CHUST"}; String CIT[] = new String[] {"\uc911\uc559 \uc778\ub3c4\ub124\uc2dc\uc544 \uc2dc\uac04", "CIT", "\uc911\uc559 \uc778\ub3c4\ub124\uc2dc\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CIST"}; String CLT[] = new String[] {"\uce60\ub808 \uc2dc\uac04", "CLT", @@ -153,6 +155,8 @@ "Pitcairn \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PDT"}; String PKT[] = new String[] {"\ud30c\ud0a4\uc2a4\ud0c4 \uc2dc\uac04", "PKT", "\ud30c\ud0a4\uc2a4\ud0c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PKST"}; + String PONT[] = new String[] {"Pohnpei Time", "PONT", + "Pohnpei Summer Time", "PONST"}; String PST[] = new String[] {"\ud0dc\ud3c9\uc591 \ud45c\uc900\uc2dc", "PST", "\ud0dc\ud3c9\uc591 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PDT"}; String RST[] = new String[] {"\ub3d9\ubd80 \ud45c\uc900\uc2dc", "EST", @@ -169,8 +173,6 @@ "\ub3d9\ubd80 \uc77c\uad11\uc808\uc57d\uc2dc\uac04(\ud0dc\uc988\uba54\uc774\ub2c8\uc544)", "EST"}; String TMT[] = new String[] {"\ud22c\ub974\ud06c\uba54\ub2c8\uc2a4\ud0c4 \uc2dc\uac04", "TMT", "\ud22c\ub974\ud06c\uba54\ub2c8\uc2a4\ud0c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TMST"}; - String TRUT[] = new String[] {"\ud2b8\ub8e8\ud06c \uc2dc\uac04", "TRUT", - "\ud2b8\ub8e8\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TRUST"}; String ULAT[]= new String[] {"\uc6b8\ub780\ubc14\ud0c0\ub974 \uc2dc\uac04", "ULAT", "\uc6b8\ub780\ubc14\ud0c0\ub974 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ULAST"}; String WART[] = new String[] {"\uc11c\ubd80 \uc544\ub974\ud5e8\ud2f0\ub098 \uc2dc\uac04", "WART", @@ -309,6 +311,7 @@ {"America/Atikokan", EST}, {"America/Atka", HAST}, {"America/Bahia", BRT}, + {"America/Bahia_Banderas", CST}, {"America/Barbados", AST}, {"America/Belem", BRT}, {"America/Belize", CST}, @@ -446,10 +449,13 @@ {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, + {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"Davis \uc2dc\uac04", "DAVT", "Davis \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"\ub4a4\ubabd \ub4a4\ub974\ube4c \uc2dc\uac04", "DDUT", "\ub4a4\ubabd \ub4a4\ub974\ube4c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "DDUST"}}, + {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST", + "Macquarie Island Summer Time", "MIST"}}, {"Antarctica/Mawson", new String[] {"\ubaa8\uc2a8 \uc2dc\uac04", "MAWT", "\ubaa8\uc2a8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MAWST"}}, {"Antarctica/McMurdo", NZST}, @@ -752,6 +758,7 @@ {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, {"Pacific/Chatham", CHAST}, + {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, {"Pacific/Efate", new String[] {"\ube44\ub204\uc544\ud22c \uc2dc\uac04", "VUT", "\ubc14\ub204\uc544\ud22c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "VUST"}}, @@ -790,8 +797,8 @@ {"Pacific/Palau", new String[] {"\ud314\ub77c\uc6b0 \uc2dc\uac04", "PWT", "\ud314\ub77c\uc6b0 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PWST"}}, {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Ponape", new String[] {"\ud3ec\ub098\ud504 \uc2dc\uac04", "PONT", - "\ud3ec\ub098\ud504 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PONST"}}, + {"Pacific/Pohnpei", PONT}, + {"Pacific/Ponape", PONT}, {"Pacific/Port_Moresby", new String[] {"\ud30c\ud478\uc544\ub274\uae30\ub2c8 \uc2dc\uac04", "PGT", "\ud30c\ud478\uc544\ub274\uae30\ub2c8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PGST"}}, {"Pacific/Rarotonga", new String[] {"\ucfe0\ud06c \uad70\ub3c4 \uc2dc\uac04", "CKT", @@ -804,12 +811,12 @@ "\uae38\ubc84\ud2b8 \uad70\ub3c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "GILST"}}, {"Pacific/Tongatapu", new String[] {"\ud1b5\uac00 \uc2dc\uac04", "TOT", "\ud1b5\uac00 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TOST"}}, - {"Pacific/Truk", TRUT}, + {"Pacific/Truk", CHUT}, {"Pacific/Wake", new String[] {"\uc6e8\uc774\ud06c \uc2dc\uac04", "WAKT", "\uc6e8\uc774\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "WAKST"}}, {"Pacific/Wallis", new String[] {"\uc6d4\ub9ac\uc2a4 \ud6c4\ud22c\ub098 \uc2dc\uac04", "WFT", "\uc6d4\ub9ac\uc2a4 \ud6c4\ud2b8\ub098 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "WFST"}}, - {"Pacific/Yap", TRUT}, + {"Pacific/Yap", CHUT}, {"Poland", CET}, {"PRC", CTT}, {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -75,6 +75,8 @@ "Centraleuropeisk sommartid", "CEST"}; String CHAST[] = new String[] {"Chatham, normaltid", "CHAST", "Chatham, sommartid", "CHADT"}; + String CHUT[] = new String[] {"Chuuk Time", "CHUT", + "Chuuk Summer Time", "CHUST"}; String CIT[] = new String[] {"Centralindonesisk tid", "CIT", "Centralindonesisk sommartid", "CIST"}; String CLT[] = new String[] {"Chile, normaltid", "CLT", @@ -153,6 +155,8 @@ "Pitcairn, sommartid", "PDT"}; String PKT[] = new String[] {"Pakistan, normaltid", "PKT", "Pakistan, sommartid", "PKST"}; + String PONT[] = new String[] {"Pohnpei Time", "PONT", + "Pohnpei Summer Time", "PONST"}; String PST[] = new String[] {"Stilla havet, normaltid", "PST", "Stilla havet, sommartid", "PDT"}; String RST[] = new String[] {"Eastern, normaltid", "EST", @@ -169,8 +173,6 @@ "Eastern, sommartid (Tasmanien)", "EST"}; String TMT[] = new String[] {"Turkmenistan, normaltid", "TMT", "Turkmenistan, sommartid", "TMST"}; - String TRUT[] = new String[] {"Truk, normaltid", "TRUT", - "Truk, sommartid", "TRUST"}; String ULAT[]= new String[] {"Ulaanbaatar, normaltid", "ULAT", "Ulaanbaatar, sommartid", "ULAST"}; String WART[] = new String[] {"V\u00e4stargentina, normaltid", "WART", @@ -309,6 +311,7 @@ {"America/Atikokan", EST}, {"America/Atka", HAST}, {"America/Bahia", BRT}, + {"America/Bahia_Banderas", CST}, {"America/Barbados", AST}, {"America/Belem", BRT}, {"America/Belize", CST}, @@ -446,10 +449,13 @@ {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, + {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"Davis, normaltid", "DAVT", "Davis, sommartid", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville, normaltid", "DDUT", "Dumont-d'Urville, sommartid", "DDUST"}}, + {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST", + "Macquarie Island Summer Time", "MIST"}}, {"Antarctica/Mawson", new String[] {"Mawson, normaltid", "MAWT", "Mawson, sommartid", "MAWST"}}, {"Antarctica/McMurdo", NZST}, @@ -752,6 +758,7 @@ {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, {"Pacific/Chatham", CHAST}, + {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, {"Pacific/Efate", new String[] {"Vanuatu, normaltid", "VUT", "Vanuatu, sommartid", "VUST"}}, @@ -790,8 +797,8 @@ {"Pacific/Palau", new String[] {"Palau, normaltid", "PWT", "Palau, sommartid", "PWST"}}, {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Ponape", new String[] {"Ponape, normaltid", "PONT", - "Ponape, sommartid", "PONST"}}, + {"Pacific/Pohnpei", PONT}, + {"Pacific/Ponape", PONT}, {"Pacific/Port_Moresby", new String[] {"Papua Nya Guinea, normaltid", "PGT", "Papua Nya Guinea, sommartid", "PGST"}}, {"Pacific/Rarotonga", new String[] {"Cook\u00f6arna, normaltid", "CKT", @@ -804,12 +811,12 @@ "Gilbert\u00f6arna, sommartid", "GILST"}}, {"Pacific/Tongatapu", new String[] {"Tonga, normaltid", "TOT", "Tonga, sommartid", "TOST"}}, - {"Pacific/Truk", TRUT}, + {"Pacific/Truk", CHUT}, {"Pacific/Wake", new String[] {"Wake, normaltid", "WAKT", "Wake, sommartid", "WAKST"}}, {"Pacific/Wallis", new String[] {"Wallis & Futuna, normaltid", "WFT", "Wallis & Futuna, sommartid", "WFST"}}, - {"Pacific/Yap", TRUT}, + {"Pacific/Yap", CHUT}, {"Poland", CET}, {"PRC", CTT}, {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -75,6 +75,8 @@ "\u4e2d\u6b27\u590f\u4ee4\u65f6", "CEST"}; String CHAST[] = new String[] {"\u67e5\u8428\u59c6\u6807\u51c6\u65f6\u95f4", "CHAST", "\u67e5\u8428\u59c6\u590f\u4ee4\u65f6", "CHADT"}; + String CHUT[] = new String[] {"Chuuk Time", "CHUT", + "Chuuk Summer Time", "CHUST"}; String CIT[] = new String[] {"\u4e2d\u90e8\u5370\u5ea6\u5c3c\u897f\u4e9a\u65f6\u95f4", "CIT", "\u4e2d\u90e8\u5370\u5ea6\u5c3c\u897f\u4e9a\u590f\u4ee4\u65f6", "CIST"}; String CLT[] = new String[] {"\u667a\u5229\u65f6\u95f4", "CLT", @@ -153,6 +155,8 @@ "\u76ae\u7279\u5eb7\u5c9b\u590f\u4ee4\u65f6", "PDT"}; String PKT[] = new String[] {"\u5df4\u57fa\u65af\u5766\u65f6\u95f4", "PKT", "\u5df4\u57fa\u65af\u5766\u590f\u4ee4\u65f6", "PKST"}; + String PONT[] = new String[] {"Pohnpei Time", "PONT", + "Pohnpei Summer Time", "PONST"}; String PST[] = new String[] {"\u592a\u5e73\u6d0b\u6807\u51c6\u65f6\u95f4", "PST", "\u592a\u5e73\u6d0b\u590f\u4ee4\u65f6", "PDT"}; String RST[] = new String[] {"\u4e1c\u90e8\u6807\u51c6\u65f6\u95f4", "EST", @@ -169,8 +173,6 @@ "\u4e1c\u90e8\u590f\u4ee4\u65f6\uff08\u5854\u65af\u9a6c\u5c3c\u4e9a\uff09", "EST"}; String TMT[] = new String[] {"\u571f\u5e93\u66fc\u65f6\u95f4", "TMT", "\u571f\u5e93\u66fc\u590f\u4ee4\u65f6", "TMST"}; - String TRUT[] = new String[] {"\u7279\u9c81\u514b\u65f6\u95f4", "TRUT", - "\u7279\u9c81\u514b\u590f\u4ee4\u65f6", "TRUST"}; String ULAT[]= new String[] {"\u5e93\u4f26\u65f6\u95f4", "ULAT", "\u5e93\u4f26\u590f\u4ee4\u65f6", "ULAST"}; String WART[] = new String[] {"\u897f\u963f\u6839\u5ef7\u65f6\u95f4", "WART", @@ -309,6 +311,7 @@ {"America/Atikokan", EST}, {"America/Atka", HAST}, {"America/Bahia", BRT}, + {"America/Bahia_Banderas", CST}, {"America/Barbados", AST}, {"America/Belem", BRT}, {"America/Belize", CST}, @@ -446,10 +449,13 @@ {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, + {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"\u6234\u7ef4\u65af\u65f6\u95f4", "DAVT", "\u6234\u7ef4\u65af\u590f\u4ee4\u65f6", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville \u65f6\u95f4", "DDUT", "Dumont-d'Urville \u590f\u4ee4\u65f6", "DDUST"}}, + {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST", + "Macquarie Island Summer Time", "MIST"}}, {"Antarctica/Mawson", new String[] {"\u83ab\u68ee\u65f6\u95f4", "MAWT", "\u83ab\u68ee\u590f\u4ee4\u65f6", "MAWST"}}, {"Antarctica/McMurdo", NZST}, @@ -752,6 +758,7 @@ {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, {"Pacific/Chatham", CHAST}, + {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, {"Pacific/Efate", new String[] {"\u74e6\u5974\u963f\u56fe\u65f6\u95f4", "VUT", "\u74e6\u5974\u963f\u56fe\u590f\u4ee4\u65f6", "VUST"}}, @@ -790,8 +797,8 @@ {"Pacific/Palau", new String[] {"\u5e1b\u7409\u65f6\u95f4", "PWT", "\u5e1b\u7409\u590f\u4ee4\u65f6", "PWST"}}, {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Ponape", new String[] {"Ponape \u65f6\u95f4", "PONT", - "Ponape \u590f\u4ee4\u65f6", "PONST"}}, + {"Pacific/Pohnpei", PONT}, + {"Pacific/Ponape", PONT}, {"Pacific/Port_Moresby", new String[] {"\u5df4\u5e03\u4e9a\u65b0\u51e0\u5185\u4e9a\u65f6\u95f4", "PGT", "\u5df4\u5e03\u4e9a\u65b0\u51e0\u5185\u4e9a\u590f\u4ee4\u65f6", "PGST"}}, {"Pacific/Rarotonga", new String[] {"\u5e93\u514b\u7fa4\u5c9b\u65f6\u95f4", "CKT", @@ -804,12 +811,12 @@ "\u5409\u4f2f\u7279\u7fa4\u5c9b\u590f\u4ee4\u65f6", "GILST"}}, {"Pacific/Tongatapu", new String[] {"\u4e1c\u52a0\u65f6\u95f4", "TOT", "\u4e1c\u52a0\u590f\u4ee4\u65f6", "TOST"}}, - {"Pacific/Truk", TRUT}, + {"Pacific/Truk", CHUT}, {"Pacific/Wake", new String[] {"\u5a01\u514b\u65f6\u95f4", "WAKT", "\u5a01\u514b\u590f\u4ee4\u65f6", "WAKST"}}, {"Pacific/Wallis", new String[] {"\u74e6\u5229\u65af\u53ca\u798f\u675c\u7eb3\u7fa4\u5c9b\u65f6\u95f4", "WFT", "\u74e6\u5229\u65af\u53ca\u798f\u675c\u7eb3\u7fa4\u5c9b\u590f\u4ee4\u65f6", "WFST"}}, - {"Pacific/Yap", TRUT}, + {"Pacific/Yap", CHUT}, {"Poland", CET}, {"PRC", CTT}, {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java Sun Aug 29 22:41:28 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -75,6 +75,8 @@ "\u4e2d\u6b50\u590f\u4ee4\u6642\u9593", "CEST"}; String CHAST[] = new String[] {"\u67e5\u5766\u6a19\u6e96\u6642\u9593", "CHAST", "\u67e5\u5766\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "CHADT"}; + String CHUT[] = new String[] {"Chuuk Time", "CHUT", + "Chuuk Summer Time", "CHUST"}; String CIT[] = new String[] {"\u4e2d\u5370\u5ea6\u5c3c\u897f\u4e9e\u6642\u9593", "CIT", "\u4e2d\u5370\u5ea6\u5c3c\u897f\u4e9e\u590f\u4ee4\u6642\u9593", "CIST"}; String CLT[] = new String[] {"\u667a\u5229\u6642\u9593", "CLT", @@ -153,6 +155,8 @@ "\u76ae\u7279\u5eb7\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "PDT"}; String PKT[] = new String[] {"\u5df4\u57fa\u65af\u5766\u6642\u9593", "PKT", "\u5df4\u57fa\u65af\u5766\u590f\u4ee4\u6642\u9593", "PKST"}; + String PONT[] = new String[] {"Pohnpei Time", "PONT", + "Pohnpei Summer Time", "PONST"}; String PST[] = new String[] {"\u592a\u5e73\u6d0b\u6a19\u6e96\u6642\u9593", "PST", "\u592a\u5e73\u6d0b\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "PDT"}; String RST[] = new String[] {"\u6771\u65b9\u6a19\u6e96\u6642\u9593", "EST", @@ -169,8 +173,6 @@ "\u6771\u90e8\u590f\u4ee4\u6642\u9593 (\u5854\u65af\u6885\u5c3c\u4e9e\u5cf6)", "EST"}; String TMT[] = new String[] {"\u571f\u5eab\u66fc\u6642\u9593", "TMT", "\u571f\u5eab\u66fc\u590f\u4ee4\u6642\u9593", "TMST"}; - String TRUT[] = new String[] {"\u7279\u9b6f\u514b\u6642\u9593", "TRUT", - "\u7279\u9b6f\u514b\u590f\u4ee4\u6642\u9593", "TRUST"}; String ULAT[]= new String[] {"\u5eab\u502b\u6642\u9593", "ULAT", "\u5eab\u502b\u590f\u4ee4\u6642\u9593", "ULAST"}; String WART[] = new String[] {"\u897f\u963f\u6839\u5ef7\u6642\u9593", "WART", @@ -309,6 +311,7 @@ {"America/Atikokan", EST}, {"America/Atka", HAST}, {"America/Bahia", BRT}, + {"America/Bahia_Banderas", CST}, {"America/Barbados", AST}, {"America/Belem", BRT}, {"America/Belize", CST}, @@ -446,10 +449,13 @@ {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, + {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"\u81fa\u7dad\u65af\u6642\u9593", "DAVT", "\u81fa\u7dad\u65af\u590f\u4ee4\u6642\u9593", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville \u6642\u9593", "DDUT", "Dumont-d'Urville \u590f\u4ee4\u6642\u9593", "DDUST"}}, + {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST", + "Macquarie Island Summer Time", "MIST"}}, {"Antarctica/Mawson", new String[] {"\u83ab\u68ee\u6642\u9593", "MAWT", "\u83ab\u68ee\u590f\u4ee4\u6642\u9593", "MAWST"}}, {"Antarctica/McMurdo", NZST}, @@ -753,6 +759,7 @@ {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, {"Pacific/Chatham", CHAST}, + {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, {"Pacific/Efate", new String[] {"\u74e6\u5974\u963f\u5716\u6642\u9593", "VUT", "\u74e6\u5974\u963f\u5716\u590f\u4ee4\u6642\u9593", "VUST"}}, @@ -791,8 +798,8 @@ {"Pacific/Palau", new String[] {"\u5e1b\u7409\u6642\u9593", "PWT", "\u5e1b\u7409\u590f\u4ee4\u6642\u9593", "PWST"}}, {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Ponape", new String[] {"Ponape \u6642\u9593", "PONT", - "Ponape \u590f\u4ee4\u6642\u9593", "PONST"}}, + {"Pacific/Pohnpei", PONT}, + {"Pacific/Ponape", PONT}, {"Pacific/Port_Moresby", new String[] {"\u5df4\u5e03\u4e9e\u65b0\u5e7e\u5167\u4e9e\u6642\u9593", "PGT", "\u5df4\u5e03\u4e9e\u65b0\u5e7e\u5167\u4e9e\u590f\u4ee4\u6642\u9593", "PGST"}}, {"Pacific/Rarotonga", new String[] {"\u5eab\u514b\u7fa4\u5cf6\u6642\u9593", "CKT", @@ -805,12 +812,12 @@ "\u5409\u4f2f\u7279\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "GILST"}}, {"Pacific/Tongatapu", new String[] {"\u6771\u52a0\u6642\u9593", "TOT", "\u6771\u52a0\u590f\u4ee4\u6642\u9593", "TOST"}}, - {"Pacific/Truk", TRUT}, + {"Pacific/Truk", CHUT}, {"Pacific/Wake", new String[] {"\u5a01\u514b\u6642\u9593", "WAKT", "\u5a01\u514b\u590f\u4ee4\u6642\u9593", "WAKST"}}, {"Pacific/Wallis", new String[] {"\u74e6\u5229\u65af\u53ca\u798f\u675c\u7d0d\u7fa4\u5cf6\u6642\u9593", "WFT", "\u74e6\u5229\u65af\u53ca\u798f\u675c\u7d0d\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "WFST"}}, - {"Pacific/Yap", TRUT}, + {"Pacific/Yap", CHUT}, {"Poland", CET}, {"PRC", CTT}, {"PST8PDT", PST},
--- a/jdk/src/share/lib/security/java.security-solaris Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/lib/security/java.security-solaris Sun Aug 29 22:41:28 2010 -0700 @@ -260,3 +260,30 @@ # Example, # ocsp.responderCertSerialNumber=2A:FF:00 +# +# Policy for failed Kerberos KDC lookups: +# +# When a KDC is unavailable (network error, service failure, etc), it is +# put inside a blacklist and accessed less often for future requests. The +# value (case-insensitive) for this policy can be: +# +# tryLast +# KDCs in the blacklist are always tried after those not on the list. +# +# tryLess[:max_retries,timeout] +# KDCs in the blacklist are still tried by their order in the configuration, +# but with smaller max_retries and timeout values. max_retries and timeout +# are optional numerical parameters (default 1 and 5000, which means once +# and 5 seconds). Please notes that if any of the values defined here is +# more than what is defined in krb5.conf, it will be ignored. +# +# Whenever a KDC is detected as available, it is removed from the blacklist. +# The blacklist is reset when krb5.conf is reloaded. You can add +# refreshKrb5Config=true to a JAAS configuration file so that krb5.conf is +# reloaded whenever a JAAS authentication is attempted. +# +# Example, +# krb5.kdc.bad.policy = tryLast +# krb5.kdc.bad.policy = tryLess:2,2000 +krb5.kdc.bad.policy = tryLast +
--- a/jdk/src/share/lib/security/java.security-windows Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/lib/security/java.security-windows Sun Aug 29 22:41:28 2010 -0700 @@ -260,3 +260,30 @@ # Example, # ocsp.responderCertSerialNumber=2A:FF:00 +# +# Policy for failed Kerberos KDC lookups: +# +# When a KDC is unavailable (network error, service failure, etc), it is +# put inside a blacklist and accessed less often for future requests. The +# value (case-insensitive) for this policy can be: +# +# tryLast +# KDCs in the blacklist are always tried after those not on the list. +# +# tryLess[:max_retries,timeout] +# KDCs in the blacklist are still tried by their order in the configuration, +# but with smaller max_retries and timeout values. max_retries and timeout +# are optional numerical parameters (default 1 and 5000, which means once +# and 5 seconds). Please notes that if any of the values defined here is +# more than what is defined in krb5.conf, it will be ignored. +# +# Whenever a KDC is detected as available, it is removed from the blacklist. +# The blacklist is reset when krb5.conf is reloaded. You can add +# refreshKrb5Config=true to a JAAS configuration file so that krb5.conf is +# reloaded whenever a JAAS authentication is attempted. +# +# Example, +# krb5.kdc.bad.policy = tryLast +# krb5.kdc.bad.policy = tryLess:2,2000 +krb5.kdc.bad.policy = tryLast +
--- a/jdk/src/share/native/common/check_code.c Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/share/native/common/check_code.c Sun Aug 29 22:41:28 2010 -0700 @@ -2730,7 +2730,10 @@ operand); const char *result_signature; check_and_push(context, signature, VM_STRING_UTF); - result_signature = strchr(signature, JVM_SIGNATURE_ENDFUNC) + 1; + result_signature = strchr(signature, JVM_SIGNATURE_ENDFUNC); + if (result_signature++ == NULL) { + CCerror(context, "Illegal signature %s", signature); + } if (result_signature[0] == JVM_SIGNATURE_VOID) { stack_results = ""; } else { @@ -3654,14 +3657,13 @@ const char **signature_p, fullinfo_type *full_info_p) { const char *p = *signature_p; - fullinfo_type full_info = MAKE_FULLINFO(0, 0, 0); + fullinfo_type full_info = MAKE_FULLINFO(ITEM_Bogus, 0, 0); char result; int array_depth = 0; for (;;) { switch(*p++) { default: - full_info = MAKE_FULLINFO(ITEM_Bogus, 0, 0); result = 0; break; @@ -3714,7 +3716,14 @@ char buffer_space[256]; char *buffer = buffer_space; char *finish = strchr(p, JVM_SIGNATURE_ENDCLASS); - int length = finish - p; + int length; + if (finish == NULL) { + /* Signature must have ';' after the class name. + * If it does not, return 0 and ITEM_Bogus in full_info. */ + result = 0; + break; + } + length = finish - p; if (length + 1 > (int)sizeof(buffer_space)) { buffer = malloc(length + 1); check_and_push(context, buffer, VM_MALLOC_BLK);
--- a/jdk/src/solaris/classes/java/io/UnixFileSystem.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/solaris/classes/java/io/UnixFileSystem.java Sun Aug 29 22:41:28 2010 -0700 @@ -187,7 +187,6 @@ } } } - assert canonicalize0(path).equals(res) || path.startsWith(javaHome); return res; } }
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java Sun Aug 29 22:41:28 2010 -0700 @@ -1141,6 +1141,13 @@ } result = result.resolve(element); } + + // check file exists (without following links) + try { + UnixFileAttributes.get(result, false); + } catch (UnixException x) { + x.rethrowAsIOException(result); + } return result; }
--- a/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c Sun Aug 29 22:41:28 2010 -0700 @@ -1052,30 +1052,38 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env, jobject this) { jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID); - int fd; - - int t = 1; + int fd, t = 1; +#ifdef AF_INET6 + int domain = ipv6_available() ? AF_INET6 : AF_INET; +#else + int domain = AF_INET; +#endif if (IS_NULL(fdObj)) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed"); return; - } else { -#ifdef AF_INET6 - if (ipv6_available()) { - fd = JVM_Socket(AF_INET6, SOCK_DGRAM, 0); - } else -#endif /* AF_INET6 */ - { - fd = JVM_Socket(AF_INET, SOCK_DGRAM, 0); - } } - if (fd == JVM_IO_ERR) { + + if ((fd = JVM_Socket(domain, SOCK_DGRAM, 0)) == JVM_IO_ERR) { NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Error creating socket"); return; } +#ifdef AF_INET6 + /* Disable IPV6_V6ONLY to ensure dual-socket support */ + if (domain == AF_INET6) { + int arg = 0; + if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg, + sizeof(int)) < 0) { + NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6"); + close(fd); + return; + } + } +#endif /* AF_INET6 */ + setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof(int)); #ifdef __linux__ @@ -1088,7 +1096,7 @@ * On Linux for IPv6 sockets we must set the hop limit * to 1 to be compatible with default ttl of 1 for IPv4 sockets. */ - if (ipv6_available()) { + if (domain == AF_INET6) { int ttl = 1; setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&ttl, sizeof(ttl));
--- a/jdk/src/solaris/native/java/net/PlainSocketImpl.c Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/solaris/native/java/net/PlainSocketImpl.c Sun Aug 29 22:41:28 2010 -0700 @@ -181,6 +181,12 @@ jboolean stream) { jobject fdObj, ssObj; int fd; + int type = (stream ? SOCK_STREAM : SOCK_DGRAM); +#ifdef AF_INET6 + int domain = ipv6_available() ? AF_INET6 : AF_INET; +#else + int domain = AF_INET; +#endif if (socketExceptionCls == NULL) { jclass c = (*env)->FindClass(env, "java/net/SocketException"); @@ -194,25 +200,29 @@ (*env)->ThrowNew(env, socketExceptionCls, "null fd object"); return; } -#ifdef AF_INET6 - if (ipv6_available()) { - fd = JVM_Socket(AF_INET6, (stream ? SOCK_STREAM: SOCK_DGRAM), 0); - } else -#endif /* AF_INET6 */ - { - fd = JVM_Socket(AF_INET, (stream ? SOCK_STREAM: SOCK_DGRAM), 0); - } - if (fd == JVM_IO_ERR) { + + if ((fd = JVM_Socket(domain, type, 0)) == JVM_IO_ERR) { /* note: if you run out of fds, you may not be able to load * the exception class, and get a NoClassDefFoundError * instead. */ NET_ThrowNew(env, errno, "can't create socket"); return; - } else { - (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd); } +#ifdef AF_INET6 + /* Disable IPV6_V6ONLY to ensure dual-socket support */ + if (domain == AF_INET6) { + int arg = 0; + if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg, + sizeof(int)) < 0) { + NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6"); + close(fd); + return; + } + } +#endif /* AF_INET6 */ + /* * If this is a server socket then enable SO_REUSEADDR * automatically and set to non blocking. @@ -221,9 +231,15 @@ if (ssObj != NULL) { int arg = 1; SET_NONBLOCKING(fd); - JVM_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, - sizeof(arg)); + if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, + sizeof(arg)) < 0) { + NET_ThrowNew(env, errno, "cannot set SO_REUSEADDR"); + close(fd); + return; + } } + + (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd); } /*
--- a/jdk/src/solaris/native/sun/nio/ch/Net.c Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/solaris/native/sun/nio/ch/Net.c Sun Aug 29 22:41:28 2010 -0700 @@ -170,6 +170,22 @@ if (fd < 0) { return handleSocketError(env, errno); } + +#ifdef AF_INET6 + /* Disable IPV6_V6ONLY to ensure dual-socket support */ + if (domain == AF_INET6) { + int arg = 0; + if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg, + sizeof(int)) < 0) { + JNU_ThrowByNameWithLastError(env, + JNU_JAVANETPKG "SocketException", + "sun.nio.ch.Net.setIntOption"); + close(fd); + return -1; + } + } +#endif + if (reuse) { int arg = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
--- a/jdk/src/windows/classes/java/io/Win32FileSystem.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/src/windows/classes/java/io/Win32FileSystem.java Sun Aug 29 22:41:28 2010 -0700 @@ -424,7 +424,6 @@ } } } - assert canonicalize0(path).equalsIgnoreCase(res); return res; } }
--- a/jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh Sun Aug 29 22:41:28 2010 -0700 @@ -55,7 +55,7 @@ Linux ) FS="/" ;; - Windows* ) + Windows* | CYGWIN* ) FS="\\" ;; esac
--- a/jdk/test/java/net/URI/Test.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/test/java/net/URI/Test.java Sun Aug 29 22:41:28 2010 -0700 @@ -1536,6 +1536,7 @@ serial(); urls(); npes(); + bugs(); } @@ -1572,6 +1573,19 @@ } + // miscellaneous bugs/rfes that don't fit in with the test framework + + static void bugs() { + // 6339649 - include detail message from nested exception + try { + URI uri = URI.create("http://nowhere.net/should not be permitted"); + } catch (IllegalArgumentException e) { + if ("".equals(e.getMessage()) || e.getMessage() == null) { + throw new RuntimeException ("No detail message"); + } + } + } + public static void main(String[] args) throws Exception { switch (args.length) {
--- a/jdk/test/java/nio/file/Path/Misc.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/test/java/nio/file/Path/Misc.java Sun Aug 29 22:41:28 2010 -0700 @@ -261,6 +261,21 @@ assertTrue(file.toRealPath(true).isSameFile(file.toRealPath(false))); /** + * Test: toRealPath should fail if file does not exist + */ + Path doesNotExist = dir.resolve("DoesNotExist"); + try { + doesNotExist.toRealPath(true); + throw new RuntimeException("IOException expected"); + } catch (IOException expected) { + } + try { + doesNotExist.toRealPath(false); + throw new RuntimeException("IOException expected"); + } catch (IOException expected) { + } + + /** * Test: toRealPath(true) should resolve links */ if (supportsLinks) {
--- a/jdk/test/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.sh Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/test/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.sh Sun Aug 29 22:41:28 2010 -0700 @@ -23,6 +23,7 @@ # # @test +# @ignore until 6543856 is fixed # @bug 4990825 # @summary attach to external but local JVM processes # @library ../../testlibrary
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/net/www/protocol/file/DirPermissionDenied.java Sun Aug 29 22:41:28 2010 -0700 @@ -0,0 +1,59 @@ +/* + * 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.net.URL; +import java.net.URLConnection; +import java.io.IOException; + +public class DirPermissionDenied { + public static void main(String[] args) throws Exception { + URL url = new URL("file:" + args[0]); + + try { + URLConnection uc = url.openConnection(); + uc.connect(); + } catch (IOException e) { + // OK + } catch (Exception e) { + throw new RuntimeException("Failed " + e); + } + + try { + URLConnection uc = url.openConnection(); + uc.getInputStream(); + } catch (IOException e) { + // OK + } catch (Exception e) { + throw new RuntimeException("Failed " + e); + } + + try { + URLConnection uc = url.openConnection(); + uc.getContentLengthLong(); + } catch (IOException e) { + // OK + } catch (Exception e) { + throw new RuntimeException("Failed " + e); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/net/www/protocol/file/DirPermissionDenied.sh Sun Aug 29 22:41:28 2010 -0700 @@ -0,0 +1,41 @@ +# +# 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 6977851 +# @summary NPE from FileURLConnection.connect +# @build DirPermissionDenied +# @run shell DirPermissionDenied.sh + +TESTDIR="${TESTCLASSES}/DirPermissionDeniedDirectory" +echo ${TESTDIR} + +rm -rf ${TESTDIR} +mkdir -p ${TESTDIR} +chmod 333 ${TESTDIR} + +$TESTJAVA/bin/java -classpath $TESTCLASSES DirPermissionDenied ${TESTDIR} +result=$? +rm -rf ${TESTDIR} +exit $result
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/krb5/BadKdcDefaultValue.java Sun Aug 29 22:41:28 2010 -0700 @@ -0,0 +1,40 @@ +/* + * 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 6976536 + * @summary Solaris JREs do not have the krb5.kdc.bad.policy configured by default. + * @run main/othervm BadKdcDefaultValue + */ + +import java.security.Security; + +public class BadKdcDefaultValue { + public static void main(String[] args) throws Exception { + if (!"tryLast".equalsIgnoreCase( + Security.getProperty("krb5.kdc.bad.policy"))) { + throw new Exception("Default value not correct"); + } + } +} +
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6226610.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6226610.java Sun Aug 29 22:41:28 2010 -0700 @@ -23,7 +23,7 @@ /* * @test - * @bug 6226610 + * @bug 6226610 6973030 * @run main/othervm B6226610 * @summary HTTP tunnel connections send user headers to proxy */ @@ -36,45 +36,23 @@ import java.io.*; import java.net.*; -import javax.net.ssl.*; -import javax.net.ServerSocketFactory; -import sun.net.www.*; -import java.util.Enumeration; +import sun.net.www.MessageHeader; public class B6226610 { static HeaderCheckerProxyTunnelServer proxy; - // it seems there's no proxy ever if a url points to 'localhost', - // even if proxy related properties are set. so we need to bind - // our simple http proxy and http server to a non-loopback address - static InetAddress firstNonLoAddress = null; - - public static void main(String[] args) + public static void main(String[] args) throws Exception { - try { - proxy = new HeaderCheckerProxyTunnelServer(); - proxy.start(); - } catch (Exception e) { - System.out.println("Cannot create proxy: " + e); - } + proxy = new HeaderCheckerProxyTunnelServer(); + proxy.start(); - try { - firstNonLoAddress = getNonLoAddress(); - - if (firstNonLoAddress == null) { - System.out.println("The test needs at least one non-loopback address to run. Quit now."); - System.exit(0); - } - } catch (Exception e) { - e.printStackTrace(); - } - - System.setProperty( "https.proxyHost", firstNonLoAddress.getHostAddress()); - System.setProperty( "https.proxyPort", (new Integer(proxy.getLocalPort())).toString() ); + String hostname = InetAddress.getLocalHost().getHostName(); try { - URL u = new URL("https://" + firstNonLoAddress.getHostAddress()); - java.net.URLConnection c = u.openConnection(); + URL u = new URL("https://" + hostname + "/"); + System.out.println("Connecting to " + u); + InetSocketAddress proxyAddr = new InetSocketAddress(hostname, proxy.getLocalPort()); + java.net.URLConnection c = u.openConnection(new Proxy(Proxy.Type.HTTP, proxyAddr)); /* I want this header to go to the destination server only, protected * by SSL @@ -89,33 +67,15 @@ } else System.out.println(e); - + } finally { + if (proxy != null) proxy.shutdown(); } if (HeaderCheckerProxyTunnelServer.failed) - throw new RuntimeException("Test failed: Proxy should not receive user defined headers for tunneled requests"); + throw new RuntimeException("Test failed; see output"); } - - public static InetAddress getNonLoAddress() throws Exception { - NetworkInterface loNIC = NetworkInterface.getByInetAddress(InetAddress.getByName("localhost")); - Enumeration<NetworkInterface> nics = NetworkInterface.getNetworkInterfaces(); - while (nics.hasMoreElements()) { - NetworkInterface nic = nics.nextElement(); - if (!nic.getName().equalsIgnoreCase(loNIC.getName())) { - Enumeration<InetAddress> addrs = nic.getInetAddresses(); - while (addrs.hasMoreElements()) { - InetAddress addr = addrs.nextElement(); - if (!addr.isLoopbackAddress()) - return addr; - } - } - } - return null; - } - } - class HeaderCheckerProxyTunnelServer extends Thread { public static boolean failed = false; @@ -139,6 +99,10 @@ } } + void shutdown() { + try { ss.close(); } catch (IOException e) {} + } + public void run() { try { @@ -178,6 +142,15 @@ retrieveConnectInfo(statusLine); if (mheader.findValue("X-TestHeader") != null) { + System.out.println("Proxy should not receive user defined headers for tunneled requests"); + failed = true; + } + + // 6973030 + String value; + if ((value = mheader.findValue("Proxy-Connection")) == null || + !value.equals("keep-alive")) { + System.out.println("Proxy-Connection:keep-alive not being sent"); failed = true; }
--- a/jdk/test/tools/jar/JarEntryTime.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/test/tools/jar/JarEntryTime.java Sun Aug 29 22:41:28 2010 -0700 @@ -23,7 +23,7 @@ /** * @test - * @bug 4225317 + * @bug 4225317 6969651 * @summary Check extracted files have date as per those in the .jar file */ @@ -68,17 +68,9 @@ } public static void realMain(String[] args) throws Throwable { - final long now = System.currentTimeMillis(); - final long earlier = now - (60L * 60L * 6L * 1000L); - final long yesterday = now - (60L * 60L * 24L * 1000L); - - // ZipEntry's mod date has 2 seconds precision: give extra time to - // allow for e.g. rounding/truncation and networked/samba drives. - final long PRECISION = 10000L; File dirOuter = new File("outer"); File dirInner = new File(dirOuter, "inner"); - File jarFile = new File("JarEntryTime.jar"); // Remove any leftovers from prior run @@ -99,6 +91,17 @@ PrintWriter pw = new PrintWriter(fileInner); pw.println("hello, world"); pw.close(); + + // Get the "now" from the "last-modified-time" of the last file we + // just created, instead of the "System.currentTimeMillis()", to + // workaround the possible "time difference" due to nfs. + final long now = fileInner.lastModified(); + final long earlier = now - (60L * 60L * 6L * 1000L); + final long yesterday = now - (60L * 60L * 24L * 1000L); + // ZipEntry's mod date has 2 seconds precision: give extra time to + // allow for e.g. rounding/truncation and networked/samba drives. + final long PRECISION = 10000L; + dirOuter.setLastModified(now); dirInner.setLastModified(yesterday); fileInner.setLastModified(earlier);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/pack200/CommandLineTests.java Sun Aug 29 22:41:28 2010 -0700 @@ -0,0 +1,179 @@ +/* + * 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 + * 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 CommandLineTests.sh + * @bug 6521334 6965836 6965836 + * @compile -XDignore.symbol.file CommandLineTests.java Pack200Test.java + * @run main/timeout=1200 CommandLineTests + * @summary An ad hoc test to verify the behavior of pack200/unpack200 CLIs, + * and a simulation of pack/unpacking in the install repo. + * @author ksrini + */ + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; +/* + * We try a potpouri of things ie. we have pack.conf to setup some + * options as well as a couple of command line options. We also test + * the packing and unpacking mechanism using the Java APIs. This also + * simulates pack200 the install workspace, noting that this is a simulation + * and can only test jars that are guaranteed to be available, also the + * configuration may not be in sync with the installer workspace. + */ + +public class CommandLineTests { + private static final File CWD = new File("."); + private static final File EXP_SDK = new File(CWD, "exp-sdk-image"); + private static final File EXP_SDK_LIB_DIR = new File(EXP_SDK, "lib"); + private static final File EXP_SDK_BIN_DIR = new File(EXP_SDK, "bin"); + private static final File EXP_JRE_DIR = new File(EXP_SDK, "jre"); + private static final File EXP_JRE_LIB_DIR = new File(EXP_JRE_DIR, "lib"); + private static final File RtJar = new File(EXP_JRE_LIB_DIR, "rt.jar"); + private static final File CharsetsJar = new File(EXP_JRE_LIB_DIR, "charsets.jar"); + private static final File JsseJar = new File(EXP_JRE_LIB_DIR, "jsse.jar"); + private static final File ToolsJar = new File(EXP_SDK_LIB_DIR, "tools.jar"); + private static final File javaCmd; + private static final File javacCmd; + private static final File ConfigFile = new File("pack.conf"); + private static final List<File> jarList; + + static { + javaCmd = Utils.IsWindows + ? new File(EXP_SDK_BIN_DIR, "java.exe") + : new File(EXP_SDK_BIN_DIR, "java"); + + javacCmd = Utils.IsWindows + ? new File(EXP_SDK_BIN_DIR, "javac.exe") + : new File(EXP_SDK_BIN_DIR, "javac"); + + jarList = new ArrayList<File>(); + jarList.add(RtJar); + jarList.add(CharsetsJar); + jarList.add(JsseJar); + jarList.add(ToolsJar); + } + + // init test area with a copy of the sdk + static void init() throws IOException { + Utils.recursiveCopy(Utils.JavaSDK, EXP_SDK); + creatConfigFile(); + } + + // Hopefully, this should be kept in sync with what the installer does. + static void creatConfigFile() throws IOException { + FileOutputStream fos = null; + PrintStream ps = null; + try { + fos = new FileOutputStream(ConfigFile); + ps = new PrintStream(fos); + ps.println("com.sun.java.util.jar.pack.debug.verbose=0"); + ps.println("pack.modification.time=keep"); + ps.println("pack.keep.class.order=true"); + ps.println("pack.deflate.hint=false"); + // Fail the build, if new or unknown attributes are introduced. + ps.println("pack.unknown.attribute=error"); + ps.println("pack.segment.limit=-1"); + // BugId: 6328502, These files will be passed-through as-is. + ps.println("pack.pass.file.0=java/lang/Error.class"); + ps.println("pack.pass.file.1=java/lang/LinkageError.class"); + ps.println("pack.pass.file.2=java/lang/Object.class"); + ps.println("pack.pass.file.3=java/lang/Throwable.class"); + ps.println("pack.pass.file.4=java/lang/VerifyError.class"); + ps.println("pack.pass.file.5=com/sun/demo/jvmti/hprof/Tracker.class"); + } finally { + Utils.close(ps); + Utils.close(fos); + } + } + + static void runPack200(boolean jre) throws IOException { + List<String> cmdsList = new ArrayList<String>(); + for (File f : jarList) { + if (jre && f.getName().equals("tools.jar")) { + continue; // need not worry about tools.jar for JRE + } + // make a backup copy for re-use + File bakFile = new File(f.getName() + ".bak"); + if (!bakFile.exists()) { // backup + Utils.copyFile(f.getAbsoluteFile(), bakFile.getAbsoluteFile()); + } else { // restore + Utils.copyFile(bakFile.getAbsoluteFile(), f.getAbsoluteFile()); + } + cmdsList.clear(); + cmdsList.add(Utils.getPack200Cmd()); + cmdsList.add("-J-esa"); + cmdsList.add("-J-ea"); + cmdsList.add(Utils.Is64Bit ? "-J-Xmx1g" : "-J-Xmx512m"); + cmdsList.add("--repack"); + cmdsList.add("--config-file=" + ConfigFile.getAbsolutePath()); + if (jre) { + cmdsList.add("--strip-debug"); + } + // NOTE: commented until 6965836 is fixed + // cmdsList.add("--code-attribute=StackMapTable=strip"); + cmdsList.add(f.getAbsolutePath()); + Utils.runExec(cmdsList); + } + } + + static void testJRE() throws IOException { + runPack200(true); + // the speciment JRE + List<String> cmdsList = new ArrayList<String>(); + cmdsList.add(javaCmd.getAbsolutePath()); + cmdsList.add("-verify"); + cmdsList.add("-version"); + Utils.runExec(cmdsList); + } + + static void testJDK() throws IOException { + runPack200(false); + // test the specimen JDK + List<String> cmdsList = new ArrayList<String>(); + cmdsList.add(javaCmd.getAbsolutePath()); + cmdsList.add("-verify"); + cmdsList.add("-version"); + Utils.runExec(cmdsList); + + // invoke javac to test the tools.jar + cmdsList.clear(); + cmdsList.add(javacCmd.getAbsolutePath()); + cmdsList.add("-J-verify"); + cmdsList.add("-help"); + Utils.runExec(cmdsList); + } + public static void main(String... args) { + try { + init(); + testJRE(); + testJDK(); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/pack200/Pack200Props.java Sun Aug 29 22:41:28 2010 -0700 @@ -0,0 +1,128 @@ +/* + * 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 6575373 6969063 + * @summary verify default properties of the packer/unpacker and segment limit + * @compile -XDignore.symbol.file Utils.java Pack200Props.java + * @run main Pack200Props + * @author ksrini + */ + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.jar.Pack200; +import java.util.jar.Pack200.Packer; + +/* + * Run this against a large jar file, by default the packer should generate only + * one segment, parse the output of the packer to verify if this is indeed true. + */ + +public class Pack200Props { + + public static void main(String... args) { + verifyDefaults(); + File out = new File("test" + Utils.PACK_FILE_EXT); + out.delete(); + verifySegmentLimit(out); + } + + static void verifySegmentLimit(File outFile) { + File sdkHome = Utils.JavaSDK; + File testJar = new File(new File(sdkHome, "lib"), "tools.jar"); + + System.out.println("using pack200: " + Utils.getPack200Cmd()); + + List<String> cmdsList = new ArrayList<>(); + cmdsList.add(Utils.getPack200Cmd()); + cmdsList.add("--effort=1"); + cmdsList.add("--verbose"); + cmdsList.add("--no-gzip"); + cmdsList.add(outFile.getName()); + cmdsList.add(testJar.getAbsolutePath()); + List<String> outList = Utils.runExec(cmdsList); + + int count = 0; + for (String line : outList) { + System.out.println(line); + if (line.matches(".*Transmitted.*files of.*input bytes in a segment of.*bytes")) { + count++; + } + } + if (count == 0) { + throw new RuntimeException("no segments or no output ????"); + } else if (count > 1) { + throw new RuntimeException("multiple segments detected, expected 1"); + } + } + + private static void verifyDefaults() { + Map<String, String> expectedDefaults = new HashMap<>(); + Packer p = Pack200.newPacker(); + expectedDefaults.put("com.sun.java.util.jar.pack.default.timezone", + p.FALSE); + expectedDefaults.put("com.sun.java.util.jar.pack.disable.native", + p.FALSE); + expectedDefaults.put("com.sun.java.util.jar.pack.verbose", "0"); + expectedDefaults.put(p.CLASS_ATTRIBUTE_PFX + "CompilationID", "RUH"); + expectedDefaults.put(p.CLASS_ATTRIBUTE_PFX + "SourceID", "RUH"); + expectedDefaults.put(p.CODE_ATTRIBUTE_PFX + "CharacterRangeTable", + "NH[PHPOHIIH]"); + expectedDefaults.put(p.CODE_ATTRIBUTE_PFX + "CoverageTable", + "NH[PHHII]"); + expectedDefaults.put(p.DEFLATE_HINT, p.KEEP); + expectedDefaults.put(p.EFFORT, "5"); + expectedDefaults.put(p.KEEP_FILE_ORDER, p.TRUE); + expectedDefaults.put(p.MODIFICATION_TIME, p.KEEP); + expectedDefaults.put(p.SEGMENT_LIMIT, "-1"); + expectedDefaults.put(p.UNKNOWN_ATTRIBUTE, p.PASS); + + Map<String, String> props = p.properties(); + int errors = 0; + for (String key : expectedDefaults.keySet()) { + String def = expectedDefaults.get(key); + String x = props.get(key); + if (x == null) { + System.out.println("Error: key not found:" + key); + errors++; + } else { + if (!def.equals(x)) { + System.out.println("Error: key " + key + + "\n value expected: " + def + + "\n value obtained: " + x); + errors++; + } + } + } + if (errors > 0) { + throw new RuntimeException(errors + + " error(s) encountered in default properties verification"); + } + } +} +
--- a/jdk/test/tools/pack200/Pack200Simple.sh Wed Jul 05 17:20:50 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,197 +0,0 @@ -# -# Copyright (c) 2003, 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 Pack200Simple.sh -# @bug 6521334 -# @build Pack200Test -# @run shell/timeout=1200 Pack200Simple.sh -# @summary An ad hoc test to verify class-file format. -# @author Kumar Srinivasan - -# The goal of this test is to assist javac or other developers -# who modify class file formats, to quickly test those modifications -# without having to build the install workspace. However it must -# be noted that building the install workspace is the only know -# way to prevent build breakages. - -# Pack200 developers could use this as a basic smoke-test, however -# please note, there are other more elaborate and thorough tests for -# this very purpose. - -# We try a potpouri of things ie. we have pack.conf to setup some -# options as well as a couple of command line options. We also test -# the packing and unpacking mechanism using the Java APIs. - -# print error and exit with a message -errorOut() { - if [ "x$1" = "x" ]; then - printf "Error: Unknown error\n" - else - printf "Error: %s\n" "$1" - fi - - exit 1 -} - -# Verify directory context variables are set -if [ "${TESTJAVA}" = "" ]; then - errorOut "TESTJAVA not set. Test cannot execute. Failed." -fi - -if [ "${TESTSRC}" = "" ]; then - errorOut "TESTSRC not set. Test cannot execute. Failed." -fi - - -if [ "${TESTCLASSES}" = "" ]; then - errorOut "TESTCLASSES not set. Test cannot execute. Failed." -fi - -# The common java utils we need -PACK200=${TESTJAVA}/bin/pack200 -UNPACK200=${TESTJAVA}/bin/unpack200 -JAR=${TESTJAVA}/bin/jar - -# For Windows and Linux needs the heap to be set, for others ergonomics -# will do the rest. It is important to use ea, which can expose class -# format errors much earlier than later. - -OS=`uname -s` - - -case "$OS" in - Windows*|CYGWIN* ) - PackOptions="-J-Xmx512m -J-ea" - break - ;; - - Linux ) - PackOptions="-J-Xmx512m -J-ea" - break - ;; - - * ) - PackOptions="-J-ea" - ;; -esac - -# Creates a packfile of choice expects 1 argument the filename -createConfigFile() { - # optimize for speed - printf "pack.effort=1\n" > $1 - # we DO want to know about new attributes - printf "pack.unknown.attribute=error\n" >> $1 - # optimize for speed - printf "pack.deflate.hint=false\n" >> $1 - # keep the ordering for easy compare - printf "pack.keep.class.order=true\n" >> $1 -} - - -# Tests a given jar, expects 1 argument the fully qualified -# name to a test jar, it writes all output to the current -# directory which is a scratch area. -testAJar() { - PackConf="pack.conf" - createConfigFile $PackConf - - # Try some command line options - CLIPackOptions="$PackOptions -v --no-gzip --segment-limit=10000 --config-file=$PackConf" - - jfName=`basename $1` - - ${PACK200} $CLIPackOptions ${jfName}.pack $1 > ${jfName}.pack.log 2>&1 - if [ $? != 0 ]; then - errorOut "$jfName packing failed" - fi - - # We want to test unpack200, therefore we dont use -r with pack - ${UNPACK200} -v ${jfName}.pack $jfName > ${jfName}.unpack.log 2>&1 - if [ $? != 0 ]; then - errorOut "$jfName unpacking failed" - fi - - # A quick crc compare test to ensure a well formed zip - # archive, this is a critical unpack200 behaviour. - - unzip -t $jfName > ${jfName}.unzip.log 2>&1 - if [ $? != 0 ]; then - errorOut "$jfName unzip -t test failed" - fi - - # The PACK200 signature should be at the top of the log - # this tag is critical for deployment related tools. - - head -5 ${jfName}.unzip.log | grep PACK200 > /dev/null 2>&1 - if [ $? != 0 ]; then - errorOut "$jfName PACK200 signature missing" - fi - - - # we know the size fields don't match, strip 'em out, its - # extremely important to ensure that the date stamps match up. - # Don't EVER sort the output we are checking for correct ordering. - - ${JAR} -tvf $1 | sed -e 's/^ *[0-9]* //g'> ${jfName}.ref.txt - ${JAR} -tvf $jfName | sed -e 's/^ *[0-9]* //g'> ${jfName}.cmp.txt - - diff ${jfName}.ref.txt ${jfName}.cmp.txt > ${jfName}.diff.log 2>&1 - if [ $? != 0 ]; then - errorOut "$jfName files missing" - fi -} - -# These JARs are the largest and also the most likely specimens to -# expose class format issues and stress the packer as well. - -JLIST="${TESTJAVA}/lib/tools.jar ${TESTJAVA}/jre/lib/rt.jar" - - -# Test the Command Line Interfaces (CLI). -mkdir cliTestDir -_pwd=`pwd` -cd cliTestDir - -for jarfile in $JLIST ; do - if [ -f $jarfile ]; then - testAJar $jarfile - else - errorOut "Error: '$jarFile' does not exist\nTest requires a j2sdk-image\n" - fi -done -cd $_pwd - -# Test the Java APIs. -mkdir apiTestDir -_pwd=`pwd` -cd apiTestDir - -# Strip out the -J prefixes. -JavaPackOptions=`printf %s "$PackOptions" | sed -e 's/-J//g'` - -# Test the Java APIs now. -$TESTJAVA/bin/java $JavaPackOptions -cp $TESTCLASSES Pack200Test $JLIST || exit 1 - -cd $_pwd - -exit 0
--- a/jdk/test/tools/pack200/Pack200Test.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/test/tools/pack200/Pack200Test.java Sun Aug 29 22:41:28 2010 -0700 @@ -24,111 +24,97 @@ import java.util.*; import java.io.*; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryMXBean; import java.util.jar.*; -import java.util.zip.*; -/* - * Pack200Test.java - * - * @author ksrini - */ + /* + * @test + * @bug 6521334 6712743 + * @summary check for memory leaks, test general packer/unpacker functionality\ + * using native and java unpackers + * @compile -XDignore.symbol.file Utils.java Pack200Test.java + * @run main/othervm/timeout=1200 -Xmx512m Pack200Test + * @author ksrini + */ /** - * These tests are very rudimentary smoke tests to ensure that the packing - * unpacking process works on a select set of JARs. + * Tests the packing/unpacking via the APIs. */ public class Pack200Test { private static ArrayList <File> jarList = new ArrayList<File>(); - static final String PACKEXT = ".pack"; + static final MemoryMXBean mmxbean = ManagementFactory.getMemoryMXBean(); + static final long m0 = getUsedMemory(); + static final int LEAK_TOLERANCE = 20000; // OS and GC related variations. /** Creates a new instance of Pack200Test */ private Pack200Test() {} - private static void doPackUnpack() { - for (File in : jarList) { - Pack200.Packer packer = Pack200.newPacker(); - Map<String, String> 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"); - // throw an error if an attribute is unrecognized - p.put(packer.UNKNOWN_ATTRIBUTE, packer.ERROR); - // 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); - - try { - JarFile jarFile = new JarFile(in); - - // Write out to a jtreg scratch area - FileOutputStream fos = new FileOutputStream(in.getName() + PACKEXT); + static long getUsedMemory() { + mmxbean.gc(); + mmxbean.gc(); + mmxbean.gc(); + return mmxbean.getHeapMemoryUsage().getUsed()/1024; + } - System.out.print("Packing [" + in.toString() + "]..."); - // Call the packer - packer.pack(jarFile, fos); - jarFile.close(); - fos.close(); - - System.out.print("Unpacking..."); - File f = new File(in.getName() + PACKEXT); - - // Write out to current directory, jtreg will setup a scratch area - JarOutputStream jostream = new JarOutputStream(new FileOutputStream(in.getName())); - - // Unpack the files - Pack200.Unpacker unpacker = Pack200.newUnpacker(); - // Call the unpacker - unpacker.unpack(f, jostream); - // Must explicitly close the output. - jostream.close(); - System.out.print("Testing..."); - // Ok we have unpacked the file, lets test it. - doTest(in); - System.out.println("Done."); - } catch (Exception e) { - System.out.println("ERROR: " + e.getMessage()); - System.exit(1); - } + private static void leakCheck() throws Exception { + long diff = getUsedMemory() - m0; + System.out.println(" Info: memory diff = " + diff + "K"); + if ( diff > LEAK_TOLERANCE) { + throw new Exception("memory leak detected " + diff); } } - private static ArrayList <String> getZipFileEntryNames(ZipFile z) { - ArrayList <String> out = new ArrayList<String>(); - for (ZipEntry ze : Collections.list(z.entries())) { - out.add(ze.getName()); - } - return out; - } + private static void doPackUnpack() { + for (File in : jarList) { + JarOutputStream javaUnpackerStream = null; + JarOutputStream nativeUnpackerStream = null; + JarFile jarFile = null; + try { + jarFile = new JarFile(in); - private static void doTest(File in) throws Exception { - // make sure all the files in the original jar exists in the other - ArrayList <String> refList = getZipFileEntryNames(new ZipFile(in)); - ArrayList <String> cmpList = getZipFileEntryNames(new ZipFile(in.getName())); + // Write out to a jtreg scratch area + File packFile = new File(in.getName() + Utils.PACK_FILE_EXT); - System.out.print(refList.size() + "/" + cmpList.size() + " entries..."); + System.out.println("Packing [" + in.toString() + "]"); + // Call the packer + Utils.pack(jarFile, packFile); + jarFile.close(); + leakCheck(); - if (refList.size() != cmpList.size()) { - throw new Exception("Missing: files ?, entries don't match"); - } + System.out.println(" Unpacking using java unpacker"); + File javaUnpackedJar = new File("java-" + in.getName()); + // Write out to current directory, jtreg will setup a scratch area + javaUnpackerStream = new JarOutputStream( + new FileOutputStream(javaUnpackedJar)); + Utils.unpackj(packFile, javaUnpackerStream); + javaUnpackerStream.close(); + System.out.println(" Testing...java unpacker"); + leakCheck(); + // Ok we have unpacked the file, lets test it. + Utils.doCompareVerify(in.getAbsoluteFile(), javaUnpackedJar); - for (String ename: refList) { - if (!cmpList.contains(ename)) { - throw new Exception("Does not contain : " + ename); - } - } - } - - private static void doSanity(String[] args) { - for (String s: args) { - File f = new File(s); - if (f.exists()) { - jarList.add(f); - } else { - System.out.println("Warning: The JAR file " + f.toString() + " does not exist,"); - System.out.println(" this test requires a JDK image, this file will be skipped."); + System.out.println(" Unpacking using native unpacker"); + // Write out to current directory + File nativeUnpackedJar = new File("native-" + in.getName()); + nativeUnpackerStream = new JarOutputStream( + new FileOutputStream(nativeUnpackedJar)); + Utils.unpackn(packFile, nativeUnpackerStream); + nativeUnpackerStream.close(); + System.out.println(" Testing...native unpacker"); + leakCheck(); + // the unpackers (native and java) should produce identical bits + // so we use use bit wise compare, the verification compare is + // very expensive wrt. time. + Utils.doCompareBitWise(javaUnpackedJar, nativeUnpackedJar); + System.out.println("Done."); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + Utils.close(nativeUnpackerStream); + Utils.close(javaUnpackerStream); + Utils.close((Closeable) jarFile); } } } @@ -137,11 +123,12 @@ * @param args the command line arguments */ public static void main(String[] args) { - if (args.length < 1) { - System.out.println("Usage: jar1 jar2 jar3 ....."); - System.exit(1); - } - doSanity(args); + // select the jars carefully, adding more jars will increase the + // testing time, especially for jprt. + jarList.add(Utils.locateJar("tools.jar")); + jarList.add(Utils.locateJar("rt.jar")); + jarList.add(Utils.locateJar("golden.jar")); + System.out.println(jarList); doPackUnpack(); } }
--- a/jdk/test/tools/pack200/PackageVersionTest.java Wed Jul 05 17:20:50 2017 +0200 +++ b/jdk/test/tools/pack200/PackageVersionTest.java Sun Aug 29 22:41:28 2010 -0700 @@ -22,13 +22,14 @@ * questions. */ -/** - * @test - * @bug 6712743 - * @summary verify package versioning - * @compile -XDignore.symbol.file PackageVersionTest.java - * @run main PackageVersionTest - */ +/* + * @test + * @bug 6712743 + * @summary verify package versions + * @compile -XDignore.symbol.file Utils.java PackageVersionTest.java + * @run main PackageVersionTest + * @author ksrini + */ import java.io.ByteArrayOutputStream; import java.io.Closeable; @@ -74,14 +75,6 @@ JAVA5_PACKAGE_MINOR_VERSION); } - static void close(Closeable c) { - if (c == null) { - return; - } - try { - c.close(); - } catch (IOException ignore) {} - } static void createClassFile(String name) { createJavaFile(name); @@ -93,7 +86,7 @@ name.substring(name.length() - 1), name + ".java" }; - compileJava(javacCmds); + Utils.compiler(javacCmds); } static void createJavaFile(String name) { @@ -108,22 +101,8 @@ } catch (IOException ioe) { throw new RuntimeException("creation of test file failed"); } finally { - close(ps); - close(fos); - } - } - - static void compileJava(String... javacCmds) { - if (com.sun.tools.javac.Main.compile(javacCmds) != 0) { - throw new RuntimeException("compilation failed"); - } - } - - static void makeJar(String... jargs) { - sun.tools.jar.Main jarTool = - new sun.tools.jar.Main(System.out, System.err, "jartool"); - if (!jarTool.run(jargs)) { - throw new RuntimeException("jar command failed"); + Utils.close(ps); + Utils.close(fos); } } @@ -136,7 +115,7 @@ jarFileName.getName(), filename }; - makeJar(jargs); + Utils.jar(jargs); JarFile jfin = null; try { @@ -163,7 +142,7 @@ } catch (IOException ioe) { throw new RuntimeException(ioe.getMessage()); } finally { - close(jfin); + Utils.close((Closeable) jfin); } } }
--- a/jdk/test/tools/pack200/SegmentLimit.java Wed Jul 05 17:20:50 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,134 +0,0 @@ -/* - * 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 6575373 - * @summary verify default segment limit - * @compile SegmentLimit.java - * @run main SegmentLimit - */ - -import java.io.BufferedReader; -import java.io.Closeable; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintStream; - -/* - * Run this against a large jar file, by default the packer should generate only - * one segment, parse the output of the packer to verify if this is indeed true. - */ - -public class SegmentLimit { - - private static final File javaHome = new File(System.getProperty("java.home")); - - public static void main(String... args) { - if (!javaHome.getName().endsWith("jre")) { - throw new RuntimeException("Error: requires an SDK to run"); - } - - File out = new File("test" + Pack200Test.PACKEXT); - out.delete(); - runPack200(out); - } - - static void close(Closeable c) { - if (c == null) { - return; - } - try { - c.close(); - } catch (IOException ignore) {} - } - - static void runPack200(File outFile) { - File binDir = new File(javaHome, "bin"); - File pack200Exe = System.getProperty("os.name").startsWith("Windows") - ? new File(binDir, "pack200.exe") - : new File(binDir, "pack200"); - File sdkHome = javaHome.getParentFile(); - File testJar = new File(new File(sdkHome, "lib"), "tools.jar"); - - System.out.println("using pack200: " + pack200Exe.getAbsolutePath()); - - String[] cmds = { pack200Exe.getAbsolutePath(), - "--effort=1", - "--verbose", - "--no-gzip", - outFile.getName(), - testJar.getAbsolutePath() - }; - InputStream is = null; - BufferedReader br = null; - InputStreamReader ir = null; - - FileOutputStream fos = null; - PrintStream ps = null; - - try { - ProcessBuilder pb = new ProcessBuilder(cmds); - pb.redirectErrorStream(true); - Process p = pb.start(); - is = p.getInputStream(); - ir = new InputStreamReader(is); - br = new BufferedReader(ir); - - File logFile = new File("pack200.log"); - fos = new FileOutputStream(logFile); - ps = new PrintStream(fos); - - String line = br.readLine(); - int count = 0; - while (line != null) { - line = line.trim(); - if (line.matches(".*Transmitted.*files of.*input bytes in a segment of.*bytes")) { - count++; - } - ps.println(line); - line=br.readLine(); - } - p.waitFor(); - if (p.exitValue() != 0) { - throw new RuntimeException("pack200 failed"); - } - p.destroy(); - if (count > 1) { - throw new Error("test fails: check for multiple segments(" + - count + ") in: " + logFile.getAbsolutePath()); - } - } catch (IOException ex) { - throw new RuntimeException(ex.getMessage()); - } catch (InterruptedException ignore){ - } finally { - close(is); - close(ps); - close(fos); - } - } -} -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/pack200/TimeStamp.java Sun Aug 29 22:41:28 2010 -0700 @@ -0,0 +1,156 @@ +/* + * 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.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.TimeZone; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; + +/* + * @test + * @bug 6966740 + * @summary verify identical timestamps, unpacked in any timezone + * @compile -XDignore.symbol.file Utils.java TimeStamp.java + * @run main/othervm TimeStamp + * @author ksrini + */ + +/** + * First we pack the file in some time zone say India, then we unpack the file + * in the current time zone, and ensure the timestamp recorded in the unpacked + * jar are the same. + */ +public class TimeStamp { + static final TimeZone tz = TimeZone.getDefault(); + + + public static void main(String... args) throws IOException { + + // make a local copy of our test file + File srcFile = Utils.locateJar("golden.jar"); + File goldenFile = new File("golden.jar"); + Utils.copyFile(srcFile, goldenFile.getAbsoluteFile()); + + JarFile goldenJarFile = new JarFile(goldenFile); + File packFile = new File("golden.pack"); + + // set the test timezone and pack the file + TimeZone.setDefault(TimeZone.getTimeZone("IST")); + Utils.pack(goldenJarFile, packFile); + TimeZone.setDefault(tz); // reset the timezone + + // unpack in the test timezone + File istFile = new File("golden.jar.java.IST"); + unpackJava(packFile, istFile); + verifyJar(goldenFile, istFile); + istFile.delete(); + + // unpack in some other timezone + File pstFile = new File("golden.jar.java.PST"); + unpackJava(packFile, pstFile); + verifyJar(goldenFile, pstFile); + pstFile.delete(); + + // repeat the test for unpack200 tool. + istFile = new File("golden.jar.native.IST"); + unpackNative(packFile, istFile); + verifyJar(goldenFile, istFile); + istFile.delete(); + + pstFile = new File("golden.jar.native.PST"); + unpackNative(packFile, pstFile); + verifyJar(goldenFile, pstFile); + pstFile.delete(); + } + + static void unpackNative(File packFile, File outFile) { + String name = outFile.getName(); + String tzname = name.substring(name.lastIndexOf(".") + 1); + HashMap<String, String> env = new HashMap<>(); + switch(tzname) { + case "PST": + env.put("TZ", "US/Pacific"); + break; + case "IST": + env.put("TZ", "Asia/Calcutta"); + break; + default: + throw new RuntimeException("not implemented: " + tzname); + } + List<String> cmdsList = new ArrayList<>(); + cmdsList.add(Utils.getUnpack200Cmd()); + cmdsList.add(packFile.getName()); + cmdsList.add(outFile.getName()); + Utils.runExec(cmdsList, env); + } + + static void unpackJava(File packFile, File outFile) throws IOException { + String name = outFile.getName(); + String tzname = name.substring(name.lastIndexOf(".") + 1); + JarOutputStream jos = null; + try { + TimeZone.setDefault(TimeZone.getTimeZone(tzname)); + jos = new JarOutputStream(new FileOutputStream(outFile)); + System.out.println("Using timezone: " + TimeZone.getDefault()); + Utils.unpackj(packFile, jos); + } finally { + Utils.close(jos); + TimeZone.setDefault(tz); // always reset + } + } + + static void verifyJar(File f1, File f2) throws IOException { + int errors = 0; + JarFile jf1 = null; + JarFile jf2 = null; + try { + jf1 = new JarFile(f1); + jf2 = new JarFile(f2); + System.out.println("Verifying: " + f1 + " and " + f2); + for (JarEntry je1 : Collections.list(jf1.entries())) { + JarEntry je2 = jf2.getJarEntry(je1.getName()); + if (je1.getTime() != je2.getTime()) { + System.out.println("Error:"); + System.out.println(" expected:" + jf1.getName() + ":" + + je1.getName() + ":" + je1.getTime()); + System.out.println(" obtained:" + jf2.getName() + ":" + + je2.getName() + ":" + je2.getTime()); + errors++; + } + } + } finally { + Utils.close(jf1); + Utils.close(jf2); + } + if (errors > 0) { + throw new RuntimeException("FAIL:" + errors + " error(s) encounted"); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/pack200/UnpackerMemoryTest.java Sun Aug 29 22:41:28 2010 -0700 @@ -0,0 +1,86 @@ +/* + * 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 6531345 + * @summary check for unpacker memory leaks + * @compile -XDignore.symbol.file Utils.java UnpackerMemoryTest.java + * @run main/othervm/timeout=1200 -Xmx32m UnpackerMemoryTest + * @author ksrini + */ + +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.io.IOException; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; + +public class UnpackerMemoryTest { + + private static void createPackFile(File packFile) throws IOException { + File tFile = new File("test.dat"); + FileOutputStream fos = null; + PrintStream ps = null; + String jarFileName = Utils.baseName(packFile, Utils.PACK_FILE_EXT) + + Utils.JAR_FILE_EXT; + JarFile jarFile = null; + try { + fos = new FileOutputStream(tFile); + ps = new PrintStream(fos); + ps.println("A quick brown fox"); + Utils.jar("cvf", jarFileName, tFile.getName()); + jarFile = new JarFile(jarFileName); + Utils.pack(jarFile, packFile); + } finally { + Utils.close(ps); + tFile.delete(); + Utils.close(jarFile); + } + } + + public static void main(String[] args) throws Exception { + String name = "foo"; + File packFile = new File(name + Utils.PACK_FILE_EXT); + createPackFile(packFile); + if (!packFile.exists()) { + throw new RuntimeException(packFile + " not found"); + } + File jarOut = new File(name + ".out"); + for (int i = 0; i < 2000; i++) { + JarOutputStream jarOS = null; + FileOutputStream fos = null; + try { + fos = new FileOutputStream(jarOut); + jarOS = new JarOutputStream(fos); + System.out.println("Unpacking[" + i + "]" + packFile); + Utils.unpackn(packFile, jarOS); + } finally { + Utils.close(jarOS); + Utils.close(fos); + } + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/pack200/Utils.java Sun Aug 29 22:41:28 2010 -0700 @@ -0,0 +1,516 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.nio.channels.FileChannel; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; +import java.util.jar.Pack200; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +/** + * + * @author ksrini + */ + +/* + * This class contains all the commonly used utilities used by various tests + * in this directory. + */ +class Utils { + static final String JavaHome = System.getProperty("test.java", + System.getProperty("java.home")); + static final boolean IsWindows = + System.getProperty("os.name").startsWith("Windows"); + static final boolean Is64Bit = + System.getProperty("sun.arch.data.model", "32").equals("64"); + static final File JavaSDK = new File(JavaHome).getParentFile(); + + static final String PACK_FILE_EXT = ".pack"; + static final String JAVA_FILE_EXT = ".java"; + static final String CLASS_FILE_EXT = ".class"; + static final String JAR_FILE_EXT = ".jar"; + + static final File TEST_SRC_DIR = new File(System.getProperty("test.src")); + static final String VERIFIER_DIR_NAME = "pack200-verifier"; + static final File VerifierJar = new File(VERIFIER_DIR_NAME + JAR_FILE_EXT); + + private Utils() {} // all static + + static { + if (!JavaHome.endsWith("jre")) { + throw new RuntimeException("Error: requires an SDK to run"); + } + } + + private static void init() throws IOException { + if (VerifierJar.exists()) { + return; + } + File srcDir = new File(TEST_SRC_DIR, VERIFIER_DIR_NAME); + List<File> javaFileList = findFiles(srcDir, createFilter(JAVA_FILE_EXT)); + File tmpFile = File.createTempFile("javac", ".tmp"); + File classesDir = new File("xclasses"); + classesDir.mkdirs(); + FileOutputStream fos = null; + PrintStream ps = null; + try { + fos = new FileOutputStream(tmpFile); + ps = new PrintStream(fos); + for (File f : javaFileList) { + ps.println(f.getAbsolutePath()); + } + } finally { + close(ps); + close(fos); + } + + compiler("-d", + "xclasses", + "@" + tmpFile.getAbsolutePath()); + + jar("cvfe", + VerifierJar.getName(), + "sun.tools.pack.verify.Main", + "-C", + "xclasses", + "."); + } + + static void dirlist(File dir) { + File[] files = dir.listFiles(); + System.out.println("--listing " + dir.getAbsolutePath() + "---"); + for (File f : files) { + StringBuffer sb = new StringBuffer(); + sb.append(f.isDirectory() ? "d " : "- "); + sb.append(f.getName()); + System.out.println(sb); + } + } + static void doCompareVerify(File reference, File specimen) throws IOException { + init(); + List<String> cmds = new ArrayList<String>(); + cmds.add(getJavaCmd()); + cmds.add("-jar"); + cmds.add(VerifierJar.getName()); + cmds.add(reference.getAbsolutePath()); + cmds.add(specimen.getAbsolutePath()); + cmds.add("-O"); + runExec(cmds); + } + + static void doCompareBitWise(File reference, File specimen) + throws IOException { + init(); + List<String> cmds = new ArrayList<String>(); + cmds.add(getJavaCmd()); + cmds.add("-jar"); + cmds.add(VerifierJar.getName()); + cmds.add(reference.getName()); + cmds.add(specimen.getName()); + cmds.add("-O"); + cmds.add("-b"); + runExec(cmds); + } + + static FileFilter createFilter(final String extension) { + return new FileFilter() { + @Override + public boolean accept(File pathname) { + String name = pathname.getName(); + if (name.endsWith(extension)) { + return true; + } + return false; + } + }; + } + + static final FileFilter DIR_FILTER = new FileFilter() { + public boolean accept(File pathname) { + if (pathname.isDirectory()) { + return true; + } + return false; + } + }; + + static final FileFilter FILE_FILTER = new FileFilter() { + public boolean accept(File pathname) { + if (pathname.isFile()) { + return true; + } + return false; + } + }; + + private static void setFileAttributes(File src, File dst) throws IOException { + dst.setExecutable(src.canExecute()); + dst.setReadable(src.canRead()); + dst.setWritable(src.canWrite()); + dst.setLastModified(src.lastModified()); + } + + static void copyFile(File src, File dst) throws IOException { + if (src.isDirectory()) { + dst.mkdirs(); + setFileAttributes(src, dst); + return; + } else { + File baseDirFile = dst.getParentFile(); + if (!baseDirFile.exists()) { + baseDirFile.mkdirs(); + } + } + FileInputStream in = null; + FileOutputStream out = null; + FileChannel srcChannel = null; + FileChannel dstChannel = null; + try { + in = new FileInputStream(src); + out = new FileOutputStream(dst); + srcChannel = in.getChannel(); + dstChannel = out.getChannel(); + + long retval = srcChannel.transferTo(0, src.length(), dstChannel); + if (src.length() != dst.length()) { + throw new IOException("file copy failed for " + src); + } + } finally { + close(srcChannel); + close(dstChannel); + close(in); + close(out); + } + setFileAttributes(src, dst); + } + + static String baseName(File file, String extension) { + return baseName(file.getAbsolutePath(), extension); + } + + static String baseName(String name, String extension) { + int cut = name.length() - extension.length(); + return name.lastIndexOf(extension) == cut + ? name.substring(0, cut) + : name; + + } + + /* + * Suppose a path is provided which consists of a full path + * this method returns the sub path for a full path ex: /foo/bar/baz/foobar.z + * and the base path is /foo/bar it will will return baz/foobar.z. + */ + private static String getEntryPath(String basePath, String fullPath) { + if (!fullPath.startsWith(basePath)) { + return null; + } + return fullPath.substring(basePath.length()); + } + + static String getEntryPath(File basePathFile, File fullPathFile) { + return getEntryPath(basePathFile.toString(), fullPathFile.toString()); + } + + public static void recursiveCopy(File src, File dest) throws IOException { + if (!src.exists() || !src.canRead()) { + throw new IOException("file not found or readable: " + src); + } + if (dest.exists() && !dest.isDirectory() && !dest.canWrite()) { + throw new IOException("file not found or writeable: " + dest); + } + if (!dest.exists()) { + dest.mkdirs(); + } + List<File> a = directoryList(src); + for (File f : a) { + copyFile(f, new File(dest, getEntryPath(src, f))); + } + } + + static List<File> directoryList(File dirname) { + List<File> dirList = new ArrayList<File>(); + return directoryList(dirname, dirList, null); + } + + private static List<File> directoryList(File dirname, List<File> dirList, + File[] dirs) { + dirList.addAll(Arrays.asList(dirname.listFiles(FILE_FILTER))); + dirs = dirname.listFiles(DIR_FILTER); + for (File f : dirs) { + if (f.isDirectory() && !f.equals(dirname)) { + dirList.add(f); + directoryList(f, dirList, dirs); + } + } + return dirList; + } + + static void recursiveDelete(File dir) throws IOException { + if (dir.isFile()) { + dir.delete(); + } else if (dir.isDirectory()) { + File[] entries = dir.listFiles(); + for (int i = 0; i < entries.length; i++) { + if (entries[i].isDirectory()) { + recursiveDelete(entries[i]); + } + entries[i].delete(); + } + dir.delete(); + } + } + + static List<File> findFiles(File startDir, FileFilter filter) + throws IOException { + List<File> list = new ArrayList<File>(); + findFiles0(startDir, list, filter); + return list; + } + /* + * finds files in the start directory using the the filter, appends + * the files to the dirList. + */ + private static void findFiles0(File startDir, List<File> list, + FileFilter filter) throws IOException { + File[] foundFiles = startDir.listFiles(filter); + list.addAll(Arrays.asList(foundFiles)); + File[] dirs = startDir.listFiles(DIR_FILTER); + for (File dir : dirs) { + findFiles0(dir, list, filter); + } + } + + static void close(Closeable c) { + if (c == null) { + return; + } + try { + c.close(); + } catch (IOException ignore) { + } + } + + static void compiler(String... javacCmds) { + if (com.sun.tools.javac.Main.compile(javacCmds) != 0) { + throw new RuntimeException("compilation failed"); + } + } + + static void jar(String... jargs) { + sun.tools.jar.Main jarTool = + new sun.tools.jar.Main(System.out, System.err, "jartool"); + if (!jarTool.run(jargs)) { + throw new RuntimeException("jar command failed"); + } + } + + // given a jar file foo.jar will write to foo.pack + static void pack(JarFile jarFile, File packFile) throws IOException { + Pack200.Packer packer = Pack200.newPacker(); + Map<String, String> 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); + FileOutputStream fos = null; + try { + // Write out to a jtreg scratch area + fos = new FileOutputStream(packFile); + // Call the packer + packer.pack(jarFile, fos); + } finally { + close(fos); + } + } + + // uses java unpacker, slow but useful to discover issues with the packer + static void unpackj(File inFile, JarOutputStream jarStream) + throws IOException { + unpack0(inFile, jarStream, true); + + } + + // uses native unpacker using the java APIs + static void unpackn(File inFile, JarOutputStream jarStream) + throws IOException { + unpack0(inFile, jarStream, false); + } + + // given a packed file, create the jar file in the current directory. + private static void unpack0(File inFile, JarOutputStream jarStream, + boolean useJavaUnpack) throws IOException { + // Unpack the files + Pack200.Unpacker unpacker = Pack200.newUnpacker(); + Map<String, String> props = unpacker.properties(); + if (useJavaUnpack) { + props.put("com.sun.java.util.jar.pack.disable.native", "true"); + } + // Call the unpacker + unpacker.unpack(inFile, jarStream); + } + + static byte[] getBuffer(ZipFile zf, ZipEntry ze) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte buf[] = new byte[8192]; + InputStream is = null; + try { + is = zf.getInputStream(ze); + int n = is.read(buf); + while (n > 0) { + baos.write(buf, 0, n); + n = is.read(buf); + } + return baos.toByteArray(); + } finally { + close(is); + } + } + + static ArrayList<String> getZipFileEntryNames(ZipFile z) { + ArrayList<String> out = new ArrayList<String>(); + for (ZipEntry ze : Collections.list(z.entries())) { + out.add(ze.getName()); + } + return out; + } + static List<String> runExec(List<String> cmdsList) { + return runExec(cmdsList, null); + } + static List<String> runExec(List<String> cmdsList, Map<String, String> penv) { + ArrayList<String> alist = new ArrayList<String>(); + ProcessBuilder pb = + new ProcessBuilder(cmdsList); + Map<String, String> env = pb.environment(); + if (penv != null && !penv.isEmpty()) { + env.putAll(penv); + } + pb.directory(new File(".")); + dirlist(new File(".")); + for (String x : cmdsList) { + System.out.print(x + " "); + } + System.out.println(""); + int retval = 0; + Process p = null; + InputStreamReader ir = null; + BufferedReader rd = null; + InputStream is = null; + try { + pb.redirectErrorStream(true); + p = pb.start(); + is = p.getInputStream(); + ir = new InputStreamReader(is); + rd = new BufferedReader(ir, 8192); + + String in = rd.readLine(); + while (in != null) { + alist.add(in); + System.out.println(in); + in = rd.readLine(); + } + retval = p.waitFor(); + if (retval != 0) { + throw new RuntimeException("process failed with non-zero exit"); + } + } catch (Exception ex) { + throw new RuntimeException(ex.getMessage()); + } finally { + close(rd); + close(ir); + close(is); + if (p != null) { + p.destroy(); + } + } + return alist; + } + + static String getUnpack200Cmd() { + return getAjavaCmd("unpack200"); + } + + static String getPack200Cmd() { + return getAjavaCmd("pack200"); + } + + static String getJavaCmd() { + return getAjavaCmd("java"); + } + + static String getAjavaCmd(String cmdStr) { + File binDir = new File(JavaHome, "bin"); + File unpack200File = IsWindows + ? new File(binDir, cmdStr + ".exe") + : new File(binDir, cmdStr); + + String cmd = unpack200File.getAbsolutePath(); + if (!unpack200File.canExecute()) { + throw new RuntimeException("please check" + + cmd + " exists and is executable"); + } + return cmd; + } + + private static List<File> locaterCache = null; + // search the source dir and jdk dir for requested file and returns + // the first location it finds. + static File locateJar(String name) { + try { + if (locaterCache == null) { + locaterCache = new ArrayList<File>(); + locaterCache.addAll(findFiles(TEST_SRC_DIR, createFilter(JAR_FILE_EXT))); + locaterCache.addAll(findFiles(JavaSDK, createFilter(JAR_FILE_EXT))); + } + for (File f : locaterCache) { + if (f.getName().equals(name)) { + return f; + } + } + throw new IOException("file not found: " + name); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/pack200/pack200-verifier/data/README Sun Aug 29 22:41:28 2010 -0700 @@ -0,0 +1,45 @@ +The files contained in the golden.jar have been harvested from many +different sources, some are hand-crafted invalid class files (odds directory), +or from random JDK builds. + +Generally these files serve to ensure the integrity of the packer and unpacker +by,